Русский
Русский
English
Статистика
Реклама

Реверс-инжиниринг протоколов управления конвектором

Предисловие

История берет свое начало в мае, когда в один из непогожих питерских дней, местная котельная решила отключить отопление. За окном было +10, влажность зашкаливала, ветер дул, а тепленькое солнышко не светило в окна от слова совсем (чертова северная сторона). В квартире стало ощутимо холодно. Кот слезал с теплых колен только дляопустошения миски. Мы же кутались в флиски и пледы. Через два дня такой жизни стало понятно - к черту все, нужен обогреватель! Требования были довольно просты - цена, определенная мощность, возможность эту самую мощность регулировать и какой-либо интерфейс (wi-fi\BT\ZigBee\485). Последнее хотелось больше для баловства и неведомого "а вдруг потребуется!". Оставлю за рамками статьи муки выбора, количество обогревателей на полках магазинов в конце весны и прочие приколы наших доставщиков. В итоге, я стал обладателем конвектора под брендом впрочем, если не показывать шильдик, то можно найти картинки аж трех производителей "клепающих" одинаковые модели. А если погуглить чуть поглубже, то окажется что в РФ франшиза на выпуск конвекторов под этими брендам принадлежит одной единственной конторе. И все встает на свои места - конвектор один, а шильдик лишь влияет на цену. Впрочем, мне то какая разница - грело бы, да управлялось.

Что-то я отвлекся. Итак, конвектор модульный:

  • нагревательный блок

  • блок с инвертором для управления

  • Wi-fi свисток

Cобрано, запущено, кот согрет, самое время посмотреть, что там с интерфейсом. Приложение для мобилки подключилось к конвектору, залило настройки wi-fi сети и радостно предложило управлять обогревателем через интернет. И в принципе на этом можно было бы закончить, но в процессе эксплуатации появилось желание - время от времени использовать конвектор для просушки одного из помещений. Датчик влажности есть, к Home Assistant подключен, дело за малым, завести туда же конвектор. Тут меня ждало полнейшее разочарование - никакого API, никаких интеграций, вообще ни_че_го. Лан, инженером же работаю, не в первой городить программно-аппаратные решения.

Часть 0. Исходные данные

Первое, что делает любой инженер - берет отвертку и смотрит внутрь. А внутри USB-модуля оказалась железка HF-LPT220. Заботливый гугл находит:

  • Статью (часть 1 и часть 2) пользователя @avstepanov Краткое содержание: Кондиционер, модуль такой же, попробовали wi-fi, API нет, решили проблему через управление по IR.

  • Сайт производителя

Краткие характеристики модуля:

- Support IEEE802.11b/g/n Wireless Standards
- Based on High-Flying Cost Effective Wi-Fi SOC: MC300 chipset
- Support UART/GPIO Data Communication Interface
- Support Work As STA/AP Mode
- Support Smart LinkFunction(APP program provide)
- Support Wireless and Remote Firmware Upgrade Function
- Support WPS Function(Reserved)
- Support Internal/ExternalPinAntenna Option
- Single +3.3V Power Supply
- Smallest Size: 22mm x 13.5mm x3mm , SMT17 Package
- FCC/CE Certificated

Закатываем рукава достаем чемоданчик с инструментарием:

Инструменты

Железки:
- Mikrotik для перехвата пакетов
- Логический анализатор (клон saleae Logic 8) - для анализа интерфейса, потребуется в третьей части
- Различные кабели (USB-AM - USB-AF)
- USB-UART преобразователь. В моем случае - CP2102

ПО:
- Wireshark
- Java Decompiler
- Android Studio
- Putty

Часть 1. Wi-Fi!

Раз мобильное приложение общается с железкой через wi-fi, логично запустить сниффер и посмотреть что там бегает. Хорошо что микротик умеет "зеркалить" траффик в Wireshark (wiki mikrotik, инструкция попроще). Запускаем wireshark, включаем обогреватель и наблюдаем.

После отрабатывания DHCP-клиента, железка запрашивает IP адрес dongle.***.ru, где *** представительство в РФ (не вендор). Просто примем эту информацию к сведенью и сделаем вывод - в других международных регионах скорее всего будут свои фирмы-представители и, соответственно, адреса.

Происходит установка TCP-соединения и начинается обмен AT-командами

< - запрос от сервера, конвектору > - ответ от конвектора, серверу< AT+NDBGL=0,0< AT+APPVER> +ok< AT+WSMAC> =<ver>-20170810 . +ok=<MAC>

Данные команды повторяются несколько раз, как и ответы на них, видимо, происходит не очень быстрая обработка со стороны сервера.

Идем в документацию с сайта hi-flying и действительно находим:
AT+NDBGL - Enable\Disable UART information
AT+WSMAC - Set\Query Module MAC address parameters. Setting is valid after reset.
AT+VER - Query module software version information. AT+APPVER в документе отсутствует, т.к. модуль и прошивка датированы 2017 г. а вот документация на сайте 2016.

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

А вот вторая, заставляет задуматься.

 "Входящие" пакеты "Входящие" пакеты"Исходящие""Исходящие"

Честно говоря, в эпоху пристального внимания к безопасности IoT, не надеялся увидеть что-либо дельное, однако Серьезно? Как-то это не похоже на зашифрованный TLS\SSL\Ipsec - траффик.

Cходу можно сделать предположение - последний байт, это контрольная, однобайтовая сумма. Открываем калькулятор и складываем AA+C+A+1+1A+1+6+5+1 = E8. Ясно, понятно. Начинаем жать все кнопки в приложении и обнаруживаем некоторые закономерности, попутно пишем на LUA dissector для Wireshark. Не парсить, же байты каждый раз =)

Получаем занятную штуку, на примере: aa 0c 0a 01 1a 01 06 00 00 00 00 05 00 01 e8

Наименование

Размер(байт)

Примечание и возможные значения

Пример

Заголовок

2

Байты неизменны из пакета в пакет, возможно, это внутренний ID устройства. С MAC не совпадают.

aa 0c

Команда или событие

1

09 - произошло изменение состояния - от конвектора
0a - установить (запрос на установку) параметры - от сервера
8a - подтверждение установки параметров (ответ на 0а)
88 - отправка данных на сервер. По запросу от сервера. (см. ниже)

0a(установить)

Статус

1

00 - отключен
01 - включен
02 - неизвестно (резерв?)
03 - блокировка клавиш на конвекторе

01(включить)

Температура

1

Поддерживаемая температура. Задается в приложении или на устройстве.

1a (установить 26 гр.)

Режим

1

Режимы эксплуатации:
01 - Comfort - обычный нагрев.
02 - Night - ночной режим, ниже комфортного на 4 градуса
03 - Незамерз. - режим для дач, когда поддерживается 5 гр.

01 (установить Comfort)

Мощность

1

01 - 1 ур. - минимальная

05 - 5 ур. - максимальная
06 - Auto - автоматическая

06(установить режим Auto)

Таймер

2

Таймер на отключение, в минутах, минуты в hex, утка в зайце
Например, 22:59
22*60+59=1379 минут =0563h

00 00 (таймер выставить в 00:00)

Статус таймера

1

00 - оключен
01 - включен

00 (отключить)

Температура в помещении

1

Температура с датчика
(при установке = 00)

00

Неизвестно

2

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

05 00

Дисплей

1

00 - отключен
01 - включен
Да, все верно, у конвектора можно отключить адскую зеленую подсветку.

01 (дисплей включить)

Контрольная сумма

1

Сумма всех предыдущих байт. Формально, остаток от деления на 255.

e8

Отдельно хочется выделить запрос текущей конфигурации от сервера:

Data

Примечание

AA 03 08 10 04 C9

Конвектор отвечает пакетом выше, с кодом команды 88

* На этапе инициализации используются дополнительные пакеты и команды, но оставим это за рамками статьи.

Фуф, с данными, вроде как понятно. Но будет ли устройство принимать команды от стороннего сервера? Адрес сервера забит в прошивку. Мы конечно можем, подменить ответ DNS-сервера на локальном маршрутизаторе, но сначала стоит попробовать что-нибудь попроще.

Посмотрим, какие порты открыты на сервере конвекторе. Linux\WSL > Bash > Netcat
nc -vnz <IP конвектора> 1-65000 2>&1 | grep succeeded

Через довольно продолжительное время, обнаружится открытый, 8899 порт. ONVIF у конвектора? Whaaat?! Но нам то что? Попробуем отправить пакет на включение и выставление настроек:
echo -e "\xAA\x0C\x0A\x01\x17\x01\x01\x00\x00\x00\x00\x00\x00\x00\xDA" |
nc <IP конвектора> 8899

И, внезапно, оно работает!

Есть одно, НО. При отправке запроса о текущей конфигурации (AA 03 08 10 04 C9), ответ отправляется не тому кто запросил, а на сервер с которым установлено соединение. Как итог, управление возможно только в слепую, никаких данных о включении, отключении, режиме и температуре получить невозможно.

Есть два способа изменить это поведение (сборка своей прошивки не в счет).
Первый. Так как в прошивке зашито DNS-имя, можно изменить IP-адрес в ответе DNS-сервера, так чтобы dongle.*****.ru ссылался на 192.168.0.* - т.е. прописать статическую DNS запись.
Плюс данного способа - все настройки делаются на маршрутизаторе\DNS-сервере в пару кликов.
Минус - очевидно, способ нерабочий, если ваш DHCP-сервер выдает клиентам публичные DNS-сервера (8.8.8.8, 1.1.1.1 и прочие "семейные DNS")

Второй способ приведен ниже, в части посвященной UART и касается изменении адреса сервера в модуле wi-fi.
Плюсы - гарантированная работа в ЛВС.
Минусы - жесткая привязка к конкретной ЛВС - это надо помнить.

Итак, запускаем (или пишем на коленке) на локальной машине простенький tcp-сервер. Отправляем железке AA 03 08 10 04 C9 в ответ получаем aa 0c 88 01 15 01 01 00 00 00 18 00 70 00 00 00 6e Теперь, все работает как надо.

Промежуточные результаты: Можно начинать писать свой шлюз\OPC-сервер\плагин для системы управления умным домом.

Часть 2. Android

А что если есть более простой способ рулить конвектором? Например, подключить систему управления умным домом напрямую к серверу и перекидываться JSON'ами. Реализовать такое управление, безусловно, проще.
Чтож, стоит посмотреть, как мобильное приложение общается с сервером. Запускаем wireshark, настраиваем mikrotik и смотрим. А посмотреть есть на что.

Приложение обращается к тому же самому IP - 82.209.**.** (правда я не увидел запроса к DNS, но возможно ОС взяла значение из кэша). А так же сморим первый TCP Stream. Да у нас тут целый запрос-ответ.

ЗапросЗапрос

Ответ (К сожалению в ответе пришлось бы блюрить огромное количество данных, по этому вставка текстом, некоторые заголовки вырезаны):

HTTP/1.1 200 OKServer: nginx/1.12.2Content-Type: application/json;X-Powered-By: PHP/7.0.27X-Powered-CMS: <название одной популярной CMS>{  "result": {    "token": "<токен>",    "user": {      "name": ""    },    "enc_key": "<ключ>",    "server": {      "host": "dongle.<вендор>.ru",      "port": "10001"    },}

Что имеем? В запросе используется голый http, передающий в открытом виде:
appcode - бренд. Напомню, производитель изготавливает оборудование под разными брендами.
login - номер мобильного телефона, который является логином в приложении
password - пароль. Не хэш. Именно пароль, указываемый при регистрации, и использующийся для входа в приложение.

Интересное в ответе:
-На той стороне используется би_cms_.
-Нам передают токен
-Забегая вперед скажу, что нам передают ключ шифрования - enc_key

*Б - безопасность. Но давайте посмотрим что происходит дальше, а потом проанализируем все вместе.

Сморим, что же происходит дальше. А дальше происходит небольшой обмен командами. Cервер запрашивает присвоенный токен, приложение его отправляет и в ответ получает это:

IoZAWjxg/vHjEBEZvX1zTkrmbT2k8tVG0T1NjHjw2Qx1fwChQsv7PkRKKQ=6829b7302ad50470a5ddb3cd41566dafIoZAWjxg/vHjEBEZvX1zTgwVJIsFn6VqMtnyYurmE3p9TjpjjgxfpJDlRMyTKNqmZto39j4X4Y8nKH/XPIdynRedAM/4gQ4s9fXbd402ed9aec13b9a3ab4521212294f7cIoZAWjxg/vHjEBEZvX1zTgwVJIsFn6VqMtnyYurmE3p9TjpjjgxfpJDlRMyTKNqmZto39j4X4Y8nKH/XPIdynRedAM/4gQ4s9fXbd402ed9aec13b9a3ab4521212294f7c

Погодите, шифрование? Вот это поворот! Тут наши полномочия, как говорится все.
Но погодите, мы встречаем 3 одинаковых последовательности. Причем, одно из сообщений дублируется два раза. Открываем приложение, нажимаем разные кнопочки и обнаруживаем, что некоторые пакеты не меняются.
Делаем первый промежуточный вывод - шифрование не привязано ко времени.

Конец сообщения очень сильно что-то напоминает. Да и по закону жанра в конце сообщения должен быть хэш\CRC. Проводим некоторое время в калькуляторах перебирая алгоритмы и действительно, конец сообщения содержит свой хэш в MD5 (дайджест?). Ок.

Осталось определить алгоритм шифрования. Developer android заботливо подсказывает, что алгоритмов поддерживается дофига, но рекомендуется использовать AES256. Запомним.
На вопрос "Как определить алгоритм шифрования зная шифротекст?", гугл лаконично отвечает "Никак, анализируй приложение (де)шифровщик".

Забрались далеко, отступать не наши методы. Качаем APK, при помощи dex2jar конвертируем в jdk и открываем в JD.

Можно заняться полным реверсом (не ассемблер же), но быстрее будет запустить поиск по ключевому слову. Вопрос, что искать? Что-то отвечающее за шифрование - "encrypt"

Результаты поискаРезультаты поиска

Внезапно.

  • Библиотека от espressif

  • Библиотека от hyflying, с их SmartLink'ом.

  • Три класса с реализующих AES. Причем во всех трех классах используются разные режимы шифрования.

Библиотеки от espressiа и hyflying можно отложить на потом, WifiUtils, логично предположить, отвечает за шифрование Wi-Fi. Остаются TcpServices, EncryptUtils и AES256Chipher. Заглянем в EncryptUtils и увидим:

public class EncryptUtils {private static final String AES_MODE = "AES/CBC/PKCS7Padding";private static final String CHARSET = "UTF-8";private static final String ENC_PASSWORD;private static final String HASH_ALGORITHM = "SHA-256";private static final String TAG = EncryptUtils.class.getSimpleName();private static final byte[] ivBytes;static {ENC_PASSWORD = EncryptUtils.class.getSimpleName().concat(EncryptUtils.class.getSimpleName());ivBytes = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };}public static String decrypt(String paramString) {try {return decrypt(ENC_PASSWORD, paramString);}private static String decrypt(String paramString1, String paramString2) throws GeneralSecurityException {try {SecretKeySpec secretKeySpec = generateKey(paramString1);byte[] arrayOfByte = Base64.decode(paramString2, 2);return new String(decrypt(secretKeySpec, ivBytes, arrayOfByte), "UTF-8");}private static SecretKeySpec generateKey(String paramString) throws NoSuchAlgorithmException, UnsupportedEncodingException {MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");byte[] arrayOfByte = paramString.getBytes("UTF-8");messageDigest.update(arrayOfByte, 0, arrayOfByte.length);return new SecretKeySpec(messageDigest.digest(), "AES");}

Краткое содержание:
Переменной ENC_PASSWORD два раза присваиваем имя текущего класса ("EncryptUtilsEncryptUtils"). Получаем хэш и на его основе генерим ключ, которым и дешифруем данные.

Запускаем Android Studio и пишем простенький код (или пользуемся он-лайн дешифровщиками) и скармливаем наш шифротекст.

Fail. Пробуем по другому, снова фейл. И так и сяк - Fail.

Окей, посмотрим что лежит во втором классе - AES256Chipher

paramString1 - шифротекстparamString2 - ключpublic static String decrypt(String paramString1, String paramString2) {         <отрезание и проверка MD5, not null и все такое прочее>           MessageDigest messageDigest = MessageDigest.getInstance("SHA384");          try {            byte[] arrayOfByte2 = messageDigest.digest(paramString2.getBytes("UTF-8"));            byte[] arrayOfByte1 = Arrays.copyOfRange(arrayOfByte2, 32, 48);            arrayOfByte2 = Arrays.copyOfRange(arrayOfByte2, 0, 32);                    try {              Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");              IvParameterSpec ivParameterSpec = new IvParameterSpec(arrayOfByte1);              cipher.init(2, new SecretKeySpec(arrayOfByte2, "AES"), ivParameterSpec);              return new String(cipher.doFinal(Base64.decode(paramString1, 0)));  }

Краткое содержание: берем пароль, считаем от него SHA384 (почему 384?), разбиваем на два байтовых массива [32-48] и [0-32].
Первый - вектор инициализации (IV)
Второй -ключ, который и скармливаем SecretKeySpec

Вроде, ничего криминального, все так делают. Внимание вопрос - что же у нас может выступать в роли пароля? Может быть, тот самый enc_key из JSONa передающийся открытым http?
Пробуем, и вуаля, сообщения расшифровываются. Внутри нас ждет тот самый REST API с командами getDeviceParams, setDeviceParams, changedDeviceParams. Можно начинать писать плагин для системы управления.

Возникают смешанные чувства:- Передача номера телефона и пароля в открытом виде. Я даже не знаю, что тут написать. Хэш? SSL\TLS? Не, не слышали. Зато, на сайте разработчиков гордо красуется "Входим в ТОП-100 разработчиков мобильных приложений".- Ключ шифрования (по сути) передается в открытом виде при установлении каждой сессии. А сессия создается при каждом запуске приложения. Нет, он не сохраняется. Открыл приложение, выставил температуру, закрыл приложение - такой же жизненный цикл имеет ключ. Т.е. нам достаточно перехватить начало одной, любой сессии и все, можем рулить железкой.- Зачем в приложении аж 3 класса реализующих AES? Ладно, тут ответ очевиден - "я его слепила из того что было"

Однако!- Благодаря этому, можно легко написать сторонне приложение\плагин\расширение для системы управления умным домом.Утечки ПД, нет, т.к. нет ФИО (оно вообще нигде не указывается, даже при регистрации)

Часть 3. UART

Как выяснилось в первой части, наш wi-fi свисток, это всего лишь "UART to Wi-Fi" преобразователь. Это значит, что мы можем при помощи Esp32\Arduino\RPI создать свою железку для управления конвектором - с MTTQ, bluetooth и прочими соединениями. Надо лишь узнать протокол.

Итак, свисток имеет разъем USB-AM, и подписи на плате (см. фото выше) +5v, Tx, Rx, GND. Дело за малым, взять кабель AM - AF, разрезать, зачистить и в параллель подключить логический анализатор. +5v, можно оставить в покое. Таким образом, сразу будем видеть и Тx и Rx - главное, определиться с какой стороны смотреть.

Запуск, тыканье в кнопочки на мобильнике и

Данные канала RxДанные канала Rx

что-то это напоминает.

UART to Wi-Fi оказался тупым конвертером. Никакой внутренней обработки, никакой логики. Формат сообщения такой же как и в первой части.

В Wireshark мы видели AT-команды. Да и в документации про это что-то было. Берем UART-USB, выставляем +5В и подключаем. Главное Tx и Rx подключить перекрестно (очевидно, но можно забыть). Запускаем Putty или любой другой терминальный клиент. Выбираем com-порт в документации указана скорость 115200, но по факту 9600.

Окей, железка что-то шлет в терминал, но на ввод не реагирует. Курим ман и находим - для перехода в режим настройки необходимо отправить "+++" (без enter'а), на что HF-LPT220 ответит "a" и нам надо в ответ послать такую же "a". Сделать это все надо за 3 с.

Скриншот из инструкции HF-LPT220Скриншот из инструкции HF-LPT220

После данной эквилибристики, железка становится отзывчивой. Введем AT+H и увидим список доступных команд:

AT+H

AT+APPVER: Show application version.
AT+DCDC=on/off: Enable or disable DCDC Mode .
AT+SMEM: Show memory.
AT+FLSHRD: Show flash data.
AT+UART: Set/Get the UART0/UART1 Parameters.
AT+NDBGL:set/get debug level
AT+MDCH: Put on/off automatic switching WIFI mode.
AT+ENTM: Goto Through MOde.
AT+SMTLKST=mode,protocol: Setup smartlnk mode and protocol.
AT+RELD: Reload the default setting and reboot.
AT+MID: Get The Module ID.
AT+WRMID: Write Module ID.
AT+VER: Get application version.
AT+BVER: Get bootloader version.
AT+CFGRD: Get current system config.
AT+FCLR: Clear Fsetting.
AT+CFGTF: Save Current Config to Default Config.
AT+CFGW=on/off: Enable or disable write config to flash
AT+SRST:Soft Reset the Module.
AT+SLEEP=ms:Cpu sleep ms.
AT+E: Echo ON/Off, to turn on/off command line echo function.
AT+Z: Reset the Module.
AT+H:show help
AT+SOCKB: Set/Get Parameters of socket_b.
AT+TCPDISB: Connect/Dis-connect the TCP_B Client link.
AT+TCPTOB: Set/Get TCP_B time out.
AT+TCPLKB: Get The state of TCP_B link.
AT+RCVB: Recv data from socket_b
AT+SNDB: Send data to socket_b
AT+NETP: Set/Get the Net Protocol Parameters.
AT+TCPLK: Get The state of TCP link.
AT+TCPTO: Set/Get TCP time out.
AT+TCPDIS: Connect/Dis-connect the TCP Client link
AT+MAXSK: Set/Get MAX num of TCP socket (1~5)
AT+DISPS: Disable power saving mode of WIFI
AT+WSLQ: Get Link Quality of the Module (Only for STA Mode).
AT+SMTLK: Start Smartlink.
AT+WSSSID: Set/Get the AP's SSID of WIFI STA Mode.
AT+WAP: Set/Get the AP parameters.
AT+WAPMXSTA: Set/Get the Max Number Of Sta Connected to Ap.
AT+WSKEY: Set/Get the Security Parameters of WIFI STA Mode.
AT+WAKEY: Set/Get the Security Parameters of WIFI AP Mode.
AT+WIFI=UP/DOWN: Power down or up the wifi chip.
AT+WPSBTNEN:enable/disable wps button.
AT+WALKIND:enable/disable LED indication of AP connection.
AT+WALK:Show sta information of AP connection.
AT+WSCAN: Get The AP site Survey (only for STA Mode).
AT+WMODE: Set/Get the WIFI Operation Mode (AP or STA).
AT+WSLK: Get Link Status of the Module (Only for STA Mode).
AT+WIFI=UP/DOWN: Power down or up the wifi chip.
AT+WSMAC: Set/Get Module MAC Address.
AT+NTPSER: Set/Get NTP Server address.
AT+UDPLCPT: Set/Get local UDP port.
AT+WANN: Set/Get The WAN setting if in STA mode.
AT+LANN: Set/Get The LAN setting if in ADHOC mode.
AT+WADHCP:enable/disable AP dhcp server and set ip address pool
AT+ASWD: Set/Query WiFi configuration code.
AT+NTPRF: Set/Query NTP.
AT+NTPEN: Enable/Disable NTP Server.
AT+NTPTM: Set/Query Ntp Time.
AT+NTPSER: Set/Query Ntp Server.
AT+PLANG=EN/CN: Set/Get the language of WEB page.
AT+WEBU: Set/Get the Login Parameters of WEB page.
AT+OTA: Auto upgrade firmware.
AT+UPURL: Set/Get the path of remote upgrade.

Можно позапускать всякое, но интерес представляет AT+SOCKB, который возвращает "+ok=TCP,10001,dongle.******.ru". Как внезапно

Попробуем заменить на что-нибудь свое?

"AT+SOCKB=TCP,10001,192.168.0.2". Возвращаем модуль в конвектор и смотрим в wireshark. Теперь железка пытается установить соединение не с сервером в интернете, а с ПК из локальной сети.

Выводы и заключение.

Буква S в аббревиатуре IoT обозначает Security

Существует три способа управления конвектором. Через сервер производителя (REST API), напрямую из ЛВС, через UART.

Остался открытый вопрос с модулем для HA - возможно никогда-нибудь, он будет написан=).

Источник: habr.com
К списку статей
Опубликовано: 15.03.2021 08:17:24
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Реверс-инжиниринг

Умный дом

Ballu

Homeassistant

Домашняя автоматизация

Iot

Iot security

Electrolux

Security

Умныйдом

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru