From 8f470e37efdb0ab32b39c9c7074a5f724a3d1a5b Mon Sep 17 00:00:00 2001 From: Jannik Beyerstedt Date: Tue, 10 Oct 2017 11:03:49 +0200 Subject: [PATCH] [FIX] several bugs at the time calculations fixes by rewriting them --- config_times.json | 10 ++-- functions.php | 119 ++++++++++++++++++++++++++++++---------------- tests.php | 78 ++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 45 deletions(-) create mode 100644 tests.php diff --git a/config_times.json b/config_times.json index 6e6aec1..ba28507 100644 --- a/config_times.json +++ b/config_times.json @@ -5,15 +5,15 @@ }, "time1": { "on": "16:00", - "off": "23:00" + "off": "23:30" }, "time2": { - "on": "05:45", - "off": "06:15" + "on": "04:45", + "off": "05:15" }, "time3": { - "on": "06:45", - "off": "08:00" + "on": "06:30", + "off": "08:30" }, "instant-on": null } \ No newline at end of file diff --git a/functions.php b/functions.php index 9d18032..3d7ea97 100644 --- a/functions.php +++ b/functions.php @@ -33,20 +33,68 @@ class LightStatus { return 's='.(int)$this->state.' t='.$this->waitTime; } - /* re-calculate values */ - public function update() { + /* re-calculate values, returns true if successful */ + public function update($currentTime = null) { global $sun_zenith; global $timezone; - // calculate sunset and sunrise times + if (null == $currentTime) { + $currentTime = time(); + } + + $sunset = null; + $sunrise = null; + $times = []; + + // calculate times date_default_timezone_set($timezone); $gmtOffset = date("Z") / (60*60); - $this->sunrise = date_sunrise(time(), SUNFUNCS_RET_STRING, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); - $this->sunset = date_sunset(time(), SUNFUNCS_RET_STRING, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); + if (($currentTime - strtotime("12:00")) > 0) { + // currentTime is in the evening + $this->sunset = date_sunset(time(), SUNFUNCS_RET_STRING, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); + $this->sunrise = date_sunrise((time() + 24*60*60), SUNFUNCS_RET_STRING, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); - $sunrise = date_sunrise(time(), SUNFUNCS_RET_TIMESTAMP, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); - $sunset = date_sunset(time(), SUNFUNCS_RET_TIMESTAMP, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); + $sunset = date_sunset(time(), SUNFUNCS_RET_TIMESTAMP, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); + $sunrise = date_sunrise((time() + 24*60*60), SUNFUNCS_RET_TIMESTAMP, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); + + for ($i = 1; $i <= 3; $i++) { + $timeKey = 'time'.$i; + + $startTime = strtotime($this->times[$timeKey]['on']); + if ((strtotime("00:00")+24*60*60) - $startTime > 12*60*60) { + $startTime += 24*60*60; + } + $stopTime = strtotime($this->times[$timeKey]['off']); + if ((strtotime("00:00")+24*60*60) - $stopTime > 12*60*60) { + $stopTime += 24*60*60; + } + + $times[] = ["on"=>$startTime, "off"=>$stopTime]; + } + } else { + // currentTime is in the morning + $this->sunset = date_sunset((time() - 24*60*60), SUNFUNCS_RET_STRING, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); + $this->sunrise = date_sunrise(time(), SUNFUNCS_RET_STRING, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); + + $sunset = date_sunset((time() - 24*60*60), SUNFUNCS_RET_TIMESTAMP, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); + $sunrise = date_sunrise(time(), SUNFUNCS_RET_TIMESTAMP, $this->times['position']['lat'], $this->times['position']['long'], $sun_zenith, $gmtOffset); + + for ($i = 1; $i <= 3; $i++) { + $timeKey = 'time'.$i; + + $startTime = strtotime($this->times[$timeKey]['on']); + if ($startTime - strtotime("00:00") > 12*60*60) { + $startTime -= 24*60*60; + } + $stopTime = strtotime($this->times[$timeKey]['off']); + if ($stopTime - strtotime("00:00") > 12*60*60) { + $stopTime -= 24*60*60; + } + + $times[] = ["on"=>$startTime, "off"=>$stopTime]; + } + } // -- first check, if an instant-on time is set -- if ($this->times['instant-on'] != null) { @@ -65,55 +113,46 @@ class LightStatus { } } - // -- otherwise check, if the ruleset requires the lights on -- - // first check, if it's at daylight - $currentTime = time(); - if ($currentTime < $sunrise || $currentTime > $sunset) { + // -- if no instant-on time is set, follow normal conditions -- + if ($sunset < $currentTime && $sunrise > $currentTime) { $this->isNight = true; // it's night: check, if we are in one of the time intervals - for ($i = 1; $i <= 3; $i++) { - $timeKey = 'time'.$i; - - $startTime = strtotime($this->times[$timeKey]['on']); - $stopTime = strtotime($this->times[$timeKey]['off']); - if ($stopTime < $startTime) { - $stopTime += (24*60*60); - if (($stopTime - $currentTime) > (24*60*60)) { - $startTime -= (24*60*60); - $stopTime -= (24*60*60); - } - } - - if ($currentTime > $startTime && $currentTime < $stopTime) { + $this->changeTime = null; + foreach ($times as $t) { + if ($t["on"] < $currentTime && $t["off"] > $currentTime) { + // we are in this interval $this->state = true; - $this->changeTime = (int)(($stopTime - $currentTime) / 60); + $this->changeTime = (int)(($t["off"] - $currentTime) / 60); $this->waitTime = 1; return true; - } elseif ( ($startTime - $currentTime) < (12*60*60) || ($startTime+(24*60*60) - $currentTime) < (12*60*60) ) { - // right before the next time interval + } else if ($t["on"] > $currentTime) { + // we are right before this interval $this->state = false; - if ($currentTime < $startTime) { - $this->changeTime = (int)( ($startTime - $currentTime) / 60 ); - } else { - $this->changeTime = (int)( (($startTime+(24*60*60)) - $currentTime) / 60 ); - } + $this->changeTime = (int)(($t["on"] - $currentTime) / 60); $this->waitTime = 1; return true; } + // otherwise we are after this interval, but potentioally before next interval } - $this->state = false; - $this->changeTime = (int)(($stopTime - $currentTime) / 60); - $this->waitTime = 1; - return true; + if ($this->changeTime == null) { + // we are after the last interval, so changeTime is not set yet + $this->state = false; + $this->changeTime = (int)(($sunrise - $currentTime) / 60); + $this->waitTime = $this->changeTime; + return true; + } - } else if ($currentTime > $sunrise && $currentTime < $sunset) { + } else if ($currentTime > $sunrise || $sunset > $currentTime) { $this->isNight = false; - // it's day: nothing else check + // it's day: nothing else to check $this->state = false; $this->changeTime = (int)(($sunset - $currentTime) / 60); + if ($this->changeTime < 0) { + $this->changeTime += 24*60; // changeTime is in Minutes + } $this->waitTime = $this->changeTime; return true; @@ -123,7 +162,7 @@ class LightStatus { } } - /* save modified $times array to config file */ + /* save modified $times array to config file, returns true if successful */ public function saveTimes() { global $config_filename; diff --git a/tests.php b/tests.php new file mode 100644 index 0000000..5ded08f --- /dev/null +++ b/tests.php @@ -0,0 +1,78 @@ +update(); + +$testTimes = ["09:00", + "11:00", + "15:00", + "20:00", + "23:55", + "00:05 +1day", + "05:00 +1day", + "06:00 +1day", + "07:00 +1day", + "09:00 +1day", + "11:00 +1day",]; +?> + + + + + + + + Lightscontrol Manual Tests + + + + + + + Standard Metrics: + + + + + + + + + + + + + +
Sonnenaufgang:sunrise ?>
Sonnenuntergang:sunset ?>
Aktuelle Zeit:
Nacht (ja/nein):isNight) ? "ja" : "nein" ?>
+ + Test Sequences: + + + + + + + update(strtotime($t));?> + + + + +
now:Night: isNight)?"1":"0" ?>, State: state)?"1":"0" ?>, + Change: changeTime ?> (changeTime/60) ?>:changeTime%60 ?>h), + API:
:Night: isNight)?"1":"0" ?>, State: state)?"1":"0" ?>, + Change: changeTime ?> (changeTime/60) ?>:changeTime%60 ?>h), + API:
+ + Config Array: +
times) ?>
+ + +