Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
DmitriySolomatin opened this issue Jun 1, 2020 · 22 comments
Open

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

DmitriySolomatin opened this issue Jun 1, 2020 · 22 comments

Comments

@DmitriySolomatin
Copy link

При интеграции в HomeKit появляется аксессуар в таком виде:

В списке аксессуаров Экран аксессуара
photo_2020-06-01_17-49-03 photo_2020-06-01_17-49-03 (2)

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

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

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

@DmitriySolomatin
Copy link
Author

Немного почитал 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
Copy link
Owner

mavrikkk commented Jun 4, 2020

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

@mavrikkk
Copy link
Owner

mavrikkk commented Jun 4, 2020

если есть желание, то попробуйте переделать 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
Copy link

mksmo commented Aug 13, 2020

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

@QwertiTarantino
Copy link

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

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

@vrslev
Copy link

vrslev commented Feb 4, 2021

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

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

@mavrikkk
Copy link
Owner

mavrikkk commented Feb 4, 2021

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

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

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

@vrslev
Copy link

vrslev commented Feb 4, 2021

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

@mavrikkk
Copy link
Owner

mavrikkk commented Feb 4, 2021

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

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

@vrslev
Copy link

vrslev commented Feb 4, 2021

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

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

  1. Если, к примеру, текущая температура 100 градусов, установленная такая же. Вода остыла на 1 градус и HomeKit посылает запрос подогреть до 100 градусов. Автоматизация же не будет работать

триггер - включен режим подогрев

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

@mavrikkk
Copy link
Owner

mavrikkk commented Feb 4, 2021

  1. Вода остыла на 1 градус и HomeKit посылает запрос подогреть до 100 градусов

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

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

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

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

@vrslev
Copy link

vrslev commented Feb 4, 2021

По поводу подогрева: я согласен, нет смысла постоянно подогревать воду до 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
Copy link
Owner

mavrikkk commented Feb 4, 2021

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

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

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

@vrslev
Copy link

vrslev commented Feb 4, 2021

Проверил, оказалось, 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
Copy link
Owner

mavrikkk commented Feb 4, 2021

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

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

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

@vrslev
Copy link

vrslev commented Feb 6, 2021

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

@iamuvirus
Copy link

iamuvirus commented Feb 23, 2021

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

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

@vrslev
Copy link

vrslev commented Feb 23, 2021

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

@sbasmanov
Copy link

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

@vrslev
Copy link

vrslev commented Oct 24, 2022

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

@sbasmanov
Copy link

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

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

@sbasmanov
Copy link

В общем эту шляпу можно заставить работать без дополнительных автоматизаций, нужен только 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants