&$event) { if($event->dateTimeEvent < $now) { logger(DEBUG, _("Executing event") . $key, __FILE__ . ":" . __LINE__); if (is_callable($event->function)) { 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__); } $event->published = $now; if (!empty($event->recurrence)) { nextOccurence($event, $key); }else { logger(DEBUG, _("Unsetting event") . $key, __FILE__ . ":" . __LINE__); unset($events[$key]); } } } } } 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, $date) { $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) { $n = 0; logger(DEBUG, _("Calculating next occurence of event #") . $event->key, __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, $event->dateTimeEvent) === true); // loop until the date is not comprise in exceptions dates } // datetime format : "yyyy-mm-dd hh:mm:ss" function setOneshotEvent(device &$deviceObject, string $datetime, $property, $value, $function=null, $replace=false, $method=null) { global $events; $events[] = new event; $key = array_key_last($events); $events[$key]->key = $key; $events[$key]->dateTimeEvent = new dateTime($datetime); $events[$key]->ieeeAddress = $deviceObject->ieeeAddress; $events[$key]->topic = $deviceObject->topic; $events[$key]->param = $property; $events[$key]->value = $value; $events[$key]->device = & $deviceObject; $events[$key]->function = $function; if ($method !==null) $events[$key]->method =$method; } // startDatetime and stopDatetime format : "yyyy-mm-dd hh:mm:ss" function setRecurrentEvent(string $id, $function, string $ieeeAddress, string $property, $value, int $method=0 , string $startDatetime, string $stopDatetime, bool $isInterval, int $hours=0, int $minutes=0, int $seconds=0, int $days=0, int $weeks=0, int $months=0, int $years=0) { global $events, $indexDevices; $string =""; $stringTemp = ""; logger(INFO, _("Setting recurrent event"), __FILE__ . ":" . __LINE__); if (!empty($years)) $stringTemp .= $years . "Y"; if (!empty($months)) $stringTemp .= $months . "M"; if (!empty($week)) $stringTemp .= $week . "W"; if (!empty($days)) $stringTemp .= $days . "D"; if (!empty($stringTemp)) $string = "P" . $stringTemp; $stringTemp = ""; if (!empty($hours)) $stringTemp .= $hours . "H"; if (!empty($minutes)) $stringTemp .= $minutes . "M"; if (!empty($seconds)) $stringTemp .= $seconds . "S"; if (!empty($stringTemp)) $string .= "T" . $stringTemp; logger(DEBUG, _("reccurrent event string : ") . $string, __FILE__ . ":" . __LINE__); $key = searchEventByID($id); if($key !== false) { deleteEvent($key); } $event = new event; $event->id = $id; // pb in recurrent event in case of date and not interval if ($isInterval === true) { if (($event->dateTimeEvent->add($event->recurrence)) === false) { logger(ERROR, _("Error in event recurrence. event: ") . $id , __FILE__ . ":" . __LINE__); return true; } $event->recurrence = new DateInterval($string); $event->isInterval = true; }else { $event->recurrence = $string; $event->isInterval = false; } if (!empty($startDatetime)) { $event->startDatetime = new datetime($startDatetime); }else { $event->startDatetime = now(); logger(DEBUG, _("Datetime is ") . $event->startDatetime->format("Y-m-d H:i:s"), __FILE__ . ":" . __LINE__); } if (!empty($stopDatetime)) { $event->stopDatetime = new datetime($stopDatetime); } $event->dateTimeEvent = $event->startDatetime; if (!empty($ieeeAddress)) { $event->ieee_address = $ieeeAddress; $event->topic = $indexDevices[$deviceObject]->topic; $event->device = &$indexDevices[$deviceObject]; $event->param = $property; $event->value = $value; } if ($method !== null) $event->method = $method; $events[] = $event; $r = key($events); $events[$r]->key = $r; $events[$r]->dateTimeEvent = nextOccurence($events[$r], $r); return $r; } function setDelay(device &$deviceObject, float $delay, string $unit, string $property, $value, $function, bool $replace=false, int $method=null) { global $events, $logLevel; $oldLevel = $logLevel; $logLevel = DEBUG; $datetime = new dateTime(); strtolower($unit); switch($unit) { case "second": $s = "S"; break; case "minute": $s = "M"; break; case "hour": $s = "H"; break; case "day": $s = "D"; break; case "week": $s = "W"; break; case "month": $s = "M"; break; case "year": $s = "Y"; break; } if (empty($s)) { logger(ERROR, _("setDelay error: unit is empty"), __FILE__ . ":" . __LINE__); } if (($datetime->add(new DateInterval('PT'. $delay . $s))) === false) { logger(ERROR, _("setDelay error: datetime->add"), __FILE__ . ":" . __LINE__); } //print_r($datetime); if ($replace) { $eventKey = searchEvent($deviceObject, $property, $value); if ($eventKey !== false) deleteEvent($eventKey); } //$dt = $datetime->format("Y-m-d\TH:i:s\Z"); $events[] = new event; $key = array_key_last($events); $events[$key]->dateTimeEvent = $datetime; $events[$key]->ieeeAddress = $deviceObject->ieeeAddress; $events[$key]->topic = $deviceObject->topic; $events[$key]->param = $property; $events[$key]->value = $value; $events[$key]->device = & $deviceObject; $events[$key]->function = $function; if ($method !== null) $events[$key]->method = $method; logger (DEBUG, _('Setting new delay in $events[]'), __FILE__ . ":" . __LINE__); //print_r($events[$key]); $logLevel = $oldLevel; } function removeEvent(device $deviceObject, string $property , $value) { global $events; $eventKey = searchEvent($deviceObject, $property , $value); if ($eventKey !== false) { deleteEvent($eventKey); } } function searchEvent(device $deviceObject, string $property, $value, $function=null) { global $events; logger(DEBUG, sprintf(_("searching event for device %s, property %s and value %s"), $deviceObject->friendlyName, $property, bool2string($value)), __FILE__ . ":" . __LINE__); foreach($events as $key => $event) { //echo "Event : $event => $value" . EOL; //echo "===>";print_r($event); echo EOL; if($event->topic == $deviceObject->topic and $event->param == $property and $event->value == $value and $event->ieeeAddress == $deviceObject->ieeeAddress) { return $key; } } return false; } function searchEventByID($id) { global $events; logger(DEBUG, sprintf(_("searching event by ID %s"), $id), __FILE__ . ":" . __LINE__); foreach($events as $key => $event) { if ($event->id == $id) { return $key; } } return false; } // warning delete event does not manage method of the device (IDLE, ) function deleteEvent(int $eventKey) { global $events; if ($eventKey !== false) { logger(INFO, _("delete event key =") . $eventKey, __FILE__ . ":" . __LINE__); if (array_key_exists($eventKey, $events)) { unset ($events[$eventKey]); }else { logger(ERROR, _("event key does not exists: ") . $eventKey, __FILE__ . ":" . __LINE__); } } } ?>