Выполнение правил с учетом нестабильного сигнала

Добрый день!

Я хочу синхронизировать 2 реле (master - slave), при чем каждый из них может периодически терять соединение с контроллером.

Можно ли не изобретая велосипед повторно выполнить MQTT команду (или нечто подобное) на включение/выключение реле после восстановления сигнала?

Сейчас, если связь со slave на момент whenChanged была потеряна, состояние slave не придет в нужное после восстановления состояния.

defineRule("test_rule_1", {
    whenChanged: "wb-mr3_30/K1",
    then: function(newValue, devName, cellName) {
        dev["wb-mr6c_57"]["K1"] = newValue;
    }
});
  1. создать “референсный” виртуальный девайс
  2. из его состояния записывать состояния реле 1 и реле 2
  3. после очередной записи сделать проверку состояния реле 1 и реле 2
  4. если это не удается сделать с каким-то реле, значит с ним связи нет - цикл запись-проверка соответствующего реле
  5. если значение не совпадает, значит “синхронизация” не произошла, произвести повторно
root@wirenboard-ANMSNLVK:~# mosquitto_sub -t /devices/wb-mr3_30/controls/K1/# -v &
[1] 9247
/devices/wb-mr3_30/controls/K1/meta/type switch
/devices/wb-mr3_30/controls/K1/meta/order 1
/devices/wb-mr3_30/controls/K1 1

root@wirenboard-ANMSNLVK:~# mosquitto_pub -t /devices/wb-mr3_30/controls/K1/on -m 0
/devices/wb-mr3_30/controls/K1/on 0
/devices/wb-mr3_30/controls/K1 0

# выдергиваю wb-mr3_30

/devices/wb-mr3_30/controls/K1/meta/error r

mosquitto_pub -t /devices/wb-mr3_30/controls/K1/on -m 1
/devices/wb-mr3_30/controls/K1/on 1
/devices/wb-mr3_30/controls/K1 1
/devices/wb-mr3_30/controls/K1/meta/error rw

# подключаю wb-mr3_30
/devices/wb-mr3_30/controls/K1/meta/error w
/devices/wb-mr3_30/controls/K1 0
root@wirenboard-ANMSNLVK:~# mosquitto_pub -t /devices/wb-mr3_30/controls/K1/on -m 1
/devices/wb-mr3_30/controls/K1/on 1
/devices/wb-mr3_30/controls/K1 1
/devices/wb-mr3_30/controls/K1/meta/error (null)

проблема в том, что даже если девайс отключен, значение топика меняется.

Значение топика /devices/wb-mr3_30/controls/K1/on меняется в mqtt-клиенте, а не на устройстве.

root@wirenboard-ANMSNLVK:~# mosquitto_sub -t /devices/wb-mr3_30/controls/K1/# -v &
[1] 9247
/devices/wb-mr3_30/controls/K1/meta/type switch
/devices/wb-mr3_30/controls/K1/meta/order 1
/devices/wb-mr3_30/controls/K1 1

root@wirenboard-ANMSNLVK:~# mosquitto_pub -t /devices/wb-mr3_30/controls/K1/on -m 0
/devices/wb-mr3_30/controls/K1/on 0
/devices/wb-mr3_30/controls/K1 0

# выдергиваю wb-mr3_30

/devices/wb-mr3_30/controls/K1/meta/error r

mosquitto_pub -t /devices/wb-mr3_30/controls/K1/on -m 1
/devices/wb-mr3_30/controls/K1/on 1
/devices/wb-mr3_30/controls/K1 1
/devices/wb-mr3_30/controls/K1/meta/error rw

# подключаю wb-mr3_30
/devices/wb-mr3_30/controls/K1/meta/error w
/devices/wb-mr3_30/controls/K1 0

Здесь считайте значение реле вместо повторной публикации

root@wirenboard-ANMSNLVK:~# mosquitto_pub -t /devices/wb-mr3_30/controls/K1/on -m 1
/devices/wb-mr3_30/controls/K1/on 1
/devices/wb-mr3_30/controls/K1 1
/devices/wb-mr3_30/controls/K1/meta/error (null)

Как виртуальные устройства реагируют на перезагрузку контроллера?
Сохранится предыдущее состояние?

Код синхронизации состояний двух реле:

   defineVirtualDevice("wb-mr3_30_v", {
      title: "Regulations Switch",
      cells: {
        K1: {
          type: "switch",
          value: false // default
        }
      }
    });

    defineVirtualDevice("wb-mr6c_57_v", {
      title: "Regulations Switch",
      cells: {
        K1: {
          type: "switch",
          value: false // default
        }
      }
    });

    defineVirtualDevice("common_switch", {
      title: "Regulations Switch",
      cells: {
        K1: {
          type: "switch",
          value: false // default
        }
      }
    });

    defineRule("wb-mr3_30_back_sync", {
        whenChanged: "wb-mr3_30/K1",
        then: function(newValue, devName, cellName) {
            if (dev["wb-mr3_30_v"]["K1"] != newValue) {
                dev["wb-mr3_30"]["K1"] = dev["wb-mr3_30_v"]["K1"];
            }
        }
    });

    defineRule("wb-mr6c_57_back_sync", {
        whenChanged: "wb-mr6c_57/K1",
        then: function(newValue, devName, cellName) {
            if (dev["wb-mr6c_57_v"]["K1"] != newValue) {
                dev["wb-mr6c_57"]["K1"] = dev["wb-mr6c_57_v"]["K1"];
            }
        }
    });

    defineRule("wb-mr6c_57_rule", {
        whenChanged: "wb-mr6c_57_v/K1",
        then: function(newValue, devName, cellName) {
            dev["wb-mr6c_57"]["K1"] = newValue;
        }
    });

    defineRule("wb-mr3_30_rule", {
        whenChanged: "wb-mr3_30_v/K1",
        then: function(newValue, devName, cellName) {
            dev["wb-mr3_30"]["K1"] = newValue;
        }
    });

    defineRule("common_switch_rule", {
        whenChanged: "common_switch/K1",
        then: function(newValue, devName, cellName) {
            dev["wb-mr3_30_v"]["K1"] = newValue;
            dev["wb-mr6c_57_v"]["K1"] = newValue;
        }
    });

Устойчив к потере сигнала реле и к перезагрузкам.

По поводу сохранения состояния виртуального устройства тупанул, там же retained. Восстанавливается по последнему сообщению.

Спасибо за идею :grinning: