Некорректное поведение правил

Здравствуйте! Столкнулся со странным поведением правил. По задумке правило должно плавно увеличивать освещённость за заданное время и также плавно уменьшать до выключения. На одном контроллере всё работает корректно, а на другом, примерно раз в неделю, всё начинает “падать”. Зависает и через какое-то время отходит. Перезагрузка помогает опять же, на неделю. Не могу понять, в чём проблема: в программе или в самом контроллере. Скрины и файлы прилагаю


Screenshot_2
Screenshot_4
Screenshot_3
log_20240429T084630.log (407,0 КБ)
Правило для света.txt (19,8 КБ)

P.S. Сейчас 9:27 и это всё отлипло и я смог сделать ребут
Может ему памяти не хватает или что-то забито?

На всякий случай правило полива:
Правило полива.txt (7,4 КБ)

Сегодня утром опять с ошибками, но чисто физически всё прошло нормально
Screenshot_1

Ошибка где-то тут, но я пока не могу понять, в чём именно. Возможно где-то в логике

На данный момент остановился вот на таком:


Старую ошибку не выдаёт. Буду следить

Добрый день.
Судя по логам - нет устройства в которое публикуется значение.
Целесообразно в лог глянуть - с какого момента начинаются ошибки.
Ну и - включен ли для брокера persistence?

Внёс изменения в правило. Пока без ошибок. Брокер посмотреть могу на выходных. Его надо включить или выключить?

Выключить, база persistence (retained значений) в общем не нужна.

1 лайк

Только что сделал. Будем следить за результатом.

1 лайк

Здравствуйте. В журнале очень много одинаковых сообщений.
Screenshot_3


log_20240508T084128.log (193,8 КБ)

Предполагаю, что вопрос где-то в правиле. А именно в таймере

defineRule("cron minute timer", { //Просто задание, которое выполняется каждую минуту и взводит/опускает флаги "Рассвет", "Закат"
  when: cron("00 * * * * *"),
  then: function () {
    //log.info(grow_box, "cron timer executed! DEBUG ONLY.");
    d = new Date(); //Текущее время
    //sunraiseStartTime 
    if ((dev["light_"+grow_box]["sunraiseProcess"]==false) && (d > sunraiseStartTime) && (d<sunraiseStopTime)){
      log.info(grow_box, "cron timer executed! Sunraise process START", "sunraiseStartTime",sunraiseStartTime ,"sunraiseStopTime",sunraiseStopTime);
      dev["light_"+grow_box]["sunraiseProcess"] = true;
    }
    //sunsetStartTime
    if ((dev["light_"+grow_box]["sunsetProcess"]==false) && (d > sunsetStartTime) && (d<sunsetStopTime)){
      log.info(grow_box, "cron timer executed! SunSET process START", "sunsetStartTime",sunsetStartTime ,"sunsetStopTime",sunsetStopTime);
      dev["light_"+grow_box]["sunsetProcess"] = true;
    }
    //dayProcess
    if ((dev["light_"+grow_box]["dayProcess"]==false) && (d > sunraiseStopTime) && (d<sunsetStartTime)){
      log.info(grow_box, "cron timer executed! DAY process START","sunraiseStopTime",sunraiseStopTime,"sunsetStartTime",sunsetStartTime);
      dev["light_"+grow_box]["dayProcess"] = true;
    }
  }
});

defineRule("cron day timer", { //Просто задание, которое выполняется раз в сутки и меняет дату в переменных на текущую.
  when: cron("01 00 00 * * *"),
  then: function () {
    setTimeVariable();
  }
});

function string_to_time(srcString) { 
  //log.info("string_to_time_"+grow_box, srcString)
  var d = new Date();
  var datetime = new Date(d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate()+'T' + srcString + 'Z');
  datetime.setMinutes(datetime.getMinutes() + datetime.getTimezoneOffset());//Приведем к локальному:
  return datetime; 
};


function setTimeVariable() { 
  sunraiseStartTime = string_to_time(ps["sun_start_time"]); //Время начала "рассвета"
  sunraiseStopTime = new Date(sunraiseStartTime);
  sunraiseStopTime.setMinutes(sunraiseStopTime.getMinutes() + parseInt(ps["sun_start_duration"])); //окончание "рассвета"
  sunsetStartTime = string_to_time(ps["sun_stop_time"]);//Время начала "заката"
  sunsetStopTime = new Date(sunsetStartTime);
  sunsetStopTime.setMinutes(sunsetStopTime.getMinutes() + parseInt(ps["sun_stop_duration"])); //окончание "заката"
};


defineRule("SunRaise_starter", { //название правила 
whenChanged: "light_"+grow_box+"/sunraiseProcess", //При изменении переуключателя "рассвет"
  then: function (newValue, devName, cellName) { //выполняй следующие действия
    log.info("light_"+grow_box+" sunraiseProcess function", newValue, devName, cellName); //Это лог.
    if (newValue){ //Запускаем "рассвет"
      dura = (sunraiseStopTime - sunraiseStartTime)/1000; //время в секундах
      setPointLight = Number(ps["light_setpoint"]); // уставка освещенности
      light_increment = setPointLight/dura; //увеличение освещенности в секунду расчетное
      setPointLight = 1;
	  log.info("light_"+grow_box+" sunraiseProcess", "dura", dura, "dimmer_increment", dimmer_increment); //Это лог.
      startTicker(grow_box+"raiseTicker", 1000); //Запуск таймера, отрабатывает раз в секунду.
    } else { //Останавливаем "рассвет"
      timers[grow_box+"raiseTicker"].stop(); 
      log.info("light_"+grow_box+"Ticker STOP sunraise");
    }
  }
});

defineRule("SunSet_starter", { //название правила 
whenChanged: "light_"+grow_box+"/sunsetProcess", //При изменении переуключателя "Закат"
  then: function (newValue, devName, cellName) { //выполняй следующие действия
    log.info("light_"+grow_box+" sunsetProcess function", newValue, devName, cellName); //Это лог.
    if (newValue){ //Запускаем "закат"
      dev["light_"+grow_box]["dayProcess"] = false;
      setPointLight = Number(ps["light_setpoint"]); // уставка освещенности
      dura = (sunsetStopTime - sunsetStartTime)/1000; //время в секундах
      light_increment = -(setPointLight)/dura; //уменьшение освещения в секунду расчетное. От уставки!
      //dev["light_"+grow_box+"/dayProcess"] = false; //Выключаем "день"
	  log.info("light_"+grow_box+" sunsetProcess", "dura", dura, "light_increment", light_increment, "setPointLight", setPointLight); //Это лог.
      startTicker(grow_box+"raiseTicker", 1000); //Запуск таймера, отрабатывает раз в секунду.
    } else { //Останавливаем "закат"
      timers[grow_box+"raiseTicker"].stop(); 
      log.info("light_"+grow_box+"Ticker STOP sunset");
      setPointLight = 0;
      dev[dimmer_light] = dimmer_zeroValue;
    }
  }
});


defineRule("handmadeSunTicker", { // Таймер плавного рассвета/заката
  when: function () { return timers[grow_box+"raiseTicker"].firing; },
  then: function () {
    setPointLight += light_increment;
    if (setPointLight>=Number(ps["light_setpoint"])){
      log.info("light_"+grow_box+"raiseTicker STOP ON setPointLight");
      dev["light_"+grow_box+"/sunraiseProcess"] = false; //Выключаем "рассвет" Таймер остановит правило "SunRaise_starter"
    }
    if (setPointLight<=0){
      log.info("light_"+grow_box+"setTicker STOP ON setPointLight");
      dev["light_"+grow_box+"/sunsetProcess"] = false; //Выключаем "закат" Таймер остановит правило "SunSet_starter"
    }

  }
});

Сценарий света Я.Коласа.txt (19,2 КБ)

Можете посмотреть? а то что-то я не могу понять, в чём проблема…

Я, к сожалению не вижу одинаковых сообщений.
Можете уточнить - какие именно кажутся лишними?


И такое повторение по всем правилам много раз за один период (рассвет или закат) во время выключения таймера (плавного увеличения или уменьшения мощности). Это можно отследить в файле, который я прислал выше

Да, будет вызываться каждую минуту. Если считаете вызов при выключенном контроле лишним - добавьте проверку условия, добавив, например ```setPointLight<=0 && dev[“light_”+grow_box+“/sunsetProcess”]

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

Да, вполне может вызваться два раза. Второй раз - после срабатывания уже запущенного на момент первого срабатывания таймера. Так как контрол уже выключен - второй раз он не выключится.

Правило срабатывает корректно. Просто может ли такой частый вызов функций в большом количестве правил приводить к торможению контроллера?
То есть может ли из-за этого раз в неделю “ложиться” контроллер?

Я добавил. Завтра посмотрим на результат.

Здравствуйте. Всё хорошо. Ошибок нет, многократного повторения тоже нет. Спасибо большое за помощь!

Ну отлично, рад.

1 лайк