Термостат OpenTherm на ESP8266

tsv_33
Offline
Зарегистрирован: 11.04.2019

7694948@bk.ru

Калинин Роман Ш...
Offline
Зарегистрирован: 26.10.2019

tsv_33 пишет:

Калинин Роман Шадиманович пишет:
А как связаться с автором?

А кто и что Вас интересует?


Просто собирать некогда, нужно pid и mqtt от платы в принципе, ну я посмотрел по форуму, она идеально подходит мне, есть только вопрос по установке температуры гвс, моя самоделка так и не научилась выставлять ее, да и собранно все у меня на проводах, если ваша может температуру гвс выставлять будет вообще замечательно! Котел baxi main four 240

Калинин Роман Ш...
Offline
Зарегистрирован: 26.10.2019

СПАСИБО!

tsv_33
Offline
Зарегистрирован: 11.04.2019

OldNavi, не замечали одну особенность, а именно подмену переменных? К примеру, ровненько читается температура воды в баке бойлера, потом провал до температуры отопительной воды, температура же отопительной воды падает в "0".

OldNavi
Offline
Зарегистрирован: 22.08.2019

Замечал,  в предыдущих версиях.  Но поправил в своей. Причина тоже понятна - например если послали сообщение а пришел таймаут или ошибка - и соответственно данные сбиваются.  Я у себя поменял логику - на другую - каждый response имеет в заголовки тип запроса - и на основании его я заполняю уже значения в обработчике асинхронного ответа.

  void static HandleReply(unsigned long response) {
    OpenThermMessageID id = ot.getDataID(response);
    uint8_t flags;
    switch (id)
    {
    case OpenThermMessageID::SConfigSMemberIDcode:
        vars.SlaveMemberIDcode.value = response >> 0 & 0xFF; 
        flags = (response & 0xFFFF) >> 8 & 0xFF;
        vars.dhw_present.value = flags & 0x01;
        vars.control_type.value = flags & 0x02;
        vars.cooling_present.value = flags & 0x04;
        vars.dhw_tank_present.value = flags & 0x08;
        vars.pump_control_present.value = flags & 0x10;
        vars.ch2_present.value = flags & 0x20;
        break;
    case OpenThermMessageID::Status:
        // Статус котла получен

.....

void static responseCallback(unsigned long result, OpenThermResponseStatus status)
  {
    DEBUG.println("Status of response " + String(status));
    DEBUG.println("Result of response " + String(result));
    ot_response = result;
    switch (status)
    {
    case OpenThermResponseStatus::INVALID:
      WARN.println("Ошибочный ответ от котла");
      if(debug)
        client.publish((vars.mqttTopicPrefix.value + "/message").c_str(), "Ошибочный ответ от котла");
      break;
    case OpenThermResponseStatus::TIMEOUT:
      WARN.println("Таймаут ответа от котла");
      if(debug)
        client.publish((vars.mqttTopicPrefix.value + "/message").c_str(), "Таймаут ответа от котла");
      break;
      timeout_count++;
      if (timeout_count > TIMEOUT_TRESHOLD)
      {
        vars.online.value = false;
        timeout_count = TIMEOUT_TRESHOLD;
      }
      break;
    case OpenThermResponseStatus::SUCCESS:
      timeout_count = 0;
      vars.online.value = true;
      HandleReply(result);
      break;
    default:
      break;
    }
  }

 

tsv_33
Offline
Зарегистрирован: 11.04.2019

Бегло пробежался по вашему проекту, сразу бросилось в глаза:

#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <ESP8266mDNS.h>

Ошибка?

OldNavi
Offline
Зарегистрирован: 22.08.2019

Ага,  очепятка - включил хедер дважды.

tsv_33
Offline
Зарегистрирован: 11.04.2019

OldNavi, планировщиком не пользуетесь?

OldNavi
Offline
Зарегистрирован: 22.08.2019

Вопрос не понял, про какой планировщик речь ?  Если про потоки выполнения - то да пользуюсь, есть же в коде

#include <Scheduler.h>


void setup()
{
.....
  Serial.begin(115200);
  setup_wifi();

  // Запускаем основные потоки - в одном обрабатываем сообщения OpenTherm
  // Второй поток отвечает за обслуживание всего остального
  Scheduler.start(&OtHandler);
  Scheduler.start(&MainTask);

  Scheduler.begin();
}

 

tsv_33
Offline
Зарегистрирован: 11.04.2019

Планировщиком заданий, скажем уставкой температуры в доме по времени, или ГВС...

OldNavi
Offline
Зарегистрирован: 22.08.2019

tsv_33 пишет:

Планировщиком заданий, скажем уставкой температуры в доме по времени, или ГВС...

А ну, этим у меня Home Assistant занимается на малинке -  крутая штука для написания всяких автоматизаций и сценариев.  Более того у меня там завязано оочень много чего, включая управление рециркуляцией, аварийным переключением котлов, освещением, датчиками безопасности интеграцией с HomeKit, Tasmota Sonoff и т.д.  По сути это система умного дома - которая интегрируется со всем и всея. https://www.home-assistant.io

tsv_33
Offline
Зарегистрирован: 11.04.2019

Ага, понял.

tsv_33
Offline
Зарегистрирован: 11.04.2019

Добавил  uptime работы esp.

String Uptime()
{
  String Time = "";
  unsigned long dd = 0;
  int hh = 0;
  int mm = 0;
  int ss = 0;
  int Rollover = 0;
  int HighMillis = 0;
  unsigned long secUp = millis() / 1000;
  if (millis() >= 3000000000) 
 {
    HighMillis = 1;
  }
  if (millis() <= 100000 && HighMillis == 1)
 {
    Rollover ++;
    HighMillis = 0;
  }
  ss = secUp % 60;
  mm = (secUp / 60) % 60;                             
  hh = (secUp / (60 * 60)) % 24;                      
  dd = (Rollover * 50) + (secUp / (60 * 60 * 24));    
  if (dd > 0)Time += "0";                             
  Time += (String)dd + " д ";
  if (hh < 10)Time += "0";
  Time += (String)hh + ":";
  if (mm < 10)Time += "0";
  Time += (String)mm + ":";
  if (ss < 10)Time += "0";
  Time += (String)ss;
  return Time;
}

 

RET
Offline
Зарегистрирован: 03.10.2019

Приветствую. Всё пытаюсь ещё доработать свой код для работы с котлом Bosch. Возник вопрос касательно расшифровки ответа котла на запрос c ID-3.

Ответ приходит в HEX со значением 40031108. А вот как его привести в понятный вид, что бы увидеть два параметра HB: Slave configuration и LB: Slave MemberID. Что то совсем запутался в понятии старших и младших битов.

Так же и с ID-6, ответ в HEX c0060303, а вот как его перевести в понятный глазу вид не понимаю.

tsv_33
Offline
Зарегистрирован: 11.04.2019

Так в винде калькулятор есть, "программист", а что бы увидеть, вам нужны четыре цифры справа налево, LB-08, HB-11 и т.д., а расшифровку смотрите в протоколе.

RET
Offline
Зарегистрирован: 03.10.2019

tsv_33 пишет:

Так в винде калькулятор есть, "программист", а что бы увидеть, вам нужны четыре цифры справа налево, LB-08, HB-11 и т.д., а расшифровку смотрите в протоколе.

Спасибо, вроде бы понял. То есть, что бы передать в моем случае котлу "нужный" Master MemberID code, запрос на отправку должен выглядеть так?:

 // Записать ID-2; мастер-код MemberID
unsigned int data = 0x1000;
unsigned long request = ot.buildRequest(OpenThermRequestType::WRITE, OpenThermMessageID::MConfigMMemberIDcode, data);
ot.sendRequest(request);

 

tsv_33
Offline
Зарегистрирован: 11.04.2019

Нет. В вашем случае:

// Записать ID-2; мастер-код MemberID
unsigned int data = 0x0008;
unsigned long request = ot.buildRequest(OpenThermRequestType::WRITE, OpenThermMessageID::MConfigMMemberIDcode, data);
ot.sendRequest(request);

 

RET
Offline
Зарегистрирован: 03.10.2019

А, т.е. ему обратно так же в HEX'ах надо передавать?

tsv_33
Offline
Зарегистрирован: 11.04.2019

Да, в протоколе написано "u8  unsigned 8-bit integer 0 .. 255", но в HEX.

itf1
Offline
Зарегистрирован: 13.11.2019

Добрый день.

Новенький в этой теме - подскажите пожалуйста, а какое оборудование вы используете для коммуникации с котлами по протоколу OpenTherm?

tsv_33
Offline
Зарегистрирован: 11.04.2019

Не понял... Протокол так отвечает на ваш вопрос

3.1  Medium Definition- Characteristics of the Transmission Line 
Number of Wires    :  2 
Wiring type    :  untwisted pair * 
Maximum line length    :  50 metres 
Maximum cable resistance    :  2 * 5 Ohms 
Polarity of connections    :  Polarity-free, i.e. interchangeable. 
 
* In electrically noisy environments it may be necessary to use twisted pair or screened cable.
Калинин Роман Ш...
Offline
Зарегистрирован: 26.10.2019

Привет всем! OldNavi а не напишешь тут что в configuration.yaml добавить чтобы такой же интерфейс получить как у тебя? Спасибо!

И еще один вопрос как ему отдать температуру помещения?

Вижу что получает тут:

vars.house_temp.value = json["house_temp"] | 23.0;

А как ему ее отдать не понимаю.....

Еще раз заранее спасибо!

OldNavi
Offline
Зарегистрирован: 22.08.2019

Калинин Роман Шадиманович пишет:

Привет всем! OldNavi а не напишешь тут что в configuration.yaml добавить чтобы такой же интерфейс получить как у тебя? Спасибо!

 

Ну configuration.yaml свой я точно не выложу - там извините приватная информация о других системах по мимо опентерма.  Да и несложно его составлять, здесь просто напишу пару примеров как описать сенсоры

В binary_sensors.yaml пишете бинарные датчики какие вам нужны (те у которых всего 2 состояния)

- platform: mqtt
  name: "Ошибка"
  state_topic: "opentherm/state"
  value_template: '{{ value_json.fault }}'
  availability_topic: "opentherm/status" 
  payload_on: true
  payload_off: false

В sensors.yaml пишете что то типа

- platform: mqtt
  name: "Уставка ГВС"
  device_class: temperature
  state_topic: "opentherm/state"
  value_template: '{{ value_json.dhw_temp_set }}'
  availability_topic: "opentherm/status"
  unit_of_measurement: "°C" 

В input_number.yaml пишете то что будете вводить

ustavka_gvs:
    name: Установка ГВС
    min: 0
    max: 60
    unit_of_measurement: "°C"
    icon: mdi:temperature
ustavka_heat:
    name: Установка Отопления
    min: 0
    max: 85
    step: 0.5
    unit_of_measurement: "°C"
    icon: mdi:temperature    

и в automations.yaml пишете связывающие из автоматизации

- id: 'xxxxxxxx'
  alias: Установка Отопления
  trigger:
  - entity_id: input_number.ustavka_heat
    platform: state
  condition:
  - condition: template
    value_template: '{{ states(''sensor.otoplenie'') not in [''unavailable'', ''unknown'']
      }}'
  action:
  - data:
      payload_template: '{ "heater_temp": {{ states(''input_number.ustavka_heat'')
        }} }'
      topic: opentherm/cmnd
    service: mqtt.publish

Цитата:

И еще один вопрос как ему отдать температуру помещения?

Вижу что получает тут:

vars.house_temp.value = json["house_temp"] | 23.0;

А как ему ее отдать не понимаю.....

Еще раз заранее спасибо!

Все просто - написать в MQTT opentherm/cmnd топик сообщение в виде json c атрибутом house_temp.  

Калинин Роман Ш...
Offline
Зарегистрирован: 26.10.2019

Да, извините это понятно! Спасибо сейчас буду разбираться!

Калинин Роман Ш...
Offline
Зарегистрирован: 26.10.2019

Извините еще раз... А не сможете объяснить примером какими средствами в HA возможно писать в топик сообщения... просто я для три как начал пользоваться HA и непонимаю куда и что....

OldNavi пишет:

Все просто - написать в MQTT opentherm/cmnd топик сообщение в виде json c атрибутом house_temp.  

это понятно что все просто... Я тут с синтаксисом JAML намучался но потихоньку понимаю вроде бы...

OldNavi
Offline
Зарегистрирован: 22.08.2019

Вызвать сервис mqtt.publish - в примерах же видно

      payload_template: '{ "heater_temp": {{ states(''input_number.ustavka_heat'')
        }} }'
      topic: opentherm/cmnd
    service: mqtt.publish

 

Калинин Роман Ш...
Offline
Зарегистрирован: 26.10.2019

Спасибо большое буду дальше разбираться!

Калинин Роман Ш...
Offline
Зарегистрирован: 26.10.2019

OldNavi пишет:

Вызвать сервис mqtt.publish - в примерах же видно

      payload_template: '{ "heater_temp": {{ states(''input_number.ustavka_heat'')
        }} }'
      topic: opentherm/cmnd
    service: mqtt.publish

 

хорошо а как его вызвать... не пойму... я вижу это так я беру данные с датчиков и скриптом отправляю их через сервис mqtt 

Если можно примером покажите:

забираем данные с датчика так-то

Отправляем их так- то 

все это делается тут -то..

Еще раз извините за тупые вопросы, да еще и не по теме топика.... И огромное спасибо Вам!

OldNavi
Offline
Зарегистрирован: 22.08.2019

Вам все равно прийдется погрузится в документацию HA и почитать как работает автоматизация и что прописывается в automations.yaml.

И я же привел пример

- id: 'xxxxxxxx'
  alias: Установка Отопления
  trigger:
  - entity_id: input_number.ustavka_heat
    platform: state
  condition:
  - condition: template
    value_template: '{{ states(''sensor.otoplenie'') not in [''unavailable'', ''unknown'']
      }}'
  action:
  - data:
      payload_template: '{ "heater_temp": {{ states(''input_number.ustavka_heat'')
        }} }'
      topic: opentherm/cmnd
    service: mqtt.publish

Который делает следующее - 

если изменилось состояние entity_id - в данном случае ползунка ввода уставки отопления и выполнены условия из секции condition - то по action вызвать service mqtt.publish  что бы он отправил строку в виде json описанную в параметре payload.

Засим предлагаю закрыть вопрос по обучению конфигурирования HA - это оффтопик.

Калинин Роман Ш...
Offline
Зарегистрирован: 26.10.2019

Спасибо большое все получилось!