YandexStation icon indicating copy to clipboard operation
YandexStation copied to clipboard

Кондиционер HAIER FLEXIS SUPER MATCH AS25S2SF2FA-W hvac_modes: null

Open VSDodonov opened this issue 1 year ago • 12 comments

Кондиционер HAIER FLEXIS SUPER MATCH AS25S2SF2FA-W добавлен в УДЯ через интеграцию приложения EVO. hvac_modes: null - нет управления в HA, отображается только температура. image image image Информация из https://iot.quasar.yandex.ru/m/user/devices/ID {"status":"ok","request_id":"e7093072-adae-49c9-985b-51877eaf8aa4","id":"1185b158-b0d2-4305-9195-e522af843e7a","name":"Кондиционер","names":["Кондиционер"],"type":"devices.types.thermostat.ac","icon_url":"https://avatars.mds.yandex.net/get-iot/icons-devices-devices.types.thermostat.ac.svg/orig","state":"online","groups":[],"room":"Гостиная","capabilities":[{"retrievable":true,"type":"devices.capabilities.on_off","state":{"instance":"on","value":true},"parameters":{"split":false}},{"retrievable":true,"type":"devices.capabilities.range","state":{"instance":"temperature","value":24},"parameters":{"instance":"temperature","name":"температура","unit":"unit.temperature.celsius","random_access":true,"looped":false,"range":{"min":16,"max":30,"precision":1}}},{"retrievable":true,"type":"devices.capabilities.mode","state":{"instance":"program","value":"cool"},"parameters":{"instance":"program","name":"программа","modes":[{"value":"cool","name":"Охлаждение"},{"value":"heat","name":"Нагрев"},{"value":"fan_only","name":"Вентиляция"},{"value":"dry","name":"Осушение"},{"value":"auto","name":"Авто"}]}},{"retrievable":true,"type":"devices.capabilities.mode","state":{"instance":"fan_speed","value":"min"},"parameters":{"instance":"fan_speed","name":"скорость вентиляции","modes":[{"value":"auto","name":"Авто"},{"value":"max","name":"Максимальный"},{"value":"min","name":"Минимальный"},{"value":"normal","name":"Нормальный"}]}},{"retrievable":true,"type":"devices.capabilities.toggle","state":{"instance":"mute","value":false},"parameters":{"instance":"mute","name":"без звука"}},{"retrievable":true,"type":"devices.capabilities.toggle","state":{"instance":"controls_locked","value":false},"parameters":{"instance":"controls_locked","name":"блокировка управления"}}],"properties":[{"type":"devices.properties.float","retrievable":true,"reportable":false,"parameters":{"instance":"temperature","name":"температура","unit":"unit.temperature.celsius"},"state":{"percent":null,"status":null,"value":23},"state_changed_at":"2023-04-19T19:48:49Z","last_updated":"2023-04-19T19:53:44Z"}],"skill_id":"e23ddc88-6be9-4246-a2a7-fe6152a92175","external_id":"36302","favorite":true}

VSDodonov avatar Apr 19 '23 20:04 VSDodonov

+1 ситуация полностью идентична еще заметил, если вывести через custom:mushroom-climate-card image и нажать на на активацию, вылазит следующее сообщение с ошибкой Не удалось вызвать службу climate/turn_on. argument of type 'NoneType' is not iterable

wbln avatar May 16 '23 08:05 wbln

@AlexxIT крч, у этого кондея 1 параметр по другому называется. нужно внести правки в 4 места:

в файле custom_components/yandex_station/climate.py 1 - заменить в 189 строке

              elif instance == "thermostat":

на

              elif instance == "program":

2 - заменить в 158 строке

              elif instance == "thermostat":

на

              elif instance == "program":

3 - заменить в 129 строке

              self.device["id"], on=True, thermostat=hvac_mode

на

              self.device["id"], on=True, program=hvac_mode

и в файле custom_components/yandex_station/core/yandex_quasar.py 4 - заменить в 340 строке

                "devices.capabilities.custom.button" if k.isdecimal() else  IOT_TYPES[k]

на

                "devices.capabilities.custom.button" if k.isdecimal()
                else "devices.capabilities.mode" if k == "program"
                else IOT_TYPES[k]

как это по красоте сделать - ХЗ, по этому пулл-реквест делать не буду (влом после ревью ковыряться если понадобится) у меня локально все работает. если в какой нибудь обнове поправите - будет здорово, а нет - так и пофих, кому надо - сами поправят локально.

image image

wbln avatar Jun 18 '23 01:06 wbln

@wbln спасибо тебе, добрый человек! Помогло с кондеем AS35S2SF2FA-B. Подозреваю что эта проблема касается всех кондиционеров итегрирующихся в УДЯ через EVO приложение

@AlexxIT вот бы пофиксить... что б каждый раз не лазить в код... Спасибо!

ups: есть проблемы с настройками режимов работы из HA

Kirorus avatar Jun 27 '23 14:06 Kirorus

@wbln Спасибо, помогло!

TovArtem avatar Jun 28 '23 14:06 TovArtem

@wbln, спасибо огромное! AS25S2SF2FA так же заработал, однако, в режим обогрева переключать не хочет. Появляется вот такое уведомление:

Screenshot_3

А в логе вижу следующее:

Logger: homeassistant.components.websocket_api.http.connection

Source: custom_components/yandex_station/core/yandex_quasar.py:355
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 24 июля 2023 г. в 22:44:11 (6 occurrences)
Last logged: 24 июля 2023 г. в 22:47:25

[140710585256720] {'request_id': 'df7ee461-add0-4e28-a694-e53972cb5e19', 'status': 'error', 'code': 'INTERNAL_ERROR', 'message': 'Случилось что-то непонятное. Подождите немного и попробуйте ещё раз.'}
[140710585256720] {'request_id': '3a84db04-d89c-492e-9caf-7a975f5a7501', 'status': 'error', 'code': 'INTERNAL_ERROR', 'message': 'Случилось что-то непонятное. Подождите немного и попробуйте ещё раз.'}
[140710585256720] {'request_id': 'f07826bd-e298-40c5-a7bf-fa1c1444661b', 'status': 'error', 'code': 'INTERNAL_ERROR', 'message': 'Случилось что-то непонятное. Подождите немного и попробуйте ещё раз.'}
[140710585256720] {'request_id': 'fa7ba29d-fd64-420d-ae88-ad5bb53e8bbc', 'status': 'error', 'code': 'INTERNAL_ERROR', 'message': 'Случилось что-то непонятное. Подождите немного и попробуйте ещё раз.'}
[140710585256720] {'request_id': '261dd969-2d14-4900-b451-a2ca60a87ce3', 'status': 'error', 'code': 'INTERNAL_ERROR', 'message': 'Случилось что-то непонятное. Подождите немного и попробуйте ещё раз.'}
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 205, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1965, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2005, in _execute_service
    return await cast(
           ^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 235, in handle_service
    return await service.entity_service_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 848, in entity_service_call
    response_data = task.result()  # pop exception if have
                    ^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1192, in async_request_call
    return await coro
           ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 892, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/config/custom_components/yandex_station/climate.py", line 124, in async_set_hvac_mode
    await self.quasar.device_action(
  File "/config/custom_components/yandex_station/core/yandex_quasar.py", line 355, in device_action
    assert resp["status"] == "ok", resp
           ^^^^^^^^^^^^^^^^^^^^^^
AssertionError: {'request_id': '21a5229b-412d-4b59-a964-105bfd8d7576', 'status': 'error', 'code': 'INTERNAL_ERROR', 'message': 'Случилось что-то непонятное. Подождите немного и попробуйте ещё раз.'}

У вас также?

upd: Действительно режимы из HA переключаются некорректно. На секунду переключает на выбранный режим, а затем сразу обратно в тот, что был установлен изначально. Но именно на обогрев не переключает вообще, выдаёт ошибку как на скриншоте выше.

Napalmcold avatar Jul 24 '23 22:07 Napalmcold

Napalmcold починил крч эту шайтан машину.

1 - обогрев, осушение, вентиляция проблема была в том, что был еще 1 пункт, в котором нужно было изменить "thermostat" на "program", но когда я его менял в лоб - интеграция работала криво, по этому, я отказался ковыряться и разбираться что с ней не так, да и не нужна мне она особо, кондей на обогрев - это какое-то кощунство, но ок, надо значит надо =)

в файле custom_components/yandex_station/climate.py начиная со 117 строки, есть вот такой код, в котором есть кусок, очень похожий на костыль,

    async def async_set_hvac_mode(self, hvac_mode):
        if hvac_mode == HVAC_MODE_OFF:
            await self.quasar.device_action(self.device["id"], on=False)
        elif hvac_mode == HVAC_MODE_HEAT:  <=== вот это и ниже выглядит странным
            if self._preset_modes is not None:
                await self.quasar.device_action(self.device["id"], on=True)
            else:
                await self.quasar.device_action(
                    self.device["id"], on=True, thermostat=hvac_mode
                )
        else:   <=== примерно вот до сюда
            await self.quasar.device_action(
                self.device["id"], on=True, thermostat=hvac_mode
            )

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

    async def async_set_hvac_mode(self, hvac_mode):
        if hvac_mode == HVAC_MODE_OFF:
            await self.quasar.device_action(self.device["id"], on=False)
        else:
            if self._preset_modes is not None:
                await self.quasar.device_action(self.device["id"], on=True)
            else:
                await self.quasar.device_action(self.device["id"], on=True, program=hvac_mode)

причем даже тут есть место, которое оставил как есть (проверка if self._preset_modes is not None:) по тому что не знаю, вдруг туда что-то действительно когда-то приходит (у меня не приходило, и код не выполнялся, но пусть будет.

после чего - все режимы стали работать, но...

2 - переключение на предыдущий режим. сначала я подумал, что я криворукий, и мои костыли что-то сломали, но нет (я то криворукий, но костыли нормальные =)). В открытых ишью, я вижу, что проблема эта есть не только на наших кондеях, а значит, проблема более масштабная, ну и пришлось чуть-чуть подумать. Путем тыканий "пальцем в небо" было найдено костыльное, но вроде бы рабочее решение, которое превратило код выше в следующий:

    async def async_set_hvac_mode(self, hvac_mode):
        if hvac_mode == HVAC_MODE_OFF:
            await self.quasar.device_action(self.device["id"], on=False)
        else:
            if self._preset_modes is not None:
                await self.quasar.device_action(self.device["id"], on=True)
            else:
                if (self._is_on):
                    await self.quasar.device_action(self.device["id"], program=hvac_mode)
                    await self.quasar.device_action(self.device["id"], fan_speed='min')
                else:
                    await self.quasar.device_action(self.device["id"], on=True, program=hvac_mode, fan_speed='min')

еще добавил включение вентилятора на минимум при переходе между режимами, а то он иногда включается на авто, а это иногда громко, стоило это - дополнительного пика кондея, но IMHO не страшно.

единственный минус, HA сейчас не всегда меняет статус в своем UI, т.е. кондей переключается допустим с охлаждения на обогрев, в EVO показывает, что кондей переключился, а HA показывает охлаждение (да, знаю, обновляется статус не сразу, но он иногда вобще не обновляется, и что с этим делать - ХЗ, но да и пофиг)

так же, нашел, как изящнее сделать в custom_components/yandex_station/core/yandex_quasar.py

вместо накостыливания проверки (как я описал выше) можно просто добавить параметр в енум IOT_TYPES, т.е. добавить строку

    "program": "devices.capabilities.mode",

что бы получилось как-то так:

    "fan_speed": "devices.capabilities.mode",
    "thermostat": "devices.capabilities.mode",
    "program": "devices.capabilities.mode",
    "heat": "devices.capabilities.mode",
    "volume": "devices.capabilities.range",

а то, что я писал выше про поменять

                "devices.capabilities.custom.button" if k.isdecimal() else  IOT_TYPES[k]

на

                "devices.capabilities.custom.button" if k.isdecimal()
                else "devices.capabilities.mode" if k == "program"
                else IOT_TYPES[k]

делать не надо уже.

image image image image image

wbln avatar Aug 11 '23 08:08 wbln

@wbln, привет!

Переустановил интеграцию, и поменял все строчки, которые ты указал в последних двух постах, в том числе с учётом того, что 4й пункт из первого поста уже делать не надо. По итогу ошибка пропала, но режимы переключаются всё равно странно. То нормально, то всё равно переключаются обратно на предыдущий. В логах никаких ошибок не вижу по интеграции. Сам не пробовал попереключаться между режимами туда сюда? По моим наблюдениям, косяки с откатом к предыдущему состоянию случаются чаще, когда переходишь из охлаждения на какой-либо другой или из вентиляции. Вот из вентиляции вообще редко получается уйти в другой режим, к примеру в обогрев, постоянно уходит назад.

Napalmcold avatar Aug 29 '23 17:08 Napalmcold

@Napalmcold из за архитектуры интеграции, ожидать какого-то, близкого к идеальному, взаимодействия тут и не стоит, на то есть ряд причин: 1 - мы цепляем кандер к облаку яндекса 2 - мы цепляем HA к облаку яндекса через облачную прокладку 3 - хайер, прям наплевательски относится к поддержке и обновлениям (не знаю как всей, но конкретно этих кондеров точно) а значит прошивка на ESP'шке в кондее - хреновая. Что говорить, через EVO порой кондей не отвечает, а с пульта порой включаются не те режимы. 4 - ПО кондея даже не смотрит в сторону гарантированной доставки 5 - все запросы из HA, через все эти прослойки отправляются асинхронно, а значит чтоб хоть как-то сделать подобие гарантированной доставки, они могут отправляться до 5 раз. т.е. отправил что надо выключить, ответа нет, отправил еще что надо выключить, ответа нет, ну ок, не выключаешься, давай тогда хоть сделаем потеплее, кондей выключается, потом включается и делает потеплее, или не включается.

Отсюда вывод первый - не нужно чаще чем в 20-30 секунд переключаться между режимами.

Общался с поддержкой Хайер, они сказали что по mqtt кондей не завязать.

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

Отсюда вывод второй - сильно лучше, уже врядли будет, если не найдется кто-то, кто сделает другую интеграцию, но это будет уже другая история.

wbln avatar Sep 04 '23 15:09 wbln

https://github.com/AlexxIT/YandexStation/releases/tag/v3.13.0

AlexxIT avatar Jan 14 '24 12:01 AlexxIT

Все еще не работает с этим кондеем При изменении режима на 3.13.0 версии пишет, что не хватает ключа program в мапе core/yandex_quasar.py: IOT_TYPES

  File "/usr/src/homeassistant/homeassistant/components/climate/__init__.py", line 646, in async_turn_on
    await self.async_set_hvac_mode(mode)
  File "/config/custom_components/yandex_station/climate.py", line 156, in async_set_hvac_mode
    await self.quasar.device_action(
  File "/config/custom_components/yandex_station/core/yandex_quasar.py", line 351, in device_action
    "type": IOT_TYPES[instance],
            ~~~~~~~~~^^^^^^^^^^
KeyError: 'program'

Если же добавить туда program, то при изменении режима из homeassistant OFF->ANY будет ошибка, вроде, со стороны яндекса:

Не удалось вызвать службу climate/set_hvac_mode. {'request_id': 'x', 'status': 'error', 'code': 'DEVICE_OFF', 'message': 'Сначала нужно включить устройство'}

Видимо, этот кондей требует вначале включать его

await self.quasar.device_action(self.device["id"], "on", True)

А, затем уже менять режим Попробую сам пропатчить. Если все получится - создам MR

Alxspb avatar Jan 18 '24 11:01 Alxspb

Получилось заставить его работать так: git diff (master)

Index: custom_components/yandex_station/core/yandex_quasar.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/custom_components/yandex_station/core/yandex_quasar.py b/custom_components/yandex_station/core/yandex_quasar.py
--- a/custom_components/yandex_station/core/yandex_quasar.py	(revision dd5aab15275990a57191336d46ab2997f8c3101e)
+++ b/custom_components/yandex_station/core/yandex_quasar.py	(date 1705580410359)
@@ -15,6 +15,7 @@
     "temperature": "devices.capabilities.range",
     "fan_speed": "devices.capabilities.mode",
     "thermostat": "devices.capabilities.mode",
+    "program": "devices.capabilities.mode",
     "heat": "devices.capabilities.mode",
     "volume": "devices.capabilities.range",
     "pause": "devices.capabilities.toggle",
Index: custom_components/yandex_station/climate.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/custom_components/yandex_station/climate.py b/custom_components/yandex_station/climate.py
--- a/custom_components/yandex_station/climate.py	(revision dd5aab15275990a57191336d46ab2997f8c3101e)
+++ b/custom_components/yandex_station/climate.py	(date 1705580546631)
@@ -144,7 +144,8 @@
     async def async_set_hvac_mode(self, hvac_mode: HVACMode):
         if hvac_mode == HVACMode.OFF:
             await self.quasar.device_action(self.device["id"], "on", False)
-        elif self.hvac_instance is None:
+        elif self.hvac_instance is None or (
+                self.hvac_instance == "program" and self.state == HVACMode.OFF):
             await self.quasar.device_action(self.device["id"], "on", True)
         else:
             await self.quasar.device_action(

Alxspb avatar Jan 18 '24 12:01 Alxspb

Никто так еще и не разобрался как с такими кондиционерами работать напрямую? Решение evo делал waveaccess, там websocket - адрес сервера есть в коде приложения, а вот набор команд это загадка.

and7ey avatar Mar 21 '24 17:03 and7ey