Merge branch 'master' of git.labolyon.fr:DTux/moha
This commit is contained in:
commit
be7db07714
@ -143,6 +143,10 @@ function apiServer($read)
|
||||
logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__);
|
||||
htmlSend($spawn, deleteDevice($argList));
|
||||
break;
|
||||
case "test":
|
||||
logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__);
|
||||
htmlSend($spawn, test($argList));
|
||||
break;
|
||||
default:
|
||||
if (is_numeric(array_key_first($argList)))
|
||||
{
|
||||
|
@ -559,4 +559,13 @@ function apiDisplayByType($argList)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
function test()
|
||||
{
|
||||
global $hooks;
|
||||
logger(DEBUG, _("Testing doors") , __FILE__ . ":" . __LINE__);
|
||||
echo "testing doors";
|
||||
return $hooks["alerte_intrusion"]->testPortes();
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -18,6 +18,9 @@ class topic {
|
||||
public $config;
|
||||
public $callback;
|
||||
public $getOnStart = false;
|
||||
public $lastSeen;
|
||||
public $timeOut = 5;
|
||||
public $notificationSent = false;
|
||||
}
|
||||
|
||||
class device
|
||||
@ -33,6 +36,7 @@ class device
|
||||
public $toConfirm;
|
||||
public $triggerDevice;
|
||||
public $properties = array();
|
||||
public $lastSeen;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@ -72,6 +76,7 @@ class event
|
||||
public $recurrenceInterval; // interval : for recurrent event
|
||||
public $exceptionInterval; // array of object ranges
|
||||
public $method; // cf: constants.php (IDLE, AUTO, MANUAL)
|
||||
public $isInterval; // 0 => recurence by date 1 => by interval
|
||||
}
|
||||
|
||||
class watch
|
||||
|
64
events.php
64
events.php
@ -7,13 +7,15 @@ logger(DEBUG, _("Including events.php"), __FILE__ . ":" . __LINE__);
|
||||
function checkEvents()
|
||||
{
|
||||
global $logLevel, $events;
|
||||
logger(DEBUG, _("Checking events"), __FILE__ . ":" . __LINE__);
|
||||
|
||||
$oldLevel = $logLevel;
|
||||
//$logLevel = DEBUG;
|
||||
$exception = false;
|
||||
if ($events === null)
|
||||
/*if ($events === null)
|
||||
{
|
||||
$events = array();
|
||||
}
|
||||
}*/
|
||||
foreach ($events as $key => &$event)
|
||||
{
|
||||
$now = now();
|
||||
@ -23,7 +25,8 @@ function checkEvents()
|
||||
if($event->dateTimeEvent < $now)
|
||||
{
|
||||
logger(DEBUG, _("Event must be executed"), __FILE__ . ":" . __LINE__);
|
||||
if (!empty($event->exceptionInterval))
|
||||
|
||||
if (!empty($event->exceptionInterval) and $event->isInterval == true)
|
||||
{
|
||||
logger(DEBUG, _("Testing exceptions"), __FILE__ . ":" . __LINE__);
|
||||
foreach($event->exceptionInterval as $key => $value)
|
||||
@ -37,15 +40,20 @@ function checkEvents()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($exception === false)
|
||||
{
|
||||
if (is_callable($this->function))
|
||||
if (is_callable($event->function))
|
||||
{
|
||||
$this->function($event);
|
||||
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)
|
||||
{
|
||||
@ -53,7 +61,6 @@ function checkEvents()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}elseif (!empty($event->dateTimeEvent) and $event->dateTimeEvent < now())
|
||||
{
|
||||
logger(DEBUG, sprintf(_("Sending command set %s => %s to %s"),$event->param, bool2string($event->value), $event->device->friendlyName), __FILE__ . ":" . __LINE__);
|
||||
@ -89,9 +96,11 @@ function setOneshotEvent(device &$deviceObject, string $datetime, $property, $va
|
||||
|
||||
// startDatetime and stopDatetime format : "yyyy-mm-dd hh:mm:ss"
|
||||
|
||||
function setRecurrentEvent(device &$deviceObject, string $property, $value, string $startDatetime, string $stopDatetime, int $hours, int $minutes, int $seconds, int $days, int $weeks, int $months, int $years, int $method = null)
|
||||
function setRecurrentEvent($function, $ieeeAddress, string $property, $value, bool $isInterval, string $startDatetime, string $stopDatetime, int $hours, int $minutes, int $seconds, int $days, int $weeks, int $months, int $years, int $method = null)
|
||||
{
|
||||
global $events;
|
||||
global $events, $indexDevices;
|
||||
logger(INFO, _("Setting recurrent event"), __FILE__ . ":" . __LINE__);
|
||||
|
||||
$string = "P";
|
||||
if (!empty($years)) $string .= $years . "Y";
|
||||
if (!empty($months)) $string .= $months . "M";
|
||||
@ -101,24 +110,51 @@ function setRecurrentEvent(device &$deviceObject, string $property, $value, stri
|
||||
if (!empty($hours)) $string .= $hours . "H";
|
||||
if (!empty($months)) $string .= $months . "M";
|
||||
if (!empty($seconds)) $string .= $seconds . "S";
|
||||
logger(DEBUG, _("reccurrent event string : ") . $string, __FILE__ . ":" . __LINE__);
|
||||
|
||||
|
||||
$event = new event;
|
||||
|
||||
// pb in recurrent event in case of date and not interval
|
||||
if ($isInterval === true)
|
||||
{
|
||||
$event->recurrenceInterval = new DateInterval($string);
|
||||
}else
|
||||
{
|
||||
$event->recurrenceInterval = 0;
|
||||
}
|
||||
|
||||
if (!empty($startDatetime))
|
||||
{
|
||||
$event->startDatetime = new datetime($startDatetime);
|
||||
}else
|
||||
{
|
||||
$event->startDatetime = now();
|
||||
}
|
||||
$event->dateTimeEvent = $event->startDatetime;
|
||||
|
||||
if (!empty($stopDatetime))
|
||||
{
|
||||
$event->stopDatetime = new datetime($stopDatetime);
|
||||
$event->ieee_address = $deviceObject->ieeeAddress;
|
||||
$event->topic = $deviceObject->topic;
|
||||
$event->device = & $deviceObject;
|
||||
}
|
||||
if (!empty($ieeeAddress))
|
||||
{
|
||||
$event->ieee_address = $ieeeAddress;
|
||||
$event->topic = $indexDevices[$deviceObject]->topic;
|
||||
$event->device = &$indexDevices[$deviceObject];
|
||||
$event->param = $property;
|
||||
$event->value = $value;
|
||||
$event->dateTimeEvent = $event->startDatetime;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function setDelay(device &$deviceObject, float $delay, string $unit, string $property, $value, bool $replace=false, int $method = null)
|
||||
|
@ -5,8 +5,11 @@ class notificationFreemobile
|
||||
private $name = "freemobile";
|
||||
public $active = true;
|
||||
public $level;
|
||||
private $dest = array(
|
||||
"daniel" => "32886706&pass=JTGUY6l5OG73zX",
|
||||
public $curlErr;
|
||||
public $lastTry;
|
||||
public $lastTryTimeout = 5;
|
||||
protected $dest = array(
|
||||
"daniel" => "15480189&pass=yVpPmCWmUl2HGp",
|
||||
);
|
||||
|
||||
function __construct()
|
||||
@ -16,37 +19,50 @@ class notificationFreemobile
|
||||
|
||||
function send($message, $destinataire=NOTIF_DEFAULT_DEST)
|
||||
{
|
||||
global $curlErr;
|
||||
$result = false;
|
||||
$error = false;
|
||||
if ($this->active === true)
|
||||
{
|
||||
$ch = curl_init();
|
||||
// set url
|
||||
curl_setopt($ch, CURLOPT_URL, $this->url . $this->dest[$destinataire] . "&msg=" . urlencode(trim($message)));
|
||||
echo $this->url . urlencode(trim($message)) . EOL;
|
||||
|
||||
//return the transfer as a string
|
||||
//curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
// $result contains the output string
|
||||
if ($curlErr <= 10)
|
||||
if ($this->curlErr <= 5)
|
||||
{
|
||||
$result = curl_exec($ch);
|
||||
if ($result === false)
|
||||
logger(DEBUG, _("Curl sending message"), false, __FILE__ . ":" . __LINE__);
|
||||
echo $this->url . urlencode(trim($message)) . EOL;
|
||||
curl_exec($ch);
|
||||
if (curl_errno($ch) != 0)
|
||||
{
|
||||
$curlErr += 1;
|
||||
$this->curlErr += 1;
|
||||
$this->lastTry = time();
|
||||
logger(ERROR, sprintf( _("Curl return error %d: %s when sending notification"), curl_errno($ch), curl_error($ch)), false, __FILE__ . ":" . __LINE__);
|
||||
$error = true;
|
||||
}else
|
||||
{
|
||||
logger(DEBUG, sprintf(_("Curl return: %s when sending notification"), $result), false);
|
||||
logger(DEBUG, sprintf(_("Curl return: %s when sending notification"), $result), false, __FILE__ . ":" . __LINE__);
|
||||
$this->curlErr = 0;
|
||||
}
|
||||
} //TODO managing curl errors
|
||||
}else
|
||||
{
|
||||
if ((time() - $this->lastTry) > ($this->lastTryTimeout*60))
|
||||
{
|
||||
$this->curlErr -= 1;
|
||||
}
|
||||
$error = true;
|
||||
}
|
||||
|
||||
|
||||
//TODO managing curl errors
|
||||
// close curl resource to free up system resources
|
||||
curl_close($ch);
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
return $error;
|
||||
}
|
||||
}
|
||||
|
||||
$notificationMethods["freemobile"] = new notificationFreemobile();
|
||||
|
||||
?>
|
||||
|
@ -1,4 +1,6 @@
|
||||
<?php
|
||||
require_once "events.php";
|
||||
|
||||
class alerte_intrusion extends hook
|
||||
{
|
||||
public $hookName = "alerte_intrusion";
|
||||
@ -27,24 +29,30 @@ class alerte_intrusion extends hook
|
||||
}
|
||||
}
|
||||
|
||||
public function test()
|
||||
public function testPortes()
|
||||
{
|
||||
global $indexDevices;
|
||||
logger(DEBUG, _("Function alerte_intrusion->testPorte"), __FILE__ . ":" . __LINE__);
|
||||
|
||||
$msg = "";
|
||||
foreach ($this->devicelist as $device => $property)
|
||||
{
|
||||
if($indexDevices[$device]->properties[$property] != false)
|
||||
{
|
||||
$msg .= $indexDevices->friendlyName . " is open" . EOL;
|
||||
$msg .= $indexDevices[$device]->friendlyName . " is open" . EOL;
|
||||
}
|
||||
}
|
||||
if ($msg != "")
|
||||
if (!empty($msg))
|
||||
{
|
||||
logger(ALERT, $msg, __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
return nl2br($msg);
|
||||
}
|
||||
}
|
||||
|
||||
$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);
|
||||
|
||||
?>
|
||||
|
@ -237,7 +237,7 @@ class rdc_store extends hook
|
||||
}
|
||||
}
|
||||
|
||||
private function send($level)
|
||||
private function send($level, $method)
|
||||
{
|
||||
global $indexDevices;
|
||||
$deviceObject = $indexDevices[RDC_STORE];
|
||||
|
@ -31,16 +31,16 @@ class rdc_wc_eclairage extends hook
|
||||
if ($targetDevice->properties["state_l2"]["method"] == IDLE)
|
||||
{
|
||||
$targetDevice->properties["state_l2"]["method"] = MANUAL;
|
||||
setDelay($device, $this->delayManual, $this->timeUnit, "state_l2", "OFF", true);
|
||||
setDelay($targetDevice, $this->delayManual, $this->timeUnit, "state_l2", "OFF", true);
|
||||
}
|
||||
}elseif ($value == "OFF")
|
||||
{
|
||||
$targetDevice->properties["state_l2"]["method"] = IDLE;
|
||||
removeEvent($device, "state_l2", "OFF");
|
||||
removeEvent($targetDevice, "state_l2", "OFF");
|
||||
}
|
||||
break;
|
||||
case "occupancy":
|
||||
logger(DEBUG, "CASE: occupancy", __FILE__ . ":" . __LINE__);
|
||||
logger(DEBUG, "CASE: WC occupancy", __FILE__ . ":" . __LINE__);
|
||||
logger(DEBUG, "method =" . $targetDevice->properties["state_l2"]["method"], __FILE__ . ":" . __LINE__);
|
||||
if ($value === true and $targetDevice->properties["state_l2"]["method"] == IDLE)
|
||||
{
|
||||
@ -50,7 +50,7 @@ class rdc_wc_eclairage extends hook
|
||||
{
|
||||
//$targetDevice->properties["state_l2"]["method"] = IDLE;
|
||||
//$this->send($targetDevice, "OFF");
|
||||
setDelay($device, $this->delay, $this->timeUnit, "state_l2", "OFF", true, IDLE);
|
||||
setDelay($targetDevice, $this->delay, $this->timeUnit, "state_l2", "OFF", true, IDLE);
|
||||
}
|
||||
}
|
||||
logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, bool2string($value)), __FILE__ . ":" . __LINE__);
|
||||
|
37
moha.php
37
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
|
||||
@ -64,13 +64,13 @@ if (!init()) exit(1);
|
||||
bindtextdomain("moha", "./locale");
|
||||
textdomain("moha");
|
||||
|
||||
function notify($message)
|
||||
function notify($message, $destinataire=NOTIF_DEFAULT_DEST)
|
||||
{
|
||||
global $notificationMethods;
|
||||
$result = false;
|
||||
foreach($notificationMethods as $value)
|
||||
{
|
||||
$result = $result | $value->send($message);
|
||||
$result = $result | $value->send($message, $destinataire);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
@ -95,8 +95,10 @@ function logger($level, $log, $pos = "", $notif = true)
|
||||
if(notify("Moha\n" . $logString) === false)
|
||||
{
|
||||
logger(INFO, _("Notification not sent"), __FILE__ . ":" . __LINE__, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function init()
|
||||
@ -200,6 +202,18 @@ require "events.php";
|
||||
require "db_functions.php";
|
||||
require "apiserver/apiserver.php";
|
||||
|
||||
logger(DEBUG, _("Loading stored events datas from ") . $dataPath . "events.db", __FILE__ . ":" . __LINE__);
|
||||
if (file_exists($dataPath . "events.db"))
|
||||
{
|
||||
if (($db = loadDB($dataPath . "events.db")) === false)
|
||||
{
|
||||
logger(ERROR, _("Can not load events db"), __FILE__ . ":" . __LINE__);
|
||||
}else
|
||||
{
|
||||
$events = $db;
|
||||
}
|
||||
|
||||
}
|
||||
// topics definition
|
||||
listHooks("./topics_callbacks", $topicsCallbacks);
|
||||
if (!empty($topicsCallbacks))
|
||||
@ -236,6 +250,11 @@ if (file_exists($dataPath . "topics.db"))
|
||||
}else
|
||||
{
|
||||
$topics = $db;
|
||||
foreach($topics as $topicName => $topic )
|
||||
{
|
||||
$topic->notificationSent = false;
|
||||
logger(DEBUG, "topic: " . $topicName . " is " . bool2string($topic->notificationSent));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -253,18 +272,7 @@ if (file_exists($dataPath . "devices.db"))
|
||||
}
|
||||
}
|
||||
|
||||
logger(DEBUG, _("Loading stored events datas from ") . $dataPath . "events.db", __FILE__ . ":" . __LINE__);
|
||||
if (file_exists($dataPath . "events.db"))
|
||||
{
|
||||
if (($db = loadDB($dataPath . "events.db")) === false)
|
||||
{
|
||||
logger(ERROR, _("Can not load events db"), __FILE__ . ":" . __LINE__);
|
||||
}else
|
||||
{
|
||||
$events = $db;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Program start
|
||||
logger(DEBUG, _("Program start"), __FILE__ . ":" . __LINE__, false);
|
||||
@ -338,6 +346,7 @@ while (true)
|
||||
//logger(DEBUG, _("looping"), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
checkEvents();
|
||||
checkTopicsAvailability();
|
||||
if ($apiServerIsActive) apiServer($read);
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ function linky2mqttCallback($topic, $message)
|
||||
{
|
||||
global $topics, $logFh, $devices, $included;
|
||||
$topicName = $topic[0];
|
||||
$topics[$topicName]->lastSeen = time();
|
||||
$friendlyName = $topic[1]; // get friendlyName
|
||||
logger(INFO, sprintf(_("Incoming notification of device %s"), $topicName, $fn), __FILE__ . ":" . __LINE__);
|
||||
$payloadArray = json_decode($message->payload, true);
|
||||
@ -36,4 +37,6 @@ function linky2mqttCallback($topic, $message)
|
||||
//print_r($device["device"]);
|
||||
}
|
||||
$topics["linky2mqtt"]->callback = "linky2mqttCallback";
|
||||
$topics["linky2mqtt"]->timeOut = 3; // timeOut in minutes
|
||||
$topics["linky2mqtt"]->lastSeen = time();
|
||||
?>
|
||||
|
@ -4,7 +4,7 @@ if (!array_key_exists("pws2mqtt", $devices)) $devices["pws2mqtt"] = array();
|
||||
|
||||
function pws2mqttCallback($topic, $message)
|
||||
{
|
||||
global $logFh, $devices, $included;
|
||||
global $logFh, $devices, $included, $topics;
|
||||
$topicName = $topic[0];
|
||||
$fn = $topic[1];
|
||||
logger(INFO, sprintf(_("Incoming notification of device %s => friendly name : %s"), $topicName, $fn), __FILE__ . ":" . __LINE__);
|
||||
@ -30,6 +30,7 @@ function pws2mqttCallback($topic, $message)
|
||||
{
|
||||
$device = &$device[$fn];
|
||||
}
|
||||
$topics[$topicName]->lastSeen = time();
|
||||
unset($payloadArray["friendly_name"]);
|
||||
unset($payloadArray["ieeeAddress"]);
|
||||
unset($payloadArray["type"]);
|
||||
@ -60,6 +61,8 @@ function pws2mqttCallback($topic, $message)
|
||||
}
|
||||
};
|
||||
$topics["pws2mqtt"]->callback = "pws2mqttCallback";
|
||||
$topics["pws2mqtt"]->timeOut = 3; //timeOut in minutes
|
||||
$topics["pws2mqtt"]->lastSeen = time();
|
||||
|
||||
if (!is_callable("pws2mqttGetList"))
|
||||
{
|
||||
|
@ -7,6 +7,7 @@ function zigbee2mqttCallback($topic, $message)
|
||||
{
|
||||
global $topics, $devices, $included, $logFh, $indexFriendlyNames, $devicesRequest;
|
||||
|
||||
$topics[$topic[0]]->lastSeen = time();
|
||||
if ($topic[1] == "bridge")
|
||||
{
|
||||
switch ($topic[2])
|
||||
@ -117,5 +118,6 @@ function zigbee2mqttCallback($topic, $message)
|
||||
};
|
||||
|
||||
$topics["zigbee2mqtt"]->callback = "zigbee2mqttCallback";
|
||||
|
||||
$topics["zigbee2mqtt"]->timeOut = 3;
|
||||
$topics["zigbee2mqtt"]->lastSeen = time();
|
||||
?>
|
||||
|
21
utils.php
21
utils.php
@ -16,6 +16,27 @@
|
||||
print ("MOHA-" . $logString . EOL);
|
||||
}
|
||||
}*/
|
||||
|
||||
function checkTopicsAvailability()
|
||||
{
|
||||
global$topics;
|
||||
foreach($topics as $topicName => $topic)
|
||||
{
|
||||
if ($topic->status == 1)
|
||||
{
|
||||
logger(DEBUG, "time is " . time() . " lastSeen is " . $topic->lastSeen, __FILE__ . ":" . __LINE__ );
|
||||
|
||||
if ((time() - $topic->lastSeen > $topic->timeOut*60) and ($topic->notificationSent == false))
|
||||
{
|
||||
if (logger(ALERT, $topicName . _(" is not available"), __FILE__ . ":" . __LINE__) == false);
|
||||
{
|
||||
$topic->notificationSent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testActionneurs(array $actionneurs)
|
||||
{
|
||||
global $indexDevices;
|
||||
|
Loading…
Reference in New Issue
Block a user