Думается мне что здесь проблема - вынеси обработку Web/MQTT из этого условия - должно реагировать получше. Мне приехали мои ESPшки - буду собирать свой ОТ контроллер, на этой же базе - в 2 головы глядишь и интереснее пойдет.
OldNavi, нет, не помогает. Весь код, что в условии, что за его пределми - 1сек. Как только комментирую ot.begin(handleInterrupt); сервера летают, датчик тоже, но ОТ не работает.
обработка прерываний не должна брать много - код под вопросмо что я вижу в библиотеке openterm - это sendRequest()
unsigned long OpenTherm::sendRequest(unsigned long request)
{
if (!sendRequestAync(request)) return 0;
while (!isReady()) {
process();
yield();
}
return response;
}
Закоментируй
ot.sendRequest(request); в loop() и посмотри на поведение, если залетает (но ОТ не будет работать)
то вижу несколько вариантов
1/ Воспользоваться processResponseCallback(). который передаешь в конструкторе и там добавлять обработку
2/ использовать sendRequestAsync() и прописать свой while(!isRead) {} цикл
Ну и видится проблема в том, что ты заспамил шину ОТ запросами (а запрос ответ может быть до 1сек согласно спецификации).
У тебя в кажом начале цикла есть - вызов setBolierStatus() который в в ответе уже дает много флагов статуса (есть ошибка или нет, включена горелка и т.д.) см спецификацию протокола
Дальше этот код можно наверное утащить в setup() и если что дергать при реконекте
// Записать ID-2; мастер-код MemberID
unsigned int data = 0x0004;
unsigned long request = ot.buildRequest(OpenThermRequestType::WRITE, OpenThermMessageID::MConfigMMemberIDcode, data);
ot.sendRequest(request);
Которые внутри шлют новые запросы по ОТ, как пример
unsigned long getCentralHeatingEnabled() {
unsigned long response = ot.setBoilerStatus(enableCentralHeating, enableHotWater, enableCooling);
OpenThermResponseStatus responseStatus = ot.getLastResponseStatus();
if (responseStatus = OpenThermResponseStatus::SUCCESS)
return ot.isCentralHeatingActive(response);
}
ну и так далее... Вообщем ИМХО тут есть место для оптимизации ибо сам ОТ протокол ну очень медленный -
Bit rate : 1000 bits/sec nominal - по сути 15 сообщений максимум по ОТ за секунду (сообщение + ответ = 64 бита) - и каждый посыл блокирующий
ИМХО тут надо и цикл оптимизировать и разводить запросы по времени набирая полный набор параметров секунд за 10 - примерно как в tasmota сделано. Желание знать актуальную температуру каждую секунду похвально - но бессмыслено - она и раз за минуту не изменится. ну и тд и тп.
Сейчас на полный цикл обработки данных уходит 10-12 сек. Оригинальный код автора библиотеки http://ihormelnyk.com/mqtt_thermostat кушает на треть меньше. но там и данных меньше. Про код с ID2, что его можно в setup(), не прокатывает, а без него мой котёл только мониторится, а вот отправлять код каждые раз в 50 секунд вполне (тут надо покопаться в инфе, фигурируют цифры 40 и 20 сек.). Если котёл в течении этого времени не получит кода подтверждения из ID3 режим ОТ отключается, термостат только мониторит и то не всё. Другим котлам это по барабану. В любом случае сама библиотека ОТ вызывает вопросы.
Я полазил по коду библиотеки - он впринципе нормально реализован, из минусов он только работает нормально под core 2.3.0 - под 2.5.2 падает. Но не суть - проблема таже - sendRequest() это синхронный запрос и он может возвращать данные до 1 секунды. 2-я проблема - это спамминг шины ОТ - если читать спецификацию то следующий запрос можно делать не ранее чем через 100 милисекунд после последнего ответа. Думается мне, что я попробую реализацию через шедуллер с 2-мя тасками через https://www.arduinolibraries.info/libraries/esp8266-scheduler - в одном будет коммуникация с ОТ через библиотеку с таймингами, во второй таске уже MQTT и Вебсервак с блекджеком и б..ми. Но это пока не скоро - надо платку согласования еще распаять.
void loop(void) {
new_ts = millis();
if (new_ts - ts > 1000) {
unsigned long response = ot.setBoilerStatus(enableCentralHeating, enableHotWater, enableCooling, enableOutsideTemperatureCompensation, enableCentralHeating2);
OpenThermResponseStatus responseStatus = ot.getLastResponseStatus();
//=============================================================================================
// Оператор switch сравнивает значение переменной со значением, определенном в операторах case.
// Когда найден оператор case, значение которого равно значению переменной, выполняется
// программный код в этом операторе.
//=============================================================================================
int step = loop_counter++;
switch (step) {
case 0:
if (responseStatus == OpenThermResponseStatus::SUCCESS) {
//=======================================================================================
// Эта группа элементов данных определяет информацию о конфигурации как на ведомых, так
// и на главных сторонах. Каждый из них имеет группу флагов конфигурации (8 бит)
// и код MemberID (1 байт). Перед передачей информации об управлении и состоянии
// рекомендуется обмен сообщениями о допустимой конфигурации ведомого устройства
// чтения и основной конфигурации записи. Нулевой код MemberID означает клиентское
// неспецифическое устройство. Номер/тип версии продукта следует использовать в сочетании
// с "кодом идентификатора участника", который идентифицирует производителя устройства.
//=======================================================================================
unsigned long request3 = ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::SConfigSMemberIDcode, 0xFFFF);
unsigned long respons3 = ot.sendRequest(request3);
uint8_t SlaveMemberIDcode = respons3 >> 0 & 0xFF;
unsigned long request2 = ot.buildRequest(OpenThermRequestType::WRITE, OpenThermMessageID::MConfigMMemberIDcode, SlaveMemberIDcode);
unsigned long respons2 = ot.sendRequest(request2);
unsigned long request127 = ot.buildRequest(OpenThermRequestType::READ, OpenThermMessageID::SlaveVersion, 0);
unsigned long respons127 = ot.sendRequest(request127);
uint16_t dataValue127_type = respons127 & 0xFFFF;
uint8_t dataValue127_num = respons127 & 0xFF;
unsigned result127_type = dataValue127_type / 256;
unsigned result127_num = dataValue127_num;
unsigned long request126 = ot.buildRequest(OpenThermRequestType::WRITE, OpenThermMessageID::MasterVersion, 0x013F);
unsigned long respons126 = ot.sendRequest(request126);
uint16_t dataValue126_type = respons126 & 0xFFFF;
uint8_t dataValue126_num = respons126 & 0xFF;
unsigned result126_type = dataValue126_type / 256;
unsigned result126_num = dataValue126_num;
Serial.println("Тип и версия термостата: тип " + String(result126_type) + ", версия " + String(result126_num));
Serial.println("Тип и версия котла: тип " + String(result127_type) + ", версия " + String(result127_num));
}
break;
case 1:
if (responseStatus == OpenThermResponseStatus::SUCCESS) {
if (iv_mode == 1) {
op = pid(sp, pv, pv_last, ierr, dt);
ot.setBoilerTemperature(op); // Записываем заданную температуру СО, вычисляемую ПИД регулятором (переменная op)
}
if (iv_mode == 2) {
op = curve(temp_n);
ot.setBoilerTemperature(op); // Записываем заданную температуру СО, вычисляемую кривыми
}
if (iv_mode == 3) {
op = curve(temp_n, temp_k, temp_t);
ot.setBoilerTemperature(op); // Записываем заданную температуру СО, вычисляемую кривыми с учётом температуры в помещении
}
break;
}
case 2:
if (responseStatus == OpenThermResponseStatus::SUCCESS) {
ot.setDHWTemperature(spdhw); // Записываем заданную температуру ГВС
}
break;
case 3:
if (responseStatus == OpenThermResponseStatus::SUCCESS) {
ot.setMaxCHTemperature(spmaxch); // Записываем максимальную температуру СО
}
break;
default:
loop_counter = 0; // Начинаем с шага 0
return;
}
***********
}
Переделал часть кода, теперь котёл сам запрашивает подтверждения от термостата, точнее он и раньше это делал, но ответы валились каждую секунду, теперь раз в 45 сек. и ОТ не отваливается. То же справедливо и для уставок, запись идёт только когда есть запрос на это. Полагаю, что и остальные запросы на чтение ОТ надо поместить в case, решит проюлему спаминга.
Вроде добился, что контекст псевдо 2-х поточного кода заработал. У меня теперь веб сервер отвечает в течении порядка 100ms - т.е практически сразу. Заодно пришил и конфигуратор и OTA.
О_О. Поимел сегодня секса с этой библиотекой opentherm_library. Выяснилась такая бяка - если использовать SPIFFS для сохранения конфига и в это время прилетает прерывание от ОТ адаптера - все падает в корку. После долго дебага и гугления с рашифровкой стек трейса выяснилась собственно простая вещь - при записи файла SPIFFS отключает флеш от основного адресного пространства и соответственно когда прилетает прерывание у обработчики и вызываевых им функций не стоит атрибута ICACHE_RAM_ATTR и соответственно инструкция пытается выполнится из флеша (а его то уже тютю) и мы падаем в эксепшен. Соответственно пришлось поправить библиотеку в OpenTherm.cpp добавив необходимые аттрибуты и все перестало падать. Кому надо берите исправленную библиотеку здесь - https://github.com/OldNavi/opentherm_library.git. Pull Requst в основной репозиторий я сделал - но хз приет его автор или нет, посмотрим.
Да, эту информацию будет давать Home Assistant. Кстати вопрос такой - а с другими параметрами - например ID=54 Room Temperature - не пробовали ? Может БАКСИ сам будет все считать, есть у меня подозрение что он внутри себя все может делать и не надо всякие PID прикручивать.
По внешнему подключению температурного датчика думал, у меня вся автоматика на modbus сделана и датчиков в доме штук 5. Пока не стал заморачиваться...
Нет 54-го. К сожалению возможности Слима ограничены, даже модуляцию не выдаёт, по сему АЦП задействовал. Вот можно глянуть какие ID в Бакси Слим рулятся http://otgw.tclcode.com/matrix.cgi#boilers Кстати, в моей прошивке по ссылке выше, есть ещё 2 регулятора (кривые).
По внешнему подключению температурного датчика думал, у меня вся автоматика на modbus сделана и датчиков в доме штук 5. Пока не стал заморачиваться...
Нет 54-го. К сожалению возможности Слима ограничены, даже модуляцию не выдаёт, по сему АЦП задействовал. Вот можно глянуть какие ID в Бакси Слим рулятся http://otgw.tclcode.com/matrix.cgi#boilers Кстати, в моей прошивке по ссылке выше, есть ещё 2 регулятора (кривые).
Я переехал с самодельной автоматики на HA (он модбас тоже поддерживает) - вещь оказалось собственно. А там написать автоматизацию которая с датчиков будет что то усредненное считать по температуре и слать через MQTT dв бакси - это как два байта об асфальт.
У меня так и было сделано, температура усреднялась от 4-х датчиков, в операторской панели Weintek MT6070iH, 7″ был сделан термостат, он всё вычислял и рулил Слимом в режиме вкл/выкл 3 года. Захотелось ОТ...
Нее, не отвечает засранец :-) Ну и ладно - и так обойдемся
Добавил обработку флагов ошибки (а не только кода OEM) -
----------- Конфигурация ---------------
Границы установок контура отопления = от 0 до 0
Границы установок контура ГВС = от 0 до 0
ГВС встроен = 0
Тип управления = Модуляция
ГВС = проточная
----------- Статусы ---------------
Ошибка котла = 0
Код ошибки = E0
Сервис требуется = нет
Удаленный сброс разрешен = нет
Ошибка низкого давления воды = нет
Ошибка по газу/огню = нет
Ошибка по тяге воздуха = нет
Перегрев теплоносителя = нет
ID 5 Request - 50000 Response - C0050000 Status: SUCCESS
ID 9 Request - 90000 Response - F0090000 Status: INVALID
ID 10 Request - A0000 Response - C00A3900 Status: SUCCESS
ID 11 Request - 800B0000 Response - C00B001A Status: SUCCESS
ID 12 Request - C0000 Response - F00C0000 Status: INVALID
ID 13 Request - 800D0000 Response - 700D0000 Status: INVALID
ID 15 Request - F0000 Response - F00F0000 Status: INVALID
ID 16 Request - 90101500 Response - 70100000 Status: INVALID
ID 17 Request - 110000 Response - 60110000 Status: INVALID
ID 18 Request - 120000 Response - F0120000 Status: INVALID
ID 19 Request - 80130000 Response - 70130000 Status: INVALID
ID 20 Request - 140000 Response - F0140000 Status: INVALID
ID 21 Request - 80150000 Response - 70150000 Status: INVALID
ID 22 Request - 80160000 Response - 70160000 Status: INVALID
ID 23 Request - 10171500 Response - F0170000 Status: INVALID
ID 24 Request - 10181500 Response - F0180000 Status: INVALID
ID 28 Request - 801C0000 Response - E01C0000 Status: INVALID
ID 33 Request - 210000 Response - F0210000 Status: INVALID
ID 58 Request - 3A0000 Response - F03A0000 Status: INVALID
ID 100 Request - 80640000 Response - 70640000 Status: INVALID
ID 115 Request - 80730000 Response - 70730000 Status: INVALID
ID 116 Request - 740000 Response - F0740000 Status: INVALID
ID 117 Request - 80750000 Response - 70750000 Status: INVALID
ID 118 Request - 80760000 Response - 70760000 Status: INVALID
ID 119 Request - 770000 Response - F0770000 Status: INVALID
ID 120 Request - 780000 Response - F0780000 Status: INVALID
ID 121 Request - 80790000 Response - 70790000 Status: INVALID
ID 122 Request - 807A0000 Response - 707A0000 Status: INVALID
ID 123 Request - 7B0000 Response - F07B0000 Status: INVALID
Зарефакторил код. Сделал универсальную обработку json - одну на mqtt и web и пришил кривые из твоего кода (не уверен что правильно) . Осталось нарисовать вед морду с javascript и положить в SPIFFS и будет готово.
По поводу ПИД и кривых. Путанница какая то, ваша переменная heat_temp_set это уставка для ID-1 котла, она же в моём коде OP, вычисляемая ПИД и кривыми. И не вижу уставки целевой комнатной температуры (в моём коде SP), участвует в вычислении и ПИД, и кривых. PV понятно, прилетает из вне и становится house_temp.
А уровень модуляции ID-17? В моём Бакси её нет. Я её вычисляю АЦП ЕСПешки из ШИМ с катушки модуляции котла.
enableCentralHeating управляется? Когда house_temp_compsenation = true и температура уставки в помещении heat_temp_set меньше чем текущая температура в помещении house_temp. В данном условии, false.
enableCentralHeating управляется - но я не хочу его вводить в ПИД или куда еще - отключая котел. Ведь в этом случае выключается циркуляция. У меня идея в том что при TCHset меньше чем нижняя граница - котел сам отключит пламя.
Да, постциркуляция вечная получается, но если enableCentralHeating = false котёл не отключается он в ждущем режиме, и постциркуляция в этом случае или 3 мин, или 4 часа как дип в плате управления выбран.
Интересно.... Даже очень.
А киньте рабочий вариант на почту. Проверю на себе без изменений.
Вот этот работает
Не работает функция обратного вызова, чтение топиков
Опять приветствую многоуважаемое сообщество. Возвращаюсь к началу поста и описываемой проблеме. Причина с медлительностью веб сервера в библиотеке
Точнее в setup
Весь код начинает работать с циклом в 1 сек. Особенность библиотеки такая. Возможно ли решить некую многозадачность?
306
void
loop
() {
307
new_ts = millis();
308
if
(new_ts - ts > 1000) {
Думается мне что здесь проблема - вынеси обработку Web/MQTT из этого условия - должно реагировать получше. Мне приехали мои ESPшки - буду собирать свой ОТ контроллер, на этой же базе - в 2 головы глядишь и интереснее пойдет.
OldNavi, нет, не помогает. Весь код, что в условии, что за его пределми - 1сек. Как только комментирую ot.begin(handleInterrupt); сервера летают, датчик тоже, но ОТ не работает.
обработка прерываний не должна брать много - код под вопросмо что я вижу в библиотеке openterm - это sendRequest()
Закоментируй
ot.sendRequest(request); в loop() и посмотри на поведение, если залетает (но ОТ не будет работать)
то вижу несколько вариантов
1/ Воспользоваться
processResponseCallback(). который передаешь в конструкторе и там добавлять обработку2/ использовать sendRequestAsync() и прописать свой while(!isRead) {} цикл
3/ Посмотреть в сторону Scheduler https://www.arduino.cc/en/Reference/Scheduler
Залетает...и без запросов то же.
Ну и видится проблема в том, что ты заспамил шину ОТ запросами (а запрос ответ может быть до 1сек согласно спецификации).
У тебя в кажом начале цикла есть - вызов setBolierStatus() который в в ответе уже дает много флагов статуса (есть ошибка или нет, включена горелка и т.д.) см спецификацию протокола
Дальше этот код можно наверное утащить в setup() и если что дергать при реконекте
Дальше в цикле ты публикуешь в MQ
Которые внутри шлют новые запросы по ОТ, как пример
ну и так далее... Вообщем ИМХО тут есть место для оптимизации ибо сам ОТ протокол ну очень медленный -
Bit rate : 1000 bits/sec nominal - по сути 15 сообщений максимум по ОТ за секунду (сообщение + ответ = 64 бита) - и каждый посыл блокирующий
ИМХО тут надо и цикл оптимизировать и разводить запросы по времени набирая полный набор параметров секунд за 10 - примерно как в tasmota сделано. Желание знать актуальную температуру каждую секунду похвально - но бессмыслено - она и раз за минуту не изменится. ну и тд и тп.
Сейчас на полный цикл обработки данных уходит 10-12 сек. Оригинальный код автора библиотеки http://ihormelnyk.com/mqtt_thermostat кушает на треть меньше. но там и данных меньше. Про код с ID2, что его можно в setup(), не прокатывает, а без него мой котёл только мониторится, а вот отправлять код каждые раз в 50 секунд вполне (тут надо покопаться в инфе, фигурируют цифры 40 и 20 сек.). Если котёл в течении этого времени не получит кода подтверждения из ID3 режим ОТ отключается, термостат только мониторит и то не всё. Другим котлам это по барабану. В любом случае сама библиотека ОТ вызывает вопросы.
Я полазил по коду библиотеки - он впринципе нормально реализован, из минусов он только работает нормально под core 2.3.0 - под 2.5.2 падает. Но не суть - проблема таже - sendRequest() это синхронный запрос и он может возвращать данные до 1 секунды. 2-я проблема - это спамминг шины ОТ - если читать спецификацию то следующий запрос можно делать не ранее чем через 100 милисекунд после последнего ответа. Думается мне, что я попробую реализацию через шедуллер с 2-мя тасками через https://www.arduinolibraries.info/libraries/esp8266-scheduler - в одном будет коммуникация с ОТ через библиотеку с таймингами, во второй таске уже MQTT и Вебсервак с блекджеком и б..ми. Но это пока не скоро - надо платку согласования еще распаять.
Переделал часть кода, теперь котёл сам запрашивает подтверждения от термостата, точнее он и раньше это делал, но ответы валились каждую секунду, теперь раз в 45 сек. и ОТ не отваливается. То же справедливо и для уставок, запись идёт только когда есть запрос на это. Полагаю, что и остальные запросы на чтение ОТ надо поместить в case, решит проюлему спаминга.
Определённо сдвиг в лучшую сторону есть. Нужен совет. Как лучше организовать чтение переменных ОТ в одном case или каждую в отдельном?
ИМХО лучше в отдельном case
Сервер заработал :-)
Выложил бы полный код куданить на Гитхаб например.
Вроде добился, что контекст псевдо 2-х поточного кода заработал. У меня теперь веб сервер отвечает в течении порядка 100ms - т.е практически сразу. Заодно пришил и конфигуратор и OTA.
Всё же есть одна особенность. Обработка 3 и 2 ID должны быть в одном case.
Положил свою реализацию на основе async запросов и параллельных тасков на Гитхаб
https://github.com/OldNavi/OpenThermController.git
Пока реализовано
1/ WiFi manager - для конфига WiFI и MQTT
2/ Сохранение конфига при применении команд
3/ MQTT с JSON
4/ HTTP Server пока простой
5/ ОТА поддерживается
6/ Сброс бойлера через MQTT
Мой файл на https://yadi.sk/d/aigzaKc_TUQsnQ
О_О. Поимел сегодня секса с этой библиотекой opentherm_library. Выяснилась такая бяка - если использовать SPIFFS для сохранения конфига и в это время прилетает прерывание от ОТ адаптера - все падает в корку. После долго дебага и гугления с рашифровкой стек трейса выяснилась собственно простая вещь - при записи файла SPIFFS отключает флеш от основного адресного пространства и соответственно когда прилетает прерывание у обработчики и вызываевых им функций не стоит атрибута ICACHE_RAM_ATTR и соответственно инструкция пытается выполнится из флеша (а его то уже тютю) и мы падаем в эксепшен. Соответственно пришлось поправить библиотеку в OpenTherm.cpp добавив необходимые аттрибуты и все перестало падать. Кому надо берите исправленную библиотеку здесь - https://github.com/OldNavi/opentherm_library.git. Pull Requst в основной репозиторий я сделал - но хз приет его автор или нет, посмотрим.
Я библиотеку немного модифицировал, добавил к базовым ещё обработку нескольких ID.
Прикрутил EEPROM - но кторый rotating - так глядишь не быстро сдохнет espшка
Я свою год гоняю, до полсотни раз за день шью... Ничего, жива...
Гляжу в коде нет датчика температуры (помещения), с других устройств используете?
Да, эту информацию будет давать Home Assistant. Кстати вопрос такой - а с другими параметрами - например ID=54 Room Temperature - не пробовали ? Может БАКСИ сам будет все считать, есть у меня подозрение что он внутри себя все может делать и не надо всякие PID прикручивать.
По внешнему подключению температурного датчика думал, у меня вся автоматика на modbus сделана и датчиков в доме штук 5. Пока не стал заморачиваться...
Нет 54-го. К сожалению возможности Слима ограничены, даже модуляцию не выдаёт, по сему АЦП задействовал. Вот можно глянуть какие ID в Бакси Слим рулятся http://otgw.tclcode.com/matrix.cgi#boilers Кстати, в моей прошивке по ссылке выше, есть ещё 2 регулятора (кривые).
Нда, жалко - ну да пофиг, и так сделаем хорошо
По внешнему подключению температурного датчика думал, у меня вся автоматика на modbus сделана и датчиков в доме штук 5. Пока не стал заморачиваться...
Нет 54-го. К сожалению возможности Слима ограничены, даже модуляцию не выдаёт, по сему АЦП задействовал. Вот можно глянуть какие ID в Бакси Слим рулятся http://otgw.tclcode.com/matrix.cgi#boilers Кстати, в моей прошивке по ссылке выше, есть ещё 2 регулятора (кривые).
Я переехал с самодельной автоматики на HA (он модбас тоже поддерживает) - вещь оказалось собственно. А там написать автоматизацию которая с датчиков будет что то усредненное считать по температуре и слать через MQTT dв бакси - это как два байта об асфальт.
У меня так и было сделано, температура усреднялась от 4-х датчиков, в операторской панели Weintek MT6070iH, 7″ был сделан термостат, он всё вычислял и рулил Слимом в режиме вкл/выкл 3 года. Захотелось ОТ...
OldNavi, из строки 98 unsigned int val_in_hex = (val * 256 * 16); уберите деление на 16, лишнее...
По ссылке выше добавил модифицированную библиотеку.
Полагаю, так проще:
Это все я уже поправил, все теперь работает... Одну загадку разгадать не могу.
Если например котел уходит в ошибку - то температуру ГВС показывает как 133 градуса, че хрень пока не пойму
PS: Кстати мой PR в opentherm library - смерджили - можно обновить библиотеку.
Хм, это не температура, похоже на код ошибки, типа Е 133, но из ID-5 читаться должен (расшифровка = по моему блокировка газа).
Полагаю, ошибка здесь кроется:
Блин! Спасибо - совсем copy-past проглядел. Кстати, табличке http://otgw.tclcode.com/matrix.cgi#boilers
не доверяю, бакси отвечает на большее количество кодов - сейчас дамп пишу - попробую собрать статистику
Блин! Спасибо - совсем copy-past проглядел. Кстати, табличке http://otgw.tclcode.com/matrix.cgi#boilers
не доверяю, бакси отвечает на большее количество кодов - сейчас дамп пишу - попробую собрать статистику
Слим-Слимом, но пихают туда платы разных производителей...
Нее, не отвечает засранец :-) Ну и ладно - и так обойдемся
Добавил обработку флагов ошибки (а не только кода OEM) -
----------- Конфигурация ---------------
ID 5 Request - 50000 Response - C0050000 Status: SUCCESS
ID 9 Request - 90000 Response - F0090000 Status: INVALID
ID 10 Request - A0000 Response - C00A3900 Status: SUCCESS
ID 11 Request - 800B0000 Response - C00B001A Status: SUCCESS
ID 12 Request - C0000 Response - F00C0000 Status: INVALID
ID 13 Request - 800D0000 Response - 700D0000 Status: INVALID
ID 15 Request - F0000 Response - F00F0000 Status: INVALID
ID 16 Request - 90101500 Response - 70100000 Status: INVALID
ID 17 Request - 110000 Response - 60110000 Status: INVALID
ID 18 Request - 120000 Response - F0120000 Status: INVALID
ID 19 Request - 80130000 Response - 70130000 Status: INVALID
ID 20 Request - 140000 Response - F0140000 Status: INVALID
ID 21 Request - 80150000 Response - 70150000 Status: INVALID
ID 22 Request - 80160000 Response - 70160000 Status: INVALID
ID 23 Request - 10171500 Response - F0170000 Status: INVALID
ID 24 Request - 10181500 Response - F0180000 Status: INVALID
ID 28 Request - 801C0000 Response - E01C0000 Status: INVALID
ID 33 Request - 210000 Response - F0210000 Status: INVALID
ID 58 Request - 3A0000 Response - F03A0000 Status: INVALID
ID 100 Request - 80640000 Response - 70640000 Status: INVALID
ID 115 Request - 80730000 Response - 70730000 Status: INVALID
ID 116 Request - 740000 Response - F0740000 Status: INVALID
ID 117 Request - 80750000 Response - 70750000 Status: INVALID
ID 118 Request - 80760000 Response - 70760000 Status: INVALID
ID 119 Request - 770000 Response - F0770000 Status: INVALID
ID 120 Request - 780000 Response - F0780000 Status: INVALID
ID 121 Request - 80790000 Response - 70790000 Status: INVALID
ID 122 Request - 807A0000 Response - 707A0000 Status: INVALID
ID 123 Request - 7B0000 Response - F07B0000 Status: INVALID
Зарефакторил код. Сделал универсальную обработку json - одну на mqtt и web и пришил кривые из твоего кода (не уверен что правильно) . Осталось нарисовать вед морду с javascript и положить в SPIFFS и будет готово.
Надо глянуть. Бегло пробежался, не вижу сетпоинта комнатной температуры...
Здесь ошибки нет? .value не хватает.
Точно, поправил. Хотя странно что компилятор не ругался
По поводу ПИД и кривых. Путанница какая то, ваша переменная heat_temp_set это уставка для ID-1 котла, она же в моём коде OP, вычисляемая ПИД и кривыми. И не вижу уставки целевой комнатной температуры (в моём коде SP), участвует в вычислении и ПИД, и кривых. PV понятно, прилетает из вне и становится house_temp.
А уровень модуляции ID-17? В моём Бакси её нет. Я её вычисляю АЦП ЕСПешки из ШИМ с катушки модуляции котла.
heat_temp_set - имеет разное значение в зависимости от house_temp_compsenation
Если house_temp_compsenation = false - то это прямое значение для уставки ID-1 если true - то это уставка комнатной температуры.
house_temp - это переменная куда будет прилетать актуальная температура в комнате с сенсоров
ID-17 у меня используется толька для в функии дампа - проверить какие ID поддерживаются.
Теперь понятно. А уличный датчик штатный в котле или, так же с сенсоров прилетает?
Который в котле.
enableCentralHeating управляется? Когда house_temp_compsenation = true и температура уставки в помещении heat_temp_set меньше чем текущая температура в помещении house_temp. В данном условии, false.
enableCentralHeating управляется - но я не хочу его вводить в ПИД или куда еще - отключая котел. Ведь в этом случае выключается циркуляция. У меня идея в том что при TCHset меньше чем нижняя граница - котел сам отключит пламя.
Да, постциркуляция вечная получается, но если enableCentralHeating = false котёл не отключается он в ждущем режиме, и постциркуляция в этом случае или 3 мин, или 4 часа как дип в плате управления выбран.