Помощь с логикой включения света по датчику движения WB-MSW v3

Доброго времени суток! Прошу помочь кодом или ошибкой в логике для следующей задачи.
Имеется пару десятков универсальных датчиков wb-msw v3, сейчас мучаюсь с простой задачей - включать свет по движению, при ряде условий:

  • включить свет, если есть движение и недостаточно освещения
  • не выключать свет, если он включён датчиком движения и значение освещения превысило минимальное до тех пор, пока не пропадёт движение
  • не выключать освещение включённое датчиком, если он был зафиксирован выключателем

Сейчас проблема в том, что таймер не сбрасывается по какой-то причине и свет выключается и включается каждое значение таймера.
Вот код:

function msw3_Motion (devmsw3_Motion, devrele, toogle, MinIlluminance){
	log.debug("rule create", devmsw3_Motion);
	var motion_timer = 0;
	var motion_ind = 0; //индикатор, что свет включён от датчика
	var MaxMotion = 90;
	var timeout_in_msec = 10000;// Пауза перед выключением

	defineRule ("msw3_Motion "+devmsw3_Motion, {
		whenChanged: devmsw3_Motion+"/Max Motion",
		then: function(newValue, devName, cellName) {
          log (devmsw3_Motion," max motion:", newValue, " Illuminance:", dev[devmsw3_Motion+"/Illuminance"], "toogle: ", dev[toogle], "motion_ind: ", motion_ind);
          if ( (newValue > MaxMotion) && ((dev[devmsw3_Motion+"/Illuminance"] < MinIlluminance) || (motion_ind == 1)) ){
        	devrele.forEach(function(x) {
              dev[x] = true ;
              log ("реле включено", dev[x]);
            });
            motion_ind = 1;
			if (motion_timer) {
        	//Уничтожаем прошлый таймер
        	clearTimeout(motion_timer);
          }
      
			motion_timer = setTimeout(function () {
                log ("NewValue:", newValue, " MaxMotion:", MaxMotion);
              	if (dev[toogle] == true) return false;
				devrele.forEach(function(x) {
						dev[x] = false ;
				});
				motion_timer = null;
              	motion_ind = 0;
			}, timeout_in_msec);
		  log ("Новый таймер: ", motion_timer);
		  }

    }});
}
msw3_Motion ("wb-msw-v3_127", ["wb-mr6c_65/K1"], "wb-gpio_EXT1_IN1/doublePress", 50); //тамбур

буду признателен за любой совет или помощь

тут ошибка - motion_timer у вас не булево значение

2 лайка

К сожалению не помогло :frowning: Поставил метки в лог, таймер удаляется, новый создаётся но почему-то свет выключается по первому таймеру. С 2023-04-07 11:25:02 видно, что реле выключается
Вот правки:
var motion_timer = null;

            motion_ind = 1;
            log ("motion_timer = ", motion_timer);
			if (motion_timer) {
        	//Уничтожаем прошлый таймер
        	clearTimeout(motion_timer);
            log (motion_timer, " удалён!");
            }

Вот лог:

|2023-04-07 11:24:48||реле включено false|
|---|---|---|
|2023-04-07 11:24:48||motion_timer = null|
|2023-04-07 11:24:48||Новый таймер: 3573|
|2023-04-07 11:24:48||wb-msw-v3_127 max motion: 858 Illuminance: 169.28 toogle: false motion_ind: 1|
|2023-04-07 11:24:48||реле включено true|
|2023-04-07 11:24:48||motion_timer = 3573|
|2023-04-07 11:24:48||3573 удалён!|
|2023-04-07 11:24:48||Новый таймер: 3574|
|2023-04-07 11:24:49||wb-msw-v3_127 max motion: 957 Illuminance: 169.28 toogle: false motion_ind: 1|
|2023-04-07 11:24:49||реле включено true|
|2023-04-07 11:24:49||motion_timer = 3574|
|2023-04-07 11:24:49||3574 удалён!|
|2023-04-07 11:24:49||Новый таймер: 3575|
|2023-04-07 11:24:52||wb-msw-v3_127 max motion: 1341 Illuminance: 129.92 toogle: false motion_ind: 1|
|2023-04-07 11:24:52||реле включено true|
|2023-04-07 11:24:52||motion_timer = 3575|
|2023-04-07 11:24:52||3575 удалён!|
|2023-04-07 11:24:52||Новый таймер: 3576|
|2023-04-07 11:25:02||NewValue: 1341 MaxMotion: 90|
**|2023-04-07 11:25:02||реле выключено true|**
**|2023-04-07 11:25:09||wb-msw-v3_127 max motion: 1206 Illuminance: 170.56 toogle: false motion_ind: 1|**
**|2023-04-07 11:25:09||реле включено false|**
**|2023-04-07 11:25:09||motion_timer = null|**
**|2023-04-07 11:25:09||Новый таймер: 3577|**
|2023-04-07 11:25:10||wb-msw-v3_127 max motion: 982 Illuminance: 170.56 toogle: false motion_ind: 1|
|2023-04-07 11:25:10||реле включено true|
|2023-04-07 11:25:10||motion_timer = 3577|
|2023-04-07 11:25:10||3577 удалён!|
|2023-04-07 11:25:10||Новый таймер: 3578|
|2023-04-07 11:25:10||wb-msw-v3_127 max motion: 795 Illuminance: 170.56 toogle: false motion_ind: 1|
|2023-04-07 11:25:10||реле включено true|
|2023-04-07 11:25:10||motion_timer = 3578|
|2023-04-07 11:25:10||3578 удалён!|
|2023-04-07 11:25:10||Новый таймер: 3579|
|2023-04-07 11:25:11||wb-msw-v3_127 max motion: 626 Illuminance: 233.6 toogle: false motion_ind: 1|
|2023-04-07 11:25:11||реле включено true|
|2023-04-07 11:25:11||motion_timer = 3579|
|2023-04-07 11:25:11||3579 удалён!|
|2023-04-07 11:25:11||Новый таймер: 3580|
|2023-04-07 11:25:12||wb-msw-v3_127 max motion: 490 Illuminance: 233.6 toogle: false motion_ind: 1|
|2023-04-07 11:25:12||реле включено true|
|2023-04-07 11:25:12||motion_timer = 3580|
|2023-04-07 11:25:12||3580 удалён!|
|2023-04-07 11:25:12||Новый таймер: 3581|
|2023-04-07 11:25:13||wb-msw-v3_127 max motion: 384 Illuminance: 233.6 toogle: false motion_ind: 1|
|2023-04-07 11:25:13||реле включено true|
|2023-04-07 11:25:13||motion_timer = 3581|
|2023-04-07 11:25:13||3581 удалён!|
|2023-04-07 11:25:13||Новый таймер: 3582|
|2023-04-07 11:25:14||wb-msw-v3_127 max motion: 302 Illuminance: 233.6 toogle: false motion_ind: 1|
|2023-04-07 11:25:14||реле включено true|
|2023-04-07 11:25:14||motion_timer = 3582|
|2023-04-07 11:25:14||3582 удалён!|
|2023-04-07 11:25:14||Новый таймер: 3583|
|2023-04-07 11:25:14||wb-msw-v3_127 max motion: 238 Illuminance: 233.6 toogle: false motion_ind: 1|
|2023-04-07 11:25:14||реле включено true|
|2023-04-07 11:25:14||motion_timer = 3583|
|2023-04-07 11:25:14||3583 удалён!|
|2023-04-07 11:25:14||Новый таймер: 3584|
|2023-04-07 11:25:15||wb-msw-v3_127 max motion: 188 Illuminance: 233.6 toogle: false motion_ind: 1|
|2023-04-07 11:25:15||реле включено true|
|2023-04-07 11:25:15||motion_timer = 3584|
|2023-04-07 11:25:15||3584 удалён!|
|2023-04-07 11:25:15||Новый таймер: 3585|
|2023-04-07 11:25:16||wb-msw-v3_127 max motion: 149 Illuminance: 233.6 toogle: false motion_ind: 1|
|2023-04-07 11:25:16||реле включено true|
|2023-04-07 11:25:16||motion_timer = 3585|
|2023-04-07 11:25:16||3585 удалён!|
|2023-04-07 11:25:16||Новый таймер: 3586|
|2023-04-07 11:25:17||wb-msw-v3_127 max motion: 118 Illuminance: 233.6 toogle: false motion_ind: 1|
|2023-04-07 11:25:17||реле включено true|
|2023-04-07 11:25:17||motion_timer = 3586|
|2023-04-07 11:25:17||3586 удалён!|
|2023-04-07 11:25:17||Новый таймер: 3587|
|2023-04-07 11:25:18||wb-msw-v3_127 max motion: 94 Illuminance: 233.6 toogle: false motion_ind: 1|
|2023-04-07 11:25:18||реле включено true|
|2023-04-07 11:25:18||motion_timer = 3587|
|2023-04-07 11:25:18||3587 удалён!|
|2023-04-07 11:25:18||Новый таймер: 3588|

Вы не изменили главное: motion_timer у вас принимает целочисленные значения, т.е. if (3575) = false. Сделайте так:

            motion_ind = 1;
            log ("motion_timer = ", motion_timer);
			if (motion_timer != null) {
        	//Уничтожаем прошлый таймер
        	clearTimeout(motion_timer);
			motion_timer = null;
            log (motion_timer, " удалён!");
            }
1 лайк

Всё также выключается после первого таймера :frowning: По какой-то причине перестали обновляться данные devmsw3_Motion+“/Max Motion” после запуска таймера до тех пор, пока таймер не закончится. :dotted_line_face:
По таймеру. По старой логике я понимал это так: motion_timer возвращает id таймера и он при каждом whenChanged и прохождении условий удаляется и создаётся новый (соответственно с новым таймаутом). Вы говорите, что таймер (функция setTimeout) должен возвращать bool, но почему тогда motion_timer (переменная присвоенная вызову функции setTimeout) возвращает id, а не bool (false || true) значение?
Как видно я не кодер ни разу, но думал уж с включением света справлюсь ))
В 13:25:13 активировало включение, в 13:25:23 сработал таймер и выключил реле.
Актуальный полный код:

function msw3_Motion (devmsw3_Motion, devrele, toogle, MinIlluminance){
	log.debug("rule create", devmsw3_Motion);
	var motion_timer = null;
	var motion_ind = 0;
	var MaxMotion = 90;
	var timeout_in_msec = 10000;// Пауза перед выключением

	defineRule ("msw3_Motion "+devmsw3_Motion, {
		whenChanged: devmsw3_Motion+"/Max Motion",
		then: function(newValue, devName, cellName) {
          log (devmsw3_Motion," max motion:", newValue, " Illuminance:", dev[devmsw3_Motion+"/Illuminance"], "toogle: ", dev[toogle], "motion_ind: ", motion_ind);
          if ( (newValue > MaxMotion) && ((dev[devmsw3_Motion+"/Illuminance"] < MinIlluminance) || (motion_ind == 1)) ){
        	devrele.forEach(function(x) {
              dev[x] = true ;
              log ("реле включено", dev[x]);
            });
            motion_ind = 1;
            log ("motion_timer = ", motion_timer);
			if (motion_timer != null) {
        	//Уничтожаем прошлый таймер
        	clearTimeout(motion_timer);
			motion_timer = null;
            log (motion_timer, " удалён!");
            }
      
			motion_timer = setTimeout(function () {
                log ("NewValue:", newValue, " MaxMotion:", MaxMotion);
              	if (dev[toogle] == true) {
                  motion_ind = 0;
                  return false;
                }
				devrele.forEach(function(x) {
						dev[x] = false ;
                  		log ("реле выключено ", dev[x]);
				});
              	motion_ind = 0;
				motion_timer = null;
 
			}, timeout_in_msec);
		  log ("Новый таймер: ", motion_timer);
		  }

    }});
}
msw3_Motion ("wb-msw-v3_127", ["wb-mr6c_65/K1"], "wb-gpio_EXT1_IN1/doublePress", 200); //тамбур

и лог:

|2023-04-07 13:25:13|реле включено false|
|---|---|
|2023-04-07 13:25:13|motion_timer = null|
|2023-04-07 13:25:13|Новый таймер: 3715|
|2023-04-07 13:25:23|NewValue: 910 MaxMotion: 90|
|2023-04-07 13:25:23|реле выключено true|
|2023-04-07 13:25:30|wb-msw-v3_127 max motion: 794 Illuminance: 132.48 toogle: false motion_ind: 0|
|2023-04-07 13:25:30|реле включено false|
|2023-04-07 13:25:30|motion_timer = null|
|2023-04-07 13:25:30|Новый таймер: 3716|
|2023-04-07 13:25:31|wb-msw-v3_127 max motion: 662 Illuminance: 132.48 toogle: false motion_ind: 1|
|2023-04-07 13:25:31|реле включено true|
|2023-04-07 13:25:31|motion_timer = 3716|
|2023-04-07 13:25:31|null удалён!|
|2023-04-07 13:25:31|Новый таймер: 3717|
|2023-04-07 13:25:31|wb-msw-v3_127 max motion: 612 Illuminance: 193.76 toogle: false motion_ind: 1|
|2023-04-07 13:25:31|реле включено true|
|2023-04-07 13:25:31|motion_timer = 3717|
|2023-04-07 13:25:31|null удалён!|
|2023-04-07 13:25:31|Новый таймер: 3718|
|2023-04-07 13:25:33|wb-msw-v3_127 max motion: 501 Illuminance: 193.76 toogle: false motion_ind: 1|
|2023-04-07 13:25:33|реле включено true|
|2023-04-07 13:25:33|motion_timer = 3718|
|2023-04-07 13:25:33|null удалён!|
|2023-04-07 13:25:33|Новый таймер: 3719|

Некорректно сравнивать значения разных типов Прочитайте, отсюда, например.

Нет, я говорю, что внутри if() должно быть булево значение, а у вас там целые числа.

это верно

это верно

Из любопытства ради, если не затруднит, объясните. Почему именно bool должно быть в этом условии (в моём понимании это, например, if (motion_timer == true (или false)) ? Ведь достаточно проверить, чтобы оно было не пустое (не null), чтобы удалить таймер. А это условие выполнялось и ранее и таймер судя по логу удалялся.
Но сейчас JS вообще сломался, не выдержав моего кода. whenChanged после запуска таймера не обновляется)

Выражение if (motion_timer) выполнит то, что внутри {}, если motion_timer == true (или если motion_timer == 1, здесь производится преобразование типов, чего лучше не делать). Если motion_timer == 2, то if получить false, и то, что внутри {} не выполнится. У вас так и происходило.
Выражение motion_timer > 0, кстати, тоже возвращает булево значение. Как и любые другие логические операторы.

1 лайк

whenChanged у вас работает, иначе в лог бы ничего не вывелось.

Да вот как раз лог и не выводит после запуска таймера, хоть как прыгай перед датчиком.

/MaxMotion - это максимальное значение за 10 сек (если вы это время не меняли). Чаще прыгать не имеет смысла. И прыгнуть надо сильнее, чем за предыдущие 10 сек. Вы уверены, что надо именно этот топик анализировать? А не CurrentMotion?
Посмотрите:
https://wirenboard.com/wiki/Wbincludes:WB-MSW_v.3_Motion_Sensor
P.s. Написал не совсем корректно, но из графиков все понятно.

2 лайка

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