1
0
This commit is contained in:
daniel Tartavel 2022-02-23 10:23:16 +01:00
parent 7d1dd25f2a
commit 34dca81ba5
21 changed files with 738 additions and 533 deletions

View File

@ -35,27 +35,26 @@ class db extends mysqli
return $this->real_escape_string($string);
}
function logProperty($device, $propertyTree, $value, $oldValue = 0)
function logProperty($device, $property, $value, $oldValue = 0)
{
global $mohaDB, $properties2log, $testMode;
$precision = 0;
//echo "############## logProperty ################\nproperty => " . $propertyTree .EOL;
if (array_key_exists($propertyTree, $properties2log))
if (array_key_exists($property, $properties2log))
{
//echo "logging in database";
$ieeeAddress = $device->ieeeAddress;
//print_r($ieeeAddress);
$query = "INSERT INTO logs (device, property, value) VALUES('" . $this->protect($ieeeAddress) . "', '" . $this->protect($propertyTree) . "', '" . $this->protect($value) . "')";
if (is_numeric($value) and !empty($properties2log[$propertyTree]))
$query = "INSERT INTO logs (device, property, value) VALUES('" . $this->protect($ieeeAddress) . "', '" . $this->protect($property) . "', '" . $this->protect($value) . "')";
echo $query;
if (is_numeric($value) and !empty($properties2log[$property]))
{
// calculate a min/max value for storing data
$minMax = $properties2log[$propertyTree];
$minMax = $properties2log[$property];
if (is_callable($minMax))
{
$minMax = $minMax($value);
}
//echo "minMax = " .$minMax . EOL;
//echo "oldValue = " . $oldValue . EOL;
//echo "Value = " . $value . EOL;
@ -75,7 +74,7 @@ class db extends mysqli
logger(ERROR, _("mysql query errror: ") . $this->error, __FILE__ . ":" . __LINE__);
}
}
logger(INFO, sprintf(_("New value (%s) of property: '%s' of device: %s stored in database"), bool2string($value), $propertyTree, $device->friendlyName), __FILE__ . ":" . __LINE__);
logger(INFO, sprintf(_("New value (%s) of property: '%s' of device: %s stored in database"), bool2string($value), $property, $device->friendlyName), __FILE__ . ":" . __LINE__);
}
}
}

View File

@ -33,7 +33,7 @@ class hook
if (isset($indexDevices[$ieeeAddress]))
{
$property = $property2change[0];
$indexDevices[$ieeeAddress]->$property["functions"][] = array($this,"callback");
$indexDevices[$ieeeAddress]->properties[$property]["functions"][] = array($this,"callback");
$property2change[1] = true;
logger(DEBUG, sprintf(_("Property '%s' is initialized with callback"), $property2change[0]), __FILE__ . ":" . __LINE__);
}else

View File

@ -4,8 +4,8 @@
define("EOL", "\n");
define("EOLR", "\n\r");
define("Z2M", "zigbee2mqtt");
define("ON", 1);
define("OFF", 0);
define("ON", true);
define("OFF", false);
define("AUTO", 0);
define("MANUAL", 1);

View File

@ -26,9 +26,10 @@ function mkDevicesDB($topic, $json, $group=false)
{
$devices[$topic]= array();
}
//print_r($json);
foreach ($json as $jsonDevice)
{
//print_r($device);
$fn = $jsonDevice->friendly_name;
$fnTree = explode("/", $fn);
$device = & $devices[$topic];
@ -55,7 +56,7 @@ function mkDevicesDB($topic, $json, $group=false)
$indexFriendlyNames[$fn] = & $device["device"];
}else
{
addDevice($device, $fn, $jsonDevice);
addDevice($device["device"], $fn, $jsonDevice);
}
}
$dbInit += 1;
@ -70,45 +71,71 @@ function mkDevicesDB($topic, $json, $group=false)
function addDevice(& $device, $fn, $jsonDevice )
{
global $listProperties, $listPropertiesKeys, $hooks, $indexDevices, $indexFriendlyNames;
$device["device"]->type = $jsonDevice->type;
$device["device"]->ieeeAddress = $jsonDevice->ieee_address;
$device->type = $jsonDevice->type;
$device->ieeeAddress = $jsonDevice->ieee_address;
if ( !empty($jsonDevice->power_source ) )
{
$device["device"]->powerSource = $jsonDevice->power_source;
$device->powerSource = $jsonDevice->power_source;
}
if ($jsonDevice->definition != null)
{
$device["device"]->description = $jsonDevice->definition->description;
searchPropertyKey($fn, $device["device"], $jsonDevice->definition->exposes, $listPropertiesKeys);
$device->description = $jsonDevice->definition->description;
searchPropertyKey($fn, $device, $jsonDevice->definition->exposes, $listPropertiesKeys);
}
searchPropertyValue($fn, $device["device"], $jsonDevice, $listProperties);
searchPropertyValue($fn, $device, $jsonDevice, $listProperties);
//indexing device
$indexDevices[$device["device"]->ieeeAddress] = & $device["device"];
$indexFriendlyNames[$fn] = & $device["device"];
$indexDevices[$device->ieeeAddress] = & $device;
$indexFriendlyNames[$fn] = & $device;
}
function searchPropertyKey($fn, &$device, $object, $listPropertiesKeys)
function searchPropertyKey($fn, &$device, $inputObject, $listPropertiesKeys)
{
foreach($listPropertiesKeys as $property)
//foreach($listPropertiesKeys as $propertyKey)
//{
logger(DEBUG, _("searching for property"), __FILE__ . ":" . __LINE__ );
if (is_object($inputObject))
{
foreach($object as $key => $value)
if (property_exists($inputObject, "property"))
{
if (gettype($value) == "object" or gettype($value) == "array")
{
searchPropertyKey($fn, $device, $value, $listPropertiesKeys);
}
if ( isset($value->property))
{
$string = $value->property;
logger(DEBUG, _("propertyKey exists filling properties"), __FILE__ . ":" . __LINE__ );
$string = $inputObject->property;
$device->properties[$string]["value"] = null;
$device->properties[$string]["functions"] = array();
foreach($inputObject as $key2 => $value2)
{
if ($key2 != "property")
{
$device->properties[$string][$key2] = $value2;
logger(DEBUG, sprintf(_("property %s value %s"), $key2, print_r($device->properties[$string][$key2])), __FILE__ . ":" . __LINE__ );
}
}
}else
{
if (property_exists($inputObject, "type"))
{
$device->type = $inputObject->type;
}
foreach($inputObject as $key => $value)
{
logger(DEBUG, sprintf(_("key = %s"), $key), __FILE__ . ":" . __LINE__ );
searchPropertyKey($fn, $device, $value, $listPropertiesKeys);
}
}
//print_r($device);
}elseif (is_array($inputObject))
{
foreach($inputObject as $value)
{
logger(DEBUG, _("value is object or group, iterating"), __FILE__ . ":" . __LINE__ );
searchPropertyKey($fn, $device, $value, $listPropertiesKeys);
}
}
}
function searchPropertyValue($fn, &$device, $object, $listProperties)
{
$objectArray = (array)$object;
@ -143,18 +170,20 @@ function iterateDevice($topic, $fn, $parentDevice, &$device, $payloadArray, $pro
global $changed, $mohaDB, $testMode;
$deviceType = (is_a($device, "device")); // = true if object
//echo "==================== New iterate =====================" .EOL;
//echo "devicetype = "; var_dump($deviceType); echo EOL;
//echo "deviceType = "; var_dump($deviceType); echo EOL;
//echo "device =>";print_r($device);echo EOL;
//echo "PropertyTree ==============> " . $propertyTree . EOL;
foreach($payloadArray as $key => $value)
{
$oldValue = null;
//echo "key =>"; print_r($key); echo EOL;
//echo "value =>"; print_r($value); echo EOL;
//echo "value =>"; var_dump($value); echo EOL;
//echo "type : " . gettype($value) .EOL;
$valueType = gettype($value);
if ($valueType == "object")
{
//logger(DEBUG, _("valueType == object"), __FILE__ . ":" . __LINE__);
$propertyTree .= $key . "/";
//echo "PropertyTree " . $propertyTree . EOL;
//echo " is Object" . EOL;
@ -170,98 +199,195 @@ function iterateDevice($topic, $fn, $parentDevice, &$device, $payloadArray, $pro
//echo "===============>";
iterateDevice($topic, $fn, $parentDevice, $device->properties[$key], $value, $propertyTree);
}else
}elseif(is_array($device))
{
//echo "is array";
if (!array_key_exists($key, $device->properties))
if (!array_key_exists($key, $device))
{
$device->properties[$key] = new stdClass;
$device[$key] = new stdClass;
}
//echo "iterating" . EOL;
iterateDevice($topic, $fn, $parentDevice, $device->properties[$key], $value, $propertyTree);
iterateDevice($topic, $fn, $parentDevice, $device[$key], $value, $propertyTree);
}elseif(is_object($device))
{
if (!property_exists($device, $key))
{
$device->$key = new stdClass;
}
iterateDevice($topic, $fn, $parentDevice, $device->$key, $value, $propertyTree);
}
}elseif ($valueType == "array")
{
//logger(DEBUG,_("valueType == array"), __FILE__ . ":" . __LINE__);
$propertyTree .= $key . "/";
if ($deviceType === true )
{
$device->properties[$key] = array();
iterateDevice($topic, $fn, $parentDevice, $device->properties[$key], $value, $propertyTree);
}else
}elseif(is_array($device))
{
$device->properties[$key] = array();
iterateDevice($topic, $fn, $parentDevice, $device->properties[$key], $value, $propertyTree);
$device[$key] = array();
iterateDevice($topic, $fn, $parentDevice, $device[$key], $value, $propertyTree);
}elseif(is_object($device))
{
$device->$key = array();
iterateDevice($topic, $fn, $parentDevice, $device->$key, $value, $propertyTree);
}
}else
{
//logger(DEBUG,_("valueType is ") . $valueType, __FILE__ . ":" . __LINE__);
//var_dump($device);echo EOL;
//if (empty($device->$key) or $value != null)
//{
if (is_a($device, "device"))
{
//logger(DEBUG,_("This is an object 'device'"), __FILE__ . ":" . __LINE__);
if(array_key_exists($key, $device->properties))
{
if ($device->properties[$key]["value"] != $value)
{
changeValue($device->properties[$key]["value"], $value, $parentDevice, $propertyTree, $key);
}
}else
{
$device->properties[$key] = array("value" => $value);
$device->properties[$key]["functions"] = array();
}
}elseif (is_array($device))
{
//logger(DEBUG,_("deviceType") . $deviceType, __FILE__ . ":" . __LINE__);
if (array_key_exists($key, $device))
{
if (is_array($device[$key]))
{
if ($device[$key]["value"] != $value)
{
changeValue($device->$key["value"], $value, $parentDevice, $propertyTree, $key);
}
}else
{
changeValue($device[$key], $value, $parentDevice, $propertyTree, $key);
}
}else
{
$device[$key] = array("value" => $value);
$device[$key]["functions"] = array();
}
}elseif (is_object($device))
{
if(property_exists($device, $key))
{
if (is_array($device->$key))
{
$oldValue = $device->$key["value"];
}else
if ($device->$key["value"] != $value)
{
$oldValue = $device->$key;
changeValue($device->$key["value"], $value, $parentDevice, $propertyTree, $key);
}
}else
{
$device->$key = array("value" => null);
if ($device->$key != $value)
{
changeValue($device->$key, $value, $parentDevice, $propertyTree, $key);
}
}
}else
{
$device->$key = array("value" => $value);
$device->$key["functions"] = array();
}
//echo $key . ' ===> oldvalue = ' . $oldValue . " value = " . $value . EOL;
if ($oldValue !== $value)
{
$device->$key["value"] = $value;
//$changed[$fn]["key"] = $key;
//$changed[$fn]["value"] = $value;
logger(INFO, sprintf(_("Device %s property %s, %s"), $fn, $propertyTree . $key, bool2string($value)), __FILE__ . ":" . __LINE__);
$mohaDB->logProperty($parentDevice, $propertyTree . $key, $value, $oldValue);
if (!empty($device->$key["functions"]))
{
logger(DEBUG,_("executing notifications functions"), __FILE__ . ":" . __LINE__);
foreach($device->properties[$key]["functions"] as $function)
{
$function($device, $key, $value);
}
}
}
//}
}
}
}
function getDevicesValues($topic)
{
global $indexDevices, $topics;
logger(DEBUG, _("getDevicesValues function" ));
logger(DEBUG, _("getDevicesValues function" ), __FILE__ . ":" . __LINE__ );
foreach($indexDevices as $device)
{
if ($device->topic == $topic)
{
logger(DEBUG, "device: " . $device->friendlyName);
$payload = "{";
logger(DEBUG, "device: " . $device->friendlyName, __FILE__ . ":" . __LINE__ );
$device->payload = array();
$flag = false;
//$properties = array_slice($device, 12);
//logger(DEBUG, print_r($properties, true));
if (!empty($device->properties))
{
foreach($device->properties as $property => $value)
{
if ($flag)
{
$payload .= ",";
}else {
$flag = true;
$device->payload[$property] = "";
}
$payload .= '"' . $property . '":""';
}
$device->payload = $payload . "}";
logger(DEBUG, $device->payload);
//logger(DEBUG, print_r($device->payload, true), __FILE__ . ":" . __LINE__ );
$device->get();
}else
{
logger(DEBUG, _("no properties to get for device: " . $device->friendlyName ), __FILE__ . ":" . __LINE__ );
}
}
}
}
function getDeviceByFriendlyname(&$device, $topic, $fn, $payloadArray, $create = false)
{
global $devices, $indexDevices, $indexFriendlyNames;
$n = explode("/", $fn);
//echo "topic => ". $topic . EOL;
$device = &$devices[$topic];
foreach($n as $value)
{
//print_r($device[$value]);
if (array_key_exists($value, $device))
{
$device = &$device[$value];
}elseif($create === true)
{
$device[$value] = array();
$device = &$device[$value];
}else
{
logger(ERROR, sprintf(_(" device with friendlyname %s not found"), $fn), __FILE__ . ":" . __LINE__);
return false;
}
}
if (! array_key_exists("device", $device))
{
if ($create === true)
{
logger(WARNING, _("init of ") . $fn, __FILE__ . ":" . __LINE__);
$device["device"] = new device;
$device["device"]->type = $payloadArray->type;
$device["device"]->ieeeAddress = $payloadArray->ieeeAddress;
$device["device"]->friendlyname = $fn;
$indexDevices[$device["device"]->ieeeAddress] = & $device["device"];
$indexFriendlyNames[$fn] = & $device["device"];
}
}else
{
logger(INFO, sprintf(_(" device with friendlyname %s exists"), $fn), __FILE__ . ":" . __LINE__);
}
return true;
}
function changeValue(&$oldValue, $value, &$parentDevice, $propertyTree, $key)
{
global $mohaDB;
$object = $parentDevice->properties[$key];
//$changed[$fn]["key"] = $key;
//$changed[$fn]["value"] = $value;
logger(INFO, sprintf(_("Logging Device %s property %s, %s"), $parentDevice->friendlyName, $propertyTree . $key, bool2string($value)), __FILE__ . ":" . __LINE__);
$mohaDB->logProperty($parentDevice, $key, $value, $oldValue);
$oldvalue = $value;
if (!empty($object["functions"]))
{
logger(DEBUG,_("executing notifications functions"), __FILE__ . ":" . __LINE__);
foreach($object["functions"] as $function)
{
$function($parentDevice, $key, $value);
}
}
}

View File

@ -23,7 +23,7 @@ class <name_of_class> extends hook
{
// here your code
logger (INFO,sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, $value), __FILE__ . ":" . __LINE__);
logger (INFO,sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, bool2string($value)), __FILE__ . ":" . __LINE__);
}
}

View File

@ -56,20 +56,20 @@ function checkEvents()
$logLevel = $oldLevel;
}
function setOneshotEvent(&$device, $datetime, $property, $value, $replace=false)
function setOneshotEvent(&$deviceObject, $datetime, $property, $value, $replace=false)
{
global $events;
$events[] = new event;
$key = key($events);
$events[$key]->dateTimeEvent = new dateTime($datetime);
$events[$key]->ieeeAddress = $device->ieeeAddress;
$events[$key]->topic = $device->topic;
$events[$key]->ieeeAddress = $deviceObject->ieeeAddress;
$events[$key]->topic = $deviceObject->topic;
$events[$key]->param = $property;
$events[$key]->value = $value;
$events[$key]->device = & $device;
$events[$key]->device = & $deviceObject;
}
function setRecurrentEvent(&$device, $property, $value, $startDatetime, $stopDatetime, $hours, $minutes, $seconds, $days, $weeks, $months, $years)
function setRecurrentEvent(&$deviceObject, $property, $value, $startDatetime, $stopDatetime, $hours, $minutes, $seconds, $days, $weeks, $months, $years)
{
global $events;
$string = "P";
@ -87,9 +87,9 @@ function setRecurrentEvent(&$device, $property, $value, $startDatetime, $stopDat
$event->recurrenceInterval = new DateInterval($string);
$event->startDatetime = new datetime($startDatetime);
$event->stopDatetime = new datetime($stopDatetime);
$event->ieee_address = $device->ieeeAddress;
$event->topic = $device->topic;
$event->device = & $device;
$event->ieee_address = $deviceObject->ieeeAddress;
$event->topic = $deviceObject->topic;
$event->device = & $deviceObject;
$event->param = $property;
$event->value = $value;
$event->dateTimeEvent = $event->startDatetime;
@ -100,7 +100,7 @@ function setRecurrentEvent(&$device, $property, $value, $startDatetime, $stopDat
}
}
function setDelay(&$device, $delay, $unit="second", $property, $value, $replace=false)
function setDelay(&$deviceObject, $delay, $unit, $property, $value, $replace=false)
{
global $events, $logLevel;
$oldLevel = $logLevel;
@ -142,40 +142,40 @@ function setDelay(&$device, $delay, $unit="second", $property, $value, $replace=
//print_r($datetime);
if ($replace)
{
$eventKey = searchEvent($device, $property, $value);
$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 = $device->ieeeAddress;
$events[$key]->topic = $device->topic;
$events[$key]->ieeeAddress = $deviceObject->ieeeAddress;
$events[$key]->topic = $deviceObject->topic;
$events[$key]->param = $property;
$events[$key]->value = $value;
$events[$key]->device = & $device;
$events[$key]->device = & $deviceObject;
logger (DEBUG, _('Setting new delay in $events[]'), __FILE__ . ":" . __LINE__);
print_r($events[$key]);
//print_r($events[$key]);
$loglevel = $oldLevel;
}
function removeEvent($device, $property , $value)
function removeEvent($deviceObject, $property , $value)
{
if (($eventKey = searchEvent($device, $property , $value)) === true)
if (($eventKey = searchEvent($deviceObject, $property , $value)) === true)
{
deleteEvent($eventKey);
}
}
function searchEvent($device, $property , $value)
function searchEvent($deviceObject, $property , $value)
{
global $events;
logger(DEBUG, sprintf(_("searching event for device %s, property %s and value %s"), $device->friendlyName, $property, bool2string($value)), __FILE__ . ":" . __LINE__);
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 == $device->topic and $event->param == $property and $event->value == $value and $event->ieeeAddress == $device->ieeeAddress)
if($event->topic == $deviceObject->topic and $event->param == $property and $event->value == $value and $event->ieeeAddress == $deviceObject->ieeeAddress)
{
//echo "==============================\nfound " . $key . "\n=================================" . EOL;
return $key;

View File

@ -12,7 +12,7 @@ class etage_plan_travail_eclairage extends hook
// $device -> calling device
// $property -> property of the device (given by mqtt)
// $value -> value of the property
public function callBack(&$device, $property, $value)
public function callBack($device, $property, $value)
{
// here your code
if($value == "ON") // ON

View File

@ -19,38 +19,40 @@ class rdc_chambre_eclairage extends hook
// $device -> calling device
// $property -> property of the device (given by mqtt)
// $value -> value of the property
public function callBack(&$device, $property, $value)
public function callBack($device, $property, $value)
{
global $devices, $indexDevices;
$lux = $indexDevices[RDC_CHAMBRE_LUMINOSITE]->illuminance_lux;
$lux = $indexDevices[RDC_CHAMBRE_LUMINOSITE]->properties["illuminance_lux"];
$targetAmbiance = $indexDevices[RDC_CHAMBRE_AMBIANCE];
$targetEclairage = $indexDevices[RDC_CHAMBRE_ECLAIRAGE];
if ($property == "occupancy" and $value == "ON")
{
$this->send(RDC_CHAMBRE_AMBIANCE, "ON", "OFF", AUTO);
$this->send($targetAmbiance, "ON", "OFF", AUTO);
}elseif ($property == "contact" and $value = true and getValue(RDC_CHAMBRE_ECLAIRAGE, "state_l1") == "OFF")
{
$this->send(RDC_CHAMBRE_ECLAIRAGE, "ON", "OFF", AUTO);
$this->send($targetEclairage, "ON", "OFF", AUTO);
}
logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, bool2string($value)), __FILE__ . ":" . __LINE__);
}
private function send($device, $state, $delayState = false, $method = MANUAL)
private function send($deviceObject, $state, $delayState = false, $method = MANUAL)
{
global $devices, $indexDevices;
$device = &$indexDevices[$device];
$msg = array("state" => $state);
if ($device->state["value"] != $state)
if ($deviceObject->properties["state"]["value"] != $state)
{
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $device->friendlyName), __FILE__ . ":" . __LINE__);
$device->payload = $msg;
$device->set();
$device->method = $method;
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $deviceObject->friendlyName), __FILE__ . ":" . __LINE__);
$deviceObject->payload = $msg;
$deviceObject->set();
$deviceObject->method = $method;
}else
{
logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $device->friendlyName), __FILE__ . ":" . __LINE__);
logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $deviceObject->friendlyName), __FILE__ . ":" . __LINE__);
}
//echo 'delaystate = ' . var_dump($delayState);
if ($delayState !== false) setDelay($device, $this->delay, $this->timeUnit, "state", $delayState, true);
if ($delayState !== false) setDelay($deviceObject, $this->delay, $this->timeUnit, "state", $delayState, true);
}
}

View File

@ -15,9 +15,8 @@ class alerte_intrusion extends hook
public $timeUnit = "minute"; // unit of time for delay, second, minute, day, week, month, year
// callback fonction. Is called with these 4 parameters
public function callBack(&$device, $param, $value)
public function callBack($device, $param, $value)
{
global $devices, $indexDevices;
switch($param)
{
case "contact":

View File

@ -22,7 +22,10 @@ class rdc_salon_eclairage extends hook
{
global $indexDevices;
logger(INFO, _("hook : rdc_salon_eclairage"), __FILE__ . ":" . __LINE__);
$device = &$indexDevices[RDC_SALON_ECLAIRAGE_PANNEAU];
$deviceTarget = &$indexDevices[RDC_SALON_ECLAIRAGE_PANNEAU];
$lux = $indexDevices[RDC_SALON_LUMINOSITE];
$mvmt = $indexDevices[RDC_SALON_MVMT];
$mvmt2 = $indexDevices[RDC_SALON_MVMT2];
switch($param)
{
case "occupancy":
@ -31,30 +34,30 @@ class rdc_salon_eclairage extends hook
if ($value == ON and getValue(RDC_SALON_LUMINOSITE, "illuminance_lux") <= $this->luminance_min)
{
logger(DEBUG, _("setting to ON"), __FILE__ . ":" . __LINE__);
$this->send("ON", null, AUTO);
removeEvent($device, "state", "OFF");
$this->send($deviceTarget, "ON", null, AUTO);
removeEvent($deviceTarget, "state", "OFF");
}elseif ($value == OFF)
{
logger(DEBUG, _("Value is OFF"), __FILE__ . ":" . __LINE__);
if (getValue(RDC_SALON_MVMT, "occupancy") == OFF and (getValue(RDC_SALON_MVMT2, "occupancy") == OFF))
{
logger(DEBUG, _("Setting to OFF"), __FILE__ . ":" . __LINE__);
setDelay($device, $this->delay, $this->timeUnit, "state", "OFF", true);
//$this->send("ON", "OFF", AUTO);
setDelay($deviceTarget, $this->delay, $this->timeUnit, "state", "OFF", true);
//$this->send($deviceTarget, "ON", "OFF", AUTO);
}
}
break;
case "contact":
logger(DEBUG, _("CASE: Contact Door"), __FILE__ . ":" . __LINE__);
if ($value == false and getValue(RDC_SALON_LUMINOSITE, "illuminance_lux") <= $this->luminance_min and getValue(RDC_SALON_ECLAIRAGE_PANNEAU, "state") == "OFF")
if ($value == false and getValue(RDC_SALON_LUMINOSITE, "illuminance_lux") <= $this->luminance_min and getValue($deviceTarget->ieeeAddress, "state") == "OFF")
{
logger(DEBUG, _("Door is open and illumance < min"), __FILE__ . ":" . __LINE__);
if (getValue(RDC_SALON_MVMT, "occupancy") == ON or getValue(RDC_SALON_MVMT2, "occupancy") == ON)
{
$this->send("ON", null, AUTO);
$this->send($deviceTarget, "ON", null, AUTO);
}else
{
$this->send("ON", "OFF", AUTO);
$this->send($deviceTarget, "ON", "OFF", AUTO);
}
}
break;
@ -63,39 +66,39 @@ class rdc_salon_eclairage extends hook
if ($value >= $this->luminance_max)
{
logger(DEBUG, _("illuminace is > to max"), __FILE__ . ":" . __LINE__);
//$this->send("OFF", null, AUTO);
//$this->send($deviceTarget, "OFF", null, AUTO);
//removeEvent($indexDevices[RDC_SALON_ECLAIRAGE_PANNEAU], "state", "OFF");
if (searchEvent($device, "state", "OFF") === false)
if (searchEvent($deviceTarget, "state", "OFF") === false)
{
setDelay($device, $this->delay, $this->timeUnit, "state", "OFF", true);
setDelay($deviceTarget, $this->delay, $this->timeUnit, "state", "OFF", true);
}
}elseif ($value <= $this->luminance_min and (getValue(RDC_SALON_MVMT, "occupancy") == ON OR getValue(RDC_SALON_MVMT2,"occupancy") == ON))
{
logger(DEBUG, _("illuminance < min and movement detected"), __FILE__ . ":" . __LINE__);
$this->send("ON", null, AUTO);
$this->send($deviceTarget, "ON", null, AUTO);
}
break;
}
logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $param, bool2string($value)), __FILE__ . ":" . __LINE__);
}
private function send($state, $delayState = false, $method = MANUAL)
private function send(&$deviceTarget, $state, $delayState = false, $method = MANUAL)
{
global $indexDevices;
$device = & $indexDevices[RDC_SALON_ECLAIRAGE_PANNEAU];
$msg = array("state" => $state);
if ($device->state["value"] != $state)
if ($deviceTarget->properties["state"]["value"] != $state)
{
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $device->friendlyName), __FILE__ . ":" . __LINE__);
$device->payload = $msg;
$device->set();
$device->method = $method;
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $deviceTarget->friendlyName), __FILE__ . ":" . __LINE__);
$deviceTarget->payload = $msg;
$deviceTarget->set();
$deviceTarget->method = $method;
}else
{
logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $device->friendlyName), __FILE__ . ":" . __LINE__);
logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $deviceTarget->friendlyName), __FILE__ . ":" . __LINE__);
}
//echo 'delaystate = ' . var_dump($delayState);
if ($delayState !== false) setDelay($device, $this->delay, $this->timeUnit, "state", $delayState, true);
if ($delayState !== false) setDelay($deviceTarget, $this->delay, $this->timeUnit, "state", $delayState, true);
}
}

View File

@ -26,14 +26,16 @@ class rdc_sdb_eclairage extends hook
// callback fonction. Is called with these 3 parameters
public function callBack(&$device, $property, $value)
{
global $devices, $indexDevices;
global $indexDevices;
//var_dump($value);
$deviceTarget = $indexDevices[RDC_SDB_WC_ECLAIRAGE];
switch($property)
{
case "occupancy":
if ($value == ON)
{
if (getValue(RDC_SDB_WC_ECLAIRAGE, "state_l1") != "ON")
if (getValue($deviceTarget->ieeeAddress, "state_l1") != "ON")
{
$this->send("ON");
}
@ -42,13 +44,13 @@ class rdc_sdb_eclairage extends hook
}
break;
case "state_l1":
if ($value == ON)
if ($value == "ON")
{
setDelay($indexDevices[RDC_SDB_WC_ECLAIRAGE], $this->delayManual, $this->timeUnit, "state_l1", "OFF", true);
setDelay($deviceTarget, $this->delay, $this->timeUnit, "state_l1", "OFF", true);
$device->method = MANUAL;
}elseif ($value = OFF)
}elseif ($value = "OFF")
{
removeEvent($indexDevices[RDC_SDB_WC_ECLAIRAGE], "state_l1", "OFF");
removeEvent($deviceTarget, "state_l1", "OFF");
}
break;
}
@ -57,13 +59,12 @@ class rdc_sdb_eclairage extends hook
private function send($state)
{
global $devices, $indexDevices;
global $indexDevices;
$msg = array("state_l1" => $state);
$device = &$indexDevices[RDC_SDB_WC_ECLAIRAGE];
logger(INFO, sprintf(_("publishing message: %s to %s"), $state, $device->friendlyName), __FILE__ . ":" . __LINE__);
$device->payload = $msg;
$device->set(null);
}
}
$hooks["rdc_sdb_eclairage"] = new rdc_sdb_eclairage();

View File

@ -11,9 +11,9 @@ class rdc_wc_eclairage extends hook
public $timeUnit = "minute"; // unit of time for delay, second, minute, day, week, month, year
// callback fonction. Is called with these 4 parameters
public function callBack(&$device, $property, $value)
public function callBack($device, $property, $value)
{
global $devices, $indexDevices;
global $indexDevices;
//var_dump($value);
switch($property)
{

View File

@ -13,7 +13,7 @@ $listProperties = array("powerSource" => "batterie");
$listPropertiesKeys = array("expose");
//global variables
$logLevel = ALL; // INFO | NOTICE | WARNING | ERROR | ALERT; //ALL;
$notificationLevel = ALERT | ERROR;
$topics = array(); // list of topics
$mids = array(); // list of message IDs
@ -39,20 +39,20 @@ $flagHooks = false;
if ($testMode)
{
$logLevel = ALL; // INFO | NOTICE | WARNING | ERROR | ALERT; //ALL;
$mqttServerIp = "192.168.1.253"; // IP address of mqttserver in test mode
$dataPath = ".";
$dataPath = "./";
$logFile = "./moha.log"; // Path of log file
$configDir = "./config"; // default config dir (production value is /etc/moha/)
}else
{
$logLevel = 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
$configDir = "/etc/moha"; // default config dir (production value is /etc/moha/)
}
if (!init()) exit(1);
// gettext
@ -70,7 +70,7 @@ function notify($message)
return $result;
}
function logger($level, $log, $pos = false, $notif = true)
function logger($level, $log, $pos = "", $notif = true)
{
global $logFh, $logLevel, $notificationLevel, $logLevels;
$logString = date("c") . ' ' . $logLevels[$level] . " " ;
@ -100,7 +100,7 @@ function init()
date_default_timezone_set('Europe/Paris');
if (! $logFh = fopen($logFile, "w") )
{
echo _("error opening log file");
echo _("error opening log file in ") . getcwd();
return false;
}
return true;
@ -144,7 +144,7 @@ function endMoha()
$client->disconnect();
while ($connected)
{
if ( $x++ <= 60)
if ( $x++ >= 60)
{
fclose($logFh);
exit (1);
@ -190,9 +190,9 @@ require "config/properties2log.php";
require "mqtt_functions.php";
require "events.php";
require "db_functions.php";
require "webserver.php";
require "webserver/webserver.php";
logger(DEBUG, _("Loading stored devices datas"), __FILE__ . ":" . __LINE__);
logger(DEBUG, _("Loading stored devices datas from ") . $dataPath . "moha.db", __FILE__ . ":" . __LINE__);
if (loadDB($devices, $dataPath . "moha.db") === false)
{
logger(ERROR, _("Can not load device db"), __FILE__ . ":" . __LINE__);
@ -251,6 +251,7 @@ foreach($topics as $name => $topic)
// starting main loop
logger(INFO, _("Starting loop"), __FILE__ . ":" . __LINE__, false);
$oneshot = false;
while (true)
{
$client->loop(); // mqtt server loop()
@ -280,7 +281,7 @@ while (true)
}
if($hooksInitialized == 0) // all hooks are not initialized
{
//$i = 1;
$i = 1;
foreach($hooks as $hookName => $hook)
{
if ($hook->initialized === false)
@ -295,9 +296,9 @@ while (true)
logger(DEBUG, _("All hooks initialized"), __FILE__ . ":" . __LINE__);
$flagHooks = true;
}else // executed when initialization finished
}else // executed when hooks initialization finished but database init not finished
{
logger(DEBUG, _("looping"), __FILE__ . ":" . __LINE__);
//logger(DEBUG, _("looping"), __FILE__ . ":" . __LINE__);
}
checkEvents();

View File

@ -1,25 +1,37 @@
<?php
//TODO to test and debug
$topics["linky2mqtt"] = new topic;
$devices["linky2mqtt"] = array();
$topics["linky2mqtt"]->callback = function($topic, $message)
{
global $topics, $logFh, $devices, $included;
$topicName = $topic[0];
$friendlyName = $topic[1]; // get friendlyName
logger(INFO, sprintf(_("Incoming notification of device %s"), $topic[0], $topic[1]), __FILE__ . ":" . __LINE__);
$device = & $devices[$topic[0]];
$payloadArray = json_decode($message->payload);
if (!isset($device[$fn])) //must not exists, but ...
logger(INFO, sprintf(_("Incoming notification of device %s"), $topicName, $fn), __FILE__ . ":" . __LINE__);
$payloadArray = json_decode($message->payload, true);
if (!array_key_exists($fn, $device))
{
logger(LOG_WARNING, $logFh, _("init of ") . $fn, __FILE__ . ":" . __LINE__);
$device[$fn] = array();
$device[$fn]["device"] = new device;
$device[$fn]["device"]->type = "mesure";
$device[$fn]["device"]->ieeeAddress = $payloadArray["ADSC"];
$indexDevices[$device[$fn]["device"]->ieeeAddress] = & $device[$fn]["device"];
}
echo "initializing $fn";
$device[$fn] = array("device" => new device);
$device = &$device[$fn];
$device["device"]->friendlyName = $payloadArray["friendly_name"];
$device["device"]->ieeeAddress = $payloadArray["ieeeAddress"];
$device["device"]->type = $payloadArray["type"];
$indexDevices[$device["device"]->ieeeAddress] = & $device["device"];
$indexFriendlyNames[$fn] = & $device["device"];
}else
{
$device = &$device[$fn];
}
unset($payloadArray["friendly_name"]);
unset($payloadArray["ieeeAddress"]);
unset($payloadArray["type"]);
//$device = getDeviceByFriendlyname($topicName, $fn, $payloadArray, true);
changeDevice($topicName, $friendlyName, $device["device"], $payloadArray);
//print_r($device["device"]);
}

View File

@ -1,43 +1,56 @@
<?php
$topics["pws2mqtt"] = new topic;
$devices["pws2mqtt"] = array();
$topics["pws2mqtt"]->callback = function($topic, $message)
{
global $topics, $logFh, $devices, $included;
$fn = $topic[1]; // get friendlyname
logger(INFO, sprintf(_("Incoming notification of device %s => friendly name : %s"), $topic[0], $topic[1]), __FILE__ . ":" . __LINE__);
$device = & $devices[$topic[0]];
$payloadArray = json_decode($message->payload);
if (!isset($device[$fn]))
global $logFh, $devices, $included;
$topicName = $topic[0];
$fn = $topic[1];
logger(INFO, sprintf(_("Incoming notification of device %s => friendly name : %s"), $topicName, $fn), __FILE__ . ":" . __LINE__);
$device = & $devices[$topicName];
$payloadArray = json_decode($message->payload, true);
// friendlyname
if (!array_key_exists($fn, $device))
{
logger(WARNING, $logFh, _("init of ") . $fn, __FILE__ . ":" . __LINE__);
$device[$fn] = array();
$device[$fn]["device"] = new device;
$device[$fn]["device"]->type = $payloadArray->type;
$device[$fn]["device"]->ieeeAddress = $payloadArray->ieeeAddress;
$device[$fn]["device"]->friendlyname = $fn;
$indexDevices[$device[$fn]["device"]->ieeeAddress] = & $device[$fn]["device"];
}
echo "initializing $fn";
$device[$fn] = array("device" => new device);
$device = &$device[$fn];
$device["device"]->friendlyName = $payloadArray["friendly_name"];
$device["device"]->ieeeAddress = $payloadArray["ieeeAddress"];
$device["device"]->type = $payloadArray["type"];
$device["device"]->topic = $topicName;
$indexDevices[$device["device"]->ieeeAddress] = & $device["device"];
$indexFriendlyNames[$fn] = & $device["device"];
}else
{
$device = &$device[$fn];
}
unset($payloadArray["friendly_name"]);
unset($payloadArray["ieeeAddress"]);
unset($payloadArray["type"]);
foreach ($payloadArray as $property => $value)
{
$str = substr($property, -1);
if ($str == "f")
{
$newProperty = rtrim($property, "f") . "c";
$payloadArray->{$newProperty} = farenheit2celsius($value);
$payloadArray[$newProperty] = farenheit2celsius($value);
}elseif ($str == "h")
{
$newProperty = substr($property, 0, -3) . "kmh";
$payloadArray->{$newProperty} = mph2kmh($value);
$payloadArray[$newProperty] = mph2kmh($value);
}
if ($property == "baromin")
{
$newProperty = "barominmb";
$payloadArray->{"barominmb"} = millibars($value);
$payloadArray["barominmb"] = millibars($value);
}
}
changeDevice($topic[0], $fn, $device["device"], $payloadArray);
//$device = getDeviceByFriendlyname($topicName, $fn, $payloadArray, true);
changeDevice($topicName, $fn, $device["device"], $payloadArray);
}
?>

View File

@ -1,8 +1,12 @@
<?php
$callback = function($topic, $message)
$topics["zigbee2mqtt"] = new topic;
$devices["zigbee2mqtt"] = array();
$topics["zigbee2mqtt"]->callback = function($topic, $message)
{
global $topics, $logFh, $devices, $included;
global $topics, $devices, $included, $logFh;
if ($topic[1] == "bridge")
{
switch ($topic[2])
@ -13,7 +17,7 @@ $callback = function($topic, $message)
case "devices":
logger(DEBUG,_("Inserting zigbee devices in DB"), __FILE__ . ":" . __LINE__);
$topics[$topic[0]]->devices = json_decode($message->payload);
fwrite($logFh, var_export($topics[$topic[0]]->devices, true));
//fwrite($logFh, var_export($topics[$topic[0]]->devices, true));
mkDevicesDB($topic[0], $topics[$topic[0]]->devices);
getDevicesValues($topic[0]);
break;
@ -40,36 +44,46 @@ $callback = function($topic, $message)
}elseif (($topic[array_key_last($topic)]) != "get" and ($topic[array_key_last($topic)]) != "set" and $included)
{
$topic = explode ("/", $message->topic, 2); // get topic name
$topicName = $topic[0];
$fn = $topic[1];
$device = null;
$fnTree = explode ("/" , $topic[1]); // get friendlyname
echo $topic[0] . " => " . $topic[1] . EOL;
//$devices[$topic[0]][$fnTree[0]]->json = json_decode($message->payload);
if ($fnTree[array_key_last($fnTree)] == "availability")
echo $topicName . " => " . $fn . EOL;
logger(DEBUG, _("end of fnTree = ") . end($fnTree), __FILE__ . ":" . __LINE__);
$fnTreeEnd = end($fnTree);
switch($fnTreeEnd)
{
unset ($fnTree[array_key_last($fnTree)]);
$payloadArray = array("availability" => $message->payload);
case "l1":
case "l2":
$fnTreeEnd = "state_" . $fnTreeEnd;
case "mode":
case "contact":
case "availability":
array_pop ($fnTree);
$fn = implode("/", $fnTree);
$fn = implode("/", $fnTree);
$payloadArray = array($fnTreeEnd => $message->payload);
//TODO payl
$payloadArray = array($fnTreeEnd => $message->payload);
//TODO payload can be a json object
break;
default:
$payloadArray = json_decode($message->payload,true);
}
logger(DEBUG, _("friendlyname = ") . $fn, __FILE__ . ":" . __LINE__);
if ((getDeviceByFriendlyname($device, $topicName, $fn, $payloadArray, true)) === false)
{
logger(ERROR, sprintf(_("device with friendlyname %s not found"), $fn), __FILE__ . ":" . __LINE__);
}
print_r($device);
changeDevice($topicName, $fn, $device["device"], $payloadArray);
}else
{
$payloadArray = json_decode($message->payload);
}
$device = & $devices[$topic[0]];
foreach($fnTree as $fn)
{
//print_r($device) ;
if (!isset($device[$fn])) //must not exists, but ...
{
logger(LOG_WARNING, $logFh, _("init of ") . $fn, __FILE__ . ":" . __LINE__);
$device[$fn] = array();
$device[$fn]["device"] = new device;
addDevice($device[$fn], $fn, $payloadArray);
}
$device = & $device[$fn];
}
changeDevice($topic[0], $topic[1], $device["device"], $payloadArray);
//fwrite($logFh, print_r($msg, true));
logger(DEBUG, _("Zigbee2mqtt doing nothing !?"));
}
};
$topics["zigbee2mqtt"] = new topic;
$topics["zigbee2mqtt"]->callback = & $callback;
?>

View File

@ -9,6 +9,9 @@ function bool2string($var)
}elseif($var === true)
{
return "true";
}elseif ($var === null)
{
return "null";
}else
{
return $var;
@ -72,13 +75,13 @@ function getDevice($topic, $fn)
function getValue($ieeeAddress, $property)
{
global $indexDevices;
return $indexDevices[$ieeeAddress]->$property["value"];
return $indexDevices[$ieeeAddress]->properties[$property]["value"];
}
function setValue($fn, $property, $value)
{
global $indexDevices;
$indexDevices(RDC_SALON_MVMT2)->occupancy["value"] = $value;
$indexDevices[$ieeeAddress]->properties[$property]["value"] = $value;
}
logger(DEBUG, _("signal handling"), __FILE__ . ":" . __LINE__, false);

View File

@ -1,318 +0,0 @@
<?php
// server init: No Timeout
set_time_limit(0);
ob_implicit_flush();
$error_message = null;
$error_code = null;
$listenHost = "0.0.0.0";
$listenPort = 1025;
$Dashboards = array();
require_once $configDir . "/dashboard_conf.php";
require_once "class/main.php";
// opening listening server
$socket = stream_socket_server("tcp://" . $listenHost . ":" . $listenPort, $error_code, $error_message) or logger(ERROR, _("Could not create socket") . EOL);
stream_set_blocking($socket, false);
$read = array( $socket );
function htmlSend($socket, $text)
{
$httpHeader = "HTTP/1.1 200 OK" . EOLR .
"Date: " . date("r") . EOLR .
"Connection: close" . EOLR .
"Content-Type: text/html; charset=UTF-8" . EOLR . EOLR;
$response = $httpHeader . '<!doctype html>' . EOL . '<html lang="fr">' . EOL . '<head>' . EOL . '<meta charset="utf-8">' . EOL . '<title>Moha</title>' . EOL . '</head><body>' . $text . "</body></html>";
stream_socket_sendto($socket, $response);
}
function webListTopics()
{
global $topics;
logger(DEBUG, _("webListTopics function"));
$response = "";
foreach ($topics as $name => $topic)
{
$response .= '<a href="/browse&topic=' . $name . '">' . $name ."</a><br>";
}
return $response;
}
function webBrowse($socket, $argList)
{
global $topics, $devices;
logger(DEBUG, _("Generic response to choose device and property"), __FILE__ . ":" . __LINE__);
//$response = "<html><header></header><body>" . _("unknown command") . "</body></html>";
$response = "";
$flag = false;
if (array_key_exists("topic", $argList))
{
if (array_key_exists($argList["topic"], $topics))
{
logger(DEBUG, _("Topic exists") , __FILE__ . ":" . __LINE__);
$topicRef = '<a href="browse&amp;topic=' . $argList["topic"];
if (array_key_exists("fn", $argList))
{
logger(DEBUG, _("FriendlyName exists: ") . $argList["fn"] , __FILE__ . ":" . __LINE__);
$fn = "";
$fnArray = explode("/", $argList["fn"]);
$device = $devices[$argList["topic"]];
var_dump($fnArray);
foreach($fnArray as $value)
{
if ($flag) $fn .= "/";
$fn .= $value;
if (!array_key_exists($value, $device))
{
htmlSend($socket, sprintf(_('"%s" does not exists')));
return false;
}
$device = $device[$value];
$flag = true;
}
var_dump($device);
if (array_key_exists("device", $device)) // TODO
{
$device = $device["device"];
$fn .= "device/" . $fn;
}
if (is_a($device, "device"))
{
foreach($device as $key => $value)
{
if ($key != "devicarray_key_existse" and is_array($value))
{
//print_r($value);
if (array_key_exists("value", $value))
{
$response .= $key . ' = ' . bool2string($value["value"]) . "<br>";
}else
{
$response .= $key . ' = ' . bool2string($value) . "<br>";
}
}
}
}else
{
foreach($device as $key => $value)
{
$response .= $topicRef . "&amp;fn=" . $fn . "/" . $key . '">' . $key . "</a><br>";
}
}
logger(DEBUG, _("response: ") . EOL . $response , __FILE__ . ":" . __LINE__);
//htmlSend($socket, $response);
}else
{
foreach($devices[$argList["topic"]] as $key => $value)
{
print "key = " . print_r($key, true) . " value = " . print_r($value, true) . EOLR;
logger(DEBUG, _("devices de topic: ") . $key , __FILE__ . ":" . __LINE__);
$response .= $topicRef . "&amp;fn=" . $key . '">' . $key . "</a><br>";
logger(DEBUG, _("response: ") . $response , __FILE__ . ":" . __LINE__);
}
}
}else
{
$response = webListTopics();
}
}else
{
$response = webListTopics();
}
htmlSend($socket, $response);
}
function webDashboard($socket, $n = 0)
{
global $dashboards, $indexDevices;
logger(DEBUG, _("webDashboard function"));
$response = "";
if(array_key_exists($n, $dashboards))
{
foreach ($dashboards[$n] as $ieeeAddress => $property)
{
logger(DEBUG, _($indexDevices[$ieeeAddress]->friendlyName . " => " . bool2string($indexDevices[$ieeeAddress]->$property["value"])));
$response .= $indexDevices[$ieeeAddress]->friendlyName . " => " . bool2string($indexDevices[$ieeeAddress]->$property["value"]) . "<br>";
}
}else
{
$response = _("dashboard not found");
}
htmlSend($socket, $response);
}
function askWebServer($read)
{
global $topics, $indexDevices, $devices;
$array = array();
$argList =array();
if ( stream_select( $read, $array, $array, 0 ))
{
logger(DEBUG, _("socket ready to read"), __FILE__ . ":" . __LINE__);
$spawn = stream_socket_accept($read[0]);
if ($spawn !== false)
{
logger(DEBUG, _("socket accepted"), __FILE__ . ":" . __LINE__);
$input = fgets($spawn, 4096);
logger(DEBUG, $input, __FILE__ . ":" . __LINE__);
$input = substr($input,5);
$input = explode(" ", $input); // suppress text
if (!empty($input[0]))
{
$argTmp = explode("&", urldecode($input[0]));
foreach($argTmp as $tmp)
{
logger(DEBUG, $tmp, __FILE__ . ":" . __LINE__);
if(strpos($tmp, "=") === false)
{
logger(DEBUG, _("no ="), __FILE__ . ":" . __LINE__);
$argList["cmd"] = trim($tmp);
}else
{
$argList[trim(strchr($tmp, "=", true))] = trim(substr(strchr($tmp, "="), 1));
}
}
logger(DEBUG, print_r($argList, true), __FILE__ . ":" . __LINE__);
/*if (array_key_exists("browse", $argList))
{
logger(DEBUG, _("Browsing"));
webBrowse($spawn, $argList);
return true;
}elseif(array_key_exists("dashboard", $argList))
{
webDashboard($spawn, $argList["dashboard"]);
return true;
}*/
if(array_key_exists("cmd", $argList))
{
$command = strtolower($argList["cmd"]);
logger(DEBUG, _("command is ") . $command, __FILE__ . ":" . __LINE__);
switch($command)
{
case "dashboard":
webDashboard($spawn, $argList["dashboard"]);
break;
case "browse":
logger(DEBUG, _("Browsing"), __FILE__ . ":" . __LINE__);
webBrowse($spawn, $argList);
//return true;
break;
case "get":
logger(DEBUG, _("GET reached"), __FILE__ . ":" . __LINE__);
if(!array_key_exists("topic", $argList) or !array_key_exists("fn", $argList) or !array_key_exists("property", $argList))
{
$response = "GET: " . _("no parameters passed, need topic, fn and property");
}else
{
if (($device = getDevice($argList["topic"], $argList["fn"])) === false)
{
htmlSend($spawn, sprintf(_('"%s" or "%s" does not exists'), $argList["topic"], $argList["fn"]));
return false;
}
$property = $argList["property"];
$response = "GET: " . bool2string($device->$property["value"]);
}
htmlSend($spawn, $response);
break;
case "set":
logger(DEBUG, _("SET reached"), __FILE__ . ":" . __LINE__);
if(!array_key_exists("topic", $argList) or !array_key_exists("fn", $argList) or !array_key_exists("property", $argList) or !array_key_exists("value", $argList))
{
$response = "SET: " . _("no parameters passed, need topic, fn, property and value") . "passed";
htmlSend($spawn, $response);
}else
{
$response = "setting property " . $argList["property"] . " of " . $argList["fn"] . " to value: " . $argList["value"];
htmlSend($spawn, $response);
$payload = array($argList["property"] => $argList["value"]);
publish(Z2M . "/" . $argList["fn"], $payload);
}
break;
case "dump":
case "print":
logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__);
if (array_key_exists($argList["object"], $GLOBALS))
{
$var = $GLOBALS[$argList["object"]];
if (isset($argList["topic"]))
{
$topic = $argList["topic"];
}
if (isset($argList["address"]))
{
$var = $var[$argList["address"]];
}elseif (isset($argList["fn"]))
{
if(!empty($topic))
{
$var = getDevice($topic, $argList["fn"]);
}else
{
$str = _("topic is not defining: add &topic=\nThese topics are availables: ");
foreach($topics as $key => $value)
{
$str .= $key . EOL;
}
logger(ERROR, $str, __FILE__ . ":" . __LINE__);
}
}
$error = error_get_last();
if($error !== null)
{
$response = $error["message"] . " file: " . $error["file"] . " line: " . $error["line"];
}
if ($command === "print")
{
$response = "<pre>" . nl2br(print_r($var, true)) . "<pre>";
}elseif($command === "dump")
{
$response = "Dump" . EOL;
$response .= "<pre>" . nl2br(var_export($var, true)) . "<pre>";
}
}else
{
$response = _("Object do not exists");
}
htmlSend($spawn, $response);
break;
case "notify":
logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__);
if (!array_key_exists("topic", $argList) or !array_key_exists("fn", $argList) or !array_key_exists("property", $argList) or !array_key_exists("condition", $argList) or !array_key_exists("value", $argList))
{
$response = _("Error: With 'notify' command, you need 4 parameters: topic, fn, property, condition, value");
htmlSend($spawn, $response);
}else
{
$response = _("notify command have been set");
$monitored[] = new watch($argList["topic"], $argList["fn"], $argList["property"], $argList["condition"], $argList["value"]);
htmlSend($spawn, $response);
}
logger(DEBUG, print_r($monitored, true), __FILE__ . ":" . __LINE__);
break;
default:
webBrowse($spawn, $argList);
}
}else
{
webDashboard($spawn);
}
}else
{
webDashboard($spawn);
}
}
}
}
?>

238
webserver/cmd_functions.php Normal file
View File

@ -0,0 +1,238 @@
<?php
function webDashboard($socket, $n = 0)
{
global $dashboards, $indexDevices;
logger(DEBUG, _("webDashboard function"));
$response = "";
if(array_key_exists($n, $dashboards))
{
foreach ($dashboards[$n] as $ieeeAddress => $property)
{
$value = $indexDevices[$ieeeAddress]->properties[$property]["value"];
if ($value === null)
{
$value ="null";
}
logger(DEBUG, _($indexDevices[$ieeeAddress]->friendlyName . " => " . bool2string($value)));
$response .= $indexDevices[$ieeeAddress]->friendlyName . " => " . bool2string($value) . "<br>";
}
}else
{
$response = _("dashboard not found");
}
htmlSend($socket, $response);
}
function webBrowse($socket, $argList)
{
global $topics, $devices;
logger(DEBUG, _("Generic response to choose device and property"), __FILE__ . ":" . __LINE__);
//$response = "<html><header></header><body>" . _("unknown command") . "</body></html>";
$response = "";
$flag = false;
$tab = "";
if (array_key_exists("topic", $argList))
{
if (array_key_exists($argList["topic"], $topics))
{
logger(DEBUG, _("Topic exists") , __FILE__ . ":" . __LINE__);
$topicRef = '<a href="/?browse&amp;topic=' . htmlentities($argList["topic"]);
if (array_key_exists("fn", $argList))
{
logger(DEBUG, _("FriendlyName exists: ") . $argList["fn"] , __FILE__ . ":" . __LINE__);
$fn = "";
$fnArray = explode("/", $argList["fn"]);
$device = $devices[$argList["topic"]];
//var_dump($fnArray);
foreach($fnArray as $value)
{
if ($flag) $fn .= "/";
$fn .= $value;
if (!array_key_exists($value, $device))
{
htmlSend($socket, sprintf(_('"%s" does not exists'), $value));
return false;
}
$device = $device[$value];
$flag = true;
}
//var_dump($device);
if (array_key_exists("device", $device)) // TODO
{
$device = $device["device"];
$fn .= "device/" . $fn;
}
if (is_a($device, "device"))
{
foreach($device->properties as $key => $value)
{
$response .= $key . "<br>";
$response .= $tab . "[<br>";
echo memory_get_usage();
//$response = value($key, $value, $response);
iterateProperty($key, $value, $response, $tab);
$response .= $tab . "]<br>";
}
/*foreach($device->properties as $key => $value)
{
$response = value($key, $value, $response);
}*/
}else
{
foreach($device as $key => $value)
{
$response .= $topicRef . htmlentities("&fn=" . $fn . "/" . $key) . '">' . $key . "</a><br>\n";
}
}
logger(DEBUG, _("response: ") . EOL . $response , __FILE__ . ":" . __LINE__);
//htmlSend($socket, $response);
}else
{
foreach($devices[$argList["topic"]] as $key => $value)
{
print "key = " . print_r($key, true) . " value = " . print_r($value, true) . EOLR;
logger(DEBUG, _("devices de topic: ") . $key , __FILE__ . ":" . __LINE__);
$response .= $topicRef . htmlentities("&fn=" . $key) . '">' . $key . "</a><br>";
logger(DEBUG, _("response: ") . $response , __FILE__ . ":" . __LINE__);
}
}
}else
{
$response = webListTopics();
}
}else
{
$response = webListTopics();
}
htmlSend($socket, $response);
}
function iterateProperty($property, $value, &$response, $tab="")
{
$tab .= "&nbsp;&nbsp;&nbsp;";
if (is_array($value) or is_object($value))
{
logger(DEBUG, _("is object or array"), __FILE__ . ":" . __LINE__ );
foreach($value as $key => $value2)
{
logger(DEBUG, $key, __FILE__ . ":" . __LINE__ );
iterateProperty($key, $value2, $response, $tab);
}
}else
{
$response .= $tab . $property . ' = ' . bool2string($value) . "<br>";//value($property, $value, "");
}
}
function webListTopics()
{
global $topics;
logger(DEBUG, _("webListTopics function"));
$response = "";
foreach ($topics as $name => $topic)
{
$response .= '<a href="/?browse&topic=' . $name . '">' . $name ."</a><br>";
}
return $response;
}
function webGet($argList)
{
if(!array_key_exists("topic", $argList) or !array_key_exists("fn", $argList) or !array_key_exists("property", $argList))
{
$response = "GET: " . _("no parameters passed, need topic, fn and property");
}else
{
if (($device = getDevice($argList["topic"], $argList["fn"])) === false)
{
$response = sprintf(_('"%s" or "%s" does not exists'), $argList["topic"], $argList["fn"]);
}else
{
$property = $argList["property"];
$response = "GET: " . bool2string($device->$property["value"]);
}
}
return $response;
}
function webSet($argList)
{
if(!array_key_exists("topic", $argList) or !array_key_exists("fn", $argList) or !array_key_exists("property", $argList) or !array_key_exists("value", $argList))
{
$response = "SET: " . _("no parameters passed, need topic, fn, property and value") . "passed";
}else
{
$response = "setting property " . $argList["property"] . " of " . $argList["fn"] . " to value: " . $argList["value"];
$payload = array($argList["property"] => $argList["value"]);
publish(Z2M . "/" . $argList["fn"], $payload);
}
return $response;
}
function webPrint($argList, $command)
{
global $GLOBALS, $topics;
if (array_key_exists($argList["object"], $GLOBALS))
{
$var = $GLOBALS[$argList["object"]];
if (isset($argList["topic"]))
{
$topic = $argList["topic"];
}
if (isset($argList["address"]))
{
$var = $var[$argList["address"]];
}elseif (isset($argList["fn"]))
{
if(!empty($topic))
{
$var = getDevice($topic, $argList["fn"]);
}else
{
$str = _("topic is not defining: add &topic=\nThese topics are availables: ");
foreach($topics as $key => $value)
{
$str .= $key . EOL;
}
logger(ERROR, $str, __FILE__ . ":" . __LINE__);
}
}
$error = error_get_last();
if($error !== null)
{
$response = $error["message"] . " file: " . $error["file"] . " line: " . $error["line"];
}
if ($command === "print")
{
$response = "<pre>" . nl2br(print_r($var, true)) . "<pre>";
}elseif($command === "dump")
{
$response = "Dump" . EOL;
$response .= "<pre>" . nl2br(var_export($var, true)) . "<pre>";
}
}else
{
$response = _("Object do not exists");
}
return $response;
}
function webNotify($argList)
{
if (!array_key_exists("topic", $argList) or !array_key_exists("fn", $argList) or !array_key_exists("property", $argList) or !array_key_exists("condition", $argList) or !array_key_exists("value", $argList))
{
$response = _("Error: With 'notify' command, you need 4 parameters: topic, fn, property, condition, value");
}else
{
$response = _("notify command have been set");
$monitored[] = new watch($argList["topic"], $argList["fn"], $argList["property"], $argList["condition"], $argList["value"]);
}
}
?>

113
webserver/webserver.php Normal file
View File

@ -0,0 +1,113 @@
<?php
// server init: No Timeout
set_time_limit(0);
ob_implicit_flush();
$error_message = null;
$error_code = null;
$listenHost = "0.0.0.0";
$listenPort = 1025;
$Dashboards = array();
require_once $configDir . "/dashboard_conf.php";
require_once "class/main.php";
require "webserver/cmd_functions.php";
// opening listening server
$socket = stream_socket_server("tcp://" . $listenHost . ":" . $listenPort, $error_code, $error_message) or logger(ERROR, _("Could not create socket"), __FILE__ . ":" . __LINE__);
stream_set_blocking($socket, false);
$read = array( $socket );
function htmlSend($socket, $text)
{
$httpHeader = "HTTP/1.1 200 OK" . EOLR .
"Date: " . date("r") . EOLR .
"Connection: close" . EOLR .
"Content-Type: text/html; charset=UTF-8" . EOLR . EOLR;
$response = $httpHeader . '<!doctype html>' . EOL . '<html lang="fr">' . EOL . '<head>' . EOL . '<meta charset="utf-8">' . EOL . '<title>Moha</title>' . EOL . '</head><body>' . $text . "</body></html>";
stream_socket_sendto($socket, $response);
}
function askWebServer($read)
{
global $topics, $indexDevices, $devices;
$array = array();
$argList =array();
//logger(DEBUG, _("askWebserver function starting"), __FILE__ . ":" . __LINE__);
if ( stream_select( $read, $array, $array, 0 ))
{
logger(DEBUG, _("socket ready to read"), __FILE__ . ":" . __LINE__);
$spawn = stream_socket_accept($read[0]);
if ($spawn !== false)
{
logger(DEBUG, _("socket accepted"), __FILE__ . ":" . __LINE__);
$input = fgets($spawn, 4096);
logger(DEBUG, $input, __FILE__ . ":" . __LINE__);
$input = substr($input,5);
$input = explode(" ", $input); // suppress text
if (!empty($input[0]))
{
$argTmp = explode("&", urldecode($input[0]));
foreach($argTmp as $tmp)
{
logger(DEBUG, $tmp, __FILE__ . ":" . __LINE__);
if(strpos($tmp, "=") === false)
{
logger(DEBUG, _("no ="), __FILE__ . ":" . __LINE__);
$argList["cmd"] = trim($tmp);
}else
{
$argList[trim(strchr($tmp, "=", true))] = trim(substr(strchr($tmp, "="), 1));
}
}
logger(DEBUG, print_r($argList, true), __FILE__ . ":" . __LINE__);
if(array_key_exists("cmd", $argList))
{
$command = strtolower($argList["cmd"]);
logger(DEBUG, _("command is ") . $command, __FILE__ . ":" . __LINE__);
switch($command)
{
case "dashboard":
webDashboard($spawn, $argList["dashboard"]);
break;
case "browse":
logger(DEBUG, _("Browsing"), __FILE__ . ":" . __LINE__);
webBrowse($spawn, $argList);
//return true;
break;
case "get":
logger(DEBUG, _("GET reached"), __FILE__ . ":" . __LINE__);
htmlSend($spawn, webGet($argList));
break;
case "set":
logger(DEBUG, _("SET reached"), __FILE__ . ":" . __LINE__);
htmlSend($spawn, webSet($argList));
break;
case "dump":
case "print":
logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__);
htmlSend($spawn, webPrint($argList, $command));
break;
case "notify":
logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__);
htmlSend($spawn, webNotify($argList));
logger(DEBUG, print_r($monitored, true), __FILE__ . ":" . __LINE__);
break;
default:
webBrowse($spawn, $argList);
}
}else
{
webDashboard($spawn);
}
}else
{
webDashboard($spawn);
}
}
}
}
?>

View File

@ -1,7 +1,6 @@
<?php
require "class/db.php";
require "header.php";
require "menu.php";