1
0

- changed webserver to apiserver

- added webserver
- a lot of debugging
- install shell script
This commit is contained in:
daniel Tartavel 2022-04-07 01:44:17 +02:00
parent 0d35b1ff3f
commit f8fc3f63ec
28 changed files with 463 additions and 223 deletions

View File

@ -18,8 +18,7 @@ for ($m=1; $m<=12; $m++)
require_once $configDir . "/aliases.php"; require_once $configDir . "/aliases.php";
require_once $configDir . "/dashboard_conf.php"; require_once $configDir . "/dashboard_conf.php";
require_once "class/main.php"; require_once "class/main.php";
require_once "webserver/cmd_functions.php"; require_once "apiserver/cmd_functions.php";
//require_once "webserver/display_stats.php";
// opening listening server // opening listening server
@ -45,7 +44,7 @@ function htmlSend($socket, $text, $meta="")
stream_socket_sendto($socket, $response); stream_socket_sendto($socket, $response);
} }
function askWebServer($read) function apiServer($read)
{ {
global $topics, $indexDevices, $devices; global $topics, $indexDevices, $devices;
$array = array(); $array = array();
@ -117,15 +116,24 @@ function askWebServer($read)
case "type": case "type":
logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__); logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__);
//htmlSend($spawn, webDisplayByType($argList)); //htmlSend($spawn, webDisplayByType($argList));
case "stat": /*case "stats":
logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__); logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__);
htmlSend($spawn, displayStats($argList)); displayStats($spawn, $argList);*/
default: default:
if (is_numeric(array_key_first($argList))) if (is_numeric(array_key_first($argList)))
{ {
webDashboard($spawn, $argList[0]); webDashboard($spawn, $argList[0]);
}else
{
logger(DEBUG, $command . _(" so default action"), __FILE__ . ":" . __LINE__);
if (file_exists("php://temp/". $command))
{
logger(DEBUG, $command . _(" is a file"), __FILE__ . ":" . __LINE__);
htmlSend($spawn, file_get_contents("php://temp/". $command), 'Content-Type: image/png');
} }
} }
}
if (array_key_exists("page", $argList)) if (array_key_exists("page", $argList))
{ {
htmlSend($spawn, '<meta http-equiv="refresh" content="1; URL=' . $argList["page"] . '" />'); htmlSend($spawn, '<meta http-equiv="refresh" content="1; URL=' . $argList["page"] . '" />');

View File

@ -4,8 +4,8 @@ require_once "events.php";
function webDashboard($socket, $n="Général") function webDashboard($socket, $n="Général")
{ {
global $dashboards, $indexDevices; global $dashboards, $indexDevices;
require_once "webserver/javascript.php"; require_once "apiserver/javascript.php";
logger(DEBUG, _("webDashboard function")); logger(DEBUG, _("webDashboard function"), __FILE__ . ":" . __LINE__);
$response = insertJavascript(); $response = insertJavascript();
if(array_key_exists($n, $dashboards)) if(array_key_exists($n, $dashboards))
@ -34,6 +34,9 @@ function webDashboard($socket, $n="Général")
{ {
logger(DEBUG, _("can get value") . ($propertyObject["access"] & 4), __FILE__ . ":" . __LINE__); logger(DEBUG, _("can get value") . ($propertyObject["access"] & 4), __FILE__ . ":" . __LINE__);
$response .= '<input type="button" id="' . $device->topic ."/" . $device->friendlyName . "/" . $propertyObject["name"] . '" value="' . _("Update") . "\" onmouseup=\"getPropertyValue('" . $device->topic . "','" . $device->friendlyName . "','" . $propertyObject["name"] . "')\">"; $response .= '<input type="button" id="' . $device->topic ."/" . $device->friendlyName . "/" . $propertyObject["name"] . '" value="' . _("Update") . "\" onmouseup=\"getPropertyValue('" . $device->topic . "','" . $device->friendlyName . "','" . $propertyObject["name"] . "')\">";
}else
{
$response .= $value;
} }
$response .= EOLH; $response .= EOLH;
}else }else
@ -99,7 +102,7 @@ function displayChoice($device, $propertyName, $value)
//$formHTML .= $device->friendlyName . aliases($device->friendlyName, $property) . ' => '; //$formHTML .= $device->friendlyName . aliases($device->friendlyName, $property) . ' => ';
$formHTML = '<input type="number" id="' . $device->topic . "/" $formHTML = '<input type="number" id="' . $device->topic . "/"
. $device->friendlyName . "/" . $device->friendlyName . "/"
. $propertyObject["name"] ."/value" . '"' . $propertyObject["name"] . '"'
. ' min="' . $propertyObject["value_min"] . '"' . ' min="' . $propertyObject["value_min"] . '"'
. ' max="' . $propertyObject["value_max"] . '"' . ' max="' . $propertyObject["value_max"] . '"'
. $step . $step
@ -110,7 +113,7 @@ function displayChoice($device, $propertyName, $value)
$formHTML .= ' max="' . $propertyObject["value_max"] . '"'; $formHTML .= ' max="' . $propertyObject["value_max"] . '"';
$formHTML .= ' value="' . $propertyObject["value"] . '"'; $formHTML .= ' value="' . $propertyObject["value"] . '"';
$formHTML .= $step; $formHTML .= $step;
$formHTML .= " oninput=\"setPropertyValue('" . $device->topic . "', '" . $device->friendlyName . "', this.value, '" . $propertyObject["name"] . "')\">"; $formHTML .= " oninput=\"setPropertyNumberValue('" . $device->topic . "', '" . $device->friendlyName . "', this.value, '" . $propertyObject["name"] . "')\">";
break; break;
case "enum": case "enum":
logger(DEBUG, _("type is enum"), __FILE__ . ":" . __LINE__); logger(DEBUG, _("type is enum"), __FILE__ . ":" . __LINE__);
@ -130,7 +133,7 @@ function mkHTML($device, $propertyName, $choice)
logger(DEBUG, "function mkHTML", __FILE__ . ":" . __LINE__); logger(DEBUG, "function mkHTML", __FILE__ . ":" . __LINE__);
foreach ($choice as $key => $value) foreach ($choice as $key => $value)
{ {
$html .= '<input type="button" id="' . $device->topic ."/" . $device->friendlyName . "/" . $propertyName . "/" . $key . '" value="' . $value . "\" onmouseup=\"setPropertyValue('" . $device->topic . "', '" . $device->friendlyName . "', '" . $value . "', '" . $propertyName . "')\">"; $html .= '<input type="button" id="' . $device->topic ."/" . $device->friendlyName . "/" . $propertyName . "/" . strtolower($value) . '" value="' . $value . "\" onmouseup=\"setPropertyValue('" . $device->topic . "', '" . $device->friendlyName . "', '" . $value . "', '" . $propertyName . "')\">";
} }
return $html; return $html;
} }
@ -179,7 +182,7 @@ function webBrowse($socket, $argList, $page="/browse")
if (is_a($device, "device")) if (is_a($device, "device"))
{ {
require_once "webserver/javascript.php"; require_once "apiserver/javascript.php";
$response .= insertJavascript(); $response .= insertJavascript();
foreach($device->properties as $key => $value) foreach($device->properties as $key => $value)
{ {
@ -400,7 +403,7 @@ function webDisplayByType($argList)
{ {
global $indexTypes, $config; global $indexTypes, $config;
require_once $config . "porpertiesbytype.php"; require_once $config . "porpertiesbytype.php";
require_once "webserver/javascript.php"; require_once "apiserver/javascript.php";
$response .= insertJavascript(); $response .= insertJavascript();
foreach($indexTypes[$argList["type"]] as $device) foreach($indexTypes[$argList["type"]] as $device)

View File

@ -6,13 +6,20 @@ return '<script language="javascript">
<!-- <!--
function setPropertyValue(topic, fn, value, property) function setPropertyValue(topic, fn, value, property)
{ {
document.getElementById(topic+"/"+fn+"/"+property+"/value").value = value; document.getElementById(topic+"/"+fn+"/"+property+"/"+value.toLowerCase()).value = value;
let xhr = new XMLHttpRequest();
xhr.open("GET", "http://192.168.1.253:' . $listenPort . '/set&fn="+fn+"&property="+property+"&topic="+topic+"&value="+value);
xhr.onload = function () {};
xhr.send();
}
function setPropertyNumberValue(topic, fn, value, property)
{
document.getElementById(topic+"/"+fn+"/"+property).value = value;
let xhr = new XMLHttpRequest(); let xhr = new XMLHttpRequest();
xhr.open("GET", "http://192.168.1.253:' . $listenPort . '/set&fn="+fn+"&property="+property+"&topic="+topic+"&value="+value); xhr.open("GET", "http://192.168.1.253:' . $listenPort . '/set&fn="+fn+"&property="+property+"&topic="+topic+"&value="+value);
xhr.onload = function () {}; xhr.onload = function () {};
xhr.send(); xhr.send();
} }
function getPropertyValue(topic, fn, property) function getPropertyValue(topic, fn, property)
{ {
let xhr = new XMLHttpRequest(); let xhr = new XMLHttpRequest();

View File

@ -0,0 +1,63 @@
<?php
class etage_bureau_eclairage extends hook
{
public $hookName = "etage_bureau_eclairage";
public $active = true; //enable/disable hook (true => enabled)
public $delay = 1; // amount of time in $timeunit
public $timeUnit = "hour"; // unit of time for delay, second, minute, hour, day, week, month, year
protected $devicelist = array(ETAGE_BUREAU_ECLAIRAGE_INTER => "action");
// callback fonction. Is called with these 3 parameters
// $device -> calling device
// $property -> property of the device (given by mqtt)
// $value -> value of the property
public function callBack($device, $property, $value)
{
logger(DEBUG, "Callback : " . $this->hookName, __FILE__ . ":" . __LINE__);
if($value == "on")
{
logger(DEBUG, "value: " . $value, __FILE__ . ":" . __LINE__);
//if(getValue(ETAGE_BUREAU_PANNEAU, "state") == 'OFF')
//{
logger(DEBUG, "Bureau panneau state: off", __FILE__ . ":" . __LINE__);
$this->send("ON", "OFF");
//}
}elseif ($value == "off")
{
//if(getValue(ETAGE_BUREAU_PANNEAU, "state") == 'ON')
//{
logger(DEBUG, "Bureau panneau state: on", __FILE__ . ":" . __LINE__);
$this->send("OFF", false);
//}
}
logger (INFO,sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, $value));
}
private function send($state, $delayState = false, $method = MANUAL)
{
global $devices, $indexDevices;
$device = & $indexDevices[ETAGE_BUREAU_PANNEAU];
$msg = array("state" => $state);
//if ($device->state_l1["value"] != $state)
//{
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $device->friendlyName));
$device->payload = $msg;
$device->set();
$device->properties["state"]["method"] = $method;
if ($delayState !== false) setDelay($device, $this->delay, $this->timeUnit, "state", $delayState, true);
//}else
//{
// logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), //json_encode($msg), $device->friendlyName));
//}
//echo 'delaystate = ' . var_dump($delayState);
}
}
$hooks["etage_bureau_eclairage"] = new etage_bureau_eclairage();
?>

View File

@ -3,10 +3,10 @@
class etage_plan_travail_eclairage extends hook class etage_plan_travail_eclairage extends hook
{ {
public $hookName = "etage_plan_travail_eclairage"; public $hookName = "etage_plan_travail_eclairage";
public $active = false; //enable/disable hook (true => enabled) public $active = true; //enable/disable hook (true => enabled)
public $delay = 3; // amount of time in $timeunit public $delay = 1; // amount of time in $timeunit
public $timeUnit = "hour"; // unit of time for delay, second, minute, hour, day, week, month, year public $timeUnit = "hour"; // unit of time for delay, second, minute, hour, day, week, month, year
protected $devicelist = array(ETAGE_CUISINE_PLAN_TRAVAIL_ECLAIRAGE => "state"); protected $devicelist = array(ETAGE_CUISINE_PLAN_TRAVAIL_INTER => "action");
// callback fonction. Is called with these 3 parameters // callback fonction. Is called with these 3 parameters
// $device -> calling device // $device -> calling device
@ -14,14 +14,16 @@ class etage_plan_travail_eclairage extends hook
// $value -> value of the property // $value -> value of the property
public function callBack($device, $property, $value) public function callBack($device, $property, $value)
{ {
logger(DEBUG, sprintf(_("property=%s, value=%s"), $property, $value), __FILE__ . ":" . __LINE__); logger(DEBUG, "Callback : " . $this->hookName, __FILE__ . ":" . __LINE__);
// here your code if($value == "single")
if($value == "ON") // ON {
if(getValue(ETAGE_CUISINE_PLAN_TRAVAIL_ECLAIRAGE, "state") == 'OFF')
{ {
$this->send("ON", "OFF"); $this->send("ON", "OFF");
}elseif($value == "OFF") }else
{ {
$this->send("OFF", null, AUTO); $this->send("OFF", false, null);
}
} }
logger (INFO,sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, $value)); logger (INFO,sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, $value));
} }
@ -31,18 +33,31 @@ class etage_plan_travail_eclairage extends hook
global $devices, $indexDevices; global $devices, $indexDevices;
$device = & $indexDevices[ETAGE_CUISINE_PLAN_TRAVAIL_SPOT]; $device = & $indexDevices[ETAGE_CUISINE_PLAN_TRAVAIL_SPOT];
$msg = array("state_l1" => $state); $msg = array("state_l1" => $state);
if ($device->state_l1["value"] != $state) //if ($device->state_l1["value"] != $state)
{ //{
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $device->friendlyName)); logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $device->friendlyName));
$device->payload = $msg; $device->payload = $msg;
$device->set(); $device->set();
$device->method = $method; $device->properties["state_l1"]["method"] = $method;
}else if ($delayState !== false) setDelay($device, $this->delay, $this->timeUnit, "state_l1", $delayState, true);
{
logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $device->friendlyName)); $device = & $indexDevices[ETAGE_CUISINE_PLAN_TRAVAIL_ECLAIRAGE];
} $msg = array("state" => $state);
//echo 'delaystate = ' . var_dump($delayState); //if ($device->state_l1["value"] != $state)
//{
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $device->friendlyName));
$device->payload = $msg;
$device->set();
$device->properties["state"]["method"] = $method;
if ($delayState !== false) setDelay($device, $this->delay, $this->timeUnit, "state", $delayState, true); if ($delayState !== false) setDelay($device, $this->delay, $this->timeUnit, "state", $delayState, true);
//}else
//{
// logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), //json_encode($msg), $device->friendlyName));
//}
//echo 'delaystate = ' . var_dump($delayState);
} }
} }

View File

@ -30,12 +30,14 @@ class hook
if ($this->active === true) if ($this->active === true)
{ {
foreach ($this->devicelist as $ieeeAddress => $property) foreach ($this->devicelist as $ieeeAddress => $property)
{
if (array_key_exists($ieeeAddress, $devices))
{ {
logger(DEBUG, _("Device: ") . $ieeeAddress, __FILE__ . ":" . __LINE__); logger(DEBUG, _("Device: ") . $ieeeAddress, __FILE__ . ":" . __LINE__);
if ($this->propertyInitialized[$ieeeAddress][$property] === false) if ($this->propertyInitialized[$ieeeAddress][$property] === false)
{ {
logger(DEBUG, _("Trying to store callback"), __FILE__ . ":" . __LINE__); logger(DEBUG, _("Trying to store callback"), __FILE__ . ":" . __LINE__);
if (isset($indexDevices[$ieeeAddress]->properties[$property]["functions"])) if (array_key_exists("functions", $indexDevices[$ieeeAddress]->properties[$property]))
{ {
$indexDevices[$ieeeAddress]->properties[$property]["functions"][$this->hookName] = array($this,"callback"); $indexDevices[$ieeeAddress]->properties[$property]["functions"][$this->hookName] = array($this,"callback");
$this->propertyInitialized[$ieeeAddress][$property] = true; $this->propertyInitialized[$ieeeAddress][$property] = true;
@ -50,6 +52,12 @@ class hook
{ {
logger(DEBUG, _("Callback already installed"), __FILE__ . ":" . __LINE__); logger(DEBUG, _("Callback already installed"), __FILE__ . ":" . __LINE__);
} }
}else
{
logger(ERROR, $ieeeAddress . (" does not exists"), __FILE__ . ":" . __LINE__);
mkIndexes();
}
} }
//echo "result => "; var_dump($result); //echo "result => "; var_dump($result);
if ($result === true) if ($result === true)

View File

@ -22,7 +22,6 @@ class topic {
class device class device
{ {
public $method; //0 = auto or 1 = manual
public $topic; public $topic;
public $ieeeAddress; public $ieeeAddress;
public $groupID; public $groupID;
@ -40,9 +39,8 @@ class device
$this->availability = array("value" => null, "functions" => array()); $this->availability = array("value" => null, "functions" => array());
} }
public function set($method=0) //, $event = null) public function set() //, $event = null)
{ {
$this->method = $method;
publish($this->topic . "/" . $this->friendlyName, $this->payload, "set"); //, $event); publish($this->topic . "/" . $this->friendlyName, $this->payload, "set"); //, $event);
} }
@ -72,6 +70,7 @@ class event
public $stopDatetime; public $stopDatetime;
public $recurrenceInterval; // interval : for recurrent event public $recurrenceInterval; // interval : for recurrent event
public $exceptionInterval; // array of object ranges public $exceptionInterval; // array of object ranges
public $method; // cf: constants.php (IDLE, AUTO, MANUAL)
} }
class watch class watch

View File

@ -43,6 +43,7 @@ $deviceTable = array(
"0x00158d0004621e1f" => "ETAGE_CUISINE_FENETRE", "0x00158d0004621e1f" => "ETAGE_CUISINE_FENETRE",
"0x00158d0001ddefe1" => "ETAGE_PORTE_FENETRE", "0x00158d0001ddefe1" => "ETAGE_PORTE_FENETRE",
"0x086bd7fffe5aeab6" => "RDC_CHAMBRE_AMBIANCE", "0x086bd7fffe5aeab6" => "RDC_CHAMBRE_AMBIANCE",
"0x00124b00251ead73" => "RDC_CHAMBRE_AMBIANCE_INTER",
"0xbc33acfffe6561e4" => "RDC_CHAMBRE_ECLAIRAGE", "0xbc33acfffe6561e4" => "RDC_CHAMBRE_ECLAIRAGE",
"0x00124b00234484ad" => "RDC_CHAMBRE_MVMT", "0x00124b00234484ad" => "RDC_CHAMBRE_MVMT",
"0x04cf8cdf3c7b6056" => "RDC_CHAMBRE_LUMINOSITE", "0x04cf8cdf3c7b6056" => "RDC_CHAMBRE_LUMINOSITE",
@ -55,7 +56,6 @@ $deviceTable = array(
foreach($deviceTable as $device => $name) foreach($deviceTable as $device => $name)
{ {
define($name, $device); define($name, $device);
//logger(DEBUG, _("defining constant ") . $name);
} }
?> ?>

View File

@ -26,8 +26,8 @@ $properties2log = array(
"dewptc" => 0.5, "dewptc" => 0.5,
"windchillc" => 0.5, "windchillc" => 0.5,
"winddir" => 40, "winddir" => 40,
"windspeedkmh" => 5, "windspeedkmh" => 10,
"windgustkmh" => 5, "windgustkmh" => 10,
"rainin" => 0.5, "rainin" => 0.5,
//"dailyrainin" => null, //"dailyrainin" => null,
//"weeklyrainin" => null, //"weeklyrainin" => null,

View File

@ -7,8 +7,9 @@ define("EOLH", "<br>\n");
define("Z2M", "zigbee2mqtt"); define("Z2M", "zigbee2mqtt");
define("ON", true); define("ON", true);
define("OFF", false); define("OFF", false);
define("AUTO", 0); define("IDLE", 1);
define("MANUAL", 1); define("AUTO", 2);
define("MANUAL", 3);
$logLevels = array( $logLevels = array(
1 => "INFO", 1 => "INFO",

View File

@ -40,10 +40,24 @@ function mkDevicesDB($topic, $json, $group=false)
//print_r($json); //print_r($json);
foreach ($json as $jsonDevice) foreach ($json as $jsonDevice)
{ {
$fn = $jsonDevice["friendly_name"];
addDevice($topic, $fn, $jsonDevice, $group);
}
$dbInit += 1;
mkIndexes();
fwrite($logFh, "################################START##################################################");
fwrite($logFh, var_export($devices, true));
fwrite($logFh, "################################END##################################################");
logger(INFO, _("Devices DB made"), __FILE__ . ":" . __LINE__);
//print_r($devices);
}
$fn = $jsonDevice->friendly_name; function addDevice($topic, $fn, $jsonDevice, $group=false )
{
global $devices, $listProperties, $listPropertiesKeys, $hooks, $indexDevices, $indexFriendlyNames;
$fnTree = explode("/", $fn); $fnTree = explode("/", $fn);
$device = & $devices[$topic]; $device = & $devices[$topic];
print_r($jsonDevice);
foreach($fnTree as $fnPart) foreach($fnTree as $fnPart)
{ {
if (!array_key_exists($fnPart, $device)) if (!array_key_exists($fnPart, $device))
@ -62,39 +76,28 @@ function mkDevicesDB($topic, $json, $group=false)
if ($group) if ($group)
{ {
//print_r($device); //print_r($device);
$device["device"]->groupID = $jsonDevice->id; $device["device"]->groupID = $jsonDevice["id"];
$device["device"]->ieeeAddress = $jsonDevice->id; $device["device"]->ieeeAddress = $jsonDevice["id"];
//$indexDevices[$device["device"]->groupID] = & $device["device"]; //$indexDevices[$device["device"]->groupID] = & $device["device"];
//$indexFriendlyNames[$topic][$fn] = & $device["device"]; //$indexFriendlyNames[$topic][$fn] = & $device["device"];
}else }else
{ {
addDevice($topic, $device["device"], $fn, $jsonDevice); $device["device"]->type = $jsonDevice["type"];
} $device["device"]->ieeeAddress = $jsonDevice["ieee_address"];
} if ( !empty($jsonDevice["power_source"] ))
$dbInit += 1;
mkIndexes();
fwrite($logFh, "################################START##################################################");
fwrite($logFh, var_export($devices, true));
fwrite($logFh, "################################END##################################################");
logger(INFO, _("Devices DB made"), __FILE__ . ":" . __LINE__);
//print_r($devices);
}
function addDevice($topic, &$device, $fn, $jsonDevice )
{
global $listProperties, $listPropertiesKeys, $hooks, $indexDevices, $indexFriendlyNames;
$device->type = $jsonDevice->type;
$device->ieeeAddress = $jsonDevice->ieee_address;
if ( !empty($jsonDevice->power_source ) )
{ {
$device->powerSource = $jsonDevice->power_source; $device["device"]->powerSource = $jsonDevice["power_source"];
} }
if ($jsonDevice->definition != null) if ($jsonDevice["definition"] != null)
{ {
$device->description = $jsonDevice->definition->description; $device["device"]->description = $jsonDevice["definition"]["description"];
searchPropertyKey($fn, $device, $jsonDevice->definition->exposes, $listPropertiesKeys); if (array_key_exists("exposes", $jsonDevice["definition"]))
{
searchPropertyKey($fn, $device["device"], $jsonDevice["definition"]["exposes"], $listPropertiesKeys);
}
}
searchPropertyValue($fn, $device["device"], $jsonDevice, $listProperties);
} }
searchPropertyValue($fn, $device, $jsonDevice, $listProperties);
//indexing device //indexing device
//$indexDevices[$device->ieeeAddress] = & $device; //$indexDevices[$device->ieeeAddress] = & $device;
@ -106,16 +109,18 @@ function searchPropertyKey($fn, &$device, $inputObject, $listPropertiesKeys)
//foreach($listPropertiesKeys as $propertyKey) //foreach($listPropertiesKeys as $propertyKey)
//{ //{
logger(DEBUG, _("searching for property"), __FILE__ . ":" . __LINE__ ); logger(DEBUG, _("searching for property"), __FILE__ . ":" . __LINE__ );
if (is_object($inputObject)) //if (is_object($inputObject))
//{
//print_r($inputObject);
if (array_key_exists("property", $inputObject))
{ {
if (property_exists($inputObject, "property")) logger(DEBUG, _("property Key exists filling properties"), __FILE__ . ":" . __LINE__ );
{ $string = $inputObject["property"];
logger(DEBUG, _("propertyKey exists filling properties"), __FILE__ . ":" . __LINE__ );
$string = $inputObject->property;
if (!array_key_exists($string, $device->properties)) if (!array_key_exists($string, $device->properties))
{ {
$device->properties[$string]["value"] = null; $device->properties[$string]["value"] = null;
$device->properties[$string]["functions"] = array(); $device->properties[$string]["functions"] = array();
$device->properties[$string]["method"] = IDLE;
} }
foreach($inputObject as $key2 => $value2) foreach($inputObject as $key2 => $value2)
{ {
@ -127,25 +132,27 @@ function searchPropertyKey($fn, &$device, $inputObject, $listPropertiesKeys)
} }
}else }else
{ {
if (property_exists($inputObject, "type")) if (array_key_exists("type", $inputObject))
{ {
$device->type = $inputObject->type; $device->type = $inputObject["type"];
} }
foreach($inputObject as $key => $value) /*foreach($inputObject as $key => $value)
{ {
logger(DEBUG, sprintf(_("key = %s"), $key), __FILE__ . ":" . __LINE__ ); logger(DEBUG, sprintf(_("key = %s"), $key), __FILE__ . ":" . __LINE__ );
searchPropertyKey($fn, $device, $value, $listPropertiesKeys); searchPropertyKey($fn, $device, $value, $listPropertiesKeys);
} }*/
} }
//print_r($device); //print_r($device);
}elseif (is_array($inputObject)) //}
/*elseif (is_array($inputObject))
{ {
foreach($inputObject as $value) foreach($inputObject as $value)
{ {
logger(DEBUG, _("value is object or group, iterating"), __FILE__ . ":" . __LINE__ ); logger(DEBUG, _("value is object or group, iterating"), __FILE__ . ":" . __LINE__ );
searchPropertyKey($fn, $device, $value, $listPropertiesKeys); searchPropertyKey($fn, $device, $value, $listPropertiesKeys);
} }
} }*/
} }
@ -209,6 +216,7 @@ function iterateDevice($topic, $fn, &$parentDevice, &$properties, $payloadArray,
{ {
$properties[$key] = array("value" => $value); $properties[$key] = array("value" => $value);
$properties[$key]["functions"] = array(); $properties[$key]["functions"] = array();
$properties[$key]["method"] = IDLE;
}elseif ($properties[$key]["value"] !== $value) }elseif ($properties[$key]["value"] !== $value)
{ {
changeValue($properties[$key], $value, $parentDevice, $propertyTree, $key); changeValue($properties[$key], $value, $parentDevice, $propertyTree, $key);
@ -302,16 +310,16 @@ function iterate2device(&$object)
$object = &$device; $object = &$device;
//print("=============" . $device->friendlyName); //print("=============" . $device->friendlyName);
if (!array_key_exists($object->ieeeAddress, $indexDevices)) //if (!array_key_exists($object->ieeeAddress, $indexDevices))
{ //{
//print("============>"); //print("============>");
$indexDevices[$object->ieeeAddress] = &$object; $indexDevices[$object->ieeeAddress] = &$object;
$indexFriendlyNames[$object->topic][$object->friendlyName] = &$object; $indexFriendlyNames[$object->friendlyName] = &$object;
if (property_exists($object, "type")) if (property_exists($object, "type"))
{ {
$indexTypes[$object->type][] = &$object; $indexTypes[$object->type][] = &$object;
} }
} //}
return true; return true;
}else }else
{ {

View File

@ -46,6 +46,7 @@ function checkEvents()
{ {
logger(DEBUG, sprintf(_("sending command set %s => %s for %s"), $event->param ,bool2string($event->value), $event->device->friendlyName), __FILE__ . ":" . __LINE__); 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"); publish(mktopic($event->device), array($event->param => $event->value), "set");
if ($event->method !== null) $event->device->properties[$event->param]["method"] = $event->method;
if (($event->dateTimeEvent->add($event->recurrenceInterval)) === false) if (($event->dateTimeEvent->add($event->recurrenceInterval)) === false)
{ {
logger(ERROR, _("Error in adding interval to event recurrence. event: ") . $key, __FILE__ . ":" . __LINE__); logger(ERROR, _("Error in adding interval to event recurrence. event: ") . $key, __FILE__ . ":" . __LINE__);
@ -56,8 +57,12 @@ function checkEvents()
}elseif (!empty($event->dateTimeEvent) and $event->dateTimeEvent < now()) }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__); 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); $mid = publish(mktopic($event->device), array($event->param => $event->value), "set"); //, $key);null
$event->published = $now; $event->published = $now;
if ($event->method !== null)
{
$event->device->properties[$event->param]["method"] = $event->method;
}
//echo "#################################\nUnsetting event $key \n###########################" . EOL; //echo "#################################\nUnsetting event $key \n###########################" . EOL;
unset($events[$key]); unset($events[$key]);
} }
@ -66,7 +71,7 @@ function checkEvents()
$logLevel = $oldLevel; $logLevel = $oldLevel;
} }
function setOneshotEvent(&$deviceObject, $datetime, $property, $value, $replace=false) function setOneshotEvent(&$deviceObject, $datetime, $property, $value, $replace=false, $method=null)
{ {
global $events; global $events;
$events[] = new event; $events[] = new event;
@ -77,9 +82,10 @@ function setOneshotEvent(&$deviceObject, $datetime, $property, $value, $replace=
$events[$key]->param = $property; $events[$key]->param = $property;
$events[$key]->value = $value; $events[$key]->value = $value;
$events[$key]->device = & $deviceObject; $events[$key]->device = & $deviceObject;
if ($method !==null) $events[$key]->method =$method;
} }
function setRecurrentEvent(&$deviceObject, $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, $method = null)
{ {
global $events; global $events;
$string = "P"; $string = "P";
@ -108,9 +114,10 @@ function setRecurrentEvent(&$deviceObject, $property, $value, $startDatetime, $s
logger(ERROR, _("Error in event recurrence. event: ") . $key, __FILE__ . ":" . __LINE__); logger(ERROR, _("Error in event recurrence. event: ") . $key, __FILE__ . ":" . __LINE__);
} }
if ($method !== null) $event->method = $method;
} }
function setDelay(&$deviceObject, $delay, $unit, $property, $value, $replace=false) function setDelay(&$deviceObject, $delay, $unit, $property, $value, $replace=false, $method = null)
{ {
global $events, $logLevel; global $events, $logLevel;
$oldLevel = $logLevel; $oldLevel = $logLevel;
@ -153,7 +160,7 @@ function setDelay(&$deviceObject, $delay, $unit, $property, $value, $replace=fal
if ($replace) if ($replace)
{ {
$eventKey = searchEvent($deviceObject, $property, $value); $eventKey = searchEvent($deviceObject, $property, $value);
if ($eventKey !== false) deleteEvent($eventKey); if ($eventKey !== false) deleteEvent($events[$eventKey]);
} }
//$dt = $datetime->format("Y-m-d\TH:i:s\Z"); //$dt = $datetime->format("Y-m-d\TH:i:s\Z");
$events[] = new event; $events[] = new event;
@ -164,16 +171,19 @@ function setDelay(&$deviceObject, $delay, $unit, $property, $value, $replace=fal
$events[$key]->param = $property; $events[$key]->param = $property;
$events[$key]->value = $value; $events[$key]->value = $value;
$events[$key]->device = & $deviceObject; $events[$key]->device = & $deviceObject;
if ($method !== null) $events[$key]->method = $method;
logger (DEBUG, _('Setting new delay in $events[]'), __FILE__ . ":" . __LINE__); logger (DEBUG, _('Setting new delay in $events[]'), __FILE__ . ":" . __LINE__);
//print_r($events[$key]); //print_r($events[$key]);
$logLevel = $oldLevel; $logLevel = $oldLevel;
} }
function removeEvent($deviceObject, $property , $value) function removeEvent($deviceObject, $property , $value, $method = null)
{ {
global $events;
$eventKey = searchEvent($deviceObject, $property , $value); $eventKey = searchEvent($deviceObject, $property , $value);
if ($eventKey !== false) if ($eventKey !== false)
{ {
if ($method !== null) $events[$eventKey]->device->method = $method;
deleteEvent($eventKey); deleteEvent($eventKey);
} }
} }
@ -188,24 +198,27 @@ function searchEvent($deviceObject, $property , $value)
//echo "===>";print_r($event); echo 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) 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; return $key;
} }
} }
return false; return false;
} }
// warning delete event does not manage method of the device (IDLE, )
function deleteEvent($eventKey) function deleteEvent($eventKey)
{ {
global $events; global $events;
if ($eventKey !== false) if ($eventKey !== false)
{ {
unset ($events[$eventKey]);
logger(INFO, _("delete event key =") . $eventKey, __FILE__ . ":" . __LINE__); logger(INFO, _("delete event key =") . $eventKey, __FILE__ . ":" . __LINE__);
if (array_key_exists($eventKey, $events))
{
unset ($events[$eventKey]);
}else }else
{ {
//try to delete an flase event logger(ERROR, _("event key does not exists: ") . $eventKey, __FILE__ . ":" . __LINE__);
logger(WARNING, _("Try to delete event with key = ") . var_export($eventKey, true), __FILE__ . ":" . __LINE__); }
} }
} }

View File

@ -22,7 +22,7 @@ class notificationFreemobile
{ {
$ch = curl_init(); $ch = curl_init();
// set url // set url
curl_setopt($ch, CURLOPT_URL, $this->url . $dest["destinataire"] . "&msg=" . urlencode(trim($message))); curl_setopt($ch, CURLOPT_URL, $this->url . $this->dest["destinataire"] . "&msg=" . urlencode(trim($message)));
echo $this->url . urlencode(trim($message)) . EOL; echo $this->url . urlencode(trim($message)) . EOL;
//return the transfer as a string //return the transfer as a string
//curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

View File

@ -122,7 +122,7 @@ class radiateurs extends hook
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $device->friendlyName), __FILE__ . ":" . __LINE__); logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $device->friendlyName), __FILE__ . ":" . __LINE__);
$device->payload = $msg; $device->payload = $msg;
$device->set(); $device->set();
$device->method = AUTO; $device->properties["current_heating_setpoint"]["method"] = AUTO;
} }
} }
} }

View File

@ -12,7 +12,8 @@ class rdc_chambre_eclairage extends hook
RDC_CHAMBRE_AMBIANCE => "state", // "ON"/"OFF" RDC_CHAMBRE_AMBIANCE => "state", // "ON"/"OFF"
RDC_CHAMBRE_ECLAIRAGE => "state_l1", // "ON"/"OFF" RDC_CHAMBRE_ECLAIRAGE => "state_l1", // "ON"/"OFF"
RDC_CHAMBRE_MVMT => "occupancy", RDC_CHAMBRE_MVMT => "occupancy",
RDC_CHAMBRE_ARMOIRE_GAUCHE => "contact" RDC_CHAMBRE_ARMOIRE_GAUCHE => "contact",
RDC_CHAMBRE_AMBIANCE_INTER => "action"
); );
// callback fonction. Is called with these 3 parameters // callback fonction. Is called with these 3 parameters
@ -26,19 +27,44 @@ class rdc_chambre_eclairage extends hook
$lux = $indexDevices[RDC_CHAMBRE_LUMINOSITE]->properties["illuminance_lux"]; $lux = $indexDevices[RDC_CHAMBRE_LUMINOSITE]->properties["illuminance_lux"];
$targetAmbiance = $indexDevices[RDC_CHAMBRE_AMBIANCE]; $targetAmbiance = $indexDevices[RDC_CHAMBRE_AMBIANCE];
$targetEclairage = $indexDevices[RDC_CHAMBRE_ECLAIRAGE]; $targetEclairage = $indexDevices[RDC_CHAMBRE_ECLAIRAGE];
logger(DEBUG, sprintf(_("property=%s, value=%s"), $property, $value), __FILE__ . ":" . __LINE__);
if ($property == "occupancy" and $value == ON) if ($property == "occupancy" and $value == ON)
{ {
logger(DEBUG, _("CASE: occupancy"), __FILE__ . ":" . __LINE__); logger(DEBUG, _("CASE: occupancy"), __FILE__ . ":" . __LINE__);
$this->send($targetAmbiance, "state", "ON", "OFF", AUTO); if ($targetAmbiance->properties["state"]["method"] == MANUAL)
{
$method = false;
$delayState = false;
}else
{
$method = AUTO;
$delayState = "OFF";
}
$this->send($targetAmbiance, "state", "ON", $delayState, $method);
}elseif ($property == "contact") }elseif ($property == "contact")
{ {
if ($value == false) logger(DEBUG, _("CASE: contact"), __FILE__ . ":" . __LINE__);
if ($value === false)
{ {
$this->send($targetEclairage, "state_l1", "ON", "OFF", AUTO); $this->send($targetEclairage, "state_l1", "ON", "OFF", AUTO);
}elseif ($value == true) }elseif ($value === true)
{ {
$this->send($targetEclairage, "state_l1", "OFF", false, null); $this->send($targetEclairage, "state_l1", "OFF", false, IDLE);
}
}elseif ($property == "state" and $value == "OFF")
{
logger(DEBUG, _("CASE: state => value = 'OFF'"), __FILE__ . ":" . __LINE__);
$targetAmbiance->properties[$property]["method"] = IDLE;
}elseif ($property == "state_l1" and $value == "OFF")
{
logger(DEBUG, _("CASE: state_l1 => value = 'OFF'"), __FILE__ . ":" . __LINE__);
$targetEclairage->properties[$property]["method"] = IDLE;
}elseif ($property == "action")
{
logger(DEBUG, _("CASE: action"), __FILE__ . ":" . __LINE__);
if ($targetAmbiance->properties[$property]["method"] == IDLE)
{
$targetAmbiance->properties[$property]["method"] == MANUAL;
} }
} }
logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, bool2string($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__);
@ -53,7 +79,7 @@ class rdc_chambre_eclairage extends hook
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $deviceObject->friendlyName), __FILE__ . ":" . __LINE__); logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $deviceObject->friendlyName), __FILE__ . ":" . __LINE__);
$deviceObject->payload = $msg; $deviceObject->payload = $msg;
$deviceObject->set(); $deviceObject->set();
$deviceObject->method = $method; $deviceObject->properties[$property]["method"] = $method;
///}else ///}else
/*{ /*{
logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $deviceObject->friendlyName), __FILE__ . ":" . __LINE__); logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $deviceObject->friendlyName), __FILE__ . ":" . __LINE__);

View File

@ -49,19 +49,19 @@ class rdc_salon_eclairage extends hook
if (getValue(RDC_SALON_MVMT, "occupancy") == OFF and (getValue(RDC_SALON_MVMT2, "occupancy") == OFF)) if (getValue(RDC_SALON_MVMT, "occupancy") == OFF and (getValue(RDC_SALON_MVMT2, "occupancy") == OFF))
{ {
logger(INFO, _("Setting to OFF"), __FILE__ . ":" . __LINE__); logger(INFO, _("Setting to OFF"), __FILE__ . ":" . __LINE__);
setDelay($deviceTarget, $this->delay, $this->timeUnit, "state", "OFF", true); //setDelay($deviceTarget, $this->delay, $this->timeUnit, "state", "OFF", true);
//$this->send($deviceTarget, "ON", "OFF", AUTO); $this->send($deviceTarget, "OFF", false, IDLE);
} }
} }
break; break;
case "contact": case "contact":
logger(INFO, _("CASE: Contact Door"), __FILE__ . ":" . __LINE__); logger(INFO, _("CASE: Contact Door"), __FILE__ . ":" . __LINE__);
if ($value == false and getValue(RDC_SALON_LUMINOSITE, "illuminance_lux") <= $this->luminance_min and getValue($deviceTarget->ieeeAddress, "state") == "OFF") if ($value == false and getValue(RDC_SALON_LUMINOSITE, "illuminance_lux") <= $this->luminance_min)
{ {
logger(INFO, _("Door is open and illumance < min"), __FILE__ . ":" . __LINE__); logger(INFO, _("Door is open and illumance < min"), __FILE__ . ":" . __LINE__);
if (getValue(RDC_SALON_MVMT, "occupancy") == ON or getValue(RDC_SALON_MVMT2, "occupancy") == ON) if ($deviceTarget->properties["state"]["method"] !== MANUAL)
{ {
$this->send($deviceTarget, "ON", false, AUTO); $this->send($deviceTarget, "ON", false);
}else }else
{ {
$this->send($deviceTarget, "ON", "OFF", AUTO); $this->send($deviceTarget, "ON", "OFF", AUTO);
@ -70,20 +70,20 @@ class rdc_salon_eclairage extends hook
break; break;
case "illuminance_lux": case "illuminance_lux":
logger(INFO, _("CASE : Illuminance"), __FILE__ . ":" . __LINE__); logger(INFO, _("CASE : Illuminance"), __FILE__ . ":" . __LINE__);
if ($value >= $this->luminance_max) if ($value >= $this->luminance_max and $deviceTarget->properties["state"]["value"] == "ON")
{ {
logger(INFO, _("illuminace is > to max"), __FILE__ . ":" . __LINE__); logger(INFO, _("illuminace is > to max"), __FILE__ . ":" . __LINE__);
//$this->send($deviceTarget, "OFF", null, AUTO); //$this->send($deviceTarget, "OFF", null, AUTO);
//removeEvent($indexDevices[RDC_SALON_ECLAIRAGE_PANNEAU], "state", "OFF"); //removeEvent($indexDevices[RDC_SALON_ECLAIRAGE_PANNEAU], "state", "OFF");
if (searchEvent($deviceTarget, "state", "OFF") === false) if (searchEvent($deviceTarget, "state", "OFF") === false)
{ {
setDelay($deviceTarget, $this->delay, $this->timeUnit, "state", "OFF", true); setDelay($deviceTarget, $this->delay, $this->timeUnit, "state", "OFF", true, IDLE);
} }
}elseif ($value <= $this->luminance_min and (getValue(RDC_SALON_MVMT, "occupancy") == ON || getValue(RDC_SALON_MVMT2,"occupancy") == ON)) }/*elseif ($value <= $this->luminance_min and (getValue(RDC_SALON_MVMT, "occupancy") == ON || getValue(RDC_SALON_MVMT2,"occupancy") == ON))
{ {
logger(INFO, _("illuminance < min and movement detected"), __FILE__ . ":" . __LINE__); logger(INFO, _("illuminance < min and movement detected"), __FILE__ . ":" . __LINE__);
$this->send($deviceTarget, "ON", false, AUTO); $this->send($deviceTarget, "ON", false, AUTO);
} }*/
break; break;
} }
logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $param, bool2string($value)), __FILE__ . ":" . __LINE__); logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $param, bool2string($value)), __FILE__ . ":" . __LINE__);
@ -99,7 +99,7 @@ class rdc_salon_eclairage extends hook
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $deviceTarget->friendlyName), __FILE__ . ":" . __LINE__); logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $deviceTarget->friendlyName), __FILE__ . ":" . __LINE__);
$deviceTarget->payload = $msg; $deviceTarget->payload = $msg;
$deviceTarget->set(); $deviceTarget->set();
$deviceTarget->method = $method; $deviceTarget->properties["state"]["method"] = $method;
/*}else /*}else
{ {
logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $deviceTarget->friendlyName), __FILE__ . ":" . __LINE__); logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $deviceTarget->friendlyName), __FILE__ . ":" . __LINE__);

View File

@ -28,7 +28,9 @@ class rdc_sdb_eclairage extends hook
{ {
global $indexDevices; global $indexDevices;
//var_dump($value); //var_dump($value);
$deviceTarget = $indexDevices[RDC_SDB_WC_ECLAIRAGE]; $deviceTarget = &$indexDevices[RDC_SDB_WC_ECLAIRAGE];
if ($deviceTarget !== null)
{
logger(DEBUG, "Callback : " . $this->hookName, __FILE__ . ":" . __LINE__); logger(DEBUG, "Callback : " . $this->hookName, __FILE__ . ":" . __LINE__);
switch($property) switch($property)
{ {
@ -37,31 +39,36 @@ class rdc_sdb_eclairage extends hook
if ($value == ON ) if ($value == ON )
{ {
$this->send("ON"); $this->send("ON");
$device->method = AUTO; $deviceTarget->properties["state_l1"]["method"] = AUTO;
} }
break; break;
case "state_l1": case "state_l1":
logger(DEBUG, _("CASE: state_l1"), __FILE__ . ":" . __LINE__); logger(DEBUG, _("CASE: state_l1"), __FILE__ . ":" . __LINE__);
if ($value == "ON") if ($value == "ON")
{ {
if ($device->method != MANUAL) if ($deviceTarget->properties["state_l1"]["method"] != MANUAL)
{ {
$delay = $this->delay; $delay = $this->delay;
$device->method = AUTO; $deviceTarget->properties["state_l1"]["method"] = AUTO;
}else }else
{ {
$delay = $this->delayManual; $delay = $this->delayManual;
$device->method = MANUAL; $deviceTarget->properties["state_l1"]["method"] = MANUAL;
} }
setDelay($deviceTarget, $delay, $this->timeUnit, "state_l1", "OFF", true); setDelay($deviceTarget, $delay, $this->timeUnit, "state_l1", "OFF", true, IDLE);
}elseif ($value == "OFF") }elseif ($value == "OFF")
{ {
removeEvent($deviceTarget, "state_l1", "OFF"); removeEvent($deviceTarget, "state_l1", "OFF");
$device->method = null; $deviceTarget->properties["state_l1"]["method"] = IDLE;
} }
break; break;
} }
logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, ($value == 0 ? "OFF" : "ON")), __FILE__ . ":" . __LINE__); logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, ($value == 0 ? "OFF" : "ON")), __FILE__ . ":" . __LINE__);
}else
{
logger (ERROR, RDC_SDB_WC_ECLAIRAGE . _(" does not exists"), __FILE__ . ":" . __LINE__);
}
} }
private function send($state) private function send($state)

View File

@ -35,6 +35,8 @@ class rdc_store extends hook
$rafale = 0; $rafale = 0;
$soleil = 0; $soleil = 0;
$storeDevice = $indexDevices[RDC_STORE]; $storeDevice = $indexDevices[RDC_STORE];
$maxLevel = 100;
$r = 100;
if (array_key_exists("position", $storeDevice->properties)) if (array_key_exists("position", $storeDevice->properties))
{ {
@ -131,10 +133,10 @@ class rdc_store extends hook
break; break;
default: default:
} }
if ($store2level <= $this->storeLevel) /*if ($store2level <= $this->storeLevel)
{ {
$this->set($store2level); $this->set($store2level);
} }*/
} }
private function set ($level) private function set ($level)

View File

@ -9,7 +9,7 @@ class rdc_wc_eclairage extends hook
RDC_WC_MVMT => "occupancy" RDC_WC_MVMT => "occupancy"
); );
public $delay = 3; // amount of time in $timeunit public $delay = 5; // amount of time in $timeunit
public $delayManual = 15; // amount of time in $timeunit for manual mode public $delayManual = 15; // amount of time in $timeunit for manual mode
public $timeUnit = "minute"; // unit of time for delay, second, minute, day, week, month, year public $timeUnit = "minute"; // unit of time for delay, second, minute, day, week, month, year
@ -17,7 +17,8 @@ class rdc_wc_eclairage extends hook
public function callBack(&$device, $property, $value) public function callBack(&$device, $property, $value)
{ {
global $indexDevices; global $indexDevices;
//var_dump($value);
$targetDevice = &$indexDevices[RDC_SDB_WC_ECLAIRAGE]; //var_dump($value);
logger(DEBUG, "Callback : " . $this->hookName, __FILE__ . ":" . __LINE__); logger(DEBUG, "Callback : " . $this->hookName, __FILE__ . ":" . __LINE__);
switch($property) switch($property)
{ {
@ -25,38 +26,39 @@ class rdc_wc_eclairage extends hook
logger(DEBUG, "CASE: state_l2", __FILE__ . ":" . __LINE__); logger(DEBUG, "CASE: state_l2", __FILE__ . ":" . __LINE__);
if ($value == "ON") if ($value == "ON")
{ {
if ($device->method == AUTO) if ($targetDevice->properties["state_l1"]["method"] !== AUTO)
{ {
setDelay($device, $this->delay, $this->timeUnit, "state_l2", "OFF", true); $targetDevice->properties["state_l1"]["method"] = MANUAL;
}else //setDelay($device, $this->delayManual, $this->timeUnit, "state_l2", "OFF", true);
{
$device->method = MANUAL;
setDelay($device, $this->delayManual, $this->timeUnit, "state_l2", "OFF", true);
} }
}elseif ($value == "OFF") }elseif ($value == "OFF")
{ {
removeEvent($device, "state_l2", "OFF"); removeEvent($device, "state_l2", "OFF", IDLE);
$device->method = null;
} }
break; break;
case "occupancy": case "occupancy":
logger(DEBUG, "CASE: occupancy", __FILE__ . ":" . __LINE__); logger(DEBUG, "CASE: occupancy", __FILE__ . ":" . __LINE__);
if ($value == true) if ($value == true)
{ {
$device->method = AUTO; $targetDevice->properties["state_l2"]["method"] = AUTO;
$this->send("ON"); //setDelay($device, $this->delay, $this->timeUnit, "state_l2", "OFF", true,IDLE);
$this->send($targetDevice, "ON");
}elseif ($targetDevice->properties["state_l2"]["method"] != MANUAL)
{
$targetDevice->properties["state_l2"]["method"] = IDLE;
$this->send($targetDevice, "OFF");
} }
} }
logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, bool2string($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__);
} }
private function send($state) private function send($targetDevice, $state)
{ {
global $indexDevices; global $indexDevices;
$deviceObject = $indexDevices[RDC_SDB_WC_ECLAIRAGE];
$msg = array("state_l2" => $state); $msg = array("state_l2" => $state);
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $deviceObject->friendlyName), __FILE__ . ":" . __LINE__); logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $targetDevice->friendlyName), __FILE__ . ":" . __LINE__);
$deviceObject->payload = $msg; $targetDevice->payload = $msg;
$deviceObject->set(null); $targetDevice->set(null);
} }
} }

View File

@ -196,7 +196,7 @@ require $configDir . "/properties2log.php";
require "mqtt_functions.php"; require "mqtt_functions.php";
require "events.php"; require "events.php";
require "db_functions.php"; require "db_functions.php";
require "webserver/webserver.php"; require "apiserver/apiserver.php";
// topics definition // topics definition
listHooks("./topics_callbacks", $hooksList); listHooks("./topics_callbacks", $hooksList);
@ -353,7 +353,7 @@ while (true)
} }
checkEvents(); checkEvents();
askWebServer($read); apiServer($read);
//} //}
} }

View File

@ -6,7 +6,7 @@ function messageReceived($message)
global $topics, $logFh, $devices, $included; global $topics, $logFh, $devices, $included;
$topic = explode ("/", $message->topic); $topic = explode ("/", $message->topic);
$callback = $topics[$topic[0]]->callback; $callback = $topics[$topic[0]]->callback;
logger(DEBUG, "message => " . var_export($message, true), __FILE__ . ":" . __LINE__); //logger(DEBUG, "message => " . var_export($message, true), __FILE__ . ":" . __LINE__);
$callback($topic, $message); $callback($topic, $message);
} }

9
tools/install.sh Executable file
View File

@ -0,0 +1,9 @@
#!/usr/bin/bash
rsync -aP --exclude "*~" --exclude *kate-swp $1/config/ /etc/moha/
chmod 0500 /etc/moha
chmod 0400 /etc/moha/*
chown domotique:domotique -R /etc/moha
rsync -aP --exclude "*~" --exclude *kate-swp $1/webserver/ /var/www/html/moha/
chmod 0400 -R /var/www/html/moha/
chmod 0500 /var/www/html/moha
chown apache:apache -R /var/www/html/moha

View File

@ -12,25 +12,25 @@ function zigbee2mqttCallback($topic, $message)
switch ($topic[2]) switch ($topic[2])
{ {
case "info": case "info":
$topics[$topic[0]]->info = json_decode($message->payload); $topics[$topic[0]]->info = json_decode($message->payload, true);
break; break;
case "devices": case "devices":
logger(DEBUG,_("Inserting zigbee devices in DB"), __FILE__ . ":" . __LINE__); logger(DEBUG,_("Inserting zigbee devices in DB"), __FILE__ . ":" . __LINE__);
$topics[$topic[0]]->devices = json_decode($message->payload); $topics[$topic[0]]->devices = json_decode($message->payload, true);
//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); mkDevicesDB($topic[0], $topics[$topic[0]]->devices);
getDevicesValues($topic[0]); getDevicesValues($topic[0]);
break; break;
case "groups": case "groups":
logger(DEBUG,_("Inserting zigbee groups in DB"), __FILE__ . ":" . __LINE__); logger(DEBUG,_("Inserting zigbee groups in DB"), __FILE__ . ":" . __LINE__);
$topics[$topic[0]]->groups = json_decode($message->payload); $topics[$topic[0]]->groups = json_decode($message->payload, true);
mkDevicesDB($topic[0], $topics[$topic[0]]->groups, true); mkDevicesDB($topic[0], $topics[$topic[0]]->groups, true);
break; break;
case "extensions": case "extensions":
$topics[$topic[0]]->extensions = json_decode($message->payload); $topics[$topic[0]]->extensions = json_decode($message->payload, true);
break; break;
case "config": case "config":
$topics[$topic[0]]->config = json_decode($message->payload); $topics[$topic[0]]->config = json_decode($message->payload, true);
break; break;
case "logging": case "logging":
//TODO //TODO
@ -64,23 +64,45 @@ function zigbee2mqttCallback($topic, $message)
array_pop ($fnTree); array_pop ($fnTree);
$fn = implode("/", $fnTree); $fn = implode("/", $fnTree);
$fn = implode("/", $fnTree); $fn = implode("/", $fnTree);
if (($payloadArray = json_decode($message->payload, true)) === null)
{
$payloadArray = array($fnTreeEnd => $message->payload); $payloadArray = array($fnTreeEnd => $message->payload);
//TODO payload can be a json object }
break; break;
default: default:
$payloadArray = json_decode($message->payload,true); $payloadArray = json_decode($message->payload, true);
} }
logger(DEBUG, _("friendlyname = ") . $fn, __FILE__ . ":" . __LINE__); logger(DEBUG, _("friendlyname = ") . $fn, __FILE__ . ":" . __LINE__);
if (!array_key_exists($fn, $indexFriendlyNames[$topicName])) $flag = 0;
$alert = 0;
while (!array_key_exists($fn, $indexFriendlyNames))
{ {
mkDevicesDB($topicName, $message->payload); logger(INFO, _("device does not exists in IndexFriendlyNames: ") . print_r($payloadArray,true), __FILE__ . ":" . __LINE__);
logger(ERROR, sprintf(_("device with friendlyname %s not found"), $fn), __FILE__ . ":" . __LINE__); if ($flag == 0)
}else
{ {
logger(DEBUG, "PayloadArray = " . print_r($payloadArray,true), __FILE__ . ":" . __LINE__); logger(INFO, "Reindexing all indexes", __FILE__ . ":" . __LINE__);
changeDevice($topicName, $fn, $indexFriendlyNames[$topicName][$fn], $payloadArray); mkIndexes();
$flag += 1;
}elseif($flag == 1)
{
logger(INFO, "getting device list from zigbee2mqtt", __FILE__ . ":" . __LINE__);
publish("zigbee2mqtt", array("bridge/devices" => ""), "get");
$flag += 1;
}elseif($flag >= 2)
{
$flage = 0;
if ($alert++ > 4)
{
logger(ALERT, _("device does not exists in IndexFriendlyNames: ") . $fn, __FILE__ . ":" . __LINE__);
break;
}
}
}
//logger(DEBUG, "PayloadArray = " . print_r($payloadArray,true), __FILE__ . ":" . __LINE__);
if ($alert <= 4)
{
changeDevice($topicName, $fn, $indexFriendlyNames[$fn], $payloadArray);
} }
}else }else
{ {
logger(DEBUG, _("Zigbee2mqtt doing get or set !?")); logger(DEBUG, _("Zigbee2mqtt doing get or set !?"));

View File

@ -81,9 +81,15 @@ function getDevice($topic, $fn)
function getValue($ieeeAddress, $property) function getValue($ieeeAddress, $property)
{ {
global $indexDevices; global $indexDevices;
if (array_key_exists($property, $indexDevices[$ieeeAddress]->properties))
{
$r = $indexDevices[$ieeeAddress]->properties[$property]["value"]; $r = $indexDevices[$ieeeAddress]->properties[$property]["value"];
logger(DEBUG, "device: " . $indexDevices[$ieeeAddress]->friendlyName . " value: " . $r, __FILE__ . ":" . __LINE__ ); logger(DEBUG, "device: " . $indexDevices[$ieeeAddress]->friendlyName . " value: " . $r, __FILE__ . ":" . __LINE__ );
}else
{
$r = false;
logger(ERROR, "device: " . $indexDevices[$ieeeAddress]->friendlyName . "property " . $property . "does not exists", __FILE__ . ":" . __LINE__ );
}
return $r; return $r;
} }

View File

@ -8,21 +8,32 @@
function displayStats($socket, $argList) function displayStats($socket, $argList)
{ {
global $indexFriendlyNames; global $indexFriendlyNames, $mohaDB;
logger(INFO, "Function displayStats", __FILE__ . ":" . __LINE__);
// Validation of the dates // Validation of the dates
if (validateDate($argList["startDate"]) && validateDate($argList["finalDate"])) if (validateDate($argList["startDate"]) && validateDate($argList["finalDate"]))
{ {
$query = "SELECT date, value FROM logs WHERE device='" . indexFriendlyNames[$argList->device] . "' AND property='" . $$argList["property"] . "' AND '" . $argList["startDate"] . ">= date AND '" . $argList["finalDate"] . "' <= date"; if (!array_key_exists($argList["fn"], $indexFriendlyNames))
if(!$this->result = $this->query($query))
{ {
logger(ERROR, _("mysql query errror: ") . $this->error, __FILE__ . ":" . __LINE__); htmlSend($socket, $argList["fn"] . _(" not found: Verify the syntax"));
} }elseif(!array_key_exists($argList["property"], $indexFriendlyNames[$argList["fn"]]->properties))
$datas = $this->result->fetch_all(MYSQLI_ASSOC); {
diagramDisplay($datas); htmlSend($socket, $argList["property"] . _(" not found : Verify the syntax"));
}else }else
{ {
htmlSend($socket, _("Dates are not of the form: YYYY-MM-DD")); $query = "SELECT date, value FROM logs WHERE device='" . $indexFriendlyNames[$argList["fn"]]->ieeeAddress . "' AND property='" . $argList["property"] . "' AND '" . $argList["startDate"] . "'>= date AND '" . $argList["finalDate"] . "' <= date ORDER BY date";
logger(DEBUG, _("query : ") . $query, __FILE__ . ":" . __LINE__);
if(!($mohaDB->result = $mohaDB->query($query)))
{
logger(ERROR, _("mysql query error: ") . $mohaDB->error, __FILE__ . ":" . __LINE__);
}
$datas = $mohaDB->result->fetch_all(MYSQLI_ASSOC);
htmlSend($socket, diagramDisplay($datas));
}
}else
{
htmlSend($socket, _("Dates are not of the form: YYYY-MM-DD 00:00:00"));
} }
} }
@ -39,8 +50,11 @@ function diagramDisplay($datas)
global $months; global $months;
$ndata = count($datas); $ndata = count($datas);
$min = min($datas); $i = $ndata;
$max = max($datas); $tmp = min($datas);
$min = $tmp["value"];
$tmp = max($datas);
$max = $tmp["value"];
//Type mime de l'image //Type mime de l'image
//Chemin vers le police à utiliser //Chemin vers le police à utiliser
$font_file = '/usr/share/fonts/TTF/dejavu/DejaVuSans.ttf'; $font_file = '/usr/share/fonts/TTF/dejavu/DejaVuSans.ttf';
@ -64,6 +78,7 @@ function diagramDisplay($datas)
//Tracer l'axe des ordonnées //Tracer l'axe des ordonnées
imageline($courbe, 50, $hauteur - $absis, 50, 20, $noir); imageline($courbe, 50, $hauteur - $absis, 50, 20, $noir);
//Decaler 10px vers le haut le si le minimum est différent de 0 //Decaler 10px vers le haut le si le minimum est différent de 0
$a = 0;
if($min != 0) if($min != 0)
{ {
$absis += 10; $absis += 10;
@ -94,14 +109,17 @@ function diagramDisplay($datas)
$j = -1; $j = -1;
$pasX = 90; $pasX = 90;
//Parcourir le tableau pour le traçage de la diagramme //Parcourir le tableau pour le traçage de la diagramme
foreach ($datas as $mois => $quantite) foreach ($datas as $row)
{ {
$date = $row["date"];
$quantite = $row["value"];
//calculer la hateur du point par rapport à sa valeur //calculer la hateur du point par rapport à sa valeur
$y = ($hauteur) - (($quantite - $min) * ($echelleY / $py)) - $absis; $y = ($hauteur) - (($quantite - $min) * ($echelleY / $py)) - $absis;
//dessiner le point //dessiner le point
imagefilledellipse($courbe, $pasX, $y, 6, 6, $rouge); imagefilledellipse($courbe, $pasX, $y, 6, 6, $rouge);
//Afficher le mois en français avec une inclinaison de 315° //Afficher le mois en français avec une inclinaison de 315°
imagefttext($courbe, 10, 315, $pasX, $hauteur - $absis + 20, $noir, $font_file, $months[$mois-1]); printf("pasx = %d hauteur = %d absis = %d noir= %d", $pasX, $hauteur, $absis, $noir);
imagefttext($courbe, 10, 315, $pasX, $hauteur - $absis + 20, $noir, $font_file, $date);
//Tacer une ligne veticale de l'axe de l'abscisse vers le point //Tacer une ligne veticale de l'axe de l'abscisse vers le point
imageline($courbe, $pasX, $hauteur - $absis + $a, $pasX, $y, $noir); imageline($courbe, $pasX, $hauteur - $absis + $a, $pasX, $y, $noir);
if($j!==-1) if($j!==-1)
@ -118,8 +136,12 @@ function diagramDisplay($datas)
$pasX +=$echelleX; $pasX +=$echelleX;
} }
//Envoyer le flux de l'image //Envoyer le flux de l'image
imagepng($courbe);
//Desallouer le memoire utiliser par l'image //header('Content-Type: image/png');
$file = tempnam("php://temp", "moha-");
imagepng($courbe,$file);
return '<img src="/' . basename($file) . '">';
//Desallouer la mémoire utiliser par l'image
imagedestroy($courbe); imagedestroy($courbe);
} }
?> ?>

2
webserver/footer.php Normal file
View File

@ -0,0 +1,2 @@
</body>
</html>

7
webserver/header.php Normal file
View File

@ -0,0 +1,7 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Moha</title>
</head>
<body>

10
webserver/index.php Normal file
View File

@ -0,0 +1,10 @@
<?php
require_once "header.php";
require_once "config.php";
require_once "db_config.php";
print (_("This is the Statistics of Moha"));
require_once "footer.php";
?>