mirror of
https://github.com/anklimov/lighthub
synced 2026-10-28 11:15:00 +00:00
docs: add CAN (lightspot) and rotary encoder docs from author drafts
Ported the two design docs (originally docx) to markdown with code-verified corrections (CAN runs at 50 kbit/s); sections still in design (T:99 rotary profiles, external SPI CAN controller) are marked 'not implemented' and tracked in BACKLOG.md.
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
# Rotary Encoder
|
||||
|
||||
> Источник: авторский документ «Rotary Encoder» (docx, 2026-10-02), сверен с кодом `lighthub/inputs.cpp`.
|
||||
|
||||
Появилась возможность подключить к контроллеру орган управления, который называется Rotary encoder (далее — энкодер).
|
||||
|
||||
Энкодер упрощает управление такими устройствами, как диммируемое и светодиодное освещение, позволяя выбор яркости/цвета/насыщенности/цветовой температуры делать тактильно, вращением рукоятки регулятора. Одним энкодером можно управлять несколькими, как локальными, так и удаленными устройствами. Освещение здесь приведено в качестве самого применимого примера. Если хотите — данным элементом управления можно регулировать все, что поддерживает команды на увеличение и уменьшение. Например, через автоматизации Home Assistant можно управлять громкостью ресивера или колонки Алиса.
|
||||
|
||||
Многие энкодеры также имеют контакт нажатия, и данная возможность тоже может быть использована. Все варианты анализа одинарных-двойных-тройных-длительных нажатий могут быть использованы аналогично с настройкой дискретных входов контроллера и использоваться для любых нужд, в том числе для включения, выключения устройств, переключения профилей управления энкодера.
|
||||
|
||||
Все возможности доступны при настройке энкодера через JSON-конфигурацию.
|
||||
|
||||
Подключить энкодер можно к прошивке LightHub на всех платформах (включенных с флагом `ROTARYENCODER`, см. «Доступность» ниже). Особенно хочется подчеркнуть возможность подключить такой элемент (наряду с дополнительными кнопками и датчиками) к контроллеру LightSpot на базе STM32 или ESP32 — минималистической системе, которая может быть смонтирована в каждом выключателе и которая может общаться с основным контроллером LightHub по двухпроводной шине CAN (см. [CAN и lightspot](../integrations/can_lightspot.md)). Также можно собрать универсальный выключатель с кнопками и рукояткой энкодера на базе ESP32 или ESP8266, взаимодействующий с остальными системами дома через WiFi (как с контроллерами LightHub, так и с другими устройствами, управляемыми через MQTT), хотя вариант проводного подключения, конечно, предпочтителен.
|
||||
|
||||
## Настройка
|
||||
|
||||
Рассмотрим настройку энкодера на примерах.
|
||||
|
||||
В данном примере энкодер подключен к следующим PIN-ам контроллера:
|
||||
|
||||
- 14 — контакт нажатия;
|
||||
- 4 и 5 — контакты A и B энкодера, соответственно.
|
||||
|
||||
Четвертый (опциональный) параметр массива `#` может задавать режим подключения энкодера. Имеет смысл пробовать менять значение в интервале 1-3, если значение по умолчанию (2) не работает корректно для какого-то отдельно взятого энкодера.
|
||||
|
||||
Параметр `T` соответствует значению **32** — это тип входа «rotary encoder».
|
||||
|
||||
Параметр `"+-"` определяет обработчик, вызываемый при вращении рукоятки энкодера по или против часовой стрелки. Обработчик аналогичен описанному в разделе «диммирование с использованием кнопок» ([button_presses.md](button_presses.md)). Но там пары параметров `icmd`/`irev` и `ecmd`/`erev` используются поочередно, а в случае энкодера первый параметр используется в случае вращения по часовой стрелке, а второй — против часовой.
|
||||
|
||||
Настройка в примере ниже переключает локальное устройство `dimmer` между состояниями ON и OFF (команда `toggle`) по однократному клику на энкодер (параметр `click`), а при вращении рукоятки по и против часовой стрелки увеличивает или уменьшает яркость локального устройства `dimmer` соответственно (команды `%+1` и `%-1`):
|
||||
|
||||
```json
|
||||
{
|
||||
"T": 32, "#": [14, 4, 5, 2],
|
||||
"+-": { "item": "dimmer/set", "icmd": "%+1", "irev": "%-1" },
|
||||
"click": { "item": "dimmer/cmd", "icmd": "toggle" }
|
||||
}
|
||||
```
|
||||
|
||||
Поворот по часовой и против часовой стрелки можно разнести на два отдельных обработчика, если вдруг это будет необходимо, чтобы управлять разными устройствами при вращении в разных направлениях. Следующее описание эквивалентно предыдущему:
|
||||
|
||||
```json
|
||||
{
|
||||
"T": 32, "#": [14, 4, 5],
|
||||
"+": { "item": "dimmer/set", "icmd": "%+1" },
|
||||
"-": { "item": "dimmer/set", "icmd": "%-1" },
|
||||
"click": { "item": "dimmer/cmd", "icmd": "toggle" }
|
||||
}
|
||||
```
|
||||
|
||||
Теперь попробуем управлять удаленным устройством `dimmer2`, подключенным к контроллеру с именем `light` через MQTT:
|
||||
|
||||
```json
|
||||
{
|
||||
"T": 32, "#": [14, 4, 5],
|
||||
"+-": { "emit": "myhome/light/dimmer2/set", "ecmd": "%+1", "erev": "%-1" },
|
||||
"click": { "emit": "myhome/light/dimmer2/cmd", "ecmd": "toggle" }
|
||||
}
|
||||
```
|
||||
|
||||
И пример по управлению удаленным устройством с itemid = 31, настроенным на контроллере с адресом 13 по CAN-шине (см. [CAN и lightspot](../integrations/can_lightspot.md)):
|
||||
|
||||
```json
|
||||
{
|
||||
"T": 32, "#": [14, 4, 5],
|
||||
"+-": { "can": [13, 31, "set"], "icmd": "%+1", "irev": "%-1" },
|
||||
"click": { "can": [13, 31, "cmd"], "icmd": "toggle" }
|
||||
}
|
||||
```
|
||||
|
||||
### Профили (act)
|
||||
|
||||
Усложним задачу. Теперь попробуем управлять одним энкодером яркостью, цветом и насыщенностью светодиодной ленты. Для этого понадобится создать несколько профилей энкодера.
|
||||
|
||||
Профили можно задать в виде JSON-массива или JSON-объекта в параметре `act`. Массив и объект аналогичны: в первом случае для активации нужного профиля будет использоваться целое число, определяющее порядковый номер элемента в массиве, содержащего нужный профиль (начиная с 1, так как значение 0 зарезервировано для активации «корневого профиля», который может быть описан непосредственно в объекте входа, на одном уровне с параметрами `#`, `T` — аналогично предыдущим примерам). Во втором случае для активации можно пользоваться именем объекта (пустая строка активирует корневой профиль). Это, конечно, делает конфиг более читаемым, но чуть более ресурсоемко.
|
||||
|
||||
В примере ниже изначально активен корневой профиль, в котором осуществляется управление яркостью светодиодной ленты. Однократный клик (команда `activate` в обработчике события `click`) активирует профиль номер 1 — в котором управляется насыщенность цвета. Однократный клик из профиля 1 переводит энкодер в профиль 2, в котором можно настроить оттенок цвета. Ну и, соответственно, клик из профиля 2 активирует корневой профиль (0). В каждом профиле длительное нажатие включает или выключает `led`.
|
||||
|
||||
```json
|
||||
{
|
||||
"T": 32, "#": [14, 4, 5],
|
||||
"+-": { "item": "led/set", "icmd": "%+1", "irev": "%-1" },
|
||||
"lcmd": { "item": "led/cmd", "icmd": "toggle" },
|
||||
"click": { "activate": 1 },
|
||||
"act": [
|
||||
{
|
||||
"+-": { "item": "led/hue", "icmd": "%+1", "irev": "%-1" },
|
||||
"lcmd": { "item": "led/cmd", "icmd": "toggle" },
|
||||
"click": { "activate": 2 }
|
||||
},
|
||||
{
|
||||
"+-": { "item": "led/sat", "icmd": "%+1", "irev": "%-1" },
|
||||
"lcmd": { "item": "led/cmd", "icmd": "toggle" },
|
||||
"click": { "activate": 0 }
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
NB: `activate` можно использовать в описании других входов контроллера — таким образом, например, нажатием других кнопок можно выбирать режим действия энкодера.
|
||||
|
||||
## Доступность (сверка с кодом, 2026-10-02)
|
||||
|
||||
- Тип входа `T:32` (`IN_RE`) работает при компиляции с флагом `ROTARYENCODER` (`inputs.cpp`).
|
||||
- Флаг включен по умолчанию: **due, esp32-wifi, esp32c3-wifi, esp8266-wifi, lighthub21, nrf52840, stm32, stm32-noip** (`build-flags/*`).
|
||||
- Массив `#`: `[контакт_нажатия, A, B, режим]`; режим по умолчанию — 2 (`inputs.cpp`, `setupRotaryEncoder`).
|
||||
- `activate` поддерживает число (индекс профиля, 0 — корневой), строку (имя профиля) и массив `["имя_входа", <значение>]` — активация профиля во внешнем входе (`inputs.cpp`, `checkInstructions`).
|
||||
|
||||
## Не реализовано
|
||||
|
||||
Черновик из исходного документа, **не реализованный** в текущем коде:
|
||||
|
||||
- вход `T:99` с профилями и обработчиками `goto`/`onenter` (переходы между профилями по событиям, «сценарный» энкодер).
|
||||
|
||||
## Связанные документы
|
||||
|
||||
- [Нажатия кнопок](button_presses.md)
|
||||
- [CAN и lightspot](../integrations/can_lightspot.md)
|
||||
- [Справочник суффиксов](suffixes_reference.md)
|
||||
@@ -0,0 +1,239 @@
|
||||
# LightHub и шина CAN
|
||||
|
||||
> Источник: авторский документ «Lighthub и шина CAN» (docx, 2026-10-02), сверен с кодом `lighthub/candriver.cpp/h`.
|
||||
> CAN-поддержка в прошивке появилась в **v4.4.0**.
|
||||
|
||||
## Что такое CAN шина
|
||||
|
||||
CAN-шины очень широко используются в промышленной и автомобильной автоматике как дешевый, но надежный транспорт для взаимодействия модулей и блоков автоматики между собой. Такие шины есть, фактически, в каждом современном автомобиле.
|
||||
|
||||
В прошивке LightHub используется фиксированная скорость **50 kbit/s** (`candriver.cpp`: `STMCan.setBaudRate(50000)` / `CAN.begin(50000)` / `Can0.begin(CAN_BPS_50K)`), что обеспечивает длину шины до нескольких сотен метров — достаточно для большинства домовладений.
|
||||
|
||||
Поддержка CAN встроена во многие современные (и не очень) микроконтроллеры. Из тех микроконтроллеров, на которых работает прошивка LightHub, встроенная поддержка используется в следующих чипах:
|
||||
|
||||
- ARM SAM3E (Arduino DUE) — библиотека `due_can`
|
||||
- ESP32 — библиотека `arduino-CAN` (пины: GPIO 35 — RX, GPIO 5 — TX)
|
||||
- STM32 — библиотека `STM32_CAN`
|
||||
|
||||
> Подключение внешнего CAN-контроллера по SPI для чипов без встроенной поддержки **не реализовано** в текущем коде (`candriver.cpp` использует только встроенные контроллеры).
|
||||
|
||||
## Какие возможности появляются у LightHub
|
||||
|
||||
Теперь нет необходимости организовывать подключение локальной сети (или WiFi) к каждому устройству. Необходим минимум один контроллер (лучше пара), который подключен одновременно и к локальной сети, и к шине CAN. Он будет выполнять роль шлюза и держателя настроек периферийных контроллеров.
|
||||
|
||||
Периферийные устройства могут подключаться только к электропитанию и двухпроводной шине CAN. А это значит, что устройств может стать кратно больше, можно использовать очень простые, небольшие и дешевые устройства и, в пределе, размещать их в любом удобном месте. Например, в подрозетниках, выключателях, кондиционерах, датчиках движения.
|
||||
|
||||
При всем прочем, даже такие упрощенные устройства умеют почти то же самое, что их «старшие братья»:
|
||||
|
||||
- тот же формат JSON-файла настройки позволяет организовывать как локальное, так и удаленное управление устройством;
|
||||
- малое устройство может иметь на борту термостаты, возможность подключения термодатчиков и прочих сенсоров, PID-регуляторы, UART для управления кондиционером или для Modbus;
|
||||
- к таким устройствам можно подключать элементы управления: кнопки, переключатели, энкодеры (элемент с вращающейся ручкой), герконы дверей и датчики движения/присутствия;
|
||||
- они также поддерживают все возможности по определению одинарных-двойных-тройных-длительных нажатий кнопок, как и все LightHub.
|
||||
|
||||
Такая архитектура позволяет еще более децентрализовать управление умным домом: каждый маленький автономный контроллер (расположенный даже в выключателе) способен решить задачи простой автоматизации и локального управления даже в том случае, если часть системы вышла из строя.
|
||||
|
||||
Кроме того, CAN-шина позволяет таким простым устройствам напрямую общаться между собой, например:
|
||||
|
||||
- для реализации сценариев переключения сцен освещения, проходных выключателей;
|
||||
- для передачи измерений сенсоров на удаленные контроллеры (например, измерения влажности помещений на контроллер форсуночного увлажнения, значения CO2 в помещениях на систему вентиляции).
|
||||
|
||||
Причем такое взаимодействие теперь может происходить без посредничества локальной сети и MQTT-брокера, что еще более увеличивает надежность и живучесть системы в целом.
|
||||
|
||||
### Примеры применения контроллеров, подключенных только по шине CAN (далее — lightspot)
|
||||
|
||||
- Автономный управляемый термостат теплого пола
|
||||
- Автономное, управляемое локальным выключателем реле или диммер света (AC или RGB)
|
||||
- Датчик движения, локально и удаленно управляющий светом, с сенсорами температуры, влажности, CO2 на борту
|
||||
- Многоклавишный многофункциональный выключатель с сенсорами температуры-влажности, энкодером
|
||||
- Удаленные счетчики воды-газа-электричества
|
||||
- Управляемые клапаны вентиляции
|
||||
- Удаленные ультразвуковые датчики приближения для управления подсветкой ступеней
|
||||
|
||||
## Как организована передача данных по шине CAN
|
||||
|
||||
Таким образом, каждое устройство в произвольный момент времени может инициировать передачу кадра данных размером до 8 байт, и этот кадр будет принят сразу всеми подключенными к шине устройствами.
|
||||
|
||||
### Формат идентификатора кадра
|
||||
|
||||
Идентификатор кадра (до 32 бит, `canid_t` в `candriver.h`):
|
||||
|
||||
| Поле | Биты | Назначение |
|
||||
|--|--|--|
|
||||
| reserve | 3 | Должно быть 0 |
|
||||
| status | 1 | 1 — статус, 0 — запрос |
|
||||
| payloadType | 4 | Тип передаваемых данных |
|
||||
| deviceId | 8 | devID устройства (1..255) |
|
||||
| itemId | 10 | 0..1023 (или sequence # для длинных кадров) |
|
||||
| subItemId | 6 | 0..62 (63 — субайтем не задан) |
|
||||
|
||||
### Типы полезной нагрузки (payloadType)
|
||||
|
||||
| Значение | Имя | Назначение |
|
||||
|--|--|--|
|
||||
| 1 | `itemCommand` | Команда или статус для/от того или иного item |
|
||||
| 2 | `lookupMAC` | Запрос devID по MAC-адресу устройства (в ответе передается devID) |
|
||||
| 3 | `configFrame` | Кадр передачи конфигурации (JSON, частями) |
|
||||
| 4 | `OTAFrame` | Кадр передачи прошивки по CAN |
|
||||
| 5 | `auth` | Аутентификация |
|
||||
| 6 | `metric` | Метрики (см. metricType) |
|
||||
| 7 | `sysCmd` | Системные команды (см. commandType) |
|
||||
| 8 | `rawPinCtrl` | Прямое управление пинами |
|
||||
|
||||
### Формат данных (datagram_t)
|
||||
|
||||
```c
|
||||
enum metricType { MAC=1, IP=2, NetMask=3, GW=4, DNS=5, UpTime=6, Salt=7 };
|
||||
|
||||
typedef union {
|
||||
uint8_t data[8];
|
||||
char payload[8];
|
||||
struct {
|
||||
itemCmdStore cmd; // команда
|
||||
itemArgStore param; // аргумент команды
|
||||
};
|
||||
struct {
|
||||
macAddress mac; // MAC-адрес
|
||||
uint16_t currentConfCRC; // CRC текущей конфигурации
|
||||
};
|
||||
struct {
|
||||
uint8_t sysCmd;
|
||||
uint8_t sysCmdData[7];
|
||||
};
|
||||
struct {
|
||||
uint32_t metric1;
|
||||
uint32_t metric2;
|
||||
};
|
||||
} datagram_t;
|
||||
```
|
||||
|
||||
Системные команды (sysCmd, `commandType`):
|
||||
|
||||
| Значение | Команда |
|
||||
|--|--|
|
||||
| 1 | `reboot` — перезагрузка контроллера |
|
||||
| 2 | `get` — получить информацию |
|
||||
| 3 | `save` — сохранить конфигурацию |
|
||||
| 4 | `load` — загрузить конфигурацию |
|
||||
|
||||
## Процедура инициализации устройства и загрузки конфигурации
|
||||
|
||||
1. **Вычисление MAC-адреса.** Этот адрес является уникальным идентификатором устройства, даже если у него отсутствует сетевой интерфейс и имеется в наличии только CAN. MAC-адрес вычисляется из уникального серийного номера чипа для ARM-базированных устройств, для AVR считывается из EEPROM, для ESP используется MAC-адрес интерфейса WiFi.
|
||||
|
||||
2. Устройство отправляет запрос в CAN-шину, установив `payloadType = lookupMAC (2)` в пакете и передав 6 байт MAC-адреса.
|
||||
|
||||
3. Мастер-контроллер, содержащий конфигурацию устройства внутри своего файла настроек, формирует ответный пакет нулевой длины с установленным битом `status` в id и заполненным полем `deviceId`. С этого момента устройство знает свой devID.
|
||||
|
||||
4. Устройство отправляет запрос в CAN-шину, установив `payloadType = configFrame (3)` и полученный на предыдущем этапе devID. В качестве sequence # для первого пакета используется значение 0xFFFF (-1), запрос каждого последующего пакета осуществляется с увеличением sequence # на единицу. В ответ на каждый запрос устройство получает кадр данных; последовательность данных содержит JSON-конфигурацию.
|
||||
|
||||
### Пример конфигурации CAN внутри конфига мастер-устройства
|
||||
|
||||
```json
|
||||
"can": {
|
||||
"addr": 14,
|
||||
"conf": {
|
||||
"DE:54:71:48:17:2E": {
|
||||
"can": { "addr": 21, "name": "olmexino" },
|
||||
"items": {
|
||||
"relay1": [[6, 1], 1],
|
||||
"relay2": [[6, 2], 5],
|
||||
"relays": [["GROUP", 3], ["relay1", "relay2"]]
|
||||
},
|
||||
"in": {
|
||||
"41": { "T": 2, "item": "relays", "can": [10, 2], "scmd": "TOGGLE", "rcmd": "" }
|
||||
}
|
||||
},
|
||||
"DE:48:4E:03:B3:DF": {
|
||||
"can": { "addr": 22, "name": "sonar" },
|
||||
"items": {
|
||||
"relay1": [[6, 1], 1]
|
||||
},
|
||||
"in": [
|
||||
{
|
||||
"T": 7, "#": [14, 15],
|
||||
"act": [
|
||||
{ "map": [0, 100], "scmd": { "can": [13, 32], "icmd": "XON 10000" } },
|
||||
{ "map": [0, 200], "scmd": { "can": [13, 31], "icmd": "XON 15000" } }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`can.addr` — devID этого контроллера. `can.conf` — объект «MAC-адрес → конфигурация периферийного контроллера»; каждая периферия содержит собственный `can` (devID и имя) и обычные секции `items`/`in`.
|
||||
|
||||
## Способ настройки взаимодействия контроллеров с использованием шины CAN
|
||||
|
||||
В процессе работы контроллеры имеют возможность отправки на один или несколько других контроллеров, подключенных по шине CAN, следующего набора пакетов:
|
||||
|
||||
| Тип управляющего воздействия | Числовое значение суффикса | Суффикс (символьное значение) |
|
||||
|--|--:|--|
|
||||
| Команды для управления удаленными устройствами | 1 | `cmd` |
|
||||
| Уставки для удаленного устройства | 2 | `set` |
|
||||
| Текущие значения сенсоров | 3 | `val` |
|
||||
| Отложенная команда | 4 | `del` |
|
||||
| Цвет в нотации HSV | 5 | `hsv` |
|
||||
| Цвет в нотации RGB | 6 | `rgb` |
|
||||
| Интенсивность вентиляции | 7 | `fan` |
|
||||
| Режим работы климатической установки | 8 | `mode` |
|
||||
| Вспомогательная команда (FREEZE / UNFREEZE / ENABLE / DISABLE) | 9 | `ctrl` |
|
||||
| Цвет (hue) | 10 | `hue` |
|
||||
| Насыщенность цвета | 11 | `sat` |
|
||||
| Цветовая температура | 12 | `temp` |
|
||||
|
||||
### Адресация объекта назначения (item)
|
||||
|
||||
Для адресации объекта назначения (item), который обработает соответствующую команду в сети CAN, используется следующая нотация:
|
||||
|
||||
```
|
||||
[ <DevID>, <ItemID>, <suffix> <subitem> ]
|
||||
```
|
||||
|
||||
- **DevID** — адрес устройства, определяется на этапе конфигурирования (см. выше). DevID = 0 адресует сообщение всем устройствам сети.
|
||||
- **ItemID** — числовой идентификатор объекта (item). Задается при настройке удаленного объекта в JSON-конфигурации того контроллера, к которому объект подключен: первый элемент массива настройки item должен быть массивом, в котором первый объект определяет тип объекта, а второй — требуемый ItemID. Пример:
|
||||
|
||||
```json
|
||||
"items": {
|
||||
"relay1": [[6, 1], 1],
|
||||
"relay2": [[6, 2], 5],
|
||||
"relays": [["GROUP", 3], ["relay1", "relay2"]]
|
||||
}
|
||||
```
|
||||
|
||||
В примере выше для объекта `relay1` определяется itemID = 1, для объекта `relay2` — itemID = 2, а для группы `relays` — itemID = 3.
|
||||
|
||||
В том случае, если ItemID пересекаются между контроллерами и пакет отправлен на широковещательный адрес 0, пакет будет выполнен сразу всеми контроллерами, в которых определен объект с данным ID.
|
||||
|
||||
- **Suffix** — числовое или символьное значение, определяющее тип управляющего воздействия согласно таблице выше. Допустимо определять дополнительные числовые суффиксы, например, для управления теми регистрами устройства Modbus, которые не укладываются в таблицу выше. В этом случае при описании устройства Modbus можно задать параметр `"id": <значение>`, где значение — число в интервале 13-31, и этот параметр можно будет адресовать, задавая данное число в массиве `can` на третьей позиции.
|
||||
- **Subitem** — опциональный параметр, который может использоваться двояко:
|
||||
- если указана **цифра** — адресация суб-объекта, входящего в удаленный управляемый объект. Примеры объектов, которые имеют внутри перечень суб-объектов: MULTIVENT (многоканальная вентиляция/кондиционирование), HUM (многоканальный форсуночный увлажнитель), адресная светодиодная лента. Для адресации соответствующего суб-объекта используется порядковый номер, согласно которому данный суб-объект описан в JSON-конфигурации контроллера назначения;
|
||||
- если указана **строка** — делается попытка преобразовать данную строку в команду, и это значение передается удаленному устройству. Удаленное устройство исполнит пакет только в том случае, если текущее состояние устройства эквивалентно данной команде. Данная функция особо полезна для удаленных групп устройств: например, можно адресовать команды управления яркостью группе светильников, а исполнят их только светильники, находящиеся в состоянии «ON».
|
||||
|
||||
## Функция шлюза
|
||||
|
||||
Мастер-контроллер, который хранит конфигурацию периферийного, также выполняет функцию шлюза между шиной CAN и интерфейсами MQTT и HTTP.
|
||||
|
||||
Так как мастер-контроллер знает имя периферийного, при подключении к MQTT-брокеру он дополнительно подписывается на командный топик периферийного. Это позволяет управлять устройствами, подключенными через шину CAN, абсолютно прозрачно, с использованием стандартной нотации командных топиков `root/name/item/[subitem/]suffix`, например, через `myhome/sonar/relay1/cmd` для примера конфига выше.
|
||||
|
||||
Когда удаленный периферийный контроллер выполнит команду (либо вследствие изменения внутреннего состояния устройства) — изменение его статуса транслируется в шину CAN. Мастер-контроллер, который владеет конфигом периферийного, транслирует такое изменение статуса в свой стандартный статусный топик, например, в `myhome/s_out/relay1/cmd`.
|
||||
|
||||
## Доступность в сборках (сверка с кодом, 2026-10-02)
|
||||
|
||||
- Флаг `CANDRV` включен по умолчанию: **esp32-wifi, lighthub21, stm32-noip**; в **esp32c3-wifi** закомментирован (`build-flags/*`).
|
||||
- Скорость: 50 kbit/s, фиксированная (`candriver.cpp`).
|
||||
- ESP32: CAN на GPIO 35 (RX) / GPIO 5 (TX) (`candriver.cpp`).
|
||||
- Поддержка SPI-кан-контроллеров для чипов без встроенной CAN — **не реализована** (см. выше).
|
||||
|
||||
## Не реализовано
|
||||
|
||||
Черновики из исходного документа, допущенные до релиза, но **не реализованные** в текущем коде:
|
||||
|
||||
- вход `T:99` с профилями, обработчиками `goto`/`onenter` и сценарным переходом между профилями;
|
||||
- подключение CAN через внешний SPI-контроллер для чипов без встроенной поддержки.
|
||||
|
||||
## Связанные документы
|
||||
|
||||
- [Rotary Encoder](../core/rotary_encoder.md) — энкодер как орган управления (в т.ч. на lightspot)
|
||||
- [Быстрая справка по MQTT](../core/mqtt_quick_reference.md)
|
||||
- [Справочник типов каналов](../core/channel_types_reference.md)
|
||||
Reference in New Issue
Block a user