Однако:
То есть простыми щелчками по кнопкам можно добиться переключения реле напрявления при включеном реле движения… Просто пощелкал мышкой.
//06_19_test_04.js
defineVirtualDevice("rolltest", { //создаём виртуальное устройство
title: "rolltest", //имя вирт устройства
cells: {
"SW_drive": {
type: "pushbutton", //тип его текст поле
value: false
},
"SW_direction": {
type: "pushbutton",
value: false
},
"drive": {
type: "switch", //тип его текст поле
value: false
},
"direction": {
type: "switch",
value: false
},
}
});
(function() {
function addVirtualRollet(id, name, control, direction, timeout, buttons, fixed) {
var moving, virt = 'virtual-rollet-' + id.toLowerCase(), data = {};
// Инициализируем виртуальное устройство со служебными полями
defineVirtualDevice(virt, {
title: name,
cells: {
open: {title: 'Открыть', type: 'pushbutton', order: 1},
close: {title: 'Закрыть', type: 'pushbutton', order: 2},
stop: {title: 'Остановить', type: 'pushbutton', order: 3},
position: {title: 'Текущая позиция', type: 'value', forceDefault: true, units: '%', value: 0, max: 100, order: 4},
target: {title: 'Целевая позиция', type: 'range', forceDefault: true, value: 0, max: 100, order: 5},
state: {title: 'Состояние', type: 'text', value: 'STOPPED', readonly: true, forceDefault: true, order: 6}
}
});
// Работа с топиками напрямую через объект
function defineVar(name, path) {
Object.defineProperty(data, name, {
configurable: true,
get: function() { return dev[path]; },
set: function(value) { dev[path] = value; }
});
}
defineVar('position', virt + '/position');
defineVar('target', virt + '/target');
defineVar('state', virt + '/state');
defineVar('route', direction);
defineVar('power', control);
// Задание цели по командам от внутренних или внешних кнопок с режимами работы
defineRule(virt + '-trigger', {
whenChanged: [virt + '/open', virt + '/close', virt + '/stop'].concat(buttons),
then: function(click, device, command) {
if (!click && !fixed) return;
if (device !== virt)
{
command = (buttons.length == 1) ? 0 : buttons.indexOf(device + '/' + command) + 1;
switch (buttons.length)
{
case 1: data.target = (data.state !== 'STOPPED' || !click) ? data.position : (data.position > 0 ? 0 : 100); break;
case 2: data.target = (data.state !== 'STOPPED') ? data.position : (command == 2 ? 0 : 100); break;
case 3: data.target = (command == 3) ? data.position : (command == 2 ? 0 : 100); break;
default: log.warning('{}: only 1/2/3 buttons can be used to control!', virt);
}
}
else
{
data.target = {'open': 100, 'close': 0, 'stop': data.position}[command];
}
}
});
// Работа с приводом: установка целевой позиции и расчет таймингов
defineRule(virt + '-action', {
whenChanged: virt + '/target',
then: function(value) {
if (moving)
{
clearInterval(moving);
data.power = false;
}
if (data.position === data.target)
{
data.route = false;
data.state = 'STOPPED';
return;
}
else
{
data.route = data.target > data.position;
data.state = data.target > data.position ? 'OPENING' : 'CLOSING';
setTimeout(function() {
data.power = true;
moving = setInterval(function() {
if (data.position !== data.target)
{
data.position += data.route ? 1 : -1;
}
else
{
clearInterval(moving);
data.power = false;
data.route = false;
data.state = 'STOPPED';
}
}, Math.round(timeout / 100));
}, 200);
}
}
});
}
// Инициализация виртуальных роллет и правил через общую функцию (датчик открытия в алгоритме не предусмотрен, расчет только на таймингам)
// Параметры: ID уст-ва, наименование, канал управления мотором, канал управления направлением, время на полное открытие/закрытые, выключатели
// Выключатели: [..] (1 - open/stop/close, 2 - open/stop и close/stop, 3 - open, close, stop), `true` после если кнопки фиксируемые!
addVirtualRollet('1', 'Пергола', 'rolltest/drive', 'rolltest/direction', 34000, ['rolltest/SW_drive', 'rolltest/SW_direction']);
//addVirtualRollet('2', 'Штора (роллета 2)', 'wb-gpio/EXT1_ON2', 'wb-gpio/EXT1_DIR2', 34000, ['wb-gpio/EXT2_DR3', 'wb-gpio/EXT2_DR4']);
})();
defineRule("Dirtest", {
whenChanged: 'rolltest/direction',
then: function(value) {
if (dev["rolltest/drive"]){
log.info("Alarm!")
log.info("direction new value:", value)
}
else{
log.info("ok")
}
}
})