Покажите какие значения внесли.
Выложу целиком:
var Thermometer = "wb-w1/28-00000b0ff412"; // Здесь указать свой датчик
var relay_on_timer_id = null;
var relay_off_timer_id = null;
var temp_on = -3; // Указать свою температуру
var temp_off = -1; // Указать свою температуру
defineVirtualDevice ("upravl_heating_skvazin", {
title: "Upravl obogrev skvazin-drenaz",
cells: {
enabled: {
type: "switch",
value: false,
},
}
});
function on_timer() {
//log.info("in function on_timer()");
dev["wb-gpio"]["EXT3_R3A1"] = true; //Здесть указать имя своего модуля,установи модуля wb-gpio в состояние "включено"
dev["wb-gpio"]["EXT3_R3A2"] = true; //Здесть указать имя своего модуля установи модуля wb-gpio в состояние "включено"
relay_on_timer_id = setTimeout(function() {
off_timer();
}, 10000); //для теста 10 сек во включенном положении, 2 часа это будет 2*60*60*1000
log.info("Relay skvaz ON, Wait 2ch");
}
function off_timer() {
// log.info("in function off_timer()");
dev["wb-gpio"]["EXT3_R3A1"] = false; //Здесть указать имя своего модуля, установи модуля wb-gpio в состояние "выключено"
dev["wb-gpio"]["EXT3_R3A2"] = false; //Здесть указать имя своего модуля, установи модуля wb-gpio в состояние "выключено"
relay_off_timer_id = setTimeout(function() {
on_timer();
}, 40000); //для теста 30 сек в выключенном положении, 4 часа это будет 4*60*60*1000
log.info("Relay skvaz OFF, Wait 4ch");
}
function Stop_Timer(){
//log.info("Timer stop");
if (relay_on_timer_id) {relay_on_timer_id = clearTimeout(relay_on_timer_id); };
if (relay_off_timer_id) {relay_off_timer_id = clearTimeout(relay_off_timer_id); };
}
defineRule("rule upravl heating skvazin", { //название правила - “контроль обогрева скважины”
whenChanged: Thermometer, //при изменении состояния датчика wb-w1/28-00000b0ff412
then: function(newValue, devName, cellName) { //выполняй следующие действия
if (dev.upravl_heating_skvazin.enabled) { // если вируальн. устр-во в положении enabled
//log.info("if dev.upravl_heating_skvazin.enabled = true");
if (newValue < temp_on) { //если температура датчика меньше xx градусов
on_timer();
}
else { // иначе
if (newValue > temp_off) { //Если температура датчика больше xx градусов
Stop_Timer();
dev["wb-gpio"]["EXT3_R3A1"] = false; //Здесть указать имя своего модуля, установи модуля wb-gpio в состояние "выключено"
dev["wb-gpio"]["EXT3_R3A2"] = false; //Здесть указать имя своего модуля, установи модуля wb-gpio в состояние "выключено"
log.info("Stop skvaz timer and off relay, temp > {}",temp_off);
}
}
}
else { // если вируальн. устр-во Upravl obogrev skvazina в положении disable, выключаем реле и завершаем таймеры
Stop_Timer();
dev["wb-gpio"]["EXT3_R3A1"] = false; //установи R3A1 модуля wb-gpio в состояние "выключено"
dev["wb-gpio"]["EXT3_R3A2"] = false; //установи R3A2 модуля wb-gpio в состояние "выключено"
log.info("Stop skvaz timer and off relay, button 'Upravl obogrev skvazin-drenaz' disable");
}
}
});
Не много не понятна ТЗ, как Вы здесь указали, нужна цикличности вкл и выкл обогрева, но по коду вижу, что есть еще ограничения по температуре и контроль запуска правила по кнопки.
Могли бы Вы указать более точно, что нужно. Т.к. в данном варианте правило привязано к изменениям термометра и мне кажется так делать совсем верно в данном случаи.
Попробуйте вот этот…
var relay_on_timer_id = null;
var relay_off_timer_id = null;
var temp_on = -3; // Указать свою температуру
var temp_off = -1; // Указать свою температуру
defineVirtualDevice ("control_heating", {
title: "Well heating",
cells: {
enabled: {
type: "switch",
value: false,
},
}
});
function on_timer() {
//log.info("in function on_timer()");
dev["wb-gpio"]["EXT2_R3A1"] = true; //Здесть указать имя своего модуля,установи модуля wb-gpio в состояние "включено"
dev["wb-gpio"]["EXT2_R3A2"] = true; //Здесть указать имя своего модуля установи модуля wb-gpio в состояние "включено"
relay_on_timer_id = setTimeout(function() {
off_timer();
}, 10000); //для теста 10 сек во включенном положении, 2 часа это будет 26060*1000
log.info("Relay ON, Wait 10s");
}
function off_timer() {
// log.info("in function off_timer()");
dev["wb-gpio"]["EXT2_R3A1"] = false; //Здесть указать имя своего модуля, установи модуля wb-gpio в состояние "выключено"
dev["wb-gpio"]["EXT2_R3A2"] = false; //Здесть указать имя своего модуля, установи модуля wb-gpio в состояние "выключено"
relay_off_timer_id = setTimeout(function() {
on_timer();
}, 30000); //для теста 30 сек в выключенном положении, 2 часа это будет 2*60*60*1000
log.info("Relay OFF, Wait 30s");
}
function Stop_Timer(){
log.info("Timer stop");
if (relay_on_timer_id) {relay_on_timer_id = clearTimeout(relay_on_timer_id);};
if (relay_off_timer_id) {relay_off_timer_id = clearTimeout(relay_off_timer_id); };
dev["wb-gpio"]["EXT2_R3A1"] = false; //установи R3A1 модуля wb-gpio в состояние "выключено"
dev["wb-gpio"]["EXT2_R3A2"] = false; //установи R3A2 модуля wb-gpio в состояние "выключено"
}
defineRule("timer_button",{
whenChanged: "control_heating/enabled",
then: function(){
if (dev.control_heating.enabled){
if ( !(relay_on_timer_id||relay_off_timer_id) ){
on_timer();
}
}
else{
Stop_Timer();
}
}
});
defineRule("rules control heating", { //название правила - “контроль обогрева скважины”
whenChanged: "wb-w1/28-00000b0ff412", //при изменении состояния датчика wb-w1/28-00000b0ff412
then: function(newValue, devName, cellName) { //выполняй следующие действия
log.info("rules control heating then:");
if (dev.control_heating.enabled) { // если вируальн. устр-во в положении enabled
log.info("newValue ={}",newValue);
if (newValue < temp_on) { //если температура датчика меньше xx градусов
if (!(relay_on_timer_id||relay_off_timer_id)){on_timer();}
log.info("Stop timer and off relay, temp > {}",temp_on);
}
else { // иначе
if (newValue > temp_off) { //Если температура датчика больше xx градусов
Stop_Timer();
log.info("Stop timer and off relay, temp > {}",temp_off);
}
}
}
else { // если вируальн. устр-во Upravl obogrev skvazina в положении disable, выключаем рыле и завершаем таймеры
Stop_Timer();
log.info("Stop timer and off relay, button 'Well heating' disable");
}
}
});
Да, давайте уточню: действительно нужно запускать нагрев по таймеру, 2 часа работаем, 4 отдыхаем. Чтобы в принципе можно было управлять работой скрипта- нужен переключатель вкл-выкл. И, в идеале, пытался сделать так, чтобы подогрев работал только при минусовых температурах. Те условия запуска таймера - переключатель в положении вкл и температура меньше, например, -2
Я примерно это и понял, у меня последний вариант работает без ошибок.
Т.е. кнопкой контролируем активность правила, а по изменениям данный с датчика контролируем выход за рамки по температуре. Вы его проверяли?
не успел еще, обязательно проверю, отпишусь
Отрабатывает все четко, спасибо огромное!!
а вот тут
if (dev.control_heating.enabled) { // если вируальн. устр-во в положении enabled
log.info(“newValue ={}”,newValue);
if (newValue < temp_on) { //если температура датчика меньше xx градусов
if (!(relay_on_timer_id||relay_off_timer_id)){on_timer();}
log.info(“Stop timer and off relay, temp > {}”,temp_on);
в лог не Start timer and on relay, temp < {}",temp_on ?
Да, тут нужно выводить в лог информацию о запуске реле, если текущая температура меньше минимальной уставки.
Привет, мне в одной ветке сказали что лучше следить не за событием нажатия, а за событием изменения счетчика нажатий. В результате, чуть модифицировал пример под работу сразу с двумя кейсами. Можете посмотреть и дать комментарии, так как я не очень силен в JS.
(function () {
'use strict';
var ActionButtons = {};
/**
* Version: 0.3.1
*
* Function that identifies what kind of press was performed: single, double or long press;
* and assigns an action for each type of press.
*
* @param {string} trigger - Name of device and control in the following format: " <device>/<control>".
* @param {object} action - Defines actions to be taken for each type of button press.
* Key: "singlePress" or "doublePress" or "triplePress" or "longPress" or "longRelease".
* Value: Object of the following structure {func: <function name>, prop: <array of parameters to be passed>}
* Example:
* {
* singlePress: {func: myFunc1, prop: ["wb-mr6c_1", "K1"]},
* doublePress: {func: myFunc2, prop: ["wb-mrgbw-d_2", "RGB", "255;177;85"]},
* triplePress: {func: myFunc3, prop: []},
* longPress: {func: myFunc4, prop: []},
* longRelease: {func: myFunc5, prop: []}
* }
* @param {number} timeToNextPress - Time (ms) after button up to wait for the next press before reseting the counter. Default is 300 ms.
* @param {number} timeOfLongPress - Time (ms) after button down to be considered as as a long press. Default is 1000 ms (1 sec).
* @param {number} intervalOfRepeat - Time (ms) before repeating action specified in LongPress action. Default is 50 ms.
*
* Note: In case longRelease function defined, longPress function will repeate till button is released.
* In case longRelease function not defined, only one action will be executed for longPress.
*/
ActionButtons.onButtonPress = function (trigger, action, timeToNextPress, timeOfLongPress, intervalOfRepeat) {
// Set default values if not passed into function
timeToNextPress = timeToNextPress || 300;
timeOfLongPress = timeOfLongPress || 1000;
intervalOfRepeat = intervalOfRepeat || 100;
var buttonPressedCounter = 0;
var actionRepeatCounter = 0;
var timerWaitNextShortPress = null;
var timerLongPress = null;
var timerWaitLongRelease = null;
var isLongPressed = false;
var isLongReleased = false;
var ruleName = "on_button_press_" + trigger.replace("/", "_").replace(/ /g, "_"); //Добавил условие для удаления пробелов
log("LOG::Define WB Rule: ", ruleName);
defineRule(ruleName, {
whenChanged: trigger,
then: function (newValue, devName, cellName) {
// Вставка для работы со счетчиками нажатий
var isButtonPressed = newValue;
if (typeof newValue === "number"){
isButtonPressed = newValue % 2 !== 0;
}
// If button is pressed, wait for a long press
if (isButtonPressed) {
if (timerWaitNextShortPress) {
clearTimeout(timerWaitNextShortPress);
}
timerLongPress = setTimeout(function () {
isLongPressed = true; // Long press identified, we will skip short press
isLongReleased = false;
buttonPressedCounter = 0;
actionRepeatCounter = 1;
if (typeof action.longPress === "object") {
if (typeof action.longPress.func === "function") {
action.longPress.func.apply(this, action.longPress.prop);
// If Long Release action define, we will repeat Long Press action till not released. Otherwise only 1 Long Press action is executed
if (typeof action.longRelease === "object") {
if (typeof action.longRelease.func === "function") {
timerWaitLongRelease = setInterval(function () {
if(!isLongReleased) {
if (typeof action.longPress === "object") {
if (typeof action.longPress.func === "function") {
action.longPress.func.apply(this, action.longPress.prop);
}
}
// log(">>>>>> long press - press (" + actionRepeatCounter++ + ") <<<<<<");
}
if(isLongReleased) {
clearInterval(timerWaitLongRelease);
}
}, intervalOfRepeat);
}
}
}
}
// log(">>>>>> long press - press (" + actionRepeatCounter++ + ") <<<<<<");
}, timeOfLongPress);
}
// If button is released, then it is not a "long press", start to count clicks
else {
if (!isLongPressed) {
if (timerLongPress) {
clearTimeout(timerLongPress);
}
buttonPressedCounter += 1;
timerWaitNextShortPress = setTimeout(function () {
switch (buttonPressedCounter) {
// Counter equals 1 - it's a single short press
case 1:
if (typeof action.singlePress === "object") {
if (typeof action.singlePress.func === "function") {
action.singlePress.func.apply(this, action.singlePress.prop);
}
}
// log(">>>>>> short press - single <<<<<<");
break;
// Counter equals 2 - it's a double short press
case 2:
if (typeof action.doublePress === "object") {
if (typeof action.doublePress.func === "function") {
action.doublePress.func.apply(this, action.doublePress.prop);
}
}
// log(">>>>>> short press - double <<<<<<");
break;
// Counter equals 3 - it's a triple short press
case 3:
if (typeof action.triplePress === "object") {
if (typeof action.triplePress.func === "function") {
action.triplePress.func.apply(this, action.triplePress.prop);
}
}
// log(">>>>>> short press - triple <<<<<<");
break;
}
// Reset the counter
buttonPressedCounter = 0;
}, timeToNextPress);
}
// Catch button released after long press
else {
if (typeof action.longRelease === "object") {
if (typeof action.longRelease.func === "function") {
// if (typeof action.longRelease.prop === "array") {
action.longRelease.func.apply(this, action.longRelease.prop);
// } else {
// action.longRelease.func.apply(this, []);
// }
}
}
// log(">>>>>> long press - release <<<<<<");
isLongPressed = false;
isLongReleased = true;
}
}
}
});
};
// export as Node module / AMD module / browser variable
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = ActionButtons;
} else if (typeof define === 'function' && define.amd) {
define(ActionButtons);
} else {
global.ActionButtons = ActionButtons;
}
}());
const flatIOs = [
{ name: 'DI0', io: ['Counter 1', 'Counter 2', 'Counter 3', 'Counter 4', 'Counter 5', 'Counter 6', 'Counter 7', 'Counter 8', 'Counter 9', 'Counter 10', 'Counter 11', 'Counter 12', 'Counter 13', 'Counter 14'] },
{ name: 'R1', io: ['K1', 'K2', 'K3', 'K4', 'K5', 'K6'] },
{ name: 'R2', io: ['K1', 'K2', 'K3', 'K4', 'K5', 'K6'] }
];
ActionButtons.onButtonPress(
flatIOs[0].name +"/"+ flatIOs[0].io[0], //Вход, за которым следим.
{
singlePress: {
func: switchRelay,
prop: [flatIOs[1].name, flatIOs[1].io[0]]
},
doublePress: {
func: switchRelay, prop: [flatIOs[1].name, flatIOs[1].io[1]]
//func: switchDimmerRGB,
//prop: ["wb-mr6c_10", "K2", "wb-mrgbw-d_24"]
},
longPress: {
func: switchRelay, prop: [flatIOs[1].name, flatIOs[1].io[2]]
//func: setRandomRGB,
//prop: ["wb-mr6c_10", "K2", "wb-mrgbw-d_24"]
}
},
300, 1000
);
/**
* Helper Functions
*/
function switchRelay(device, control) { //Принимает в параметрах устройство и выход. Переключает состояние выхода на противоположное.
log.info("LongPress switchRelay", device, control)//Это лог. Он попадает в /var/log/messages
dev[device][control] = !dev[device + "/" + control];
}
function switchDimmerRGB(relayDevice, relayControl, dimmerDevice) {
dev[relayDevice][relayControl] = true;
if (dev[dimmerDevice + "/RGB"] !== "0;0;0") {
dev[dimmerDevice]["RGB"] = "0;0;0";
}
else {
dev[dimmerDevice]["RGB"] = dev[relayDevice + "/RGB"];
}
}
function setRandomRGB(relayDevice, relayControl, dimmerDevice) {
dev[relayDevice][relayControl] = true;
dev[relayDevice + "/RGB"] = "" + Math.floor(Math.random() * 255) + ";" + Math.floor(Math.random() * 255) + ";" + Math.floor(Math.random() * 255);
dev[dimmerDevice]["RGB"] = dev[relayDevice + "/RGB"];
}
Добрый день!
Использовал ваш кусок кода для обработки 1-, 2-, Долгого- нажатий, все работает, но есть одна проблема, после запуска контроллера, автоматически включаются все выходы, где был использован этот код. Получается после подачи питания на щиток и загрузки контроллера, включается свет на тех реле где используется этот кусок кода (Version: 0.3.1), модули WB-MRPS6/S и WB-MDM3.
В лог выводится сообщение: LOG::Define WB Rule: on_button_press_wb-gpio_EXT5_IN10
Если закомментировать этот кусок кода: singlePress: { func: Switcher, prop: [“rele3”, “K5”] }, то после запуска контроллера свет автоматически не включается.
Значение регистра 6: 0: не восстанавливать состояние реле.
Код функции Switcher:
function Switcher(pDevace, pChanel){
dev[pDevace][pChanel] = !dev[pDevace][pChanel];
}
В чем проблема? Правила, свойствах, версии, настройки модуля?
Тут, думаю, дело в том что при апуске первым в mqtt топик приходит “null”, вызывая срабатывание. Можно либо сделать костыль, принудительно выключая все каналы реле либо исключить в скрипте обработку “null”.
Здравствуйте! Набросал код управления рулонными шторами.
defineRule(“roller cabinet down”, {
when: function(newValue, devName, cellName) {
return dev[“wb-gpio”][“EXT5_IN4”] = true;
},
then: function (newValue, devName, cellName) {
dev[“wb-gpio”][“EXT3_ON2”] = true;
dev[“wb-gpio”][“EXT3_DIR2”] = false;
}
});
Необходимо снимать напряжение с привода через Nнное время, добавил таймаут, но не работает. Снимает напряжение сразу, то есть привод не опускается.
defineRule(“roller cabinet down”, {
when: function(newValue, devName, cellName) {
return dev[“wb-gpio”][“EXT5_IN4”] = true;
},
then: function (newValue, devName, cellName) {
dev[“wb-gpio”][“EXT3_ON2”] = true;
dev[“wb-gpio”][“EXT3_DIR2”] = false;
setTimeout(function () {}, 30000);
dev[“wb-gpio”][“EXT3_ON2”] = false;
}
});
Подскажете, в чем может быть проблема?
И еще хотелось бы сделать так, чтобы при одном нажатии на кнопку штора опускалась до конца, а при повторном она останавливалась.
Не разобрался с виртуальными кнопками. Как сделать так, чтобы шторой можно было управлять через софт? Получается, мне сейчас нужно для опускания шторы вручную переключать два выключателя, а хотелось бы управлять так же, как и с реальной кнопки.
Заранее спасибо за помощь!
Здравствуйте!
Для создания кнопок в веб-интерфейсе нужно создать виртуальное устройство с помощью правил:
defineVirtualDevice("drapery_control", {
title: "Drapery Control",
cells: {
open: {
type: "switch",
value: false,
order: 1,
},
close: {
type: "switch",
value: false,
order: 2,
},
},
});
Результатом будет такое окно на странице Devices:
Сделал несколько исправлений, должно заработать:
defineRule("roller cabinet down", {
whenChanged: ["drapery_control/close", "wb-gpio/EXT5_IN4"], //правило срабатывает при активировании входа или включении кнопки в веб-интерфейсе
then: function (newValue, devName, cellName) {
if (newValue) {
dev["wb-gpio"]["EXT3_ON2"] = true;
dev["wb-gpio"]["EXT3_DIR2"] = false;
setTimeout(function () {
dev["wb-gpio"]["EXT3_ON2"] = false; //прописываем действия по истечению времени
dev["drapery_control"]["close"] = false;
}, 3000);
}
},
});
Спасибо за ответ! Буду пробовать!
Подскажите, как еще сделать так, чтобы при повторном нажатии на кнопку (хотя бы реальную) штора останавливалась в текущем положении? То есть нужно переключить “wb-gpio”][“EXT3_ON2”] в false
Доработал правило отображения ресурсов контроллера: отображается загрузка процессора, сведения об оперативной памяти, сведения о разделе rootfs и сведения об /mnt/data. В правиле используются фрагменты кода из тем на портале техподдержки, которыми поделились пользователи. Возможно, кому-нибудь будет полезным.
.
Правило во вложении.
controller_utilization.zip (1.0 KB)
Здравствуйте! Виртуальные кнопки создаются, но скрипт на них не реагирует…
defineVirtualDevice(“Roller blinds”, {
title: “Шторы”,
cells: {
Спальня_О: {
type: “switch”,
value: false,
order: 1,
},
Спальня_З: {
type: “switch”,
value: false,
order: 2,
},
},
})
;
defineRule(“roller sleeping room down”, {
whenChanged: [“Шторы/Спальня_З”, “wb-gpio/EXT5_IN8”],
then: function (newValue, devName, cellName) {
if (newValue) {
dev[“wb-gpio”][“EXT4_ON3”] = true;
dev[“wb-gpio”][“EXT4_DIR3”] = false;
setTimeout(function () {
dev["wb-gpio"]["EXT4_ON3"] = false;
dev["Шторы"]["Спальня_З"] = false;
}, 30000);
}
},
});
defineRule(“roller sleeping room up”, {
whenChanged: [“Шторы/Спальня_О”, “wb-gpio/EXT5_IN9”],
then: function (newValue, devName, cellName) {
if (newValue) {
dev[“wb-gpio”][“EXT4_ON3”] = true;
dev[“wb-gpio”][“EXT4_DIR3”] = true;
setTimeout(function () {
dev["wb-gpio"]["EXT4_ON3"] = false;
dev["Шторы"]["Спальня_О"] = false;
}, 30000);
}
},
});
Кнопки сейчас в отдельном правиле, помещал и в одно со скриптами - все равно ничего. Пробовал писать отдельное правило на виртуальные кнопки, тоже нет изменений
В условии нужно использовать имя виртуального устройcтва, а не его заголовок окна. Попробуйте так:
whenChanged: ["Roller blinds/Спальня_З", "wb-gpio/EXT5_IN8"],
Скрипт у меня такой:
defineRule(“roller sleeping room down”, {
whenChanged: [“Roller blinds/Спальня_З”, “wb-gpio/EXT5_IN8”],
then: function (newValue, devName, cellName) {
if (newValue) {
dev[“wb-gpio”][“EXT4_ON3”] = true;
dev[“wb-gpio”][“EXT4_DIR3”] = false;
setTimeout(function () {
dev[“wb-gpio”][“EXT4_ON3”] = false;
dev[“Roller blinds”][“Спальня_З”] = false;
}, 30000);
}
},
});
Получается нужно сделать так?
defineRule(“roller sleeping room down”, {
whenChanged: [“Roller blinds/Спальня_З”, “wb-gpio/EXT5_IN8”],
then: function (newValue, devName, cellName) {
if (newValue) {
dev[“wb-gpio”][“EXT4_ON3”] = false;
dev[“wb-gpio”][“EXT4_DIR3”] = false;
dev[“wb-gpio”][“EXT4_ON3”] = true;
setTimeout(function () {
dev[“wb-gpio”][“EXT4_ON3”] = false;
dev[“Roller blinds”][“Спальня_З”] = false;
}, 30000);
}
},
});
пт, 14 янв. 2022 г. в 08:40, Explorerol через Wiren Board Support <info@wirenboard.ru>:
Не совсем так. Если вы отключаете реле и сразу его снова включаете, то контакты реле ON3 не успеют до конца разомкнуться, как придет команда снова на включение. Для отключения реле обычно 10-50 миллисекунд. Поэтому лучше отключить реле ON3, затем сделать паузу для ожидания отключения реле, например 100 мс, затем уже переключить реле DIR3, опять сделать паузу, а затем снова включить ON3.
То есть было так:
dev[“wb-gpio”][“EXT4_ON3”] = false;
dev[“wb-gpio”][“EXT4_DIR3”] = false;
dev[“wb-gpio”][“EXT4_ON3”] = true;
А станет, например, так:
var delay_ms = 100
dev["wb-gpio"]["EXT4_ON3"] = false;
setTimeout(function () {
dev["wb-gpio"]["EXT4_DIR3"] = false;
}, delay_ms);
setTimeout(function () {
dev["wb-gpio"]["EXT4_ON3"] = true;
}, delay_ms * 2);
Подскажите еще: хочу сделать, чтобы при нажатии на кнопку один раз, штора доезжала до конца, при нажатии, второй раз - останавливалась. Идея такая: ввести переменную n, которая будет считать количество нажатий, то есть нажал один раз n=1, нажал второй раз n=2 и обнулилась после этого. При n=1 будет одна функция, при n=2 будет другая. Но как задать n? Если я задаю n после define rule, то выдает ошибку, если после whenchanged - тоже, если после then function, то норм, но тогда n всегда будет обнуляться при наступлении события нажатия на кнопку. У меня сейчас вот такой код:
defineRule(“roller cabinet room down”, {
whenChanged: [“Roller blinds/Кабинет_З”, “wb-gpio/EXT5_IN4”],
then: function (newValue, devName, cellName) {
if (newValue) {
dev[“Roller blinds”][“Кабинет_О”] = false;
dev[“wb-gpio”][“EXT3_ON2”] = false;
setTimeout(function () {
dev[“wb-gpio”][“EXT3_DIR2”] = false;
}, 100);
setTimeout(function () {
dev[“wb-gpio”][“EXT3_ON2”] = true;
}, 100);
setTimeout(function () {
if (“wb-gpio/EXT3_DIR2”==true) {
dev[“wb-gpio”][“EXT3_ON2”] = false;
dev[“Roller blinds”][“Кабинет_З”] = false; }
}, 30000);
}
},
});
пт, 14 янв. 2022 г. в 15:56, Explorerol через Wiren Board Support <info@wirenboard.ru>: