Определение defineRule в цикле не работает. Как быть?

Добрый день, понадобилось определить однотипные правила обработки событий для одинаковых устройств. Решил определить их через цикл. Но не работает, правила в итоге определяются только для последнего в цикле (хоть 100 будет устройств). Где здесь подвох и как корректно решить подобную задачу? Данные контроллера 6.9.1U/1G 610, wb-2307.

Пример кода, который подсвечивает проблему. Для получения логов достаточно подёргать бегунок на обоих девайсах. Можно добавить третье и далее устройства и убедиться, что правила будут применять только для последнего.

Код
defineVirtualDevice('my-vd', {
    title: 'TestVD' ,
    cells: {
      current: {
        title: "ток",
	    type: "range",
	    value: 0,
        min:0,
        max:60
	    },
      relay: {
        title: "реле",
	    type: "switch",
	    value: false,
        readonly: true
	    },
    }
});


defineVirtualDevice('my-vd2', {
    title: 'TestVD2' ,
    cells: {
      current: {
        title: "ток",
	    type: "range",
	    value: 0,
        min:0,
        max:60
	    },
      relay: {
        title: "реле",
	    type: "switch",
	    value: false,
        readonly: true
	    },
    }
});

var sensReleLinksArr = {
    "my-vd/current":"my-vd/relay",
    "my-vd2/current":"my-vd2/relay"
  };

for(key in sensReleLinksArr) {
  // отключение реле когда ток 0 
    defineRule({
      when: function() {
          return dev[key]==0;
        },
        then: function (newValue, devName, cellName) {
          dev[sensReleLinksArr[key]] = false;
          log("key:{}, znkey:{}, value:{}", key, sensReleLinksArr[key], newValue);
        }
      });

// включение реле, когда ток не 0 и свич уже не включен
    defineRule({
      when: function() {
            return ((dev[key]>0) && (dev[sensReleLinksArr[key]] == false));
          },
          then: function (newValue, devName, cellName) {
            dev[sensReleLinksArr[key]] = true;
            log("key:{}, znkey:{}, value:{}", key, sensReleLinksArr[key], newValue);
          }
       });
}

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

ERROR: [backend] failed to process /on request to my-vd/relay: This control is not writable

и предупреждение

WARNING: [conventions] converting empty value to boolean "false"

Добрый день.
А почему вам не подходит вариант, описанный в примере для однотипных правил?

Точно! М-да, когда постоянно не сталкиваешься, забываются такие рекомендации. А ведь поведение defineRule неестественное. Это же тоже по сути функция. И получается, что надо функцию в функцию вкладывать, чтобы получить результат. Т.е. кода больше. В общем заработало, спасибо!

Проблема не в defineRule, а в механизме работы замыканий в javascript.
Вот пример
В момент когда будет вызван callback when, key уже будет равен последнему значению key в цикле.
Это контринтуитивно, просто нужно запомнить и “фиксировать” значение, через передачу key в качестве аргумента функции сразу в цикле.

2 лайка

Эта тема была автоматически закрыта через 7 дней после последнего ответа. В ней больше нельзя отвечать.