Начальное состояние контрола

Привет.

Есть виртуальный switch, нужно установить его начальное состояние. Это состояние определяется сухим контактом, т.е. при инициализации правил нужно сделать что-то типа

dev['thermo']['heater'] = dev['wb-gpio']['D4_IN'];

Никак не пойму, где прописать эту строчку. В глобальной области видимости это как-то неправильно, да и wb-rules падает при запуске, если так сделать.

можете сделать правило, которое срабатывает на wb-gpio/D4_IN например

Правило срабатывает на изменение значения. А мне нужно текущее взять.

Сделал так, может кому пригодится:

var heater_init = false;
defineRule('dl_w_heater_init', {
    when: function() {
        return heater_init == false;
    },
    then: function () {
      	heater_init = true;
      	dev['thermostat']['Water heater'] = dev['wb-gpio']['D4_IN'];
    }
});

Цитата из документации:

whenChanged-правила вызываются также и при первом просмотре правил, если фигурирующие непосредственно в списке или внутри вызываемых функций параметры определены среди retained-значений

Читал, пробовал, не заработало, забил. Сейчас попробовал еще раз - заработало. В общем какая-то фигня была, теперь все ок.

Спасибо за “пиннок” )

А нет, вру - не работает, либо я что-то не так понимаю. Вот такое правило:

defineRule('dl_w_heater_status', {
    whenChanged: ['wb-gpio/D4_IN'],
    then: function (newValue, devName, cellName) {
      log('run');
        dev['thermostat']['Water heater'] = newValue;
    }
});

В лог ничего при инициализации (например при сохранении правила в веб-редакторе, либо при рестарте wb-rules) не выводит.

Давайте уточним:

  1. Это правило выводит в лог слово run, если вы вручную меняете состояние цифрового входа 4?
  2. Это правило НЕ выводит в лог слово run при рестарте wb-rules?
  3. Среди retained сообщений точно есть связанное с wb-gpio/D4_IN?
  1. Верно
  2. Верно
  3. Судя по всему, да:

mosquitto_sub -v -t /devices/wb-gpio/controls/D4_IN/#
сразу выводит:

/devices/wb-gpio/controls/D4_IN/meta/order 32 /devices/wb-gpio/controls/D4_IN/meta/type switch /devices/wb-gpio/controls/D4_IN/meta/readonly 1 /devices/wb-gpio/controls/D4_IN 1

mosquitto_sub -v -R -t /devices/wb-gpio/controls/D4_IN/#
не выводит ничего, пока не переключишь состояние D4

Версия wb-rules - 1.6.8. Обновляться я боюсь последнее время )

Вы правы - мы проверили, и действительно, whenChanged правила вопреки документации не исполняются при запуске движка правил и наличии retained сообщений.
Мы кратко посовещались, и решили сохранить текущее поведение whenChanged, исправив документацию.
Для выполнение инициализации можно использовать, например:

setTimeout(function() {
  log("current value of A4_IN is {}".format(dev["wb-gpio/A4_IN"])); // вместо log() подставьте свою функцию
}, 0);

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

Водонагреватель включается 2-канальным импульсным реле. Мне нужно определять статус реле. Для этого на 2 канале импульсного реле “висит” сухой контакт, воткнутый во вход D4 WB. А для переключения состояния импульсного реле используется реле Relay_1 на WB. Чтобы не плодить контролы, статус реле и переключение повесил на виртуальным свитч.

Вот так все это выглядит в коде:

defineVirtualDevice('thermostat', {
    title: 'Thermostat', //
    cells: {
        'Water heater': {
          	type: 'switch',
          	value: true
        }
    }
});

defineRule('dl_w_heater_status', {
    whenChanged: ['wb-gpio/D4_IN'],
    then: function (newValue, devName, cellName) {
        dev['thermostat']['Water heater'] = newValue;
    }
});


defineRule('dl_w_heater_init', {
    when: function() {
        return heater_init == false;
    },
    then: function () {
      	heater_init = true;
      	dev['thermostat']['Water heater'] = dev['wb-gpio']['D4_IN'];
    }
});

defineRule('dl_w_heater', {
    whenChanged: ['thermostat/Water heater'],
    then: function (newValue, devName, cellName) {
		dev['wb-gpio/Relay_1'] = 1;
      	setTimeout(function() {
          dev['wb-gpio/Relay_1'] = 0;
        }, 1000);
    }
});

Спасибо, понятно.

Кажется, вот эту часть:

можно заменить на:

setTimeout(function() {
     dev['thermostat']['Water heater'] = dev['wb-gpio']['D4_IN'];
}, 0);

Согласен, что текущее поведение лучше не трогать - сами всегда так делаем при похожих случаях :).

За совет спасибо, перепишу код.