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)
|
||||
Reference in New Issue
Block a user