Как настроить Tuya TS0201 Neo в Home Assistant ZHA: чтобы датчики температуры и влажности наконец заработали
Почему датчик _TZ3000_qaaysllp теряет показания и как это исправить с помощью кастомного quirk
Я приобрел датчик температуры, влажности и освещенности Neo Tuya TS0201 (идентификатор производителя _TZ3000_qaaysllp, также известный как NAS-TH02B2), рассчитывая на простую настройку в ZHA. Синхронизировался он нормально — батарея и освещенность появились сразу. Но температуры и влажности не было вовсе. Никаких сущностей, никаких данных, ничего.
Существующий quirk в zha-device-handlers должен был обслуживать это устройство, но не помог. После нескольких часов копания в перехваченных Zigbee-пакетах и отладочных логах ZHA я выяснил, что проблема имеет три отдельных уровня — а апстримный quirk закрывает лишь один из них. В этой статье я разбираю всё, что нашёл, и предлагаю рабочий фикс.
Симптомы: что вы увидите
После сопряжения ZHA обычно показывает:
- Процент заряда батареи — работает нормально
- Освещенность — работает нормально
- Температура — показатель отсутствует или отображается
unknown/0 - Влажность — сущность отсутствует или показывает
unknown/0
В логах Home Assistant (с включенной отладкой ZHA) можно увидеть сообщения типа:
Ignoring message on unknown endpoint 2
Или во время настройки устройства:
UNSUPPORTED_ATTRIBUTE on cluster 0x0402 (TemperatureMeasurement)UNSUPPORTED_ATTRIBUTE on cluster 0x0405 (RelativeHumidity)
Почему так происходит: первопричина
Эта проблема имеет три уровня, и чтобы датчик заработал, нужно устранить неисправности на всех трёх. Вот что происходит под капотом.
Уровень 1: устройство предоставляет неверную информацию о своих возможностях
Каждое Zigbee-устройство транслирует «простой дескриптор» (simple descriptor), который сообщает координатору, какие кластеры (функции) оно поддерживает и на каких эндпоинтах. TS0201 Neo анонсирует следующее:
Конечная точка 1: Basic, PowerConfiguration, IlluminanceMeasurement, Tuya Alarm (0xE002)
Обратите внимание, чего не хватает: TemperatureMeasurement (0x0402) и RelativeHumidity (0x0405) не указаны вообще. Устройство просто не сообщает, что умеет измерять температуру или влажность.
Уровень 2: данные поступают на неанонсированный эндпоинт
После определенной последовательности активации (о ней ниже) устройство все же начинает отправлять данные о температуре и влажности — но на конечную точку 2, о которой оно координатору никогда не сообщало. zigpy, библиотека Zigbee, которую использует ZHA, вполне справедливо отбрасывает эти сообщения:
Ignoring message on unknown endpoint 2
Существующий апстрим-quirk в zha-device-handlers (zhaquirks/tuya/ts0201.py) всё-таки добавляет виртуальный endpoint 2 в модель устройства, что частично решает эту проблему. Но он не исправляет остальные два уровня.
Уровень 3: отсутствует последовательность активации
Даже с указанным endpoint 2 устройство не начнет передавать данные о температуре и влажности, пока не получит так называемый «Tuya magic packet» — считывание определенных атрибутов кластера Basic, в первую очередь — специфичного для производителя атрибута 0xFFFE. Это тот же механизм, который zigbee2mqtt реализует как tuya.configureMagicPacket.
апстримовый quirk для ZHA этот magic packet не отправляет. Без него endpoint 2 существует в модели устройства, но устройство никогда не отправляет на него никаких данных.
Бонусный уровень: UNSUPPORTED_ATTRIBUTE уничтожает сущности
Когда ZHA инициализирует устройство, она считывает атрибуты, чтобы определить, какие сущности Home Assistant следует создать. Это устройство соответствует UNSUPPORTED_ATTRIBUTE (код ошибки 0x86) при прямом чтении кластеров температуры и влажности. Quirk «Апстрим» использует голые ID кластеров на endpoint 2, поэтому эти запросы доходят до устройства и завершаются сбоем. ZHA обнаруживает ошибку и вообще пропускает создание сущностей.
Фикс: пользовательский quirk для ZHA
Я опубликовал рабочий quirk, который закрывает все три уровня: ts0201.py — GitHub Gist
Чем отличается этот quirk
По сравнению с версией из апстрима, этот quirk добавляет:
- Mixin
TuyaCachedReadCluster— перехватывает вызовыread_attributes()и возвращает кэшированные значения (из предыдущих отчетов) или нулевое значение по умолчанию. Также он вызывает_update_attribute(), чтобы уведомить цепочку слушателей ZHA, обеспечивая создание сущностей даже тогда, когда устройство возвращаетUNSUPPORTED_ATTRIBUTE. - Magic packet в
bind()— когда ZHA настраивает подписки на отчеты в кластере alarm, quirk сначала считывает атрибуты кластера Basic, в частности специфический для Tuya0xFFFE. Это активирует стандартную отчетность кластеров устройства на endpoint 2. - Исправление бага: ID атрибута
alarm_humidity_max— в апстрим-quirk он указан как0xD00C, но на самом деле устройство отправляет отчет0xD00D. Проверено на реальных данных устройства. NodeDescriptor— добавлено в словарь замены (replacement dict), скопировано из реального ответа устройства.- Пользовательские классы кластеров на EP2 — вместо «голых» ID кластеров (которые просто маршрутизируют сообщения, но не переопределяют поведение) quirk использует классы
TuyaTemperatureMeasurementиTuyaRelativeHumidity, которые наследуют поведение кэшированного чтения.
Установка: пошаговая инструкция
Шаг 1: создайте каталог для пользовательских quirks
Если вы ещё этого не сделали, создайте каталог для пользовательских quirks. С помощью файлового редактора Home Assistant, SSH или Samba:
/homeassistant/custom_zha_quirks/
Шаг 2: загрузите quirk
Загрузите ts0201.py с GitHub Gist и поместите его в:
/homeassistant/custom_zha_quirks/ts0201.py
Шаг 3: настройте ZHA на использование пользовательских режимов
Добавьте это в свой configuration.yaml:
zha: custom_quirks_path: /config/custom_zha_quirks
Шаг 4: перезапустите Home Assistant
Требуется полный перезапуск — не просто перезагрузка конфигурации.
Шаг 5: удалите устройство и выполните сопряжение заново
Этот шаг очень важен. Многие особенности вступают в силу только во время сопряжения устройства (процесса сопряжения). После перезапуска:
- Перейдите в «Настройки» > «Устройства и службы» > «ZHA»
- Найдите устройство TS0201 и удалите его
- Переведите датчик в режим сопряжения (обычно длительным нажатием кнопки)
- Снова сопрягите устройство через ZHA
После сопряжения устройства потребуется минута-две, чтобы полностью настроиться (у устройств Tuya ограничение на параллелизм составляет примерно 2 одновременных запроса, поэтому настройка происходит последовательно). Когда всё завершится, вы должны увидеть:
- Температура — обновляется с реальными значениями
- Влажность — обновляется с реальными значениями
- Освещенность — работает как и раньше
- Батарея — работает как и раньше
Как это работает: техническое погружение
Для тех, кто хочет понять механику, вот поток данных после применения quirk:
Device pairs → ZHA applies quirk (signature matches _TZ3000_qaaysllp / TS0201) → Replacement creates virtual EP2 with custom cluster classes
ZHA configures EP1 alarm cluster → bind() override triggers magic packet → Reads Basic attributes [0x0000, 0x0001, 0x0004, 0x0005, 0x0007, 0xFFFE] → 0xFFFE activates the device's reporting mechanism
Device starts sending unsolicited reports on EP2 → TemperatureMeasurement (0x0402): measured_value in hundredths of °C → RelativeHumidity (0x0405): measured_value in hundredths of %
ZHA reads attributes during init → TuyaCachedReadCluster intercepts the read → Returns cached value (or 0 if no report yet) → Calls _update_attribute() → ZHA creates the HA entity
Ongoing operation → Device sends reports every ~1 minute (or on significant change) → zigpy routes to EP2 → custom cluster → _update_attribute() → HA entity updates
Почему _update_attribute() важен
В zigpy _update_attribute() — это центральный механизм уведомлений. При вызове он:
- Обновляет внутренний
_attr_cacheкластера - Запускает колбек
zdo.ATTR_UPDATED ClusterHandlerв ZHA, получает его и обновляет сущность Home Assistant
Без вызова _update_attribute() в переопределении кэшированного чтения ZHA никогда бы не узнала о значении и не создавала бы сущностей.
Почему работает magic packet
Атрибут 0xFFFE — это специфический для Tuya механизм. Его считывание сообщает устройству: «Я — Tuya-совместимый координатор, пожалуйста, начни отправлять мне данные через стандартные ZCL-кластеры». Без этого считывания устройство остается без отклика на EP2. Это хорошо задокументировано в кодовой базе zigbee2mqtt как configureMagicPacket.
Подтвержденные рабочие значения
После применения этого quirk вот реальные значения, полученные от устройства (из отладочных логов ZHA):
- TemperatureMeasurement (EP2) — measured_value: 2640 → 26,40 °C
- RelativeHumidity (EP2) — measured_value: 4100 → 41,00 %
- IlluminanceMeasurement (EP1) — measured_value: 0 → 0 люкс
- PowerConfiguration (EP1) — battery_percentage_remaining: 200 → 100%
Значения температуры и влажности обновляются примерно каждую минуту или при обнаружении значительного изменения (>=0,5 °C или >=5 % влажности).
Часто задаваемые вопросы
Работает ли это с моделью NAS-TH02B2?
Neo NAS-TH02B2 — самая распространённая физическая модель, которая по Zigbee идентифицирует себя как _TZ3000_qaaysllp / TS0201. Да, этот quirk предназначен именно для этого устройства.
Не возникнет ли при этом конфликт с quirk «upstream»?
Нет. Пользовательские quirks custom_zha_quirks имеют приоритет над встроенными quirks, когда сигнатура устройства совпадает. Апстримовый quirk будет проигнорирован в пользу вашего.
Нужен ли мне для этого zigbee2mqtt?
Нет. Этот фикс предназначен исключительно для ZHA (встроенной Zigbee-интеграции Home Assistant). Если вы используете zigbee2mqtt, поддержка устройств Tuya реализована иначе — через их систему конвертеров, где configureMagicPacket он уже встроен.
Устройство сопряглось, но температура по-прежнему показывает ноль
Подождите 2–3 минуты после сопряжения. Устройству необходимо завершить свой первый цикл отчетности. Если через 5 минут показатель по-прежнему равен нулю, проверьте свои логи ZHA на наличие magic packet:
[zha.zigbee.cluster_handlers] [0xABCD](tuya_alarm): bind 'Tuya Temperature and Humidity Alarm Cluster' cluster
Если вы видите это, а вслед за ним — считывание кластера Basic, значит, magic packet был отправлен.
Могу ли я использовать это с другими вариантами TS0201?
Эта особенность предназначена именно для _TZ3000_qaaysllp. Другие варианты TS0201 (например _TZ3000_fllyghyj, _TZ3000_lfa05ajd, _TZ3210_ncw88jfq) ведут себя иначе и могут потребовать других quirk. Сопоставление сигнатур гарантирует, что этот quirk применяется только к нужному устройству.
Мой показатель влажности застрял на отметке 5%
Это известная проблема, о которой сообщают некоторые пользователи даже с работающими quirks. Она может указывать на аппаратный дефект самого датчика (чипа Sensirion SHTC3), а не на проблему с quirk. Попробуйте заменить батарейки и выполнить сопряжение заново.
Связанные ресурсы
- Рабочий quirk (GitHub Gist) — скачать
ts0201.pyздесь - Упстрим-версия quirk (zha-device-handlers) — встроенная версия, на которой это основано
- Первоначальный запрос на поддержку устройства (#862) — GitHub-issue, отслеживающий это устройство
- Как установить пользовательские quirks для ZHA — руководство сообщества по установке пользовательских quirks
- Репозиторий обработчиков устройств ZHA — официальный репозиторий quirks
- Обсуждение Tuya magic packet в zigbee2mqtt — технические детали механизма 0xFFFE
- Обзор Neo NAS-TH02B2 (SmartHomeScene) — обзор аппаратного обеспечения и характеристики
Если вы сталкиваетесь с похожим датчиком Tuya, который сопрягается, но не передает данные в ZHA, описанный здесь паттерн — отсутствующий эндпоинт, активация через magic packet, кешированные чтения для предотвращения UNSUPPORTED_ATTRIBUTE — применим ко многим устройствам Tuya, а не только к TS0201. Надеюсь, это сэкономит вам те часы, которые я потратил, чтобы в этом разобраться.