wirenboard/wb-rules

Движок правил и жалюзи

mazaxaka opened this issue · 1 comments

Понял логику работы правил и почему не срабатывает моя задача.
Точный сценарий

defineVirtualDevice("jalusi", {
                    title: "Jalusi",
                    cells: {
                        state: {
                        type: "switch",
                        value: false
                        },
                    }
});


defineRule("jalusi", {
           whenChanged: "jalusi/state",
           then: function (newValue, devName, cellName){
                //dev["noolite_tx_0xc235"]["state"] = false;
                dev["noolite_tx_0xc234"]["state"] = newValue;
                dev["noolite_tx_0xc235"]["state"] = true;

           }
});

После перезапуска WB-Rules выполнив команду

mosquitto_sub -t '/devices/+/controls/+/on' -v

можно увидеть, что на устройство с адресом "C235" отправляется команда на включение. Предполагаю, что где-то есть проверка на предмет изменения состояния блока и делается следующий вывод: "В независимости от состояния виртуального устройства на блок с адресом C235 всегда улетает команда включить, давайте включать его в самом начале и не делать кучу лишней работы".
После этого при изменении состояния "jalusi" на блок улетает только команда включить блок "C234". Это означает, что если отключить 235 блок командой с пульта, например, WB больше не сможет управлять жалюзи до следующей перезагрузки.

Вариант использования для меня:

defineVirtualDevice("jalusi", {
                    title: "Jalusi",
                    cells: {
                        state: {
                        type: "switch",
                        value: false
                        },
                    }
});


defineRule("jalusi", {
           whenChanged: "jalusi/state",
           then: function (newValue, devName, cellName){
                dev["noolite_tx_0xc235"]["state"] = false;
                dev["noolite_tx_0xc234"]["state"] = newValue;
                dev["noolite_tx_0xc235"]["state"] = true;

           }
});

Каждый раз перед выполнением действия я отключаю реле, которое подает питание на жалюзи, потом перевожу реле отвечающее за направление движения в нужное положение и снова подаю питание, но это костыль.

Посмотреть принцип подключения и работы моей шторы можно посмотреть здесь http://blog.rfonoff.net/2015/02/02/управление-электрожалюзи-через-сист/

Объясните мне в чем я не прав, если это или поправьте, если я прав.
Заранее спасибо.

Из README.md:

В случае внешних устройств новое значение публикуется в топике /devices/.../controls/.../on, а соответствующее значение dev[...] изменится только после получения ответного значения в топике /devices/.../controls/... от драйвера устройства:

Таким образом, получается, что в Вашем коде может нарушиться последовательность действий вида dev[...] = value.

Для того, чтобы чётко детерминировать последовательность, можно создать три правила, которые будут реагировать по очереди на смену значений (например, так):

defineRule("jalusi-1", {
    whenChanged: "jalusi/state",
    then: function(newValue, devName, cellName) {
        dev["noolite_tx_0xc235"]["state"] = false;
    }
});


defineRule("jalusi-2", {
    when: function() { return dev["noolite_tx_0xc235/state"] == false; },
    then: function(newValue, devName, cellName) {
        dev["noolite_tx_0xc234"]["state"] = dev["jalusi"]["state"];
    }
});

defineRule("jalusi-3", {
    whenChanged: "noolite_tx_0xc234/state",
    then: function(newValue, devName, cellName) {
        dev["noolite_tx_0xc235"]["state"] = true;
    }
});

Хотя можно решить это каким-то более изящным способом.

За решением подобных вопросов, впрочем, лушче обращаться на форум - там жизнь идёт несколько бодрее.