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 . "/dashboard_conf.php";
require_once "class/main.php";
require_once "webserver/cmd_functions.php";
//require_once "webserver/display_stats.php";
require_once "apiserver/cmd_functions.php";
// opening listening server
@ -45,7 +44,7 @@ function htmlSend($socket, $text, $meta="")
stream_socket_sendto($socket, $response);
}
function askWebServer($read)
function apiServer($read)
{
global $topics, $indexDevices, $devices;
$array = array();
@ -117,15 +116,24 @@ function askWebServer($read)
case "type":
logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__);
//htmlSend($spawn, webDisplayByType($argList));
case "stat":
/*case "stats":
logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__);
htmlSend($spawn, displayStats($argList));
displayStats($spawn, $argList);*/
default:
if (is_numeric(array_key_first($argList)))
{
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))
{
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")
{
global $dashboards, $indexDevices;
require_once "webserver/javascript.php";
logger(DEBUG, _("webDashboard function"));
require_once "apiserver/javascript.php";
logger(DEBUG, _("webDashboard function"), __FILE__ . ":" . __LINE__);
$response = insertJavascript();
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__);
$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;
}else
@ -99,7 +102,7 @@ function displayChoice($device, $propertyName, $value)
//$formHTML .= $device->friendlyName . aliases($device->friendlyName, $property) . ' => ';
$formHTML = '<input type="number" id="' . $device->topic . "/"
. $device->friendlyName . "/"
. $propertyObject["name"] ."/value" . '"'
. $propertyObject["name"] . '"'
. ' min="' . $propertyObject["value_min"] . '"'
. ' max="' . $propertyObject["value_max"] . '"'
. $step
@ -110,7 +113,7 @@ function displayChoice($device, $propertyName, $value)
$formHTML .= ' max="' . $propertyObject["value_max"] . '"';
$formHTML .= ' value="' . $propertyObject["value"] . '"';
$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;
case "enum":
logger(DEBUG, _("type is enum"), __FILE__ . ":" . __LINE__);
@ -130,7 +133,7 @@ function mkHTML($device, $propertyName, $choice)
logger(DEBUG, "function mkHTML", __FILE__ . ":" . __LINE__);
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;
}
@ -179,7 +182,7 @@ function webBrowse($socket, $argList, $page="/browse")
if (is_a($device, "device"))
{
require_once "webserver/javascript.php";
require_once "apiserver/javascript.php";
$response .= insertJavascript();
foreach($device->properties as $key => $value)
{
@ -400,7 +403,7 @@ function webDisplayByType($argList)
{
global $indexTypes, $config;
require_once $config . "porpertiesbytype.php";
require_once "webserver/javascript.php";
require_once "apiserver/javascript.php";
$response .= insertJavascript();
foreach($indexTypes[$argList["type"]] as $device)

View File

@ -6,13 +6,20 @@ return '<script language="javascript">
<!--
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();
xhr.open("GET", "http://192.168.1.253:' . $listenPort . '/set&fn="+fn+"&property="+property+"&topic="+topic+"&value="+value);
xhr.onload = function () {};
xhr.send();
}
function getPropertyValue(topic, fn, property)
{
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
{
public $hookName = "etage_plan_travail_eclairage";
public $active = false; //enable/disable hook (true => enabled)
public $delay = 3; // amount of time in $timeunit
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_CUISINE_PLAN_TRAVAIL_ECLAIRAGE => "state");
protected $devicelist = array(ETAGE_CUISINE_PLAN_TRAVAIL_INTER => "action");
// callback fonction. Is called with these 3 parameters
// $device -> calling device
@ -14,14 +14,16 @@ class etage_plan_travail_eclairage extends hook
// $value -> value of the property
public function callBack($device, $property, $value)
{
logger(DEBUG, sprintf(_("property=%s, value=%s"), $property, $value), __FILE__ . ":" . __LINE__);
// here your code
if($value == "ON") // ON
logger(DEBUG, "Callback : " . $this->hookName, __FILE__ . ":" . __LINE__);
if($value == "single")
{
if(getValue(ETAGE_CUISINE_PLAN_TRAVAIL_ECLAIRAGE, "state") == '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));
}
@ -31,18 +33,31 @@ class etage_plan_travail_eclairage extends hook
global $devices, $indexDevices;
$device = & $indexDevices[ETAGE_CUISINE_PLAN_TRAVAIL_SPOT];
$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));
$device->payload = $msg;
$device->set();
$device->method = $method;
}else
{
logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $device->friendlyName));
}
//echo 'delaystate = ' . var_dump($delayState);
$device->properties["state_l1"]["method"] = $method;
if ($delayState !== false) setDelay($device, $this->delay, $this->timeUnit, "state_l1", $delayState, true);
$device = & $indexDevices[ETAGE_CUISINE_PLAN_TRAVAIL_ECLAIRAGE];
$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);
}
}

View File

@ -30,12 +30,14 @@ class hook
if ($this->active === true)
{
foreach ($this->devicelist as $ieeeAddress => $property)
{
if (array_key_exists($ieeeAddress, $devices))
{
logger(DEBUG, _("Device: ") . $ieeeAddress, __FILE__ . ":" . __LINE__);
if ($this->propertyInitialized[$ieeeAddress][$property] === false)
{
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");
$this->propertyInitialized[$ieeeAddress][$property] = true;
@ -50,6 +52,12 @@ class hook
{
logger(DEBUG, _("Callback already installed"), __FILE__ . ":" . __LINE__);
}
}else
{
logger(ERROR, $ieeeAddress . (" does not exists"), __FILE__ . ":" . __LINE__);
mkIndexes();
}
}
//echo "result => "; var_dump($result);
if ($result === true)

View File

@ -22,7 +22,6 @@ class topic {
class device
{
public $method; //0 = auto or 1 = manual
public $topic;
public $ieeeAddress;
public $groupID;
@ -40,9 +39,8 @@ class device
$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);
}
@ -72,6 +70,7 @@ class event
public $stopDatetime;
public $recurrenceInterval; // interval : for recurrent event
public $exceptionInterval; // array of object ranges
public $method; // cf: constants.php (IDLE, AUTO, MANUAL)
}
class watch

View File

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

View File

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

View File

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

View File

@ -40,10 +40,24 @@ function mkDevicesDB($topic, $json, $group=false)
//print_r($json);
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);
$device = & $devices[$topic];
print_r($jsonDevice);
foreach($fnTree as $fnPart)
{
if (!array_key_exists($fnPart, $device))
@ -62,39 +76,28 @@ function mkDevicesDB($topic, $json, $group=false)
if ($group)
{
//print_r($device);
$device["device"]->groupID = $jsonDevice->id;
$device["device"]->ieeeAddress = $jsonDevice->id;
$device["device"]->groupID = $jsonDevice["id"];
$device["device"]->ieeeAddress = $jsonDevice["id"];
//$indexDevices[$device["device"]->groupID] = & $device["device"];
//$indexFriendlyNames[$topic][$fn] = & $device["device"];
}else
{
addDevice($topic, $device["device"], $fn, $jsonDevice);
}
}
$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 )
$device["device"]->type = $jsonDevice["type"];
$device["device"]->ieeeAddress = $jsonDevice["ieee_address"];
if ( !empty($jsonDevice["power_source"] ))
{
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;
searchPropertyKey($fn, $device, $jsonDevice->definition->exposes, $listPropertiesKeys);
$device["device"]->description = $jsonDevice["definition"]["description"];
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
//$indexDevices[$device->ieeeAddress] = & $device;
@ -106,16 +109,18 @@ function searchPropertyKey($fn, &$device, $inputObject, $listPropertiesKeys)
//foreach($listPropertiesKeys as $propertyKey)
//{
logger(DEBUG, _("searching for property"), __FILE__ . ":" . __LINE__ );
if (is_object($inputObject))
{
if (property_exists($inputObject, "property"))
//if (is_object($inputObject))
//{
//print_r($inputObject);
if (array_key_exists("property", $inputObject))
{
logger(DEBUG, _("property Key exists filling properties"), __FILE__ . ":" . __LINE__ );
$string = $inputObject->property;
$string = $inputObject["property"];
if (!array_key_exists($string, $device->properties))
{
$device->properties[$string]["value"] = null;
$device->properties[$string]["functions"] = array();
$device->properties[$string]["method"] = IDLE;
}
foreach($inputObject as $key2 => $value2)
{
@ -127,25 +132,27 @@ function searchPropertyKey($fn, &$device, $inputObject, $listPropertiesKeys)
}
}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__ );
searchPropertyKey($fn, $device, $value, $listPropertiesKeys);
}
}*/
}
//print_r($device);
}elseif (is_array($inputObject))
//}
/*elseif (is_array($inputObject))
{
foreach($inputObject as $value)
{
logger(DEBUG, _("value is object or group, iterating"), __FILE__ . ":" . __LINE__ );
searchPropertyKey($fn, $device, $value, $listPropertiesKeys);
}
}
}*/
}
@ -209,6 +216,7 @@ function iterateDevice($topic, $fn, &$parentDevice, &$properties, $payloadArray,
{
$properties[$key] = array("value" => $value);
$properties[$key]["functions"] = array();
$properties[$key]["method"] = IDLE;
}elseif ($properties[$key]["value"] !== $value)
{
changeValue($properties[$key], $value, $parentDevice, $propertyTree, $key);
@ -302,16 +310,16 @@ function iterate2device(&$object)
$object = &$device;
//print("=============" . $device->friendlyName);
if (!array_key_exists($object->ieeeAddress, $indexDevices))
{
//if (!array_key_exists($object->ieeeAddress, $indexDevices))
//{
//print("============>");
$indexDevices[$object->ieeeAddress] = &$object;
$indexFriendlyNames[$object->topic][$object->friendlyName] = &$object;
$indexFriendlyNames[$object->friendlyName] = &$object;
if (property_exists($object, "type"))
{
$indexTypes[$object->type][] = &$object;
}
}
//}
return true;
}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__);
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)
{
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())
{
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;
if ($event->method !== null)
{
$event->device->properties[$event->param]["method"] = $event->method;
}
//echo "#################################\nUnsetting event $key \n###########################" . EOL;
unset($events[$key]);
}
@ -66,7 +71,7 @@ function checkEvents()
$logLevel = $oldLevel;
}
function setOneshotEvent(&$deviceObject, $datetime, $property, $value, $replace=false)
function setOneshotEvent(&$deviceObject, $datetime, $property, $value, $replace=false, $method=null)
{
global $events;
$events[] = new event;
@ -77,9 +82,10 @@ function setOneshotEvent(&$deviceObject, $datetime, $property, $value, $replace=
$events[$key]->param = $property;
$events[$key]->value = $value;
$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;
$string = "P";
@ -108,9 +114,10 @@ function setRecurrentEvent(&$deviceObject, $property, $value, $startDatetime, $s
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;
$oldLevel = $logLevel;
@ -153,7 +160,7 @@ function setDelay(&$deviceObject, $delay, $unit, $property, $value, $replace=fal
if ($replace)
{
$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");
$events[] = new event;
@ -164,16 +171,19 @@ function setDelay(&$deviceObject, $delay, $unit, $property, $value, $replace=fal
$events[$key]->param = $property;
$events[$key]->value = $value;
$events[$key]->device = & $deviceObject;
if ($method !== null) $events[$key]->method = $method;
logger (DEBUG, _('Setting new delay in $events[]'), __FILE__ . ":" . __LINE__);
//print_r($events[$key]);
$logLevel = $oldLevel;
}
function removeEvent($deviceObject, $property , $value)
function removeEvent($deviceObject, $property , $value, $method = null)
{
global $events;
$eventKey = searchEvent($deviceObject, $property , $value);
if ($eventKey !== false)
{
if ($method !== null) $events[$eventKey]->device->method = $method;
deleteEvent($eventKey);
}
}
@ -188,24 +198,27 @@ function searchEvent($deviceObject, $property , $value)
//echo "===>";print_r($event); echo EOL;
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 false;
}
// warning delete event does not manage method of the device (IDLE, )
function deleteEvent($eventKey)
{
global $events;
if ($eventKey !== false)
{
unset ($events[$eventKey]);
logger(INFO, _("delete event key =") . $eventKey, __FILE__ . ":" . __LINE__);
if (array_key_exists($eventKey, $events))
{
unset ($events[$eventKey]);
}else
{
//try to delete an flase event
logger(WARNING, _("Try to delete event with key = ") . var_export($eventKey, true), __FILE__ . ":" . __LINE__);
logger(ERROR, _("event key does not exists: ") . $eventKey, __FILE__ . ":" . __LINE__);
}
}
}

View File

@ -22,7 +22,7 @@ class notificationFreemobile
{
$ch = curl_init();
// 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;
//return the transfer as a string
//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__);
$device->payload = $msg;
$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_ECLAIRAGE => "state_l1", // "ON"/"OFF"
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
@ -26,19 +27,44 @@ class rdc_chambre_eclairage extends hook
$lux = $indexDevices[RDC_CHAMBRE_LUMINOSITE]->properties["illuminance_lux"];
$targetAmbiance = $indexDevices[RDC_CHAMBRE_AMBIANCE];
$targetEclairage = $indexDevices[RDC_CHAMBRE_ECLAIRAGE];
logger(DEBUG, sprintf(_("property=%s, value=%s"), $property, $value), __FILE__ . ":" . __LINE__);
if ($property == "occupancy" and $value == ON)
{
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")
{
if ($value == false)
logger(DEBUG, _("CASE: contact"), __FILE__ . ":" . __LINE__);
if ($value === false)
{
$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__);
@ -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__);
$deviceObject->payload = $msg;
$deviceObject->set();
$deviceObject->method = $method;
$deviceObject->properties[$property]["method"] = $method;
///}else
/*{
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))
{
logger(INFO, _("Setting to OFF"), __FILE__ . ":" . __LINE__);
setDelay($deviceTarget, $this->delay, $this->timeUnit, "state", "OFF", true);
//$this->send($deviceTarget, "ON", "OFF", AUTO);
//setDelay($deviceTarget, $this->delay, $this->timeUnit, "state", "OFF", true);
$this->send($deviceTarget, "OFF", false, IDLE);
}
}
break;
case "contact":
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__);
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
{
$this->send($deviceTarget, "ON", "OFF", AUTO);
@ -70,20 +70,20 @@ class rdc_salon_eclairage extends hook
break;
case "illuminance_lux":
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__);
//$this->send($deviceTarget, "OFF", null, AUTO);
//removeEvent($indexDevices[RDC_SALON_ECLAIRAGE_PANNEAU], "state", "OFF");
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__);
$this->send($deviceTarget, "ON", false, 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__);
@ -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__);
$deviceTarget->payload = $msg;
$deviceTarget->set();
$deviceTarget->method = $method;
$deviceTarget->properties["state"]["method"] = $method;
/*}else
{
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;
//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__);
switch($property)
{
@ -37,31 +39,36 @@ class rdc_sdb_eclairage extends hook
if ($value == ON )
{
$this->send("ON");
$device->method = AUTO;
$deviceTarget->properties["state_l1"]["method"] = AUTO;
}
break;
case "state_l1":
logger(DEBUG, _("CASE: state_l1"), __FILE__ . ":" . __LINE__);
if ($value == "ON")
{
if ($device->method != MANUAL)
if ($deviceTarget->properties["state_l1"]["method"] != MANUAL)
{
$delay = $this->delay;
$device->method = AUTO;
$deviceTarget->properties["state_l1"]["method"] = AUTO;
}else
{
$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")
{
removeEvent($deviceTarget, "state_l1", "OFF");
$device->method = null;
$deviceTarget->properties["state_l1"]["method"] = IDLE;
}
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__);
}else
{
logger (ERROR, RDC_SDB_WC_ECLAIRAGE . _(" does not exists"), __FILE__ . ":" . __LINE__);
}
}
private function send($state)

View File

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

View File

@ -9,7 +9,7 @@ class rdc_wc_eclairage extends hook
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 $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)
{
global $indexDevices;
//var_dump($value);
$targetDevice = &$indexDevices[RDC_SDB_WC_ECLAIRAGE]; //var_dump($value);
logger(DEBUG, "Callback : " . $this->hookName, __FILE__ . ":" . __LINE__);
switch($property)
{
@ -25,38 +26,39 @@ class rdc_wc_eclairage extends hook
logger(DEBUG, "CASE: state_l2", __FILE__ . ":" . __LINE__);
if ($value == "ON")
{
if ($device->method == AUTO)
if ($targetDevice->properties["state_l1"]["method"] !== AUTO)
{
setDelay($device, $this->delay, $this->timeUnit, "state_l2", "OFF", true);
}else
{
$device->method = MANUAL;
setDelay($device, $this->delayManual, $this->timeUnit, "state_l2", "OFF", true);
$targetDevice->properties["state_l1"]["method"] = MANUAL;
//setDelay($device, $this->delayManual, $this->timeUnit, "state_l2", "OFF", true);
}
}elseif ($value == "OFF")
{
removeEvent($device, "state_l2", "OFF");
$device->method = null;
removeEvent($device, "state_l2", "OFF", IDLE);
}
break;
case "occupancy":
logger(DEBUG, "CASE: occupancy", __FILE__ . ":" . __LINE__);
if ($value == true)
{
$device->method = AUTO;
$this->send("ON");
$targetDevice->properties["state_l2"]["method"] = AUTO;
//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__);
}
private function send($state)
private function send($targetDevice, $state)
{
global $indexDevices;
$deviceObject = $indexDevices[RDC_SDB_WC_ECLAIRAGE];
$msg = array("state_l2" => $state);
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $deviceObject->friendlyName), __FILE__ . ":" . __LINE__);
$deviceObject->payload = $msg;
$deviceObject->set(null);
logger(INFO, sprintf(_("publishing message: %s to %s"), json_encode($msg), $targetDevice->friendlyName), __FILE__ . ":" . __LINE__);
$targetDevice->payload = $msg;
$targetDevice->set(null);
}
}

View File

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

View File

@ -6,7 +6,7 @@ function messageReceived($message)
global $topics, $logFh, $devices, $included;
$topic = explode ("/", $message->topic);
$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);
}

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])
{
case "info":
$topics[$topic[0]]->info = json_decode($message->payload);
$topics[$topic[0]]->info = json_decode($message->payload, true);
break;
case "devices":
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));
mkDevicesDB($topic[0], $topics[$topic[0]]->devices);
getDevicesValues($topic[0]);
break;
case "groups":
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);
break;
case "extensions":
$topics[$topic[0]]->extensions = json_decode($message->payload);
$topics[$topic[0]]->extensions = json_decode($message->payload, true);
break;
case "config":
$topics[$topic[0]]->config = json_decode($message->payload);
$topics[$topic[0]]->config = json_decode($message->payload, true);
break;
case "logging":
//TODO
@ -64,23 +64,45 @@ function zigbee2mqttCallback($topic, $message)
array_pop ($fnTree);
$fn = implode("/", $fnTree);
$fn = implode("/", $fnTree);
if (($payloadArray = json_decode($message->payload, true)) === null)
{
$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 (!array_key_exists($fn, $indexFriendlyNames[$topicName]))
$flag = 0;
$alert = 0;
while (!array_key_exists($fn, $indexFriendlyNames))
{
mkDevicesDB($topicName, $message->payload);
logger(ERROR, sprintf(_("device with friendlyname %s not found"), $fn), __FILE__ . ":" . __LINE__);
}else
logger(INFO, _("device does not exists in IndexFriendlyNames: ") . print_r($payloadArray,true), __FILE__ . ":" . __LINE__);
if ($flag == 0)
{
logger(DEBUG, "PayloadArray = " . print_r($payloadArray,true), __FILE__ . ":" . __LINE__);
changeDevice($topicName, $fn, $indexFriendlyNames[$topicName][$fn], $payloadArray);
logger(INFO, "Reindexing all indexes", __FILE__ . ":" . __LINE__);
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
{
logger(DEBUG, _("Zigbee2mqtt doing get or set !?"));

View File

@ -81,9 +81,15 @@ function getDevice($topic, $fn)
function getValue($ieeeAddress, $property)
{
global $indexDevices;
if (array_key_exists($property, $indexDevices[$ieeeAddress]->properties))
{
$r = $indexDevices[$ieeeAddress]->properties[$property]["value"];
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;
}

View File

@ -8,21 +8,32 @@
function displayStats($socket, $argList)
{
global $indexFriendlyNames;
global $indexFriendlyNames, $mohaDB;
logger(INFO, "Function displayStats", __FILE__ . ":" . __LINE__);
// Validation of the dates
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(!$this->result = $this->query($query))
if (!array_key_exists($argList["fn"], $indexFriendlyNames))
{
logger(ERROR, _("mysql query errror: ") . $this->error, __FILE__ . ":" . __LINE__);
}
$datas = $this->result->fetch_all(MYSQLI_ASSOC);
diagramDisplay($datas);
htmlSend($socket, $argList["fn"] . _(" not found: Verify the syntax"));
}elseif(!array_key_exists($argList["property"], $indexFriendlyNames[$argList["fn"]]->properties))
{
htmlSend($socket, $argList["property"] . _(" not found : Verify the syntax"));
}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;
$ndata = count($datas);
$min = min($datas);
$max = max($datas);
$i = $ndata;
$tmp = min($datas);
$min = $tmp["value"];
$tmp = max($datas);
$max = $tmp["value"];
//Type mime de l'image
//Chemin vers le police à utiliser
$font_file = '/usr/share/fonts/TTF/dejavu/DejaVuSans.ttf';
@ -64,6 +78,7 @@ function diagramDisplay($datas)
//Tracer l'axe des ordonnées
imageline($courbe, 50, $hauteur - $absis, 50, 20, $noir);
//Decaler 10px vers le haut le si le minimum est différent de 0
$a = 0;
if($min != 0)
{
$absis += 10;
@ -94,14 +109,17 @@ function diagramDisplay($datas)
$j = -1;
$pasX = 90;
//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
$y = ($hauteur) - (($quantite - $min) * ($echelleY / $py)) - $absis;
//dessiner le point
imagefilledellipse($courbe, $pasX, $y, 6, 6, $rouge);
//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
imageline($courbe, $pasX, $hauteur - $absis + $a, $pasX, $y, $noir);
if($j!==-1)
@ -118,8 +136,12 @@ function diagramDisplay($datas)
$pasX +=$echelleX;
}
//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);
}
?>

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";
?>