Архитектурные заметки ZBFun на фоне трендов 2026 года: Matter, облачные сбои и попытка стандартизировать «осмотр» любого устройства


Повод

Октябрь 2026-го выдался показательным месяцем для всей индустрии умного дома. Крупный сбой AWS в одном из американских регионов на несколько часов превратил в кирпичи дверные звонки, умные замки и голосовых ассистентов у тысяч пользователей по всему миру — причём не только у тех, кто сидел на упавшем провайдере напрямую: часть затронутых сервисов просто арендовала инфраструктуру у AWS внутри, невидимо для конечного покупателя устройства.

Параллельно случались и менее громкие, но столь же показательные истории: разовые перебои в работе облачных голосовых платформ задевали заодно и локальные, казалось бы, Zigbee/Matter-устройства — просто потому, что часть служебной логики хаба-колонки всё равно крутится не дома, а на сервере производителя. Один из разборов этой истории прямо формулирует вывод: «умные» устройства ровно настолько умны, насколько умна их архитектура — не маркетинг, а инженерное решение о том, где именно живёт логика.

Это хороший повод систематизировать происходящее — не как разбор одного конкретного инцидента, а как попытку понять, что с индустрией умного дома не так структурно: какие архитектурные решения к этому привели, кто уже пытается это чинить и почему, на наш взгляд, чинят не до конца. А заодно — рассказать, почему в основе нашего ответа на эту проблему лежит не очередной «ещё более локальный хаб», а довольно скучная на первый взгляд вещь: единый машиночитаемый язык описания устройств.


1. Три поколения умного дома — и у каждого своя дыра

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

Поколение 1 — Wi-Fi + облако производителя. Лампочка, розетка, пылесос с чипом внутри, настройка в два тапа в приложении, управление из любой точки мира без лишних телодвижений. Путь команды — даже если телефон лежит в метре от лампы — идёт через интернет на сервер производителя и обратно. Это не баг, а осознанный компромисс: именно так устройство становится управляемым откуда угодно без сложной настройки сети дома. Платой за это стала ровно та картина, которую регулярно показывают крупные облачные инциденты — один упавший сервер, и вся «умная» лампочка включается только кнопкой на корпусе.

Поколение 2 — локальный хаб + mesh-радио (Zigbee). Ответ индустрии на первую проблему: сеть датчиков и исполнителей общается по низкоэнергопотребляющему радиоканалу напрямую с хабом в квартире, без интернета вообще. Сценарий «протечка → перекрыть кран» в теории должен отрабатывать автономно. Это уже архитектурно правильный шаг — собственно, с него и начинался ZBFun. Но у поколения 2 быстро проявилась вторая, не менее болезненная проблема: единого протокола смысла данных на практике не вышло. Производители массово реализуют собственные расширения поверх официального стандарта ZigBee Cluster Library, и каждому хабу/интегратору приходится городить ручные «заплатки» под конкретный бренд. Zigbee спасает от пропажи интернета, но ничего не говорит о том, что делать с диалектами внутри самого протокола.

Поколение 3 — Matter. Общий язык поверх Wi-Fi/Thread, за который наконец сели крупные игроки рынка. Matter действительно снимает часть боли: одно устройство можно одновременно завести и в экосистему крупного вендора, и в независимый хаб, работает локально, не требует облака для базовой команды. Но у стандарта есть два системных узких места, которые отмечают и независимые обзоры его текущего состояния. Во-первых, скорость покрытия типов устройств — стандарт описывает каждый тип устройства отдельно, и вендоры добавляют поддержку по одному типу за раз, так что ещё долго будут оставаться категории устройств «с логотипом Matter на коробке», которые фактически Matter не используют. Во-вторых, и это важнее — ничто не мешает реализовать «свою» версию Matter, формально сертифицированную, но на практике открытую только собственной же экосистеме вендора. Общий язык появился, но диалекты никуда не делись — они просто переехали на новый протокол.

Вывод, к которому мы пришли, анализируя эту динамику: каждое поколение решало инфраструктурную проблему предыдущего, но ни одно не решило проблему семантики — что именно означает конкретный байт в конкретном кластере конкретного устройства, и кто за эту трактовку отвечает.


2. Диагноз: где на самом деле точка отказа

Популярный совет, который сейчас массово дают пользователям умного дома: проверяйте в настройках сценария, не привязан ли он к облаку — часто это прямо обозначено отдельной пометкой в приложении.

Совет разумный, но если посмотреть на него трезво — это ручная проверка постфактум, которую пользователь должен делать сам, листая UI чужого приложения. Система сама не декларирует заранее: «вот это — автономно, вот это — нет». Граница между «работает без интернета» и «превращается в кирпич» нигде не зафиксирована как контракт — она размазана по факту реализации конкретной прошивки конкретного вендора в конкретный момент времени и может измениться со следующим обновлением без предупреждения.

Хуже того: даже когда вся цепочка формально локальная, крупные облачные сбои показывают, что и это не гарантия — потому что сам хаб может зависеть от облака для внутренних системных нужд, о которых пользователь не подозревает (авторизация, проверка лицензии, синхронизация состояния). «Локальность» в массовых системах — это свойство, которое может быть, а может не быть, в зависимости от того, как конкретно вендор развёл логику между устройством, хабом и облаком у себя внутри. Узнать об этом заранее нельзя — только опытным путём, когда уже накрыло.


3. Наш диагноз в двух тезисах

Тезис 1. Граница «автономно / зависимо» должна быть архитектурным контрактом, а не свойством конкретной прошивки.

В ZBFun это не рекомендация пользователю почаще заглядывать в приложение, а разделение, зашитое на уровне проектирования самого устройства. Ещё на этапе визуального конструирования дерева устройства архитектор явно отвечает на вопрос: переживёт ли эта логика обрыв связи с хабом? Если да — она обязана жить прямо на устройстве, и тогда физически нет сценария, в котором очередное обновление прошивки хаба незаметно утащило вашу автоматику «протечка → кран» в облако, потому что так было удобнее разработчику. Если логика принципиально межустройственная — она на хабе, и это тоже явно видно на этапе проектирования, а не выясняется задним числом по пометке в приложении.

Тезис 2. Диалекты — это не баг экосистемы, который нужно перетерпеть, а данность, которую нужно явно документировать.

Разночтения между официальным стандартом и реальными реализациями производителей — не наше предположение, а наблюдаемая закономерность всей отрасли. Попытка заставить всех производителей строго соблюдать единый стандарт уже предпринималась отраслевыми альянсами — и диалекты всё равно появляются, потому что у вендоров есть вполне законные технические причины для расширений.

Наш ответ — не ещё одна попытка добиться идеального соблюдения стандарта, а база знаний с трассируемым происхождением каждого факта. И вот тут стоит остановиться подробнее, потому что это не просто философская позиция, а конкретный работающий (ну, почти) механизм.


4. Всеядный хаб: зачем нужна стандартизация «осмотра» устройства

Если вынести за скобки маркетинг и красивые корпуса, любое ZigBee-устройство на физическом уровне делает одно и то же: у него есть конечные точки (endpoints), на них — кластеры, в кластерах — атрибуты и команды. Разница между лампочкой за 300 рублей и промышленным датчиком за 30 000 — не в механике, а в наборе и трактовке этих сущностей.

Тут неожиданно честно работает биологическая аналогия, пусть и предельно приземлённая. Какую бы экзотичную зверушку ни придумала эволюция — у неё всё равно есть вход и выход, и где-то между ними происходит главное: питание. Жираф, медуза, человек, ехидна — все по одной и той же нехитрой схеме, с поправкой на детали. Ветеринар, впервые увидевший невиданное животное, не разводит руками в ужасе — он открывает атлас, находит, что у этого вида рот находится сверху, а не спереди, и дальше уже вполне предметно понимает, с чем имеет дело. Он не обязан знать биографию каждого вида заранее — ему достаточно знать общую схему устройства организма.

ZigBee Cluster Library — ровно такой атлас для устройств умного дома. И наша работа над zbf_zcl — не «ещё один справочник кластеров», а попытка сделать этот атлас пригодным для осмотра практически любого устройства, которое вообще претендует на родство со стандартом, независимо от того, кто его сконструировал и насколько странную задачу оно решает. Нам, по большому счёту, всё равно, жираф перед нами или медуза — лишь бы у него был опознаваемый рот.

Как это работает на практике

Когда новое, незнакомое хабу устройство вступает в сеть, срабатывает не магия, а рутинная, десятилетиями обкатанная процедура: хаб запрашивает у устройства список его конечных точек, для каждой — список кластеров, для каждого кластера — список атрибутов с их типами. Это всё есть в самом протоколе, тут ничего придумывать не нужно — обычный ветеринарный осмотр по методичке.

Дальше начинается наша часть работы. Полученный список прогоняется через zbf_zcl — и происходит разделение на два потока:

  • То, что соответствует стандарту, опознаётся сразу и полностью: хаб уже знает имя атрибута, его физический смысл, единицы измерения, допустимый диапазон, обязательность. Устройство становится управляемым и читаемым без единой строчки кода, написанной специально под него. Зверь предъявил паспорт на входе — пропускаем без очереди.

  • То, что выходит за рамки стандарта (вендорские расширения, самодельные кластеры энтузиастов, откровенный «суржик» некоторых производителей), не отбрасывается и не блокирует устройство целиком, а честно помечается как нераспознанное: вот кластер, вот атрибут, мы не знаем, что это, вот сырое значение. Дальше — выбор: оставить как есть (оно хотя бы видно, просто молча стоит в углу), задокументировать руками один раз (и тогда в следующий раз опознаётся уже автоматически), либо вообще пройти мимо, если эта часть функциональности не нужна.

Ключевой момент: ломается не вся интеграция, а только нераспознанная её часть. Устройство не превращается в чёрный ящик целиком только потому, что производитель пришил ему третью лапу в виде фирменного кластера поверх десятка вполне стандартных.

Почему это важно именно сейчас

Весь смысл разговора про независимость от облака разваливается, если в итоге «локальный и надёжный» хаб работает только с отдельно купленным под него комплектом устройств. Тогда это не решение проблемы, а просто ещё одна закрытая экосистема, только маленькая и доморощенная — зоопарк на одну клетку.

Настоящая независимость — это когда вопрос «а с этим облаком работает, а с тем не очень» вообще теряет смысл. Хаб не привязан к списку поддерживаемых моделей — он привязан к стандарту. Следует устройство общей схеме хотя бы частично — оно опознаётся. Не следует вообще — это уже не вопрос стандартизации, а отдельный разговор о конкретном производителе и его отношениях с реальностью.

Сухие цифры здесь — не для красоты, а как мера того, насколько широко этот атлас уже применим: база знаний сейчас описывает 95 кластеров, 1879 атрибутов и 329 команд стандарта — с указанием источника и степени доверия к каждой конкретной записи, — а каталог реальных устройств, уже сверенных с этой схемой, насчитывает более 560 позиций от разных производителей и продолжает расти.


5. Это пока полигон, а не серийное производство

Сейчас вся эта конструкция проверяется на живом ESP32-C6, и проверяется в буквальном смысле на разрыв: сколько потянет один дешёвый чип. Мы одновременно выясняем, выдержит ли стандарт столкновение с реальным железом, и заодно — сколько графики и интерфейса можно повесить на тот же чип, чтобы он ещё и что-то показывал на экране, а не только тихо пищал в сеть. Иными словами, мы не только учим хаб быть ветеринаром, который узнаёт любого зверя по стандартному атласу, — мы заодно выясняем, насколько у этого ветеринара вообще хватит мозгов на всё это сразу.

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

Первое: мы отказались от asyncio. Стандартный путь для асинхронного кода на MicroPython — это он и есть, со всеми удобствами корутин. Но удобства не бесплатны: планировщик asyncio — это память и накладные расходы, которых на маленьком чипе, уже занятом радиостеком и обслуживанием сети, не так уж и много в запасе. Поэтому вместо него мы написали собственный кооперативный диспетчер — Spinner, умещающийся примерно в 300 строк кода, на классике yield. Никакой магии: каждая задача — обычный Python-генератор, который сам сообщает, через сколько миллисекунд его стоит разбудить снова, уступая следующей задаче в очереди, а диспетчер просто по кругу обходит все задачи и будит тех, кому пора. Грубо, зато прозрачно, предсказуемо и — что в нашем случае важнее всего — дёшево по памяти. Spinner одинаково легко крутит и тиканье радиостека Zigbee, и опрос датчиков, и будущую перерисовку экрана — все как равноправные участники одной и той же очереди, без отдельного event loop на каждую подсистему.

Второе: мы научились собирать прошивки «по размеру», а не «по максимуму». На маленький чип бессмысленно (и физически невозможно) затащить всё сразу — полный справочник из тысяч кластеров там никому не нужен, зато нужны ровно те 20–30 ходовых, которые реально участвуют в конкретном устройстве, плюс компактный API для регистрации нестандартных. Поэтому появился собственный инструмент сборки прошивки, который берёт спецификацию конкретного устройства, подтягивает ровно нужный набор библиотек под неё — и умеет «замораживать» (freeze) написанный код прямо в образ прошивки, чтобы он не занимал драгоценное место в оперативной памяти и грузился быстрее, чем обычный файл на файловой системе платы.

Это не оптимизация ради красивых цифр в бенчмарке. Это буквально вопрос «влезет или не влезет» — потому что весь смысл всей затеи в том, чтобы хаб был маленьким, дешёвым и локальным одновременно, а не выбирал что-то одно из трёх. Каждый освобождённый килобайт памяти — это либо ещё один кластер, который понимает прошивка, либо ещё один пиксель интерфейса на маленьком экране, либо просто запас прочности, чтобы устройство не падало раз в сутки от переполнения кучи.

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


6. Табло, а не пульт: как мы разводим облако и управление

Отдельно стоит разобрать то, что регулярно всплывает как самая болезненная тема при каждом крупном облачном инциденте — зависимость управления от облака и риск того, что «облако недоступно — дом замолчал».

Честно говоря, когда мы начали прорабатывать этот раздел детально, выяснилось, что простой фразы «облако никогда не командует домом» недостаточно — реальность внутри дома устроена не из одной границы, а из трёх принципиально разных участков транзита, и у каждого свои правила. Склеивать их в одну схему было нашей собственной ошибкой на черновом этапе — исправляем.

Три границы, три разных режима

EP (датчик/исполнитель) ⇄ Хаб ⇄ Internal Storage (дома) ⇄⇄⇄ External Storage/Gateway (снаружи) ⇄ Консоль снаружи
      двунаправленно         push-архив              единственный исходящий туннель,
      Call в любую сторону   (телеметрия/потоки)       инициирует Internal, не External

Граница 1 — EP ↔ Хаб. Здесь нет и не было одностороннего потока. Помимо рутинного Publish (устройство само отчитывается по расписанию), у Хаба есть прямой, независимый от цикла опроса механизм Call — синхронная команда устройству в любой момент, не дожидаясь, когда оно «само решит» отчитаться. Именно поэтому аварийное «выключить немедленно» не ждёт, пока истечёт пятиминутный интервал report’а температуры — это два разных механизма протокола, работающих параллельно.

Граница 2 — Хаб ↔ Internal Storage. Здесь действительно push-архив: Хаб выгружает телеметрию по собственной инициативе, хранилище пассивно принимает. Хаб — оперативный работник, история ему для принятия решений не нужна, поэтому эта граница спокойно может быть небыстрой и буферизованной.

Граница 3 — Internal ↔ External. Самая чувствительная, потому что здесь проходит периметр дома. Правило «нет входящих портов внутрь дома» мы не ослабляем — но реализуем его не как редкие разовые сеансы связи, а по проверенной отраслевой схеме: Internal держит один постоянный исходящий туннель наружу (тот же принцип, на котором стоят Home Assistant Cloud и Cloudflare Tunnel — устройство само звонит облаку и держит трубку, входящих соединений в роутере как класса не существует). И телеметрия, и команды идут по этому единственному каналу, просто в разные стороны по смыслу, а не как два разных входа в сеть.

Четыре типа трафика внутри одного канала

Важно не путать направление сетевого соединения (всегда наружу, от Internal) с направлением смысла данных. Внутри одного туннеля мы разводим четыре независимых группы:

Группа

Назначение

Доставка

Исполнительные команды

включить/выключить/задать уставку

pull из очереди Хабом, без батчинга — задержка критична, журналируется при исполнении

Запросы данных

консоль спрашивает конкретное значение/диапазон истории

синхронный ответ, read-only, без права влиять на состояние

Телеметрия

текущие показания датчиков

push пачками с разумным интервалом — не критична к секундам

Потоковые данные

видео и подобное

отдельный транспорт/буфер, политика хранения своя

Это разделение — не бюрократия, а разная цена ошибки: команда, доставленная с опозданием или дважды, может быть опасна; телеметрия, доставленная пачкой за 10 секунд вместо одного значения в реальном времени, не страшна никому. Батчинг экономит трафик именно там, где скорость не критична (телеметрия), и сознательно не применяется там, где критична (команды) — это не компромисс всей системы целиком, а настройка каждого потока по отдельности.

Команда, пришедшая снаружи, физически обязана осесть в очереди Internal Storage, прежде чем доберётся до Хаба — это даёт и журнал (кто, что и когда включил), и предсказуемость: Хаб, занятый тиканьем Zigbee-сети, вычитывает свою очередь команд в собственном рабочем цикле, а не прерывается по первому внешнему сигналу.

И отдельно стоит сказать честно: удалённое управление через External — это best-effort, а не настоящий emergency по скорости реакции. Реальная аварийная логика («протечка → перекрыть кран») обязана жить на EP или на Хабе локально — это прямое следствие критерия разделения слоёв, о котором мы говорили выше («переживёт ли эта логика обрыв связи с хабом»). Кнопка «выключить» в телефоне вне дома — это удобство, а не страховка; подменять ей локальную автоматику мы не планируем.

У нас облако в худшем случае становится слепым (нет свежих данных на экране), но никогда — немым пультом, который за вас решает, что делать с краном или обогревателем.


7. Что уже решено, а что — пока нет

Системная проблема индустрии

Как решает типовой рынок сегодня

Как решает ZBFun

Команда идёт через чужое облако, даже когда устройства рядом

Советуют покупать устройства «с прямым подключением к хабу» и проверять это в настройках

Архитектурно невозможно иначе — прикладная логика на устройстве обязана переживать обрыв связи с хабом

Диалекты вендоров ломают совместимость

Ручные «заплатки» под каждое устройство у мейнтейнеров открытых интеграций

Единый атлас стандарта с явной пометкой непознанных диалектов — вместо чёрного ящика

Сценарий тихо требует интернета, а пользователь не в курсе

Пометка в приложении, которую нужно проверять руками

Деление «на устройстве / на хабе» зафиксировано на этапе проектирования, это часть контракта

Крупный облачный сбой превращает управление в кирпич

«Проверяйте, что подключено напрямую» постфактум

Internal Storage всегда локален, внешнее хранилище — опциональная надстройка без права командовать

Нет единого реестра происхождения данных о стандарте

Разработчик сверяет руками или доверяет первому найденному источнику

Провенанс-реестр источников с весом доверия по каждому полю

Matter пока покрывает не все типы устройств

Ждать, пока конкретный производитель добавит поддержку

Matter — ещё один исполняемый профиль поверх той же базы знаний

«Своя» сертифицированная реализация стандарта закрыта от сторонних хабов

Оставаться в экосистеме вендора и смириться

Открытый вопрос — зависит от готовности вендора к интеграции, у нас есть идея, но она пока не воплощена

Маленький чип не тянет полноценный стек + интерфейс

Ставить более мощное (и дорогое) железо

Собственный диспетчер Spinner + сборка прошивки «по размеру» — эксперимент в процессе

Домашний сервер должен работать 24/7

Выделенный домашний компьютер под управляющее ПО

Пока экспериментальный режим, постоянный сервер — следующий, осознанно отложенный этап

Последние строки — не для красоты. Мы сознательно не обещаем того, чего ещё не реализовали.


Источники