Ежесекундное выполнение правила, либо несколько параметров WhenChanged

Добрый день.
wb-2207 (as stable), target wb6/stretch
Появилась необходимость запрограммировать небольшую систему на WB, c JS никогда не работал.
Пытаюсь написать правило, которое проверяет физические входа (в примере ниже пока что виртуальные) и выдает true/false на физический выход. Загвоздка в том, что необходимо сделать правило либо как ежесекундый цикл сканирования, либо через whenChanged, но чтобы отслеживание по изменению было по всем входящим условиям. В обоих вариантах сталкиваюсь с проблемой синтаксиса. С вариантом WhenChanged пытаюсь прописать несколько тегов, безуспешно.
Прошу совета, я слишком привык к языкам 61131-3, с JS мучаюсь на элементарных задачах.

defineRule("CommonFault", {
//whenChanged: "VInputs/DI1_CommonFault" + "VInputs/DI2_VoltageStatus" ,
  when: cron("@every 3s")  
//  then: function (newValue, devName, cellName) {
  	then: function() {
    if (dev["VInputs/DI1_CommonFault"]==true && dev["VInputs/DI2_VoltageStatus"]==false) {
      dev["VInputs/DO1_Output"] = true;
    }
 //dev["VInputs/DO1_Output"]=1;
 log("devName:{}, cellName:{}, newValue:{}", devName, cellName, newValue)
  }
});

Топики, которые надо отслеживать можно перечислить массивом:

defineRule("CommonFault", {
whenChanged: ["VInputs/DI1_CommonFault", "VInputs/DI2_VoltageStatus"] ,
  then: function (newValue, devName, cellName) {
 log("devName:{}, cellName:{}, newValue:{}", devName, cellName, newValue)
  }
});

Вроде раньше было в документации на Гитхабе про это. Проверю, если потерялось - добавим.

Спасибо, перечислил массивом и заработало!

Еще такой вопрос: мне нжуно сделать простую проверку на обрыв линии, данные берутся с трех фаз канала трансформатора WB-MAP12E. Пока устройства не пришли, то пользуюсь объявлением виртуальных девайсов для проверки. Логика простая: проверять каждую фазу, если меньше 0.5А, то выдывать дискретный сигнал обрыв линии.
Пытаюсь засунуть всё это в функцию, с последующим вызовом для N линий. Возможен ли такой синтаксис и функционал? Насколько этот способ нагружает контроллер? Пока что воюю с компилятором.

//Функция проверки линий на обрыв (имя, ток1, ток2, ток3, дискр.выход)
heater_line("HL1", "MB_AI_I1_1", "MB_AI_I1_2", "MB_AI_I1_3", "LF1");
heater_line("HL2", "MB_AI_I2_1", "MB_AI_I2_2", "MB_AI_I2_3", "LF2");
// Еще N линий

function heater_line (Name, I1, I2, I3, Out)
{
	defineRule("LineCheck",{
      whenChanged: [I1, I2, I3],
      then: (newValue, devName, cellName) {
      	if (dev[I1]<0.5 || dev[I2]<0.5 || dev[I3]<0.5) {
      		dev[Out]=true;
    	} else {
      		dev[Out]=false;
        }
	}
    });
}

Более менее разобрался, однако есть проблема, когда вызываю больше одной функции. С объявлением только одной проблем нет.

Компилятор выдает подобное непонятное сообщение, ругаясь на вторую строчку вызова функции.

Script error: Error: error error (rc -100)
anon native strict preventsyield
anon /usr/share/wb-rules-system/scripts/lib.js:251
heater_line /etc/wb-rules/Lines.js:80
anon /etc/wb-rules/Lines.js:65 preventsyield

defineVirtualDevice("HeaterLines",{
                    title: 'Heater Lines',
                    cells: {
 
                        LF1: { //Line Fault 1
                    		title: "LF1",
                    		type: "switch",
                    		value: false,
                    },
                      
                        LF2: { //Line Fault 2
                    		title: "LF2",
                    		type: "switch",
                    		value: false,
                    },
                      	MB_AI_I1_1: {
                          	title: "MB_AI_I1_1",
                          	type: "range",
                          	value: 5,
                          	max: 100,
                          	min: 0,
                    },
                        MB_AI_I1_2: {
                          	title: "MB_AI_I1_2",
                          	type: "range",
                          	value: 5,
                          	max: 100,
                          	min: 0,
                    },    
                        MB_AI_I1_3: {
                          	title: "MB_AI_I1_3",
                          	type: "range",
                          	value: 5,
                          	max: 100,
                          	min: 0,
                    },

                      	MB_AI_I2_1: {
                          	title: "MB_AI_I2_1",
                          	type: "range",
                          	value: 5,
                          	max: 100,
                          	min: 0,
                    },
                        MB_AI_I2_2: {
                          	title: "MB_AI_I2_2",
                          	type: "range",
                          	value: 5,
                          	max: 100,
                          	min: 0,
                    },    
                        MB_AI_I2_3: {
                          	title: "MB_AI_I2_3",
                          	type: "range",
                          	value: 5,
                          	max: 100,
                          	min: 0,                      
                    },   
                    },                  
});


//Функция проверки линий на обрыв (имя, ток1, ток2, ток3, дискр.выход)
heater_line("HL1", "HeaterLines/MB_AI_I1_1", "HeaterLines/MB_AI_I1_2", "HeaterLines/MB_AI_I1_3", "HeaterLines/LF1");
heater_line("HL2", "HeaterLines/MB_AI_I2_1", "HeaterLines/MB_AI_I2_2", "HeaterLines/MB_AI_I2_3", "HeaterLines/LF2");
// Еще N линий

function heater_line (Name, I1, I2, I3, Out){
	defineRule("LineCheck",{
      whenChanged: [I1, I2, I3],
      then: function (newValue, devName, cellName)	{
      dev[I1] = true;
      	if (dev[I1]<5 || dev[I2]<5 || dev[I3]<5)
      		{dev[Out]=true;}
    	if (dev[I1]>=5 && dev[I2]>=5 && dev[I3]>=5)
      		{dev[Out]=false;}
               
log("devName:{}, cellName:{}, newValue:{}", devName, cellName, newValue)
											}
 });
};

Вероятно, что каждая функция пытается создать свое правило с одним и тем же именем, а это недопустимо.
Попробуйте исправить на
defineRule(“Line " + Name + " Check”,{

1 Like

Спасибо! Всё заработало!

Имя правила можно не указывать, если не предполагаете как-то потом это имя использовать, то есть объявление будет таким:
defineRule({...});

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