И опять про умный дом. На этот раз расскажу про то, как интегрировать брелки от откатных ворот Nice Flor-S с HomeAssistant, используя подручные средства, а именно EspHome, RTL-SDR и платку с релешками с Aliexpress.

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



Внутри мы видим радио на 433 мегагерца вместе с Motorola HC08 микроконтроллером. Прям сразу вспоминаются лабы по ассеблеру для этой дряни в мои институтские годы.
План A. Где мой RTL-SDR?
Начал я с того, что воткнул RTL-SDR брелок, запустил gqrx и увидел что передача и впрямь происходит на 433Mhz и красиво отрисоввывается на “водопаде”. Теперь это надо как-то декодировать, так?

План таков: декодируем протокол и пробуем сэмулировать на 433Mhz беспроводных GPIO с нашей любимой радиоэлектронной помойки под названием Aliexress.

Следующим этапом я запустил rtl-433 и увидел… Ничегошеньки. Собственно, программа определила что что-то там на этой частоте происходил, но декодера протокола на nice flor-s у нее не было.
Пришлось загуглить, и я откопал частичную документацию протокола nice flor-s. А еще узнал, что у них есть пара уязвимостей… Упсь 😉
Протокол документирован не полностью, но статья все равно описывает достаточно много подробностей для быстрого старта. По ней мне удалось быстренько накидать простой плагинчик для rtl-433 который смог декодировать номера кнопок пульта, которые я нажимал. С некоторой удачей, можно было также декодировать таймкод (т.е. время удержания кнопки). Но что дальше? Для написания полного эмулятора брелка данных не хватало.

Проблема была в том, что протокол был документирован только частично, и в имеющейся документации не было самого важного: алгоритма по которому получается роллинг-код, которым шифруется серийный номер. По сути, кроме номера кнопки и времени удержания я больше не мог ничего получить. Загадки, загадки, загадки… Можно было попробовать сдампить прошивку HC08. Но что-то мне подсказывало, что защита от ридбэка там была включена.
Была мысль собрать полный дамп всех возможных значений счетчика через rtl-sdr, а дальше попытаться проанализировать его. Но это займет очень много времени и нет гарантии успеха. Было жалко почему-то отказываться от этого квеста, но он требовал слишком много ценного ресурса, которого у меня совершенно не было: времени.
План Б. Давайте тупо возьмем несколько релешек, чтобы они жали на кнопки!
Я аккуратно прозвонил пультик мультиметром. Его питала маленькая 12V баттарейка. Линия +12V от батарейки заходила напрямую на 4 кнопки, которые замыкали питание. Когда ни одна кнопка не нажата – схема полностью обесточена. По сути можно туда посадить транзистор/мосфет и замыкать им. Но это значило, что придется либо лепить жуткие сопли, либо разводить плату, что потребует опять много ценного ресурса: ‘времени’. Потому я сделал проще, открыл Aliexpress и заказал несколько 4-канальных модулей с реле и esp8266. Некая LC-tech компания выпускает их в 12в и 5в вариантах. После заказа 12в варианта пришлось отложить все и подождать, пока до меня доедет посылка.
Разбираемся с 4х-канальными модулями от LC-tech


Мои впечатления от инженерных решений были смешанными. С одной стороны на плате была честная опторазвязка, а прорезь на плате около одного из контактов должно было увеличить сопротивление на случай, если мы будем коммутировать высокое напряжение. Но с другой стороны, схема питания была сделана дебильно. Возможно, уже приходилось читать у меня в блоге про линейный стабилизатор в миллиметре от термодатчика на esp-14 платах от diymore. Ну, тут та же фигня: Вход на 12 вольт, потом линейный преобразователь на 5 вольт, потом линейный преобразователь на 3.3 вольта. Энергоэффективность.
Если не использовать режим энергосбережения esp8266, то выходит тот еще кипятильник. К тому же винтовые колодки на 5mm – отвратное решение для крепления многожильных кабелей с 220 вольтами – кабель под действием времени и элекричества распушается и может коротнуть. Единственная защита от этого – залудить кабель.
Ну и самое любопытное на плате – это микроконтроллер Nuvoton n76e003at20. Я впервые напал на эту любопытную железку. ESP8266 подключается к ней по UART, а уже она заправляет 2 кнопками, тремя светодиодами и четырьмя реле. Судя по datasheet’у это еще один микроконтроллер на основе 8051 архитектуры. Возможно, я сделаю в скором времени еще один пост на тему, как его программировать, но пока буду использовать стоковую прошивку.
Родная прошивка ESP8266, как и многие китайцы подцепляется к какому-то ‘ai cloud’. Что это за хрень, я даже не стал разбираться, просто залил свою прошивку на основе esphome.
С ESPhome у нас есть два способа подключить реле на этой плате. Мы можем использовать компонент UART switch. Или написать свой кастомный компонент. Копипастить мне было лень, да и я заметил одну интересную особенность в протоколе.
Согласно документации, протокол обмена выглядит так. Эти последовательности надо послать по UART, чтобы включить/выключить разные реле.
Open relay 1:A0 01 01 A2
Close relay 1:A0 01 00 A1
Open relay 2:A0 02 01 A3
Close relay 2:A0 02 00 A2
Open relay 3:A0 03 01 A4
Close relay 3:A0 03 00 A3
Open relay 4:A0 04 01 A5
Close relay 4:A0 04 00 A4
Попробуем это переосмыслить
- Байт 1. A0 – начало пакета
- Byte 2. Номер реле (1-4)
- Byte 3. Желаемое состояние 0/1
- Byte 4. Контрольная сумма. Сумма первых трех байт
А это значит, что для управления этой махарайкой нам достаточно такого кода:
#include "esphome.h"
using namespace esphome;
class LCRelay : public Component, public UARTDevice, public switch_::Switch {
public:
int relayId;
LCRelay(UARTComponent *parent, int relay): UARTDevice(parent) {
relayId = relay;
}
void setup() override {
}
void write_state(bool state) override {
uint8_t msg[4];
msg[0] = 0xA0;
msg[1] = relayId;
msg[2] = state;
msg[3] = msg[0] + msg[1] + msg[2];
/* There are no ack/nack packets.
Let's send the payload twice to be sure */
this->write_array(msg, sizeof(msg));
this->write_array(msg, sizeof(msg));
publish_state(state);
}
};
Теперь подцепим это в конфиг на yaml. Выйдет что-то подобное:
substitutions:
devicename: "gatekeeper"
esphome:
name: $devicename
platform: ESP8266
board: esp01_1m
build_path: build/gatecontrol
includes:
- lcrelay.h
uart:
id: uart
baud_rate: 115200
tx_pin: GPIO1
rx_pin: GPIO3
switch:
- platform: custom
lambda: |-
auto r1 = new LCRelay(id(uart), 1);
auto r2 = new LCRelay(id(uart), 2);
auto r3 = new LCRelay(id(uart), 3);
auto r4 = new LCRelay(id(uart), 4);
App.register_component(r1);
App.register_component(r2);
App.register_component(r3);
App.register_component(r4);
return {r1, r2, r3, r4};
switches:
- name: "${devicename} Relay 1"
id: relay1
internal: true
- name: "${devicename} Relay 2"
id: relay2
internal: true
- name: "${devicename} Relay 3"
id: relay3
internal: true
- name: "${devicename} Relay 4"
id: relay4
internal: true
Как легко заметить, я пометил все выключатели как internal. Так как мы будем имитировать нажатие кнопки, реле надо замкнуть на секунду и разомкнуть. В коде мы не можем воткнуть delay(1000), так как watchdog esp8266 прибьет наше приложение и перезагрузит все. Правильный способ с точки зрения философии esphome(Если, я конечно понял правильно идею) будет в задании этого в файле конфигурации. Для этого в секцию switch надо добавить по такому заклинанию на каждое реле, которое подключено к кнопке брелка.
- platform: template
name: "${devicename} Main Gates"
icon: mdi:gate
lambda: |-
if (id(relay1).state) {
return true;
} else {
return false;
}
turn_on_action:
- switch.turn_on: relay1
- delay: 1s
- switch.turn_off: relay1
turn_off_action:
switch.turn_off: relay1
Собираем все это хозяйство вместе
Как только прошивка задышала, я распечатал короб в который поместил модуль реле и подпаялся проводами к брелку. Так как я использовал только 3 кнопки, то четвертый реле я подцепил к разъему и вывел на корпус.


Материалы
Как обычно материалы от этой заметки можно скачать:
Leave a Reply