mirror of
https://github.com/anklimov/lighthub
synced 2026-10-28 11:15:00 +00:00
163 lines
12 KiB
Markdown
163 lines
12 KiB
Markdown
# Двойные, тройные, длительные нажатия
|
||
|
||
> Источник: Wiki LightHub (lazyhome.ru), страницы «двойные\_тройные\_длительные\_нажатия» и «несколько\_кнопок\_на\_одном\_входе». Снапшот от 2026-10-02.
|
||
|
||
Начиная с [этого коммита](https://github.com/anklimov/lighthub/commit/0044b741ac9f6fb8fc4b1ff8388e47c8bb8efd9b) у прошивки появилась возможность отслеживать одинарные, двойные, тройные, долгие нажатия
|
||
|
||
Конечный автомат, согласно которому реализован алгоритм, приведен на рисунке
|
||
|
||
(см. иллюстрацию на [wiki-странице](https://www.lazyhome.ru/dokuwiki/doku.php?id=двойные_тройные_длительные_нажатия))
|
||
|
||
Фрагмент конфига (раздел in, на примере pin 68), который задает обработчики для нажатий, приведен ниже.
|
||
Каждое событие описывается JSON объектом или массивом JSON обьектов.
|
||
Внутри объекта, возможны следующие строковые параметры:
|
||
|
||
## Типы нажатий
|
||
|
||
* `scmd` - начало первого нажатия
|
||
* `rcmd` - конец первого нажатия
|
||
* `lcmd` - первое длительное нажатие
|
||
* `click` - одиночное нажатие
|
||
* `dclick` - двойное нажатие
|
||
* `tclick` - тройное нажатие
|
||
* `scmd2` - начало двойного нажатия
|
||
* `scmd3` - начало тройного нажатия
|
||
* `lcmd2` - второе длительное нажатие
|
||
* `lcmd3` - третье длительное нажатие
|
||
* `rpcmd` - цикл первого длительного нажатия
|
||
* `rpcmd2` - цикл второго длительного нажатия
|
||
* `rpcmd3` - цикл третьего длительного нажатия
|
||
|
||
## Параметры обработчика нажатий
|
||
|
||
* `emit` - MQTT топик в который отправить значение из параметра ecmd (если в параметре отсутствует / он будет дополнен слева префиксом статусного топика)
|
||
|
||
* `ecmd` - MQTT payload
|
||
|
||
* `erev` - если параметр задан, значения ecmd и erev будут подставляться попеременно для каждого нажатия. Позволяет обеспечить, например, увеличение и уменьшение яркости лампы одной клавишей.
|
||
|
||
* `item` - имя локального устройства из items (может содержать суффикс для указания того, какое именно свойство объекта надо изменить. Например: "lamp/hue" или "lamp/sat")
|
||
|
||
* `icmd` - команда для локального устройства (ON | OFF | HALT | REST | XON | XOFF | INCREASE | DECREASE | %<цифра> и т.д)
|
||
|
||
* `irev` - если параметр задан, значения icmd и irev будут подставляться попеременно для каждого нажатия. Позволяет обеспечить, например, увеличение и уменьшение яркости лампы одной клавишей.
|
||
|
||
```json
|
||
"68":{"T":0,
|
||
"scmd":{"emit":"cmd","ecmd":"scmd"},
|
||
"rcmd":{"emit":"cmd","ecmd":"rcmd"},
|
||
"lcmd":{"emit":"cmd","ecmd":"lcmd"},
|
||
"click":{"emit":"cmd","ecmd":"click","item":"a_bedr","icmd":"TOGGLE"},
|
||
"dclick":[{"emit":"myhome/in/bedr","ecmd":"TOGGLE"},{"emit":"myhome/in/bedrspot","ecmd":"TOGGLE"}],
|
||
"tclick":{"item":"spi","icmd":"TOGGLE"},
|
||
"scmd2":{"emit":"cmd","ecmd":"scmd2"},
|
||
"scmd3":{"emit":"cmd","ecmd":"scmd3"},
|
||
"lcmd2":{"emit":"cmd","ecmd":"lcmd2"},
|
||
"lcmd3":{"emit":"cmd","ecmd":"lcmd3"},
|
||
"rpcmd":{"item":"a_bedr","icmd":"INCREASE"},
|
||
"rpcmd2":{"item":"a_bedr","icmd":"DECREASE"},
|
||
"rpcmd3":{"emit":"cmd","ecmd":"rpcmd3"}
|
||
|
||
},
|
||
```
|
||
|
||
Еще пример:
|
||
|
||
* Длительное нажатие через раз увеличивает или уменьшает яркость группы ligth (суффикс set позволяет менять яркость не включая канал, если он выключен)
|
||
* Соответственно, длительное нажатие через двойной или тройной клик позволяет так же управлять цветом и насыщенностью
|
||
* Двойное и тройное нажатие без удерживания включают/выключают группы kuhktc и gstall соответственно
|
||
* Команда %-Х уменьшает параметр на Х пунктов, соответственно %+Х увеличивает
|
||
|
||
```json
|
||
"63":{"T":2,
|
||
"click":{"item":"light","icmd":"TOGGLE"},
|
||
"rpcmd":{"item":"light/set","icmd":"%+5","irev":"%-5"},
|
||
"rpcmd2":{"item":"light/hue","icmd":"%+5","irev":"%-5"},
|
||
"rpcmd3":{"item":"light/sat","icmd":"%+5","irev":"%-5"},
|
||
"dclick":{"item":"kuhktc/cmd","icmd":"TOGGLE"},
|
||
"tclick":{"item":"gstall","icmd":"TOGGLE"}},
|
||
```
|
||
|
||
Еще пара полезных примеров для обычных (не кнопочных) выключателей
|
||
В первом - кратковременное выключение выключателя включает белый свет на полную (повторное - включает максимально насыщенный цвет и яркость 30%)
|
||
|
||
Во втором - совсем упрощенный вариант - для одноцветных ламп - лампа через раз включается на 30 и на 100 процентов яркости
|
||
|
||
```json
|
||
"56":{"T":2,
|
||
"scmd":{"item":"bedr","icmd":"ON"},
|
||
"scmd2":[{"item":"bedr","icmd":"100","irev":"30"},{"item":"bedr/sat","icmd":"0","irev":"100"}],
|
||
"rcmd":{"item":"bedr","icmd":"OFF"}},
|
||
|
||
"60":{"T":2,
|
||
"scmd":{"item":"bedrspot","icmd":"100","irev":"30"},
|
||
"rcmd":{"item":"bedrspot","icmd":"OFF"}},
|
||
```
|
||
|
||
## Несколько кнопок на одном входе
|
||
|
||
Если в обьекте, определяющем вход, обнаружен массив **"act"** и вход является аналоговым, то каждый элемент массива будет рассматриваться как отдельный вход, для которого возможна такая же обработка как для дискретного (то есть определение даблкликов, долгих нажатий и пр)
|
||
|
||
При этом анализируется параметр **"map**" у каждого элемента массива, и элемент применяется только если значение аналогового входа находится внутри заданного интервала
|
||
|
||
Это позволяет на один аналоговый вход подключить несколько кнопок через резисторы.
|
||
|
||
Важно: в параметре "T" не надо указывать аналоговый тип входа. Используются дискретные типы 0 и 2
|
||
|
||
Пример: Кнопка выкл/уменьшить яркость подключена к опорному напряжению +10В напрямую, кнопка вкл/увеличить яркость - через резистор 2,2 КОм (на плате должен быть активирован шунт - см [аналоговые входы, общая информация](analog_inputs_and_map.md#общая-информация))
|
||
|
||
```json
|
||
"in": {
|
||
"54":{"T":0,"act":
|
||
[
|
||
{
|
||
"map":[128,640],
|
||
"click":{"item":"gr_gost3","icmd":"ON"},
|
||
"dclick":{"item":"lampwc3","icmd":"ON"},
|
||
"tclick":{"item":"lampbath3","icmd":"ON"},
|
||
"rpcmd":{"item":"gr_gost3","icmd":"%+2"}
|
||
},
|
||
{
|
||
"map":[641,1024],
|
||
"click":{"item":"gr_gost3","icmd":"OFF"},
|
||
"dclick":{"item":"lampwc3","icmd":"OFF"},
|
||
"tclick":{"item":"lampbath3","icmd":"OFF"},
|
||
"rpcmd":{"item":"gr_gost3","icmd":"%-2"}
|
||
}
|
||
]}
|
||
}
|
||
```
|
||
|
||
И тот же самый пример, записанный в новой нотации конфигурирования входов, при которой элемент конфигурации in является массивом, а значит, появилась возможность без костылей настраивать входы, не привязанные напрямую к пинам процессора. Номер пина задается в параметре "#" конфигурации:
|
||
|
||
```json
|
||
"in": [
|
||
"{"T":0,"#":54, "act":
|
||
[
|
||
{
|
||
"map":[128,640],
|
||
"click":{"item":"gr_gost3","icmd":"ON"},
|
||
"dclick":{"item":"lampwc3","icmd":"ON"},
|
||
"tclick":{"item":"lampbath3","icmd":"ON"},
|
||
"rpcmd":{"item":"gr_gost3","icmd":"%+2"}
|
||
},
|
||
{
|
||
"map":[641,1024],
|
||
"click":{"item":"gr_gost3","icmd":"OFF"},
|
||
"dclick":{"item":"lampwc3","icmd":"OFF"},
|
||
"tclick":{"item":"lampbath3","icmd":"OFF"},
|
||
"rpcmd":{"item":"gr_gost3","icmd":"%-2"}
|
||
}
|
||
]}
|
||
]
|
||
```
|
||
|
||
Работают обе нотации. Если номер пина прописан сразу в двух местах, приоритет имеет параметр "#"
|
||
|
||
## Сверка с кодом (2026-10-02)
|
||
|
||
- Корректно: все ключи нажатий (`click`, `dclick`, `tclick`, `scmd`, `rcmd`, `lcmd`, `scmd2`, `scmd3`, `lcmd2`, `lcmd3`, `rpcmd`, `rpcmd2`, `rpcmd3`) читаются в `lighthub/inputs.cpp` (строки 717–790, конечный автомат `IS_*`).
|
||
- Корректно: параметры `emit`/`ecmd`/`erev`/`item`/`icmd`/`irev` обрабатываются в `lighthub/utils.cpp:701-718` (попеременная подстановка `icmd`/`irev` и `ecmd`/`erev` подтверждена).
|
||
- Корректно: массив `"act"` и `"map"` для нескольких кнопок на одном аналоговом входе обрабатываются в `lighthub/inputs.cpp` (строки 173, 631, 656, 672, 1248).
|
||
- Уточнение: для дискретных нажатий `T` использует типы 0 и 2, как указано в wiki (типы входов: `IN_PUSH_ON=0`, `IN_ACTIVE_HIGH=2` — `lighthub/inputs.h:29-34`).
|