mavrikkk / ha_kettler

allows you to connect Redmond SkyKettle, SkyCooker and SkyHeat to your Home Assistant. see README to know further
132 stars 51 forks source link

Интеграция с HomeKit iOS #32

Open DmitriySolomatin opened 4 years ago

DmitriySolomatin commented 4 years ago
При интеграции в HomeKit появляется аксессуар в таком виде: В списке аксессуаров Экран аксессуара
photo_2020-06-01_17-49-03 photo_2020-06-01_17-49-03 (2)

То есть в данный момент статус аксессуара "активен", цель 100 градусов. Но никаких действий не происходит. Если я сдвину регулятор цели, например на 95 градусов, то начнётся кипячение, но после финала аксессуар так и останется в "активном" состоянии. Текущую температуру отображает некорректно.

При этом в интерфейсе Home Assistant всё нормально. Есть возможность задать цвет, корректно отображается текущая температура. Статус состояния устройства работает.

Может кто уже смог корректно настроить для iOS?

DmitriySolomatin commented 4 years ago

Немного почитал HomeKit Accessory Protocol Specification и посмотрел в репозитории HA файл /components/homekit/type_thermostats.py.

HomeKit идентифицирует чайник, как "thermostat" и ожидает получить обязательные параметры:

  1. Current Heating Cooling State — текущий статус чайника, 0 - выключен, 1 - греет, 2 - для охладительных устройств;
  2. Target Heating Cooling State — для устройств поддерживающих температуру, чайник умеет, но предлагаю пока 0 - выключен;
  3. Current Temperature — текущая температура;
  4. Target Temperature — float - до какой температуры греть (в документации указано, что максимум 38 градусов, но тем не менее ваш компонент отдаёт _tgtemp=100 и HomeKit их видит).
  5. Temperature Display Units — 0 - Цельсии.

Данная реализация кастомного компонента предполагает, что есть три девайса: light.light_rfs_kkl00 - светильник rgb; water_heater.kettle_rfs_kkl003 - water_heater с параметрами текущей и целевой температуры; sensor.status_rfs_kkl003 - статус чайника: OFF, ON, LIGHT;

Экспортируются в HomeKit только light.light_rfs_kkl00 и water_heater.kettle_rfs_kkl003. Светильник работает нормально, с задержкой в секунд 5 (светильники на Wi-Fi ESP у меня реагируют мгновенно на переключение). А вот нагреватель скорее не работает, о чём я описал выше.

При это в компоненте HomeKit для HA я вижу код:

from .const import (
    CHAR_COOLING_THRESHOLD_TEMPERATURE,
    CHAR_CURRENT_HEATING_COOLING,
    CHAR_CURRENT_HUMIDITY,
    CHAR_CURRENT_TEMPERATURE,
    CHAR_HEATING_THRESHOLD_TEMPERATURE,
    CHAR_TARGET_HEATING_COOLING,
    CHAR_TARGET_HUMIDITY,
    CHAR_TARGET_TEMPERATURE,
    CHAR_TEMP_DISPLAY_UNITS,
    DEFAULT_MAX_TEMP_WATER_HEATER,
    DEFAULT_MIN_TEMP_WATER_HEATER,
    PROP_MAX_VALUE,
    PROP_MIN_VALUE,
    SERV_THERMOSTAT,
)

Который импортирует и нужные нам значения CHAR_CURRENT_TEMPERATURE и CHAR_CURRENT_HEATING_COOLING и ниже по коду должен отправлять их в HomeKit:

    @callback
    def async_update_state(self, new_state):
        """Update water_heater state after state change."""
        # Update current and target temperature
        temperature = new_state.attributes.get(ATTR_TEMPERATURE)
        if isinstance(temperature, (int, float)):
            temperature = temperature_to_homekit(temperature, self._unit)
            if temperature != self.char_current_temp.value:
                self.char_target_temp.set_value(temperature)

        # Update display units
        if self._unit and self._unit in UNIT_HASS_TO_HOMEKIT:
            unit = UNIT_HASS_TO_HOMEKIT[self._unit]
            if self.char_display_units.value != unit:
                self.char_display_units.set_value(unit)

        # Update target operation mode
        operation_mode = new_state.state
        if operation_mode and self.char_target_heat_cool.value != 1:
            self.char_target_heat_cool.set_value(1)  # Heat

Но тем не менее эти данные не попадают в HomeKit (текущая температура и статус чайника вкл/выкл).

Также есть код, который отвечает за приём статуса вкл/выкл и текущей температуры из HomeKit, но функционал не работает.

Оставлю свои рассуждения здесь, в надежде на то что подключится автор и другие пользователи компонента.

mavrikkk commented 4 years ago

для того, чтобы подключиться, нужен homekit...если вы или кто-либо разберется чего именно не хватает, то я добавлю... Сходу могу только вспомнить, что кто то раньше мне писал что то на эту тему...и с его слов это косяк HA...они в принципе не транслируют вообще или транслируют неправильно интеграцию water_heater. Если вместо water_heater использовать climate то все будет гуд

mavrikkk commented 4 years ago

если есть желание, то попробуйте переделать water_heater в climate...это очень просто, потому что сущности максимально похожи...

переименуйте файл water_heater в climate. в нем исправьте

from homeassistant.components.water_heater import ( WaterHeaterEntity, SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE, STATE_ELECTRIC, ATTR_TEMPERATURE )

на

from homeassistant.components.climate import ( ClimateEntity, SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE, STATE_ELECTRIC, ATTR_TEMPERATURE )

в файле init.py исправьте в списке доменов water_heater на climate

запускайтесь, ловите мелкие баги, правьте...как запустите - попробуйте подключить в homekit

mksmo commented 4 years ago

Пошел по простому пути и сделал скрипт для включения чайника. Вывел его в виде выключателя в Homekit.

QwertiTarantino commented 4 years ago

Пошел по простому пути и сделал скрипт для включения чайника. Вывел его в виде выключателя в Homekit.

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

vrslev commented 3 years ago

Я добавил в HomeKit чайник как Climate (через шаблон Generic Thermostat). То есть, сначала создал выключатель (тоже из темплейта) и сенсор текущей температуры, а также автоматизацию для переключения температуры.

Всё работает. Но есть существенная проблема: температура поддерживается, чайник все время на подогреве. Никак не могу побороть это 🤔

mavrikkk commented 3 years ago

нет такой функции в чайнике. Во всяком случае в моем G200S на момент написания интеграции не было. Может с обновлением прошивки добавили. В чайнике есть команды:

  1. кипятить
  2. подогревать и поддерживать нет функции нагреть 1 раз. Я в одном из обновлений сам добавлял эту возможность дополнительным свичом (поддерживать-не поддерживать), работало это так: каждый раз при обновлении статуса проверялась выставленная температура, текущая температура, режим работы чайника и положение свича: если режим подогрев, свич выключен и температура текущая больше установленной, то чайник выключался.

Вы можете решить эту проблему Автоматизацией HA: Условие Текущая температура больше установленной, триггер - включен режим подогрев, действие - выключить чайник

vrslev commented 3 years ago

Функции поддержки температуры нет и в моём чайнике) Видимо, HomeKit форсирует включение при первой возможности (когда температура опускается на 1 градус, например)

mavrikkk commented 3 years ago

Функции поддержки температуры нет и в моём чайнике

Вы неправильно поняли. Как раз наоборот! Нет функции нагреть и выключить (во всяком случае я такую не нашел команду на тот момент). Если вклчаешь нагрев, то чайник постоянно будет греться, это его нативное поведение. Если нужно иное, то выше я написал, как сделать: Автоматизация - и нет проблем

vrslev commented 3 years ago

Теперь более менее понятно. Но вот алгоритм в предложенной автоматизации я не понял.

Условие Текущая температура больше установленной, , действие - выключить чайник

  1. Если, к примеру, текущая температура 100 градусов, установленная такая же. Вода остыла на 1 градус и HomeKit посылает запрос подогреть до 100 градусов. Автоматизация же не будет работать триггер - включен режим подогрев
  2. А где этот режим взять? Его ведь нет в сущности water_heater чайника
mavrikkk commented 3 years ago
  1. Вода остыла на 1 градус и HomeKit посылает запрос подогреть до 100 градусов

Не попросит, он не умеет. Он тупо первоначально отдает команду подогреть, а постоянно подогревает сам чайник. Чтобы он этого не делал, нужно выключить его и все. И что значит ПОДОГРЕТЬ до 100 градусов? это уже тупо вскипятить, зачем кому то подогревать постоянно до 100?

  1. А где этот режим взять? Его ведь нет в сущности water_heater чайника

Еще как есть: @property def current_operation(self):

Это свойство может иметь 3 значения: Выкл, Кипятить, Подогреть

vrslev commented 3 years ago

По поводу подогрева: я согласен, нет смысла постоянно подогревать воду до 100 градусов. Поэтому я и хочу от этого избавиться.

Сейчас попробую продемонстрировать суть проблемы. Включил чайник на 100 градусов, он вскипятился. В HomeKit ничего не изменилось (оранжевый кружочек отвечает за вкл/выкл):

Снимок экрана 2021-02-04 в 14 13 11

В то же самое время в Home Assistant:

Снимок экрана 2021-02-04 в 14 13 31

Status: Off Climate (самодельный из темплейта): Off Water_heater: Off

Казалось бы, всё окей. Но нет, при первой возможности чайник снова включится, все объекты перейдут в режим On (или Boil — тут не имеет значения). А в HomeKit чайник так и останется всегда включенным

mavrikkk commented 3 years ago

теперь понял.

В принципе логичное поведение )) Это ж Климат! Смысл климата ПОДДЕРЖИВАТЬ, вот он и старается )) (притом еще надо почитать, кто старается то, homekit или homeassistant). Попробуйте дать команду не через homekit, а с homeassistant, но именно климату, а не чайнику. И если будет также - то виноват HA, если не будет включаться, то HomeKit

Также можно попробовать делать не через климат: Либо ждать когда вотер хеатер появится, либо переделывать в свич (но тогда совсем пропадет возможность нагревать до любой температуры отличной от 100)

vrslev commented 3 years ago

Проверил, оказалось, Home Assistant настаивал на подогреве) Капнул немного глубже и сделал автоматизацию, которая выключает объект Climate, когда выключается Switch, дублирующий функционал Water Heater:

  - trigger:
      platform: state
      entity_id: switch.kettle
      to: "off"
    action:
      service: climate.turn_off
      data:
        entity_id: climate.kettle

Конфигурация в configuration.yaml:

climate:
  platform: generic_thermostat
  name: Kettle
  heater: switch.kettle
  target_sensor: sensor.kettle_current_temp
  min_temp: 40
  max_temp: 100
  initial_hvac_mode: "off"

sensor:
  platform: template
  sensors:
    kettle_current_temp:
      value_template: "{{ state_attr('water_heater.kettle_rk_m216s', 'current_temperature') }}"

switch:
  platform: template
  switches:
    kettle:
      value_template: "{{ states('water_heater.kettle_rk_m216s') == 'electric' }}"
      turn_on:
        entity_id: water_heater.kettle_rk_m216s
        service: water_heater.set_operation_mode
        data:
          operation_mode: electric
      turn_off:
        entity_id: water_heater.kettle_rk_m216s
        service: water_heater.set_operation_mode
        data:
          operation_mode: 'off'

automation control_climate_kettle:
  - trigger:
      platform: state
      entity_id: climate.kettle
      attribute: temperature
    action:
      service: water_heater.set_temperature
      entity_id: water_heater.kettle_rk_m216s
      data_template:
        temperature: "{{ state_attr('climate.kettle', 'temperature') }}"
  - trigger:
      platform: state
      entity_id: switch.kettle
      to: "off"
    action:
      service: climate.turn_off
      data:
        entity_id: climate.kettle

Снимок экрана 2021-02-04 в 15 49 26Снимок экрана 2021-02-04 в 15 51 05

mavrikkk commented 3 years ago

Проверил, оказалось, Home Assistant настаивал на подогреве

вот, о чем я и писал )

хорошо, что вы в итоге нашли для себя выход )

vrslev commented 3 years ago

Открыл Issue: https://github.com/home-assistant/core/issues/45972. Уже есть Pull Request, в ближайшее время, видимо, починят

iamuvirus commented 3 years ago

vrslev спасибо, работает. Как это исправить? Стоит в настройках C. Причем 187 это 87C текущая температура, а 80 это я задал через Siri.

PS: Выяснил что так происходит когда диктуешь ей температуру больше 50С, до 50 адекватно воспринимает. download

vrslev commented 3 years ago

Хм, странная проблема. Скоро не придётся пользоваться костылем с Climate. В ветке HA Core сейчас переделывать сущность Water Heater. И автор интеграции HomeKit потом собирается переделать свою часть)

sbasmanov commented 1 year ago

@vrslev скопипастил себе эту автоматизацию с климатом, но что-то у меня какие-то чудеса происходят. Если в приложении Home выставить температуру и включить - всё работает. Если попросить Siri - на любую команду говорит - охлаждаю до 40 градусов Си :) Вот с другим климатом вроде нормально работает, а с этим прям никак не хочет. Есть мысли куда копать?

vrslev commented 1 year ago

@sbasmanov Перестал пользоваться Home Assistant, HomeKit и кастомными конфигурациями)

sbasmanov commented 1 year ago

@sbasmanov Перестал пользоваться Home Assistant, HomeKit и кастомными конфигурациями)

Эх, жаль. Думал почерпнуть немного опыта :) Ладно, буду строить костыли дальше :) Покупать чайник с homekit я пока еще не созрел :)

sbasmanov commented 1 year ago

В общем эту шляпу можно заставить работать без дополнительных автоматизаций, нужен только climate_template https://github.com/jcwillox/hass-template-climate

  - platform: climate_template
    unique_id: kettle1
    name: kettle1
    modes:
      - "heat"
      - "off"
    min_temp: 40
    max_temp: 100
    current_temperature_template: "{{ state_attr('water_heater.kettle_rk_g210s', 'current_temperature') }}"
    target_temperature_template: "{{ state_attr('water_heater.kettle_rk_g210s', 'temperature') }}"
    set_temperature:
      service: water_heater.set_temperature
      entity_id: water_heater.kettle_rk_g210s
      data_template:
        temperature: "{{ temperature | int }}"
    set_hvac_mode: 
      service: water_heater.set_operation_mode
      entity_id: water_heater.kettle_rk_g210s
      data: 
        operation_mode: "{{ iif(hvac_mode == 'heat', 'electric', 'off', 'off') }}"
    hvac_mode_template: >-
      {% if is_state('water_heater.kettle_rk_g210s', 'electric') %} heat
      {% else %} off
      {% endif %}

Остается единственный косяк - в iOS 15 Siri криво понимает температуры. И даже с учетом того, что везде, где только можно, стоит C, команда "включи чайник на 150 градусов" приводит к установке 66 градусов по Цельсию. При этом если сказать "включи чайник на 60 градусов Цельсия" - то магически эта зараза понимает, чего от неё хотят :) На реддите (https://www.reddit.com/r/HomeKit/comments/toom40/siri_not_setting_right_temp_ecobee_3_any_ideas_to/) пишут что это баг и dev team о нем в курсе. Но когда пофиксят - хз. Так что остается либо через команды (фиксированные значения), либо через Home App.