Астрономическое реле по прогнозу погоды

Добрый день! Столкнулся с проблемой, мое реле не сработало и почему-то не выключает проверку и выполнение правил. В лог спамится “вкл” не зависимо от положения switch. Для прогноза погоды использовал: Погода с OpenWeatherMap.
Прогноз погоды:

defineVirtualDevice("weather", { //Виртуальное устройство для записи данных и отправки их в  MQTT
  title: "weather",
  cells: {
    temperature: {
      type: "temperature",
      value: -12.0,
    },
    humidity: {
      type: "rel_humidity",
      value: 75,
    },
    wind: {
      type: "wind_speed",
      value: 3,
    },
    sunrise: {
      type: "time_sunrise",
      value: 0,
    },
    sunset: {
      type: "time_sunset",
      value: 0,
    }
  }
}); 



defineRule("weather_call", {	// регулярный запрос к серверу погоды
  when: cron("@every 10m"),
  then: function() {
   runShellCommand("wget -qO /usr/weather/data.json 'https://api.openweathermap.org/data/2.5/weather?lat=55.8377&lon=37.4946&appid=69******************&units=metric'");
    startTimer("wait_weather", 10 * 1000);  		// запустили таймер на задержку для получения данных погоды	
    log("Request sent");
  }
}); 

defineRule("parse_weather", {	// чтение полученных от сервера данных погоды
  when: function() { 
    return timers.wait_weather.firing;
  },
  then: function() {  
  	var weather_data = readConfig("/usr/weather/data.json");
    dev["weather"]["temperature"] = Number(weather_data.main.temp);
    dev["weather"]["humidity"] = Number(weather_data.main.humidity);
    dev["weather"]["wind"] = Number(weather_data.wind.speed);
    log("Time: {}".format(weather_data.dt));
    log("Temperature is: {}".format(weather_data.main.temp));
    log("Humidity is: {}".format(weather_data.main.humidity));
    log("Wind speed is: {}".format(weather_data.wind.speed));
    dev["weather"]["sunrise"] = String(weather_data.sys.sunrise);
    dev["weather"]["sunset"] = String(weather_data.sys.sunset);
  }
});
    log("Weather script updated!");

Забор текущего времени по Unix из WB:

defineVirtualDevice("actual_date", {
    title: "Actual Date" ,
    cells: {
      time: {
        title: "Time",
	    type: "string",
        value: ""
	    },
      date: {
        title: "Date",
	    type: "string",
	    value: ""
	    },
      timeunix: {
        title: "TimeUnix",
	    type: "string",
	    value: ""
	    }
    }
});

setInterval( function() { 
  //var now = new Date();
  //var h = ((now.getHours() < 10) ? "0" : "") + now.getHours();
  //var m = ((now.getMinutes() < 10) ? "0" : "") + now.getMinutes();
  //var s = ((now.getSeconds() < 10) ? "0" : "") + now.getSeconds();
  
  //dev["actual_date/time"] = h + ":" + m + ":" + s;
  dev["actual_date/date"] = Date().substr(8, 2) + "."+ Date().substr(5, 2) + "."+ Date().substr(0, 4);
  dev["actual_date/time"] = Date().substr(11, 5);
  var currentTimestamp = Math.round(new Date().getTime()/1000);
  dev["actual_date/timeunix"] = currentTimestamp.toString();

}, 1000);

Само астрономическое реле:

defineVirtualDevice('AstroRele', {
    title: 'AstroRele' ,
    cells: {
      Osv: {
        title: "Osv",
        type: "switch",
        value: ""
      },
      Prj: {
        title: "Prj",
        type: "switch",
        value: ""
      },
    }
});



defineRule({
  whenChanged: ["AstroRele/Osv", "AstroRele/Prj"],
  then: function() {
    if (dev["AstroRele/Osv"] == true){
    enableRule(kontrolvkl5); // разрешить выполнение правила
    log("Включено авто уличный свет")
    } else {
      disableRule(kontrolvkl5); // отключить проверку и выполнение правила
      log("Выключено авто уличный свет")
    }
    if (dev["AstroRele/Prj"] == true){
    enableRule(kontrolvkl6); // разрешить выполнение правила
    log("Включено авто прожектор")
    } else {
      disableRule(kontrolvkl6); // отключить проверку и выполнение правила
      log("Выключено авто прожектор")
    }
  }
});


var kontrolvkl5 = defineRule({
  asSoonAs: function() {
	var logic = (((dev["weather/sunrise"]==dev["actual_date/timeunix"]) || (dev["weather/sunset"]==dev["actual_date/timeunix"])) ? true : false);
    log("вкл");
    return  logic;
  },
  then: function () {
	if (dev["weather/sunrise"]==dev["actual_date/timeunix"]){
    dev["wb-mr6cu_74/K5"] = true;
} else if (dev["weather/sunset"]==dev["actual_date/timeunix"])
    dev["wb-mr6cu_74/K5"] = false;
  }
});

var kontrolvkl6 = defineRule({
  asSoonAs: function() {
	var logic = (((dev["weather/sunrise"]==dev["actual_date/timeunix"]) || (dev["weather/sunset"]==dev["actual_date/timeunix"])) ? true : false);
    return  logic;
  },
  then: function () {
	if (dev["weather/sunrise"]==dev["actual_date/timeunix"]){
    dev["wb-mr6cu_74/K6"] = true;
} else if (dev["weather/sunset"]==dev["actual_date/timeunix"])
    dev["wb-mr6cu_74/K6"] = false;
  }
});

Вот так выглядит лог при выключенных switch в астрореле:
image

Добрый день.

Внимательно прочитайте пожалуйста GitHub - wirenboard/wb-rules: Rule engine for Wiren Board

при изменении любого параметра, доступного в MQTT (/devices/+/controls/+). В данном случае в целях оптимизации правила просматриваются избирательно (см. ниже);

Какого поведения от функции заданной в asSoonAs ожидаете?

Должно включать/выключать освещение если текущее время == время заката/рассвета.

Я решил использовать asSoonAs чтобы команда отправлялась единоразово, чтобы можно было продолжить управлять светом вручную при необходимости и не отключать Астрономическое реле.

Так оно будет работать?

var kontrolvkl5 = defineRule({
  whenChanged: "actual_date/timeunix",
  then: function () {
    var i = 0;
    var b = 0;
    log(i , "   ", b);
	if (dev["weather/sunrise"]==dev["actual_date/timeunix"] && i == 0){
    dev["wb-mr6cu_74/K5"] = true;
      i = i+1;
      b = 0;
} else if (dev["weather/sunset"]==dev["actual_date/timeunix"] && b == 0)
    dev["wb-mr6cu_74/K5"] = false;
    b = b+1;
    i = 0;
  }
});

Это вопрос архитектурный, собственно.
Нет, ожидаете какого именно поведения от самой функции? Как описано в документации - она выполняется при любом обновлении контролов.

Как i так и b никогда не будут в условиях больше нуля. Они же локальные и явно определяются.
Я не понимаю смысла кода к сожалению.

А все я затупил что-то. Извините /\ /\

defineVirtualDevice('AstroRele', {
    title: 'AstroRele' ,
    cells: {
      Osv: {
        title: "Osv",
        type: "switch",
        value: ""
      },
      Prj: {
        title: "Prj",
        type: "switch",
        value: ""
      },
    }
});



defineRule({
  whenChanged: ["AstroRele/Osv", "AstroRele/Prj"],
  then: function() {
    if (dev["AstroRele/Osv"] == true){
    enableRule(kontrolvkl5); // разрешить выполнение правила
    log("Включено авто уличный свет")
    } else {
      disableRule(kontrolvkl5); // отключить проверку и выполнение правила
      log("Выключено авто уличный свет")
    }
    if (dev["AstroRele/Prj"] == true){
    enableRule(kontrolvkl6); // разрешить выполнение правила
    log("Включено авто прожектор")
    } else {
      disableRule(kontrolvkl6); // отключить проверку и выполнение правила
      log("Выключено авто прожектор")
    }
  }
});



var kontrolvkl5 = defineRule({
  whenChanged: "actual_date/timeunix",
  then: function () {
    log("Смотрим правило включения освещения")
	if (((dev["weather/sunrise"]-dev["actual_date/timeunix"]) <= 0) && ((dev["weather/sunrise"]-dev["actual_date/timeunix"]) >= -2)){
      log("Свет включился")
    dev["wb-mr6cu_74/K5"] = true;
} else if (((dev["weather/sunset"]-dev["actual_date/timeunix"]) <= 0) && ((dev["weather/sunset"]-dev["actual_date/timeunix"]) >= -2)){
      log("Свет выключился")
    dev["wb-mr6cu_74/K5"] = false;
    }
  }
});

var kontrolvkl6 = defineRule({
  whenChanged: "actual_date/timeunix",
  then: function () {
    log("Смотрим правило включения прожектора")
	if (dev["weather/sunrise"]==dev["actual_date/timeunix"]){
      log("Прожектор включился")
    dev["wb-mr6cu_74/K6"] = true;
} else if (dev["weather/sunset"]==dev["actual_date/timeunix"]){
      log("Прожектор выключился")
    dev["wb-mr6cu_74/K6"] = false;
    }
  }
});

Вот, не знаю будет ли понятна цель этого кода. Разные условия для проверки сработки нужен период или нет.

Сейчас у вас всё работает как и ожидается?

Вечером узнаем). Сниму видео для вас :wink:

Вот так все работает как надо:

defineVirtualDevice('AstroRele', {
    title: 'AstroRele' ,
    cells: {
      Osv: {
        title: "Osv",
        type: "switch",
        value: ""
      },
      Prj: {
        title: "Prj",
        type: "switch",
        value: ""
      },
    }
});



defineRule({
  whenChanged: ["AstroRele/Osv", "AstroRele/Prj"],
  then: function() {
    if (dev["AstroRele/Osv"] == true){
    enableRule(kontrolvkl5); // разрешить выполнение правила
    } else {
      disableRule(kontrolvkl5); // отключить проверку и выполнение правила
    }
    if (dev["AstroRele/Prj"] == true){
    enableRule(kontrolvkl6); // разрешить выполнение правила
    } else {
      disableRule(kontrolvkl6); // отключить проверку и выполнение правила
    }
  }
});



var kontrolvkl5 = defineRule({
  whenChanged: "actual_date/timeunix",
  then: function () {
	if (dev["weather/sunset"]==dev["actual_date/timeunix"]){
      log("Свет включился")
    dev["wb-mr6cu_74/K5"] = true;
} else if (dev["weather/sunrise"]==dev["actual_date/timeunix"]){
      log("Свет выключился")
    dev["wb-mr6cu_74/K5"] = false;
    }
  }
});

var kontrolvkl6 = defineRule({
  whenChanged: "actual_date/timeunix",
  then: function () {
	if (dev["weather/sunset"]==dev["actual_date/timeunix"]){
      log("Прожектор включился")
    dev["wb-mr6cu_74/K6"] = true;
} else if (dev["weather/sunrise"]==dev["actual_date/timeunix"]){
      log("Прожектор выключился")
    dev["wb-mr6cu_74/K6"] = false;
    }
  }
});
2 лайка