diff --git a/class/db.php b/class/db.php index 565c3a0..34f7392 100644 --- a/class/db.php +++ b/class/db.php @@ -39,16 +39,22 @@ class db extends mysqli { global $mohaDB, $properties2log, $testMode; $precision = 0; - $oldValue = $device->properties[$property]["lastValueLogged"]; + //echo "############## logProperty ################\nproperty => " . $propertyTree .EOL; //echo "logging in database"; //var_dump($device); $ieeeAddress = $device->ieeeAddress; //print_r($ieeeAddress); - $query = "INSERT INTO logs (device, property, value) VALUES('" . $this->protect($ieeeAddress) . "', '" . $this->protect($property) . "', '" . $this->protect(bool2string($value)) . "')"; //echo $query . EOL; if (is_numeric($value) and !empty($properties2log[$property])) { + if (!array_key_exists("lastValueLogged", $device->properties[$property])) + { + $oldvalue = -1; + }else + { + $oldValue = $device->properties[$property]["lastValueLogged"]; + } // calculate a min/max value for storing data $r = $properties2log[$property]; if (is_callable($r)) @@ -59,10 +65,9 @@ class db extends mysqli $minMax = $r; } logger(DEBUG, _("minMax = " . $minMax), __FILE__ . ":" . __LINE__); - var_dump($value) . EOL; - var_dump($minMax) . EOL; - var_dump($oldValue) . EOL; - if ( !is_numeric($oldValue)) $oldValue = 0; + //var_dump($value) . EOL; + //var_dump($minMax) . EOL; + //var_dump($oldValue) . EOL; //echo "minMax = " .$minMax . EOL; //echo "oldValue = " . $oldValue . EOL; //echo "Value = " . $value . EOL; @@ -77,6 +82,7 @@ class db extends mysqli logger(INFO, _("Test mode on: not storing in DB "), __FILE__ . ":" . __LINE__); }else { + $query = "INSERT INTO logs (device, property, value) VALUES('" . $this->protect($ieeeAddress) . "', '" . $this->protect($property) . "', '" . $this->protect(bool2string($value)) . "')"; if(!$this->result = $this->query($query)) { logger(ERROR, _("mysql query errror: ") . $this->error, __FILE__ . ":" . __LINE__); diff --git a/class/main.php b/class/main.php index 750d5e5..80a6f98 100644 --- a/class/main.php +++ b/class/main.php @@ -70,13 +70,13 @@ class event public $function; public $device; public $published; - public $dateTimeEvent; // datetime : next occurence for recurrent event + public $dateTimeEvent; // recurrent event: datetime public $startDatetime; public $stopDatetime; - public $recurrenceInterval; // interval : for recurrent event + public $recurrence; // recurrent event: interval or date to add public $exceptionInterval; // array of object ranges public $method; // cf: constants.php (IDLE, AUTO, MANUAL) - public $isInterval; // 0 => recurence by date 1 => by interval + public $isInterval = false; // 0 => recurence by date 1 => by interval } class watch diff --git a/events.php b/events.php index aa244f9..0600c9d 100644 --- a/events.php +++ b/events.php @@ -16,66 +16,155 @@ function checkEvents() { $events = array(); }*/ + $now = now(); foreach ($events as $key => &$event) { - $now = now(); - if (!empty($event->startDatetime)) + + if($event->dateTimeEvent < $now) { - logger(DEBUG, _("StartDatetime is set"), __FILE__ . ":" . __LINE__); - if($event->dateTimeEvent < $now) + if (is_callable($event->function)) { - logger(DEBUG, _("Event must be executed"), __FILE__ . ":" . __LINE__); - - if (!empty($event->exceptionInterval) and $event->isInterval == true) - { - logger(DEBUG, _("Testing exceptions"), __FILE__ . ":" . __LINE__); - foreach($event->exceptionInterval as $key => $value) - { - if($now > $value->start and $now < $value->end) - { - $exception = true; - }elseif($now > $value->stop) - { - unset($event->exceptionInterval[$key]); - } - } - } - - if ($exception === false) - { - if (is_callable($event->function)) - { - logger(DEBUG, _("executing function") . $event->function[1], __FILE__ . ":" . __LINE__); - $event->function(); - $event->published = $now; - }else - { - logger(DEBUG, sprintf(_("sending command set %s => %s for %s"), $event->param ,bool2string($event->value), $event->device->friendlyName), __FILE__ . ":" . __LINE__); - publish(mktopic($event->device), array($event->param => $event->value), "set"); - $event->published = $now; - } - if ($event->method !== null) $event->device->properties[$event->param]["method"] = $event->method; - if (($event->dateTimeEvent->add($event->recurrenceInterval)) === false) - { - logger(ERROR, _("Error in adding interval to event recurrence. event: ") . $key, __FILE__ . ":" . __LINE__); - } - } + logger(DEBUG, _("executing function") . $event->function[1], __FILE__ . ":" . __LINE__); + $event->function($event); + }elseif (is_object($event->device)) + { + logger(DEBUG, sprintf(_("sending command set %s => %s for %s"), $event->param ,bool2string($event->value), $event->device->friendlyName), __FILE__ . ":" . __LINE__); + publish(mktopic($event->device), array($event->param => $event->value), "set"); + if ($event->method !== null) $event->device->properties[$event->param]["method"] = $event->method; + }else + { + logger(ERROR, _("Event is malformed") . $key, __FILE__ . ":" . __LINE__); } - }elseif (!empty($event->dateTimeEvent) and $event->dateTimeEvent < now()) + + $event->published = $now; + } + if (!empty($event->recurrence)) { - logger(DEBUG, sprintf(_("Sending command set %s => %s to %s"),$event->param, bool2string($event->value), $event->device->friendlyName), __FILE__ . ":" . __LINE__); - $mid = publish(mktopic($event->device), array($event->param => $event->value), "set"); //, $key);null - $event->published = $now; - if ($event->method !== null) - { - $event->device->properties[$event->param]["method"] = $event->method; - } - //echo "#################################\nUnsetting event $key \n###########################" . EOL; - unset($events[$key]); + nextOccurence($event, $key, $now); + }else + { + unset($events[$key]); } } - //print_r($events); - //$logLevel = $oldLevel; +} + +function nextIntervalDate(&$event) +{ + if (($event->dateTimeEvent = $event->dateTimeEvent->add($event->recurrence)) === false) + { + logger(ERROR, _("Error in adding interval to event recurrence. event: ") . $eventKey, __FILE__ . ":" . __LINE__); + return false; + } +} + +function nextDate(&$event) +{ + $isDate = false; + $date = new DateTime; + $year = $event->dateTimeEvent->format("Y"); + $month = $event->dateTimeEvent->format("M"); + $day = $event->dateTimeEvent->format("D"); + $hour = $event->dateTimeEvent->format("H"); + $minutes = $event->dateTimeEvent->format("I"); + $seconds = $event->dateTimeEvent->format("S"); + $temp = ""; + + for ($x = 0; $x < strlen($event->recurrence); $x++) + { + switch ($event->recurrence[$x]) + { + case "P": + $isDate = true; + break; + case "T": + $isDate = false; + break; + case "Y": + $year = $temp; + $temp = 0; + break; + case "M": + if ($isdate) + { + $month = $temp; + }else + { + $minutes = $temp; + } + $temp = 0; + break; + case "W": + $temp = 0; + break; + case "H": + $hour = $temp; + $temp = 0; + case "S": + $seconds = $temp; + $temp = 0; + default: + $temp = $event->recurrence[$x] . $temp; + break; + } + } + if ($month != 0) + { + $year += 1; + }elseif ($day != 0) + { + $month += 1; + }elseif ($hour != 0) + { + $day = +1; + }elseif ($minutes != 0) + { + $hour = +1; + } + + $event->dateTimeEvent->setDate(intval($year), intval($month), intval($day)); + $event->dateTimeEvent->setTime(intval($hour), intval($minutes), intval($seconds)); +} + +function exceptionsTest(&$event, $now) +{ + $exception = false; + + logger(DEBUG, _("Testing exceptions"), __FILE__ . ":" . __LINE__); + if (!empty($event->exceptionInterval)) + { + foreach($event->exceptionInterval as $key => $value) + { + if($now > $value->start and $now < $value->end) + { + $exception = true; + }elseif($now > $value->stop) + { + unset($event->exceptionInterval[$key]); + } + } + } + return $exception; +} + +function nextOccurence(&$event, $eventKey, $now) +{ + $n = 0; + logger(DEBUG, _("Calculating next occurence"), __FILE__ . ":" . __LINE__); + do + { + if ($event->isInterval === true) + { + nextIntervalDate($event); + }else + { + nextDate($event); + } + if ($n++ > 1000) + { + logger(ERROR, _("infinite loop"), __FILE__ . ":" . __LINE__); + return 1; + } + }while (exceptionsTest($event, $now) === true); // loop until the date is not comprise in exceptions dates } // datetime format : "yyyy-mm-dd hh:mm:ss" @@ -109,7 +198,7 @@ function setRecurrentEvent($function, $ieeeAddress, string $property, $value, bo if (!empty($days)) $string .= $days . "D"; $string .= "T"; if (!empty($hours)) $string .= $hours . "H"; - if (!empty($months)) $string .= $months . "M"; + if (!empty($minutes)) $string .= $minutes . "M"; if (!empty($seconds)) $string .= $seconds . "S"; logger(DEBUG, _("reccurrent event string : ") . $string, __FILE__ . ":" . __LINE__); @@ -118,10 +207,17 @@ function setRecurrentEvent($function, $ieeeAddress, string $property, $value, bo // pb in recurrent event in case of date and not interval if ($isInterval === true) { - $event->recurrenceInterval = new DateInterval($string); + if (($event->dateTimeEvent->add($event->recurrence)) === false) + { + logger(ERROR, _("Error in event recurrence. event: ") . $key, __FILE__ . ":" . __LINE__); + return true; + } + $event->recurrence = new DateInterval($string); + $event->isInterval = true; }else { - $event->recurrenceInterval = 0; + $event->recurrence = $string; + $event->isInterval = false; } if (!empty($startDatetime)) @@ -131,12 +227,13 @@ function setRecurrentEvent($function, $ieeeAddress, string $property, $value, bo { $event->startDatetime = now(); } - $event->dateTimeEvent = $event->startDatetime; if (!empty($stopDatetime)) { $event->stopDatetime = new datetime($stopDatetime); } + + $event->dateTimeEvent = $event->startDatetime; if (!empty($ieeeAddress)) { $event->ieee_address = $ieeeAddress; @@ -146,16 +243,9 @@ function setRecurrentEvent($function, $ieeeAddress, string $property, $value, bo $event->value = $value; } - if ($event->recurrenceInterval != 0) - { - if (($event->dateTimeEvent->add($event->recurrenceInterval)) === false) - { - logger(ERROR, _("Error in event recurrence. event: ") . $key, __FILE__ . ":" . __LINE__); - return 1; - } - } if ($method !== null) $event->method = $method; - return 0; + $events[] = $event; + return false; } function setDelay(device &$deviceObject, float $delay, string $unit, string $property, $value, $function, bool $replace=false, int $method = null) diff --git a/hooks/scripts/rdc_portes_ouvertes.php b/hooks/scripts/rdc_portes_ouvertes.php index 3c37fb6..54ee1f6 100644 --- a/hooks/scripts/rdc_portes_ouvertes.php +++ b/hooks/scripts/rdc_portes_ouvertes.php @@ -11,7 +11,10 @@ class alerte_intrusion extends hook GARAGE_PORTE => "contact", RDC_CHAMBRE_BAIE => "contact", RDC_SALON_BAIE => "contact", - GARAGE_PORTAIL => "contact" + GARAGE_PORTAIL => "contact", + ETAGE_SALON_FENETRE => "contact", + ETAGE_CUISINE_FENETRE => "contact", + ETAGE_PORTE_FENETRE => "contact" ); function installHooks(&$indexDevices) @@ -40,7 +43,7 @@ class alerte_intrusion extends hook } } - public function testPortes($send=true) :array + public function testPortes($send=true, $opened=true) :array { global $indexDevices; $portes = array(); @@ -49,10 +52,20 @@ class alerte_intrusion extends hook $msg = ""; foreach ($this->devicelist as $device => $property) { - if($indexDevices[$device]->properties[$property] == false) + if (!$opened) { - $portes[] = $indexDevices[$device]->friendlyName; - $msg .= $indexDevices[$device]->friendlyName . "\n"; + if($indexDevices[$device]->properties[$property] == false) + { + $portes[] = $indexDevices[$device]->friendlyName; + $msg .= $indexDevices[$device]->friendlyName . "\n"; + } + }else + { + if($indexDevices[$device]->properties[$property] == true) + { + $portes[] = $indexDevices[$device]->friendlyName; + $msg .= $indexDevices[$device]->friendlyName . "\n"; + } } } if ($send) @@ -66,6 +79,6 @@ class alerte_intrusion extends hook $hooks["alerte_intrusion"] = new alerte_intrusion(); logger(DEBUG, _("Initializing event"), __FILE__ . ":" . __LINE__); $function = array($hooks["alerte_intrusion"], "testPortes"); -setRecurrentEvent($function, 0, 0, 0, 0, 0, 0, 21, 0, 0, 1, 0, 0, 0); +setRecurrentEvent($function, 0, 0, 0, false, 0, 0, 21, 0, 0, 0, 0, 0, 0); ?> diff --git a/hooks/scripts/rdc_temperature_int_ext.php b/hooks/scripts/rdc_temperature_int_ext.php index 304972b..c132601 100644 --- a/hooks/scripts/rdc_temperature_int_ext.php +++ b/hooks/scripts/rdc_temperature_int_ext.php @@ -23,15 +23,12 @@ class rdc_temperature_int_ext extends hook global $indexDevices, $hooks; static $time; $portes = array(); - $state = -1; + $status = -1; $msg = ""; + if (empty($time)) $time = now(); $indoorTemp = $device->properties["indoortempc"]["value"]; - $portes = $hooks["alerte_intrusion"]->testPortes(false); - foreach($portes as $value) - { - $msg .= $value . "\n"; - } + if ( $value > $indoorTemp) { @@ -57,13 +54,26 @@ class rdc_temperature_int_ext extends hook } logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, bool2string($value)), __FILE__ . ":" . __LINE__, $device); } + $portes = $hooks["alerte_intrusion"]->testPortes(false, true); if ($status == 1) { - //if ($time - DateTime(); - //logger(ALERT, _("Open doors to climate"), null ,$device); + if (empty($portes) and ($time->diff(now())->format("i")) > 5) + { + logger(ALERT, _("Open doors to climate"), null, $device); + $time = now(); + } }else { - //logger(ALERT, _("Close doors to climate\n") . $msg, null, $device); + //$portes = $hooks["alerte_intrusion"]->testPortes(false, true); + if (!empty($portes) and ($time.diff(now()).format("i") > 5)) + { + $time = now(); + foreach($portes as $porte) + { + $msg .= $porte . "\n"; + logger(ALERT, _("Close doors to climate\n") . $msg, null, $device); + } + } } } } diff --git a/moha.php b/moha.php index 7472df7..af21d96 100644 --- a/moha.php +++ b/moha.php @@ -50,7 +50,7 @@ if ($testMode) $httpServerIp = "192.168.1.253"; }else { - $logLevel = INFO | NOTICE | WARNING | ERROR | ALERT; + $logLevel = DEBUG | INFO | NOTICE | WARNING | ERROR | ALERT; $mqttServerIp = "127.0.0.1"; // IP address of mqttserver in production mode $dataPath = "/usr/share/moha/"; $logFile = "/var/log/moha.log"; // Path of log file