[FIX] several bugs at the time calculations fixes by rewriting them
This commit is contained in:
parent
492674393f
commit
8f470e37ef
|
@ -5,15 +5,15 @@
|
||||||
},
|
},
|
||||||
"time1": {
|
"time1": {
|
||||||
"on": "16:00",
|
"on": "16:00",
|
||||||
"off": "23:00"
|
"off": "23:30"
|
||||||
},
|
},
|
||||||
"time2": {
|
"time2": {
|
||||||
"on": "05:45",
|
"on": "04:45",
|
||||||
"off": "06:15"
|
"off": "05:15"
|
||||||
},
|
},
|
||||||
"time3": {
|
"time3": {
|
||||||
"on": "06:45",
|
"on": "06:30",
|
||||||
"off": "08:00"
|
"off": "08:30"
|
||||||
},
|
},
|
||||||
"instant-on": null
|
"instant-on": null
|
||||||
}
|
}
|
111
functions.php
111
functions.php
|
@ -33,20 +33,68 @@ class LightStatus {
|
||||||
return 's='.(int)$this->state.' t='.$this->waitTime;
|
return 's='.(int)$this->state.' t='.$this->waitTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* re-calculate values */
|
/* re-calculate values, returns true if successful */
|
||||||
public function update() {
|
public function update($currentTime = null) {
|
||||||
global $sun_zenith;
|
global $sun_zenith;
|
||||||
global $timezone;
|
global $timezone;
|
||||||
|
|
||||||
// calculate sunset and sunrise times
|
if (null == $currentTime) {
|
||||||
|
$currentTime = time();
|
||||||
|
}
|
||||||
|
|
||||||
|
$sunset = null;
|
||||||
|
$sunrise = null;
|
||||||
|
$times = [];
|
||||||
|
|
||||||
|
// calculate times
|
||||||
date_default_timezone_set($timezone);
|
date_default_timezone_set($timezone);
|
||||||
$gmtOffset = date("Z") / (60*60);
|
$gmtOffset = date("Z") / (60*60);
|
||||||
|
|
||||||
$this->sunrise = date_sunrise(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->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 --
|
// -- first check, if an instant-on time is set --
|
||||||
if ($this->times['instant-on'] != null) {
|
if ($this->times['instant-on'] != null) {
|
||||||
|
@ -65,55 +113,46 @@ class LightStatus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- otherwise check, if the ruleset requires the lights on --
|
// -- if no instant-on time is set, follow normal conditions --
|
||||||
// first check, if it's at daylight
|
if ($sunset < $currentTime && $sunrise > $currentTime) {
|
||||||
$currentTime = time();
|
|
||||||
if ($currentTime < $sunrise || $currentTime > $sunset) {
|
|
||||||
$this->isNight = true;
|
$this->isNight = true;
|
||||||
|
|
||||||
// it's night: check, if we are in one of the time intervals
|
// it's night: check, if we are in one of the time intervals
|
||||||
for ($i = 1; $i <= 3; $i++) {
|
$this->changeTime = null;
|
||||||
$timeKey = 'time'.$i;
|
foreach ($times as $t) {
|
||||||
|
if ($t["on"] < $currentTime && $t["off"] > $currentTime) {
|
||||||
$startTime = strtotime($this->times[$timeKey]['on']);
|
// we are in this interval
|
||||||
$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->state = true;
|
$this->state = true;
|
||||||
$this->changeTime = (int)(($stopTime - $currentTime) / 60);
|
$this->changeTime = (int)(($t["off"] - $currentTime) / 60);
|
||||||
$this->waitTime = 1;
|
$this->waitTime = 1;
|
||||||
return true;
|
return true;
|
||||||
} elseif ( ($startTime - $currentTime) < (12*60*60) || ($startTime+(24*60*60) - $currentTime) < (12*60*60) ) {
|
} else if ($t["on"] > $currentTime) {
|
||||||
// right before the next time interval
|
// we are right before this interval
|
||||||
$this->state = false;
|
$this->state = false;
|
||||||
if ($currentTime < $startTime) {
|
$this->changeTime = (int)(($t["on"] - $currentTime) / 60);
|
||||||
$this->changeTime = (int)( ($startTime - $currentTime) / 60 );
|
|
||||||
} else {
|
|
||||||
$this->changeTime = (int)( (($startTime+(24*60*60)) - $currentTime) / 60 );
|
|
||||||
}
|
|
||||||
$this->waitTime = 1;
|
$this->waitTime = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// otherwise we are after this interval, but potentioally before next interval
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->changeTime == null) {
|
||||||
|
// we are after the last interval, so changeTime is not set yet
|
||||||
$this->state = false;
|
$this->state = false;
|
||||||
$this->changeTime = (int)(($stopTime - $currentTime) / 60);
|
$this->changeTime = (int)(($sunrise - $currentTime) / 60);
|
||||||
$this->waitTime = 1;
|
$this->waitTime = $this->changeTime;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} else if ($currentTime > $sunrise && $currentTime < $sunset) {
|
} else if ($currentTime > $sunrise || $sunset > $currentTime) {
|
||||||
$this->isNight = false;
|
$this->isNight = false;
|
||||||
|
|
||||||
// it's day: nothing else check
|
// it's day: nothing else to check
|
||||||
$this->state = false;
|
$this->state = false;
|
||||||
$this->changeTime = (int)(($sunset - $currentTime) / 60);
|
$this->changeTime = (int)(($sunset - $currentTime) / 60);
|
||||||
|
if ($this->changeTime < 0) {
|
||||||
|
$this->changeTime += 24*60; // changeTime is in Minutes
|
||||||
|
}
|
||||||
$this->waitTime = $this->changeTime;
|
$this->waitTime = $this->changeTime;
|
||||||
return true;
|
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() {
|
public function saveTimes() {
|
||||||
global $config_filename;
|
global $config_filename;
|
||||||
|
|
||||||
|
|
78
tests.php
Normal file
78
tests.php
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
// -------------------------------------------
|
||||||
|
// outdoor lights control -- server
|
||||||
|
// -- Manual "Unit Tests" --
|
||||||
|
// copyright: Jannik Beyerstedt | https://jannikbeyerstedt.de
|
||||||
|
// license: http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 License
|
||||||
|
// -------------------------------------------
|
||||||
|
|
||||||
|
include "functions.php";
|
||||||
|
|
||||||
|
$light = new LightStatus();
|
||||||
|
$light->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",];
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<title>Lightscontrol Manual Tests</title>
|
||||||
|
<meta name="robots" content="noindex, nofollow">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="style.css?v1.1">
|
||||||
|
</head>
|
||||||
|
<body class="container">
|
||||||
|
Standard Metrics:
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>Sonnenaufgang:</td><td><?php echo $light->sunrise ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Sonnenuntergang:</td><td><?php echo $light->sunset ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Aktuelle Zeit:</td><td><?php echo date("H:i, Y-m-d",time()) ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Nacht (ja/nein):</td><td><?php echo ($light->isNight) ? "ja" : "nein" ?></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
Test Sequences:
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>now:</td>
|
||||||
|
<td>Night: <?php echo ($light->isNight)?"1":"0" ?>, State: <?php echo ($light->state)?"1":"0" ?>,
|
||||||
|
Change: <?php echo $light->changeTime ?> (<?php echo (int)($light->changeTime/60) ?>:<?php echo $light->changeTime%60 ?>h),
|
||||||
|
API: <?php echo $light ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php foreach ($testTimes as $t): ?>
|
||||||
|
<tr><?php $light->update(strtotime($t));?>
|
||||||
|
<td><?php echo $t ?>:</td>
|
||||||
|
<td>Night: <?php echo ($light->isNight)?"1":"0" ?>, State: <?php echo ($light->state)?"1":"0" ?>,
|
||||||
|
Change: <?php echo $light->changeTime ?> (<?php echo (int)($light->changeTime/60) ?>:<?php echo $light->changeTime%60 ?>h),
|
||||||
|
API: <?php echo $light ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
Config Array:
|
||||||
|
<pre><?php echo var_dump($light->times) ?></pre>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
|
Reference in a new issue