Обработка событий от zigbee выключателя Aqara H1 c учетом синка устройства

Всем привет!
Создаю топик на случай, если у кого возникнет похожая проблема, ну или если кто-то предложит другое решение.
отмечу, что также есть решение для похожего сценария в топике Xiaomi Aqara Zigbee Wireless Switch

Версия контроллера 8.5.1, прошивка wb-2501
При попытке написать правило для zigbee выключателя Aqara H1, так чтобы на каждый тип нажатия повесить циклическое управление тем или иным сценарием, столкнулся со следующим:
Если делать правило на изменение топика action устройства, то не получается циклическое управление, что логично, поэтому в данном случае не подходит. соответственно следующий кандидат на триггер для правила - last_seen, как величина, которая точно будет меняться от события к событию.
ниже фрагмент правила:

defineRule('hall_switch_trigger',{
  whenChanged:hall_switch+'/last_seen',//отслеживаем последнее действие 
  then:function(newValue,devName,cellName){
    var action = dev[hall_switch+'/action']
    log('hall switch pressed {}',action);
    switch(action){
      case 'single_right'://запускает сценарий "Мы Дома"
        {
          dev['atHome/button']=true;
          break;
        }
      case 'single_left'://включает/выключает свет в помещении
        {
          if(dev[wc]==true){
            dev[wc]=false
          }else{
            dev[wc]=true;
          }
          break;
        }
      case 'double_right'://запускает сценарий выключения всего света
        {
          dev['turnOffAll/button']=true;
          break;
        }
...
      default:{
        log('unused action {} at {}',action,devName)
      }
    }
  }
});

Но есть нюанс!!!
иногда устройство присылает событие синхронизации и с кодом написанным выше это работает так, что при получении такого события, будет браться последний полученный action и сценарий будет отрабатывать по нему. В итоге получаем периодическое включение/выключение света/сценариев, что не есть хорошо.
Пробуем разобраться, ищем в журнале события, которые отправлялись по нажатию и те, что отправлялись при синхронизации
первое выглядит так

'{"action":"single_left","battery":100,"device_temperature":25,"last_seen":1744145603496,"linkquality":98,"power_outage_count":14,"state":"OFF","voltage":3198}

второе выглядит так

'{"battery":100,"device_temperature":25,"last_seen":1744145530313,"linkquality":116,"power_outage_count":14,"state":"OFF","voltage":3198}

Видно, что во втором случае поля action в событии нет. Логично предположить, что в таком случае значение в топик не отправляется и в соответствующем виртуальном устройстве не изменяется. Тогда возможно есть шанс что при прописывании в контроле виртуального устройства измененного значения, оно не сбросится при получении синхронизации.
проверяем
в скрипте прописываем после того, как сохранили текущий action в переменную
dev[hall_switch+‘/action’]=‘’
при отработке сценария action становится пустым


и при получении следующей синхронизации выводится
INFO: [rule info] hall switch pressed null

Таким образом получается, завязавшись на изменение last_seen, сделать циклическое управление при нажатии одних и тех же клавиш на выключателе путем обнуления поля action в виртуальном устройстве, соответствующем выключателю

Это делается намного проще:

defineRule("ZB_BUTTON_rule", {
  whenChanged: "ZB_BUTTON/action",
  then: function (newValue, devName, cellName) {
    if (dev["ZB_BUTTON/action"] == "hold") {
      dev["night_mode/night"] = !dev["night_mode/night"];
    }    
    if (dev["ZB_BUTTON/action"] == "single") {
      publish("zigbee2mqtt/ZB_SWITCH_ZAL/set", JSON.stringify({state: "TOGGLE" }));
    }    
    dev["ZB_BUTTON/action"] = "none";
   }
});

Можете и через switch/case сделать. Тут дело удобства.
Как только обработали action, пишем в него что угодно, кроме того, что обрабатываем.
И всё…

1 лайк

Добрый день,
@AlexBell @hexprof — спасибо за ваш огромный вклад в наше сообщество!
Очень ценим вашу активность и помощь другим пользователям.