EBUS-контроллер котла My Heat. Интеграция в Home Assistant (часть 2)

19 февраля 2021, 16:05

В первой части этого блога я рассказывал о приобретении контроллера My Heat Smart, который управляет котлом отопления по шине EBUS, и которым неплохо было бы научиться управлять из-под Home Assistant'а, благо, что от производителя имеется какое-никаке описание функций API (вернее, не "какое-никакое описание", а "какого-никакого API", поскольку функционал этого API весьма беден).

Итак, первое, что нам для работы нужно получить от контроллера - это его идентификатор. Напомню, что "облачный" сервис My Heat запросы типа POST в формате JSON, а затем возвращает ответ - также в формате JSON. Запрос должен в обязательном порядке включать в себя логин облачного клиента и его пароль ключ API, который нужно предварительно получить, зайдя в веб-интерфейс администрирования:

1600x_image.png?1613748161

Чтобы получить список контроллеров, закрепленных на нашим логином, мы посылаем на адреc "https://my2.myheat.net/api/request/" вот такой запрос обратите внимание - здесь и далее логин и ключ API указаны из примеров в документации, предоставленной производителем. Я лично проверял - на практике они не работают.

{
  "action":"getDevices",
  "login":"lenino",
  "key":"f11f45d5-5e3a827467cd14-02276894"
}

В ответ мы должны получить нечто вроде этого (снова пример из документации):

{
  "data":{
    "devices":[
    {
      "id":12,
      "name":"У Моста",
      "city":"Новошешминск",
      "severity":1,
      "severityDesc":"Система работает нормально."
    },
    {
      "id":10,
      "name":"Хорошее место",
      "city":"Новошешминск",
      "severity":1,
      "severityDesc":"Система работает нормально."
    }
   ]
  },
  "err":0,
  "refreshPage":false
}

А теперь попробуем реализовать этот запрос с помощью механизмов Home Assistant'а. Для этого создадим (ручками, ручками) сенсор типа "REST". Вот такой:

sensor:
  - platform: rest
    name: "mh_getdevices"
    resource: https://my2.myheat.net/api/request/
    method: POST
    json_attributes_path: "$.data"
    json_attributes:
      - devices
    headers:
      Content-type: "application/json"
      Accept: "text/plain"
      Content-Encoding: "utf-8"
    payload: '{"action":"getDevices","login":"mylogin","key":"xxxxxxxx-yyyyyyyyyyyyyyyy-zzzzzzzz"}'
    verify_ssl: false
    value_template: '{{ value_json.err == 0 }}'

В интерфейсе Home Assistant'а идем в "Панель разработчика", на закладке "Состояния" вбиваем  в поле объект: sensor.mh_getdevices, и в поле атрибутов видим следующее: 

devices:
  - id: 12
    name: У моста
    city: Новошешминск
    severity: 1
    severityDesc: Система работает нормально.
  - id: 10
    name: Хорошее место
    city: Новошешминск
    severity: 1
    severityDesc: Система работает нормально.
friendly_name: mh_getdevices

Следующий этап: получение информации об устройствах, "прицепленных" к контроллеру. Сразу оговорюсь - для каждого контроллера придется создавать свой отдельный сенсор, указывая в запросе идентификатор нужного нам контроллера. Приведенный ниже пример показывает процесс получения данных для контроллера с идентификатором 12 (id = 12). Сначала текст в POST-запросе, как рекомендует нам документация по API. Обратите внимание:  Значение идентификатора контроллера указывается явным образом ("deviceId":12):

{
  "action":"getDeviceInfo",
  "deviceId":12,
  "login":"lenino",
  "key":"f11f45d5-5e3a827467cd14-02276894"
}

Получаем ответ:

{
  "data":{
    "heaters":[
      {
        "id":13,
        "name":"Vaillant правый",
        "disabled":false,
        "flowTemp":56,
        "returnTemp":56,
        "pressure":2.223,
        "targetTemp":0,
        "burnerHeating":false,
        "burnerWater":false,
        "modulation":0
      },
      {
        "id":37,
        "name":"Vaillant левый",
        "disabled":false,
        "flowTemp":56,
        "returnTemp":57,
        "pressure":2.436,
        "targetTemp":0,
        "burnerHeating":false,
        "burnerWater":false,
        "modulation":0
      }
    ],
    "envs":[
      {
        "id":21,
        "type":"boiler_temperature",
        "name":"Бойлер",
        "value":46.687,
        "target":45,
        "demand":false,
        "severity":1,
        "severityDesc":"Нормальное состояние."
      },
      {
        "id":22,
        "type":"room_temperature",
        "name":"Кафе",
        "value":24.812,
        "target":23,
        "demand":false,
        "severity":1,
        "severityDesc":"Нормальное состояние."
      },
      {
        "id":24,
        "type":"circuit_temperature",
        "name":"Контур отопления",
        "value":56,
        "target":null,
        "demand":false,
        "severity":1,
        "severityDesc":"Нормальное состояние."
      },
      {
        "id":23,
        "type":"room_temperature",
        "name":"Магазин",
        "value":24.187,
        "target":23,
        "demand":false,
        "severity":1,
        "severityDesc":"Нормальное состояние."
      },
      {
        "id":20,
        "type":"room_temperature",
        "name":"Бухгалтерия",
        "value":29.812,
        "target":null,
        "demand":false,
        "severity":1,
        "severityDesc":"Нормальное состояние."
      },
      {
        "id":19,
        "type":"room_temperature",
        "name":"Котельная",
        "value":27.25,
        "target":null,
        "demand":false,
        "severity":1,
        "severityDesc":"Нормальное состояние."
      }
    ],
    "engs":[
      {
        "id":40,
        "type":"pump",
        "name":"Насос магазин",
        "turnedOn":false,
        "severity":1,
        "severityDesc":"Насос работает исправно."
      },
      {
        "id":41,
        "type":"pump",
        "name":"Насос бойлер",
        "turnedOn":false,
        "severity":1,
        "severityDesc":"Насос работает исправно."
      },
      {
        "id":38,
        "type":"pump",
        "name":"Насос кафе",
        "turnedOn":false,
        "severity":1,
        "severityDesc":"Насос работает исправно."
      },
      {
        "id":39,
        "type":"pump",
        "name":"Насос бухгалтерия",
        "turnedOn":false,
        "severity":1,
        "severityDesc":"Насос работает исправно."
      }
    ],
    "alarms":{
      
    },
    "dataActual":true,
    "severity":1,
    "severityDesc":"Система работает нормально.",
    "weatherTemp":"-6.78999999999996",
    "city":"Новошешминск"
  },
  "err":0,
  "refreshPage":false
}

Реализация сенсора в Home Assistant'е. Текст сенсора:

  - platform: rest
    name: "mh_getdeviceinfo"
    resource: https://my2.myheat.net/api/request/
    method: POST
    json_attributes_path: "$.data"
    json_attributes:
      - heaters
      - envs
      - engs
      - alarms
      - dataActual
      - severity
      - severityDesc
      - weatherTemp
      - city
    headers:
      Content-type: "application/json"
      Accept: "text/plain"
      Content-Encoding: "utf-8"
    payload: '{"action":"getDeviceInfo","deviceId":"12","login":"mylogin","key":"xxxxxxxx-yyyyyyyyyyyyyy-zzzzzzzz"}'
    verify_ssl: false
    value_template: '{{ value_json.err == 0 }}'

Значение (состояние) сенсора:

heaters:
  - id: 13,
    name: Vaillant правый
    disabled: false,
    flowTemp: 56,
    returnTemp: 56,
    pressure: 2.223,
    targetTemp: 0,
    burnerHeating: false,
    burnerWater: false,
    modulation: 0
  - id: 37,
    name: Vaillant левый
    disabled: false,
    flowTemp: 56,
    returnTemp: 57,
    pressure: 2.436,
    targetTemp: 0,
    burnerHeating: false,
    burnerWater: false,
    modulation: 0
envs:
  - id: 21,
    type: boiler_temperature
    name: Бойлер
    value: 46.687,
    target: 45,
    demand: false,
    severity: 1,
    severityDesc: Нормальное состояние.
  - id: 22,
    type: room_temperature
    name: Кафе
    value: 24.812,
    target: 23,
    demand: false,
    severity: 1,
    severityDesc: Нормальное состояние.
  - id: 24,
    type: circuit_temperature
    name: Контур отопления
    value: 56,
    target: null,
    demand: false,
    severity: 1,
    severityDesc: Нормальное состояние.
  - id: 23,
    type: room_temperature
    name: Магазин
    value: 24.187,
    target: 23,
    demand: false,
    severity: 1,
    severityDesc: Нормальное состояние.
  - id: 20,
    type: room_temperature
    name: Бухгалтерия
    value: 29.812,
    target: null,
    demand: false,
    severity: 1,
    severityDesc: Нормальное состояние.
  - id: 19,
    type: room_temperature
    name: Котельная
    value: 27.25,
    target: null,
    demand: false,
    severity: 1,
    severityDesc: Нормальное состояние.
engs: 
  - id: 40,
    type: pump
    name: Насос магазин
    turnedOn: false,
    severity: 1,
    severityDesc: Насос работает исправно.
  - id: 41,
    type: pump
    name: Насос бойлер
    turnedOn: false,
    severity: 1,
    severityDesc: Насос работает исправно.
  - id: 38,
    type: pump
    name: Насос кафе
    turnedOn: false,
    severity: 1,
    severityDesc: Насос работает исправно.
  - id: 39,
    type: pump
    name: Насос бухгалтерия
    turnedOn: false,
    severity: 1,
    severityDesc: Насос работает исправно.
alarms: []
dataActual: true,
severity: 1,
severityDesc: Система работает нормально.
weatherTemp: -6.78999999999996
city: Новошешминск

Теперь настала очередь создания "конкретных" сенсоров для получения значений параметров, относящихся к контроллеру и его объектам. Эти сенсоры "выдергивают" заданные атрибуты из наших "первичных" сенсоров, возвращающих JSON-данные в качестве состояния.

Например, сенсор для получения местоположения (населенного пункта) установки контроллера с идентификатором 12

  - platform: template
    sensors:
      mh_city:
        friendly_name: "Местоположение"
        value_template: "{{ (state_attr('sensor.mh_getdevices', 'devices')|selectattr('id','eq',12)|first).city }}"

Сенсор для получения температуры подачи отопительного котла с идентификатором 13:

  - platform: template
    sensors:
      mh_heater_flow_temperature:
        friendly_name: "Температура подачи"
        unit_of_measurement: "°С"
        value_template: "{{ (state_attr('sensor.mh_getdeviceinfo', 'heaters')|selectattr('id','eq',13)|first).flowTemp | round(2) }}"

Ну вот, собственно говоря, и всё, что мне на сегодняшний день удалось "выжать" из контроллера My Heat. В следующей записи блога (если она будет) постараюсь рассмотреть вопрос уже не получения значений от контроллера, а управления контроллером путем посылки ему запросов с указанием требуемых значени параметров.

Хочется выразить благодарность коллегам 470258 и a005 с форума 4пда за неоценимую помощь в грамотном написании сенсоров.

P.S. Описанный здесь способ взаимодействия Home Assistant'а с контроллером My Heat весьма далёк от совершенства.

В частности, мне пока не удалось решить следующие вопросы:

  • Как избежать явного указания логина и ключа API в тексте сенсоров? Я хотел их заменить на подставные переменные, но у меня не получилось.
  • Идентификаторы устройств и объектов назначаются облачным софтом без вашего участия. Вы создаете объект, а идентификатор ему присваивается автоматически. Более того - если вы удалите объект, а затем создатите точно такой же вместо него - с тем же именем и теми же параметрами - его идентификатор будет уже другой, и вам придется переписывать значения в файле конфигурации сенсоров.
  • Все взаимодействие основано на указании в запросах (читай - в конфигурации сенсоров) конкретных идентификаторов. Было бы очень здорово каким-то образом полученные по запросу getDevices идентификаторы контроллеров автоматически использовать в запросах getDeviceInfo, затем полученные идентификаторы объектов группировать по типам оборудования и в конце концов получать сформированный автоматически набор "конечных" сенсоров для использования в интерфейсах Home Assistant'а. Чутьё мне подсказывает, что надо каким-то образом JSON-отклики "облака" пересылать на MQTT, а там уже реализовывать (опять же - непонятно, каким образом) механизм "discovery".

В-общем, моих знаний для решения вышеуказанных вопросов, пока маловато. Буду признателен, если кто-то изложит подсказки в комментариях. Спасибо!


Все новости мира умных домов - t.me/SprutAI_News или Instagram
Остались вопросы? Мы в Telegram - @SprutAI

Хочешь умный дом но нет времени разбираться?
Посмотри примеры работ и выбери себе интегратора.
К списку блогов

Скидки для сообщества

Z-Wave Ukraine

+380 68 641 9670
Промокод:
Sprut-UA
Размер скидки:
15%

Тематические чаты

Похожие записи

12 сентября 2020, 20:51
Создание при помощи бесплатной программы Sweet Home 3D интерактивного плана помещения для Home Assistant.
16 июля 2020, 15:13
Удобная настройка Home Assistant с помощью packages.
13 февраля 2019, 22:00
Подключение радио на Xiaomi Gateway к Home Assistant c дальнейшим использованием в автоматизациях
19 апреля 2019, 20:53
Требуется ваше мнение!
06 февраля 2019, 12:02
Автоматизированное открытие/закрытие окна
04 апреля 2019, 12:45
Самое важное из апдейта Home Assistant 0.91-0.91.4 от 03.04.19.
21 марта 2019, 11:59
Самое важное из апдейта Home Assistant 0.9 от 20.03.19.
21 февраля 2019, 21:12
Самое важное из апдейта Home Assistant 0.88 от 20.02.19.
19 января 2019, 20:49
Делюсь новостями по проекту.