2017-07-24 01:34:53 +02:00
< ? php
// -------------------------------------------
// outdoor lights control -- server
// copyright: Jannik Beyerstedt | https://jannikbeyerstedt.de
// license: http://www.gnu.org/licenses/gpl-3.0.txt GPLv3 License
// -------------------------------------------
$config_filename = 'config_times.json' ;
$timeRegex = '/^((2[0-3]|1[0-9]|0[0-9]|[^0-9][0-9]):([0-5][0-9]|[0-9]))/' ;
2017-08-23 14:11:54 +02:00
$sunsetTrue = 90 + 50 / 60 ; /* "true" sunrise/ sunset */
$sunsetCivilian = 96 ; /* Civilian Twilight */
$sunsetNautical = 102 ; /* Nauticla Twilight */
2017-08-24 08:30:40 +02:00
$sun_zenith = 93 ; /* use one of the above $sunset* or own value */
2017-07-24 01:34:53 +02:00
$timezone = " Europe/Berlin " ;
class LightStatus {
2017-08-23 14:02:31 +02:00
public $state = true ; /* current state: lights on/off */
public $changeTime = 1 ; /* minutes until next state change */
public $waitTime = 0 ; /* minutes the client should wait until next request */
2017-07-24 01:34:53 +02:00
2017-08-23 14:02:31 +02:00
public $times = null ; /* config array */
2017-07-24 01:34:53 +02:00
2017-08-23 14:02:31 +02:00
public $sunrise , $sunset ; /* time string hh:mm */
public $isNight ; /* bool, true if it's at night */
2017-07-24 01:34:53 +02:00
function __construct () {
return $this -> readTimes ();
}
2017-08-23 14:02:31 +02:00
/* return string for the service API */
2017-07-24 01:34:53 +02:00
function __toString () {
2017-07-24 12:24:19 +02:00
return 's=' . ( int ) $this -> state . ' t=' . $this -> waitTime ;
2017-07-24 01:34:53 +02:00
}
2017-10-10 11:03:49 +02:00
/* re-calculate values, returns true if successful */
public function update ( $currentTime = null ) {
2017-07-24 01:34:53 +02:00
global $sun_zenith ;
global $timezone ;
2017-10-10 11:03:49 +02:00
if ( null == $currentTime ) {
$currentTime = time ();
}
$sunset = null ;
$sunrise = null ;
$times = [];
// calculate times
2017-07-24 01:34:53 +02:00
date_default_timezone_set ( $timezone );
$gmtOffset = date ( " Z " ) / ( 60 * 60 );
2017-10-10 11:03:49 +02:00
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 );
$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 ;
}
2017-07-24 01:34:53 +02:00
2017-10-10 11:03:49 +02:00
$times [] = [ " on " => $startTime , " off " => $stopTime ];
}
}
2017-07-24 01:34:53 +02:00
// -- first check, if an instant-on time is set --
if ( $this -> times [ 'instant-on' ] != null ) {
if ( $this -> times [ 'instant-on' ] > time ()) {
$this -> state = true ;
$this -> changeTime = ( int )(( $this -> times [ 'instant-on' ] - time ()) / 60 );
2017-07-24 12:24:19 +02:00
$this -> waitTime = $this -> changeTime ;
2017-07-24 01:34:53 +02:00
return true ;
} else {
// reset instant-on
$this -> state = false ;
$this -> times [ 'instant-on' ] = null ;
$this -> saveTimes ();
}
}
2017-10-10 11:03:49 +02:00
// -- if no instant-on time is set, follow normal conditions --
if ( $sunset < $currentTime && $sunrise > $currentTime ) {
2017-08-23 14:02:31 +02:00
$this -> isNight = true ;
2017-07-24 01:34:53 +02:00
// it's night: check, if we are in one of the time intervals
2017-10-10 11:03:49 +02:00
$this -> changeTime = null ;
foreach ( $times as $t ) {
if ( $t [ " on " ] < $currentTime && $t [ " off " ] > $currentTime ) {
// we are in this interval
2017-07-24 01:34:53 +02:00
$this -> state = true ;
2017-10-10 11:03:49 +02:00
$this -> changeTime = ( int )(( $t [ " off " ] - $currentTime ) / 60 );
2017-07-24 12:24:19 +02:00
$this -> waitTime = 1 ;
2017-07-24 01:34:53 +02:00
return true ;
2017-10-10 11:03:49 +02:00
} else if ( $t [ " on " ] > $currentTime ) {
// we are right before this interval
2017-08-02 22:58:44 +02:00
$this -> state = false ;
2017-10-10 11:03:49 +02:00
$this -> changeTime = ( int )(( $t [ " on " ] - $currentTime ) / 60 );
2017-08-02 22:58:44 +02:00
$this -> waitTime = 1 ;
return true ;
2017-07-24 01:34:53 +02:00
}
2017-10-10 11:03:49 +02:00
// otherwise we are after this interval, but potentioally before next interval
2017-07-24 01:34:53 +02:00
}
2017-10-10 11:03:49 +02:00
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 ;
}
2017-07-24 01:34:53 +02:00
2017-10-10 11:03:49 +02:00
} else if ( $currentTime > $sunrise || $sunset > $currentTime ) {
2017-08-23 14:02:31 +02:00
$this -> isNight = false ;
2017-10-10 11:03:49 +02:00
// it's day: nothing else to check
2017-07-24 01:34:53 +02:00
$this -> state = false ;
$this -> changeTime = ( int )(( $sunset - $currentTime ) / 60 );
2017-10-10 11:03:49 +02:00
if ( $this -> changeTime < 0 ) {
$this -> changeTime += 24 * 60 ; // changeTime is in Minutes
}
2017-07-24 12:24:19 +02:00
$this -> waitTime = $this -> changeTime ;
2017-07-24 01:34:53 +02:00
return true ;
} else {
echo " ERROR: invalid time of day. " ;
return 'ERROR' ;
}
}
2017-10-10 11:03:49 +02:00
/* save modified $times array to config file, returns true if successful */
2017-07-24 01:34:53 +02:00
public function saveTimes () {
global $config_filename ;
if ( empty ( $this -> times )) {
return 'ERROR' ;
} else {
$json_string = json_encode ( $this -> times , JSON_PRETTY_PRINT );
file_put_contents ( $config_filename , $json_string );
return true ;
}
}
2017-08-23 14:43:13 +02:00
public function setClientLastSeen () {
$this -> times [ 'clientLastSeen' ] = time ();
$this -> saveTimes ();
}
public function getClientLastSeen () {
return $this -> times [ 'clientLastSeen' ];
}
2017-07-24 01:34:53 +02:00
private function readTimes () {
global $config_filename ;
$file_content = file_get_contents ( $config_filename );
if ( $file_content == FALSE ) {
return 'ERROR' ;
} else {
$this -> times = json_decode ( $file_content , true );
return true ;
}
}
}
function checkTimesInput ( $times ) {
global $timeRegex ;
if ( ! isset ( $_POST [ 'time1-start' ]) || ! preg_match ( $timeRegex , $_POST [ 'time1-start' ])) {
return " time1-start not valid " ;
}
if ( ! isset ( $_POST [ 'time1-stop' ]) || ! preg_match ( $timeRegex , $_POST [ 'time1-stop' ])) {
return " time1-stop not valid " ;
}
if ( ! isset ( $_POST [ 'time2-start' ]) || ! preg_match ( $timeRegex , $_POST [ 'time2-start' ])) {
return " time2-start not valid " ;
}
if ( ! isset ( $_POST [ 'time2-stop' ]) || ! preg_match ( $timeRegex , $_POST [ 'time2-stop' ])) {
return " time2-stop not valid " ;
}
if ( ! isset ( $_POST [ 'time3-start' ]) || ! preg_match ( $timeRegex , $_POST [ 'time3-start' ])) {
return " time3-start not valid " ;
}
if ( ! isset ( $_POST [ 'time3-stop' ]) || ! preg_match ( $timeRegex , $_POST [ 'time3-stop' ])) {
return " time3-stop not valid " ;
}
return true ;
}
?>