debugging
This commit is contained in:
parent
1361cb9395
commit
425107cec7
14
class/db.php
14
class/db.php
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
logger(DEBUG,"Including db.php");
|
||||
logger(DEBUG, _("Including db.php"));
|
||||
|
||||
class db extends mysqli
|
||||
{
|
||||
@ -19,13 +19,13 @@ class db extends mysqli
|
||||
}
|
||||
while ($this->connect($this->mysqlServer, $this->username, $this->passwd, $this->database) === false)
|
||||
{
|
||||
logger(ERROR,_("Connection to sql server error :") . $this->connect_error);
|
||||
logger(ERROR,_("Connection to sql server error :") . $this->connect_error, __FILE__ . ":" . __LINE__);
|
||||
sleep(5);
|
||||
$flagError = true;
|
||||
}
|
||||
if ($flagError === true)
|
||||
{
|
||||
logger(ERROR, _("Connection to sql server ready"));
|
||||
logger(ERROR, _("Connection to sql server ready"), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
$result = new mysqli_result($this);
|
||||
}
|
||||
@ -56,7 +56,7 @@ class db extends mysqli
|
||||
$minMax = $minMax($value);
|
||||
}
|
||||
|
||||
echo "minMax = " .$minMax . EOL;
|
||||
//echo "minMax = " .$minMax . EOL;
|
||||
//echo "oldValue = " . $oldValue . EOL;
|
||||
//echo "Value = " . $value . EOL;
|
||||
if ($value >= $oldValue - $minMax and $value <= $oldValue + $minMax)
|
||||
@ -67,15 +67,15 @@ class db extends mysqli
|
||||
}
|
||||
if ($testMode)
|
||||
{
|
||||
logger(INFO, _("Test mode on: not storing in DB "));
|
||||
logger(INFO, _("Test mode on: not storing in DB "), __FILE__ . ":" . __LINE__);
|
||||
}else
|
||||
{
|
||||
if(!$this->result = $this->query($query))
|
||||
{
|
||||
logger(ERROR, _("mysql query errror: ") . $this->error);
|
||||
logger(ERROR, _("mysql query errror: ") . $this->error, __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
}
|
||||
logger(INFO, sprintf(_("New value of property: '%s' of device: %s stored in database"), $propertyTree, $device->friendlyName, $value));
|
||||
logger(INFO, sprintf(_("New value of property: '%s' of device: %s stored in database"), $propertyTree, $device->friendlyName, $value), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,31 +26,31 @@ class hook
|
||||
{
|
||||
foreach ($this->devicelist as $ieeeAddress => $property2change)
|
||||
{
|
||||
logger(DEBUG, _("Device: ") . $ieeeAddress);
|
||||
logger(DEBUG, _("Device: ") . $ieeeAddress, __FILE__ . ":" . __LINE__);
|
||||
if ($property2change[1] === false)
|
||||
{
|
||||
logger(DEBUG, _("Trying to store callback"));
|
||||
logger(DEBUG, _("Trying to store callback"), __FILE__ . ":" . __LINE__);
|
||||
if (isset($indexDevices[$ieeeAddress]))
|
||||
{
|
||||
$property = $property2change[0];
|
||||
$indexDevices[$ieeeAddress]->$property["functions"][] = array($this,"callback");
|
||||
$property2change[1] = true;
|
||||
logger(DEBUG, sprintf(_("Property '%s' is initialized with callback"), $property2change[0]));
|
||||
logger(DEBUG, sprintf(_("Property '%s' is initialized with callback"), $property2change[0]), __FILE__ . ":" . __LINE__);
|
||||
}else
|
||||
{
|
||||
logger(WARNING, sprintf(_("Hook %s can not initialize Property '%s' of device %s"), $this->hookName, $property2change[0], $ieeeAddress));
|
||||
logger(WARNING, sprintf(_("Hook %s can not initialize Property '%s' of device %s"), $this->hookName, $property2change[0], $ieeeAddress), __FILE__ . ":" . __LINE__);
|
||||
$result = false;
|
||||
}
|
||||
}else
|
||||
{
|
||||
logger(DEBUG, _("Callback already installed"));
|
||||
logger(DEBUG, _("Callback already installed"), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
}
|
||||
//echo "result => "; var_dump($result);
|
||||
if ($result === true)
|
||||
{
|
||||
$this->initialized = true;
|
||||
logger(DEBUG, $this->hookName . (" initialized"));
|
||||
logger(DEBUG, $this->hookName . _(" initialized"), __FILE__ . ":" . __LINE__);
|
||||
//var_dump($this);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
logger(DEBUG,"Including class main.php");
|
||||
logger(DEBUG, _("Including class main.php"), __FILE__ . ":" . __LINE__);
|
||||
|
||||
class Message
|
||||
{
|
||||
|
@ -8,16 +8,6 @@ define("OFF", 0);
|
||||
define("AUTO", 0);
|
||||
define("MANUAL", 1);
|
||||
|
||||
// log levels
|
||||
/*define( "DEBUG", 16); // => 16
|
||||
define( "INFO", 1); // => 1
|
||||
define( "NOTICE", 2); // => 2
|
||||
define( "WARNING", 4); // => 4
|
||||
define( "ERROR", 8); // => 8
|
||||
define( "ALERT", 32);
|
||||
|
||||
*/
|
||||
|
||||
$logLevels = array(
|
||||
1 => "INFO",
|
||||
2 => "NOTICE",
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
logger(DEBUG,"Including db_functions.php");
|
||||
logger(DEBUG,_("Including db_functions.php"), __FILE__ . ":" . __LINE__);
|
||||
|
||||
// to save or not to save the DB, that is the question ...
|
||||
function storeDB($db, $filepath)
|
||||
@ -58,7 +58,7 @@ function mkDevicesDB($topic, $json, $group=false)
|
||||
fwrite($logFh, print_r($devices, true));
|
||||
fwrite($logFh, "################################END##################################################");
|
||||
|
||||
echo "Devices DB made" . EOL;
|
||||
logger(DEBUG, _("Devices DB made"), __FILE__ . ":" . __LINE__);
|
||||
//print_r($devices);
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ function changeDevice($topic, $fn, &$device, $payloadArray)
|
||||
iterateDevice($topic, $fn, $device, $device, $payloadArray);
|
||||
}else
|
||||
{
|
||||
logger(ERROR, _("payloadArray is empty!"));
|
||||
logger(ERROR, _("payloadArray is empty!"), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
|
||||
}
|
||||
@ -205,11 +205,11 @@ function iterateDevice($topic, $fn, $parentDevice, &$device, $payloadArray, $pro
|
||||
$device->$key["value"] = $value;
|
||||
//$changed[$fn]["key"] = $key;
|
||||
//$changed[$fn]["value"] = $value;
|
||||
logger(INFO, sprintf(_("Device %s property %s, %s"), $fn, $propertyTree . $key, bool2string($value)));
|
||||
logger(INFO, sprintf(_("Device %s property %s, %s"), $fn, $propertyTree . $key, bool2string($value)), __FILE__ . ":" . __LINE__);
|
||||
$mohaDB->logProperty($parentDevice, $propertyTree . $key, $value, $oldValue);
|
||||
if (!empty($device->$key["functions"]))
|
||||
{
|
||||
logger(DEBUG,_("executing notifications functions"));
|
||||
logger(DEBUG,_("executing notifications functions"), __FILE__ . ":" . __LINE__);
|
||||
foreach($device->$key["functions"] as $function)
|
||||
{
|
||||
$function($device, $key, $value);
|
||||
|
@ -5,7 +5,7 @@ function logDevice(& $device, $key, $value)
|
||||
$db = new mysqli($mysqlServer, $username, $passwd, $database);
|
||||
if ($conn->connect_error)
|
||||
{
|
||||
logger(ERROR, _("Mysql connection failed: ") . $db->connect_error);
|
||||
logger(ERROR, _("Mysql connection failed: ") . $db->connect_error, __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,25 +1,19 @@
|
||||
<?php
|
||||
|
||||
class <name_of_class>
|
||||
class <name_of_class> extends hook
|
||||
{
|
||||
public $hookName = <public name of the hook>;
|
||||
public $active = true; enable/disable hook (true => enabled)
|
||||
public $active = true; //enable/disable hook (true => enabled)
|
||||
|
||||
private $devicelist = array(<ieee address or constant defined in config/devices_constants.php>) => <property of the device to watch>);
|
||||
protected $devicelist = array(<ieee address or constant defined in config/devices_constants.php> => array(<property of the device to watch>, false));
|
||||
|
||||
// assigne the function to the sensors devices
|
||||
function __construct()
|
||||
// if you need some initialisation when creating the object, uncomment andput your code here.
|
||||
// If existing, This function is called by __construct
|
||||
/*protected function init()
|
||||
{
|
||||
global $indexDevices;
|
||||
if ($this->active === true)
|
||||
{
|
||||
foreach ($this->devicelist as $ieeeAddress => $property)
|
||||
{
|
||||
$indexDevices[$ieeeAddress]->$property["functions"][] = array($this,"callback");
|
||||
}
|
||||
}
|
||||
// put here your code to init the class
|
||||
// Your code here
|
||||
}
|
||||
*/
|
||||
|
||||
// callback fonction. Is called with these 3 parameters
|
||||
// $device -> calling device
|
||||
@ -29,7 +23,7 @@ class <name_of_class>
|
||||
{
|
||||
// here your code
|
||||
|
||||
logger (INFO, _("%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), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
|
28
events.php
28
events.php
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
logger(DEBUG,"Including events.php");
|
||||
logger(DEBUG, _("Including events.php"));
|
||||
|
||||
/* for all functions, datetime parameter format is 'dd/mm/yy hh:mm:ss' */
|
||||
|
||||
@ -15,13 +15,13 @@ function checkEvents()
|
||||
$now = now();
|
||||
if (!empty($event->startDatetime))
|
||||
{
|
||||
logger(DEBUG, _("StarDatetime is set"));
|
||||
logger(DEBUG, _("StarDatetime is set"), __FILE__ . ":" . __LINE__);
|
||||
if($event->dateTimeEvent < $now)
|
||||
{
|
||||
logger(DEBUG, _("Event must be executed"));
|
||||
logger(DEBUG, _("Event must be executed"), __FILE__ . ":" . __LINE__);
|
||||
if (!empty($event->exceptionInterval))
|
||||
{
|
||||
logger(DEBUG, _("Testing exceptions"));
|
||||
logger(DEBUG, _("Testing exceptions"), __FILE__ . ":" . __LINE__);
|
||||
foreach($event->exceptionInterval as $key => $value)
|
||||
{
|
||||
if($now > $value->start and $now < $value->end)
|
||||
@ -35,17 +35,17 @@ function checkEvents()
|
||||
}
|
||||
if ($exception === false)
|
||||
{
|
||||
logger(DEBUG, sprintf(_("sending command set %s => %s for %s"), $event->param ,bool2string($event->value), $event->device->friendlyName));
|
||||
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", $key);
|
||||
if (($event->dateTimeEvent->add($event->recurrenceInterval)) === false)
|
||||
{
|
||||
logger(ERROR, _("Error in adding interval to event recurrence. event: ") . $key);
|
||||
logger(ERROR, _("Error in adding interval to event recurrence. event: ") . $key, __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
}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));
|
||||
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);
|
||||
$event->published = $now;
|
||||
//echo "#################################\nUnsetting event $key \n###########################" . EOL;
|
||||
@ -95,7 +95,7 @@ function setRecurrentEvent(&$device, $property, $value, $startDatetime, $stopDat
|
||||
$event->dateTimeEvent = $event->startDatetime;
|
||||
if (($event->dateTimeEvent->add($event->recurrenceInterval)) === false)
|
||||
{
|
||||
logger(ERROR, _("Error in event recurrence. event: ") . $key);
|
||||
logger(ERROR, _("Error in event recurrence. event: ") . $key, __FILE__ . ":" . __LINE__);
|
||||
|
||||
}
|
||||
}
|
||||
@ -133,11 +133,11 @@ function setDelay(&$device, $delay, $unit="second", $property, $value, $replace=
|
||||
}
|
||||
if (empty($s))
|
||||
{
|
||||
logger(ERROR, _("setDelay error: unit is empty"));
|
||||
logger(ERROR, _("setDelay error: unit is empty"), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
if (($datetime->add(new DateInterval('PT'. $delay . $s))) === false)
|
||||
{
|
||||
logger(ERROR, _("setDelay error: datetime->add"));
|
||||
logger(ERROR, _("setDelay error: datetime->add"), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
//print_r($datetime);
|
||||
if ($replace)
|
||||
@ -154,7 +154,7 @@ function setDelay(&$device, $delay, $unit="second", $property, $value, $replace=
|
||||
$events[$key]->param = $property;
|
||||
$events[$key]->value = $value;
|
||||
$events[$key]->device = & $device;
|
||||
logger (DEBUG, _('Setting new delay in $events[]'));
|
||||
logger (DEBUG, _('Setting new delay in $events[]'), __FILE__ . ":" . __LINE__);
|
||||
print_r($events[$key]);
|
||||
$loglevel = $oldLevel;
|
||||
}
|
||||
@ -170,7 +170,7 @@ function removeEvent($device, $property , $value)
|
||||
function searchEvent($device, $property , $value)
|
||||
{
|
||||
global $events;
|
||||
logger(DEBUG, _("searching event for device %s, property %s and value %s"), $device->friendlyName, $property, bool2string($value));
|
||||
logger(DEBUG, _("searching event for device %s, property %s and value %s"), $device->friendlyName, $property, bool2string($value), __FILE__ . ":" . __LINE__);
|
||||
foreach($events as $key => $event)
|
||||
{
|
||||
//echo "Event : $event => $value" . EOL;
|
||||
@ -190,11 +190,11 @@ function deleteEvent($eventKey)
|
||||
if ($eventKey !== false)
|
||||
{
|
||||
unset ($events[$eventKey]);
|
||||
logger(INFO, _("delete event key =") . $eventKey);
|
||||
logger(INFO, _("delete event key =") . $eventKey, __FILE__ . ":" . __LINE__);
|
||||
}else
|
||||
{
|
||||
//try to delete an flase event
|
||||
logger(WARNING, _("Try to delete event with key = ") . var_dump($eventKey));
|
||||
logger(WARNING, _("Try to delete event with key = ") . var_dump($eventKey), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,12 +33,12 @@ class notificationFreemobile
|
||||
if ($result === false)
|
||||
{
|
||||
$curlErr += 1;
|
||||
logger(ERROR, sprintf( _("Curl return error %d: %s when sending notification"), curl_errno($ch), curl_error($ch)), false);
|
||||
logger(ERROR, sprintf( _("Curl return error %d: %s when sending notification"), curl_errno($ch), curl_error($ch)), false, __FILE__ . ":" . __LINE__);
|
||||
}/*else
|
||||
{
|
||||
logger(INFO, sprintf(_("Curl return: %s when sending notification"), $result), false);
|
||||
}*/
|
||||
}
|
||||
} //TODO managing curl errors
|
||||
// close curl resource to free up system resources
|
||||
curl_close($ch);
|
||||
return true;
|
||||
|
@ -41,7 +41,7 @@ class availability
|
||||
// $log = INFO;
|
||||
//}
|
||||
//$device->availability = $value;
|
||||
logger($log, sprintf(_("Device: %s/%s is %s"), $device->topic, $device->friendlyName, $value));
|
||||
logger($log, sprintf(_("Device: %s/%s is %s"), $device->topic, $device->friendlyName, $value), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class rdc_chambre_eclairage extends hook
|
||||
{
|
||||
$this->send(RDC_CHAMBRE_LUMINOSITE, "ON", "OFF", AUTO);
|
||||
}
|
||||
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), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
|
||||
private function send($device, $state, $delayState = false, $method = MANUAL)
|
||||
@ -37,13 +37,13 @@ class rdc_chambre_eclairage extends hook
|
||||
$msg = array("state" => $state);
|
||||
if ($device->state["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), __FILE__ . ":" . __LINE__);
|
||||
$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));
|
||||
logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $device->friendlyName), __FILE__ . ":" . __LINE__);
|
||||
|
||||
}
|
||||
//echo 'delaystate = ' . var_dump($delayState);
|
||||
|
@ -23,7 +23,7 @@ class alerte_intrusion extends hook
|
||||
case "contact":
|
||||
if ($value == false)
|
||||
{
|
||||
logger(ALERT, sprintf(_("%s est ouverte alors que personne n'est présent"), $device->friendlyName));
|
||||
logger(ALERT, sprintf(_("%s est ouverte alors que personne n'est présent"), $device->friendlyName), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -21,40 +21,54 @@ class rdc_salon_eclairage extends hook
|
||||
public function callBack(&$device, $param, $value)
|
||||
{
|
||||
global $devices, $indexDevices;
|
||||
logger(INFO, _("hook : rdc_salon_eclairage"));
|
||||
logger(INFO, _("hook : rdc_salon_eclairage"), __FILE__ . ":" . __LINE__);
|
||||
switch($param)
|
||||
{
|
||||
case "occupancy":
|
||||
logger(DEBUG, _("CASE: Occupancy => ") . bool2string($value), __FILE__ . ":" . __LINE__);
|
||||
//print_r($indexDevices[RDC_SALON_LUMINOSITE]);
|
||||
if ($value == ON and $indexDevices[RDC_SALON_LUMINOSITE]->illuminance_lux["value"] <= $this->luminance_min)
|
||||
if ($value == ON and getValue(RDC_SALON_LUMINOSITE, "illuminance_lux") <= $this->luminance_min)
|
||||
{
|
||||
logger(DEBUG, _("setting to ON"), __FILE__ . ":" . __LINE__);
|
||||
$this->send("ON", null, AUTO);
|
||||
removeEvent($indexDevices[RDC_SALON_ECLAIRAGE_PANNEAU], "state", "OFF");
|
||||
}
|
||||
if ($value == OFF)
|
||||
}elseif ($value == OFF)
|
||||
{
|
||||
if ($indexDevices(RDC_SALON_MVMT)->occupancy == OFF and $indexDevices(RDC_SALON_MVMT2)->occupancy == OFF)
|
||||
logger(DEBUG, _("Value is OFF"), __FILE__ . ":" . __LINE__);
|
||||
if (getValue(RDC_SALON_MVMT, "occupancy") == OFF)
|
||||
{
|
||||
setDelay($indexDevices[RDC_SALON_ECLAIRAGE_PANNEAU], $this->delay, $this->timeUnit, "state", "OFF", true);
|
||||
//$this->send("ON", "OFF", AUTO);
|
||||
if (getValue(RDC_SALON_MVMT2, "occupancy") == OFF)
|
||||
{
|
||||
logger(DEBUG, _("Setting to OFF"), __FILE__ . ":" . __LINE__);
|
||||
setDelay($indexDevices[RDC_SALON_ECLAIRAGE_PANNEAU], $this->delay, $this->timeUnit, "state", "OFF", true);
|
||||
//$this->send("ON", "OFF", AUTO);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "contact":
|
||||
if ($value == false and $indexDevices[RDC_SALON_LUMINOSITE]->illuminance_lux["value"] <= $this->luminance_min)
|
||||
logger(DEBUG, _("CASE: Contact Door"), __FILE__ . ":" . __LINE__);
|
||||
if ($value == false and getValue(RDC_SALON_LUMINOSITE, "illuminance_lux") <= $this->luminance_min)
|
||||
{
|
||||
//$this->send("ON", "OFF", AUTO);
|
||||
logger(DEBUG, _("Door is open and illumance < min"), __FILE__ . ":" . __LINE__);
|
||||
$this->send("ON", "OFF", AUTO);
|
||||
}
|
||||
break;
|
||||
case "illuminance_lux":
|
||||
logger(DEBUG, _("CASE : Illuminance"), __FILE__ . ":" . __LINE__);
|
||||
if ($value >= $this->luminance_max)
|
||||
{
|
||||
logger(DEBUG, _("illuminace is > to max"), __FILE__ . ":" . __LINE__);
|
||||
//$this->send("OFF", null, AUTO);
|
||||
removeEvent($indexDevices[RDC_SALON_ECLAIRAGE_PANNEAU], "state", "OFF");
|
||||
}elseif ($value <= $this->luminance_min and (getValue(RDC_SALON_MVMT, "occupancy") == ON OR getValue(RDC_SALON_MVMT2,"occupancy") == ON))
|
||||
{
|
||||
logger(DEBUG, _("illuminance < min and movement detected"), __FILE__ . ":" . __LINE__);
|
||||
$this->send("ON", null, AUTO);
|
||||
}
|
||||
break;
|
||||
}
|
||||
logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $param, bool2string($value)));
|
||||
logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $param, bool2string($value)), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
|
||||
private function send($state, $delayState = false, $method = MANUAL)
|
||||
@ -64,13 +78,13 @@ class rdc_salon_eclairage extends hook
|
||||
$msg = array("state" => $state);
|
||||
if ($device->state["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), __FILE__ . ":" . __LINE__);
|
||||
$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));
|
||||
logger(INFO, sprintf(_("not publishing message: %s to %s, already set"), json_encode($msg), $device->friendlyName), __FILE__ . ":" . __LINE__);
|
||||
|
||||
}
|
||||
//echo 'delaystate = ' . var_dump($delayState);
|
||||
|
@ -49,7 +49,7 @@ class rdc_sdb_eclairage extends hook
|
||||
}
|
||||
break;
|
||||
}
|
||||
logger (INFO, sprintf(_("%s: notification received from MQTT from %s => parameter: %s value: %s"), $this->hookName, $device->friendlyName, $property, ($value == 0 ? "OFF" : "ON")));
|
||||
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__);
|
||||
}
|
||||
|
||||
private function send($state)
|
||||
@ -57,7 +57,7 @@ class rdc_sdb_eclairage extends hook
|
||||
global $devices, $indexDevices;
|
||||
$msg = array("state_l1" => $state);
|
||||
$device = & $indexDevices[RDC_SDB_WC_ECLAIRAGE];
|
||||
logger(INFO, sprintf(_("publishing message: %s to %s"), $state, $device->friendlyName));
|
||||
logger(INFO, sprintf(_("publishing message: %s to %s"), $state, $device->friendlyName), __FILE__ . ":" . __LINE__);
|
||||
$device->payload = $msg;
|
||||
$device->set(null);
|
||||
|
||||
|
@ -28,7 +28,7 @@ class rdc_wc_eclairage extends hook
|
||||
}
|
||||
break;
|
||||
}
|
||||
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), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
|
45
moha.php
45
moha.php
@ -56,10 +56,15 @@ function notify($message)
|
||||
return $result;
|
||||
}
|
||||
|
||||
function logger($level, $log, $notif = true)
|
||||
function logger($level, $log, $pos = false, $notif = true)
|
||||
{
|
||||
global $logFh, $logLevel, $notificationLevel, $logLevels;
|
||||
$logString = date("c") . ' ' . $logLevels[$level] . " " . __FILE__ . ":" . __LINE__ . " : " . $log;
|
||||
$logString = date("c") . ' ' . $logLevels[$level] . " " ;
|
||||
if ($pos !== false)
|
||||
{
|
||||
$logString .= $pos;
|
||||
}
|
||||
$logString .= " - " . $log;
|
||||
if ($level & $logLevel)
|
||||
{
|
||||
fwrite($logFh, $logString . EOL);
|
||||
@ -70,7 +75,7 @@ function logger($level, $log, $notif = true)
|
||||
{
|
||||
if(notify("Moha\n" . $logString) === false)
|
||||
{
|
||||
logger(INFO, _("Notification not sent"), false);
|
||||
logger(INFO, _("Notification not sent"), __FILE__ . ":" . __LINE__, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -112,6 +117,8 @@ function endMoha()
|
||||
{
|
||||
global $testMode, $devices, $topics, $nSubscribed ,$client, $logFh, $connected;
|
||||
$x = 0;
|
||||
|
||||
logger(WARNING, _("moha is ending"), __FILE__ . ":" . __LINE__);
|
||||
storeDB($devices, "/usr/share/moha/moha.db");
|
||||
if($testMode) file_put_contents("moha.devices", print_r($devices, true));
|
||||
if ($connected)
|
||||
@ -137,8 +144,8 @@ function connect2mqttServer()
|
||||
global $client;
|
||||
$client->onConnect('connectResponse');
|
||||
}
|
||||
|
||||
logger(DEBUG, _("requiring php modules"), false);
|
||||
logger(WARNING, _("starting moha"), __FILE__ . ":" . __LINE__);
|
||||
logger(DEBUG, _("requiring php modules"), __FILE__ . ":" . __LINE__);
|
||||
require "class/main.php";
|
||||
require "class/db.php";
|
||||
require "class/hook_class.php";
|
||||
@ -152,7 +159,7 @@ require "webserver.php";
|
||||
//logger(DEBUG, _('assigning variable $client to mosquitto class "client"'), false);
|
||||
//$client = new Mosquitto\Client();
|
||||
|
||||
logger(DEBUG, _("Loading stored devices datas"));
|
||||
logger(DEBUG, _("Loading stored devices datas"), __FILE__ . ":" . __LINE__);
|
||||
loadDB($devices, "moha.db");
|
||||
|
||||
|
||||
@ -162,28 +169,28 @@ if (!empty($hooksList))
|
||||
{
|
||||
foreach ($hooksList as $callback)
|
||||
{
|
||||
logger(INFO, _("Including ") . $callback, false);
|
||||
logger(INFO, _("Including ") . $callback, __FILE__ . ":" . __LINE__);
|
||||
include $callback;
|
||||
}
|
||||
}
|
||||
|
||||
logger(DEBUG, _("requiring config files -> devices_constants.php"), false);
|
||||
logger(DEBUG, _("requiring config files -> devices_constants.php"), __FILE__ . ":" . __LINE__);
|
||||
//include predefined file witch define constants for devices
|
||||
if (is_readable($configDir . "/" . "devices_constants.php"))
|
||||
{
|
||||
include $configDir . "/" . "devices_constants.php";
|
||||
//echo "hooklist"; print_r($hooksList); echo EOL;
|
||||
logger(INFO, sprintf(_("%s/devices_constants.define found, so it has been included :-)"), $configDir), false);
|
||||
logger(INFO, sprintf(_("%s/devices_constants.define found, so it has been included :-)"), $configDir), __FILE__ . ":" . __LINE__, false);
|
||||
}else
|
||||
{
|
||||
logger(WARNING, sprintf(_("%s/devices_constants.define not found, so not included :-)"), $configDir), false);
|
||||
logger(WARNING, sprintf(_("%s/devices_constants.define not found, so not included :-)"), $configDir), __FILE__ . ":" . __LINE__, false);
|
||||
}
|
||||
|
||||
// making the list of hooks to include
|
||||
listHooks("./hooks", $hooksList);
|
||||
|
||||
// Program start
|
||||
logger(DEBUG, _("Program start"), false);
|
||||
logger(DEBUG, _("Program start"), __FILE__ . ":" . __LINE__, false);
|
||||
$client = new Mosquitto\Client();
|
||||
|
||||
// defining callback functions
|
||||
@ -193,7 +200,7 @@ try
|
||||
connect2mqttServer();
|
||||
}catch ( Mosquitto\Exception $err)
|
||||
{
|
||||
logger(ALERT, sprintf(_("Error connecting to mosquitto server, retrying in 10 seconds:"), $err), false);
|
||||
logger(ALERT, sprintf(_("Error connecting to mosquitto server, retrying in 10 seconds:"), $err), __FILE__ . ":" . __LINE__, false);
|
||||
sleep (10);
|
||||
exit(1);
|
||||
}
|
||||
@ -208,7 +215,7 @@ $client->onPublish('publishResponse');
|
||||
// connectong to mqtt server
|
||||
$client->connect($mqttServerIp, 1883, 5);
|
||||
|
||||
logger(INFO, _("Subscribing to bridge"), false);
|
||||
logger(INFO, _("Subscribing to bridge"), __FILE__ . ":" . __LINE__, false);
|
||||
foreach($topics as $name => $topic)
|
||||
{
|
||||
$topic->mid = $client->subscribe($name . "/#", 2);
|
||||
@ -217,20 +224,20 @@ foreach($topics as $name => $topic)
|
||||
}
|
||||
|
||||
// starting main loop
|
||||
logger(INFO, _("Starting loop"), false);
|
||||
logger(INFO, _("Starting loop"), __FILE__ . ":" . __LINE__, false);
|
||||
$oneshot = false;
|
||||
while (true)
|
||||
{
|
||||
$client->loop(); // mqtt server loop()
|
||||
if (! $included) // hooks not already included
|
||||
{
|
||||
logger(DEBUG, _("Making hooks list"), false);
|
||||
logger(DEBUG, _("Making hooks list"), __FILE__ . ":" . __LINE__, false);
|
||||
getDevicesValues(); // TODO get the values of devices
|
||||
if (!empty($hooksList)) // some hooks to include if hooklist is not empty
|
||||
{
|
||||
foreach ($hooksList as $hook) // loop to include hooks in hookslist
|
||||
{
|
||||
logger(INFO, _("Including ") . $hook, false);
|
||||
logger(INFO, _("Including ") . $hook, __FILE__ . ":" . __LINE__, false);
|
||||
include $hook;
|
||||
}
|
||||
file_put_contents("/usr/share/moha/moha.devices", print_r($devices, true)); // debugging : save device list
|
||||
@ -242,7 +249,7 @@ while (true)
|
||||
|
||||
if ($oneshot === false) // execute once initialization finished :WARNING hooks can to be not initialized
|
||||
{
|
||||
logger(DEBUG, _("Oneshot part of loop"), false);
|
||||
logger(DEBUG, _("Oneshot part of loop"), __FILE__ . ":" . __LINE__, false);
|
||||
$oneshot = true;
|
||||
}
|
||||
if($hooksInitialized == 0) // all hooks are not initialized
|
||||
@ -252,14 +259,14 @@ while (true)
|
||||
{
|
||||
if ($hook->initialized === false)
|
||||
{
|
||||
logger(WARNING, _("Hook not completely initialized :") . $hookName);
|
||||
logger(WARNING, _("Hook not completely initialized :") . $hookName, __FILE__ . ":" . __LINE__);
|
||||
$i &= $hook->installHooks();
|
||||
}
|
||||
}
|
||||
$hooksInitialized = $i;
|
||||
}else
|
||||
{
|
||||
logger(DEBUG,_("All hooks initialized"));
|
||||
logger(DEBUG,_("All hooks initialized"), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
checkEvents();
|
||||
askWebServer($read);
|
||||
|
@ -6,7 +6,7 @@ function messageReceived($message)
|
||||
global $topics, $logFh, $devices, $included;
|
||||
$topic = explode ("/", $message->topic);
|
||||
$callback = $topics[$topic[0]]->callback;
|
||||
logger(DEBUG, "topic => " . print_r($topic, true));
|
||||
logger(DEBUG, "topic => " . print_r($topic, true), __FILE__ . ":" . __LINE__);
|
||||
$callback($topic, $message);
|
||||
}
|
||||
|
||||
@ -29,33 +29,33 @@ function publish($topic, $payload, $commande="set") //, $eventKey)
|
||||
//echo "setting mids" .EOL;
|
||||
$mids[$mid] = true;
|
||||
}
|
||||
logger(LOG_INFO, $logFh, "Publishing " . $string . " with payload => " . json_encode($payload));
|
||||
logger(LOG_INFO, $logFh, "Publishing " . $string . " with payload => " . json_encode($payload), __FILE__ . ":" . __LINE__);
|
||||
}else
|
||||
{
|
||||
logger(INFO, _("Test mode on: no publishing "));
|
||||
logger(INFO, _("Test mode on: no publishing "), __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
function connectResponse($r, $message)
|
||||
{
|
||||
global $connected;
|
||||
echo sprintf(_("I got code %d and message : '%s'"), $r, $message) . EOL;
|
||||
//echo sprintf(_("I got code %d and message : '%s'"), $r, $message) . EOL;
|
||||
switch ($r)
|
||||
{
|
||||
case 0:
|
||||
echo _("Successfull connection") . EOL;
|
||||
logger(INFO, _("Successfull connection"), __FILE__ . ":" . __LINE__);
|
||||
$connected = true;
|
||||
break;
|
||||
case 1:
|
||||
echo _("Connection refused : unacceptable protocol version") . EOL;
|
||||
logger(ERROR, _("Connection refused : unacceptable protocol version"), __FILE__ . ":" . __LINE__);
|
||||
$connected = true;
|
||||
break;
|
||||
case 2:
|
||||
echo _("Connection refused : identifier rejected") . EOL;
|
||||
logger(ERROR, _("Connection refused : identifier rejected"), __FILE__ . ":" . __LINE__);
|
||||
$connected = true;
|
||||
break;
|
||||
case 3:
|
||||
echo _("Connection refused (broker unavailable )") . EOL;
|
||||
logger(ERROR, _("Connection refused (broker unavailable )"), __FILE__ . ":" . __LINE__);
|
||||
$connected = true;
|
||||
break;
|
||||
}
|
||||
@ -66,7 +66,7 @@ function subscribeResponse($mid, $qosCount)
|
||||
global $topics, $mids, $nSubscribed;
|
||||
//print_r($mids);
|
||||
$key = $mids[$mid];
|
||||
echo _("Subscribed to ") . $key . EOL;
|
||||
logger(INFO, _("Subscribed to ") . $key, __FILE__ . ":" . __LINE__);
|
||||
$topics[$key]->status = true;
|
||||
$nSubscribed += 1;
|
||||
}
|
||||
@ -75,7 +75,7 @@ function unsubscribeResponse($mid)
|
||||
{
|
||||
global $client; //$topics, $mids, $nSubscribed;
|
||||
//$key = $mids[$mid];
|
||||
echo _("Unsubscribed"); // from ") . $topics[$key]->name . EOL;
|
||||
logger(INFO, _("Unsubscribed", __FILE__ . ":" . __LINE__)); // from ") . $topics[$key]->name);
|
||||
//$topics[$key]->status = false;
|
||||
//$nSubscribed -= 1;
|
||||
$client->disconnect();
|
||||
@ -86,19 +86,19 @@ function disconnectResponse($r)
|
||||
global $connected;
|
||||
if ($r != 0)
|
||||
{
|
||||
echo _('Badly ');
|
||||
$str = _('Badly ');
|
||||
}else
|
||||
{
|
||||
echo _('Cleanly ');
|
||||
$str = _('Cleanly ');
|
||||
}
|
||||
echo _("disconnected from server") . EOL;
|
||||
logger(ERROR, $str . _("disconnected from server"));
|
||||
$connected = false;
|
||||
}
|
||||
|
||||
function publishResponse($mid)
|
||||
{
|
||||
global $mids, $events;
|
||||
logger(LOG_INFO, "Event with mid = " . $mid . " published by MQTT broker");
|
||||
logger(LOG_INFO, sprintf(_("Event with mid = %d published by MQTT broker"), $mid), __FILE__ . ":" . __LINE__);
|
||||
if (isset($mids[$mid]))
|
||||
{
|
||||
//echo "unsetting mids" . EOL;
|
||||
|
@ -7,12 +7,12 @@ $topics["linky2mqtt"]->callback = function($topic, $message)
|
||||
global $topics, $logFh, $devices, $included;
|
||||
$topicName = $topic[0];
|
||||
$friendlyName = $topic[1]; // get friendlyName
|
||||
logger(INFO, sprintf(_("Incoming notification of device %s"), $topic[0], $topic[1]));
|
||||
logger(INFO, sprintf(_("Incoming notification of device %s"), $topic[0], $topic[1]), __FILE__ . ":" . __LINE__);
|
||||
$device = & $devices[$topic[0]];
|
||||
$payloadArray = json_decode($message->payload);
|
||||
if (!isset($device[$fn])) //must not exists, but ...
|
||||
{
|
||||
logger(LOG_WARNING, $logFh, "init of " . $fn .EOL);
|
||||
logger(LOG_WARNING, $logFh, _("init of ") . $fn, __FILE__ . ":" . __LINE__);
|
||||
$device[$fn] = array();
|
||||
$device[$fn]["device"] = new device;
|
||||
$device[$fn]["device"]->type = "mesure";
|
||||
|
@ -5,13 +5,13 @@ $topics["pws2mqtt"]->callback = function($topic, $message)
|
||||
{
|
||||
global $topics, $logFh, $devices, $included;
|
||||
$fn = $topic[1]; // get friendlyname
|
||||
logger(INFO, sprintf(_("Incoming notification of device %s => friendly name : %s"), $topic[0], $topic[1]));
|
||||
logger(INFO, sprintf(_("Incoming notification of device %s => friendly name : %s"), $topic[0], $topic[1]), __FILE__ . ":" . __LINE__);
|
||||
$device = & $devices[$topic[0]];
|
||||
$payloadArray = json_decode($message->payload);
|
||||
|
||||
if (!isset($device[$fn]))
|
||||
{
|
||||
logger(WARNING, $logFh, "init of " . $fn .EOL);
|
||||
logger(WARNING, $logFh, _("init of ") . $fn, __FILE__ . ":" . __LINE__);
|
||||
$device[$fn] = array();
|
||||
$device[$fn]["device"] = new device;
|
||||
$device[$fn]["device"]->type = $payloadArray->type;
|
||||
|
@ -11,13 +11,13 @@ $callback = function($topic, $message)
|
||||
$topics[$topic[0]]->info = json_decode($message->payload);
|
||||
break;
|
||||
case "devices":
|
||||
logger(DEBUG,_("Inserting zigbee devices in DB"));
|
||||
logger(DEBUG,_("Inserting zigbee devices in DB"), __FILE__ . ":" . __LINE__);
|
||||
$topics[$topic[0]]->devices = json_decode($message->payload);
|
||||
fwrite($logFh, print_r($topics[$topic[0]]->devices, true));
|
||||
mkDevicesDB($topic[0], $topics[$topic[0]]->devices);
|
||||
break;
|
||||
case "groups":
|
||||
logger(DEBUG,_("Inserting zigbee groups in DB"));
|
||||
logger(DEBUG,_("Inserting zigbee groups in DB"), __FILE__ . ":" . __LINE__);
|
||||
$topics[$topic[0]]->groups = json_decode($message->payload);
|
||||
mkDevicesDB($topic[0], $topics[$topic[0]]->groups, true);
|
||||
break;
|
||||
@ -57,7 +57,7 @@ $callback = function($topic, $message)
|
||||
//print_r($device) ;
|
||||
if (!isset($device[$fn])) //must not exists, but ...
|
||||
{
|
||||
logger(LOG_WARNING, $logFh, "init of " . $fn .EOL);
|
||||
logger(LOG_WARNING, $logFh, _("init of ") . $fn, __FILE__ . ":" . __LINE__);
|
||||
$device[$fn] = array();
|
||||
$device[$fn]["device"] = new device;
|
||||
addDevice($device[$fn], $fn, $payloadArray);
|
||||
|
16
utils.php
16
utils.php
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
logger(DEBUG,"Including utils.php");
|
||||
logger(DEBUG, _("Including utils.php"), __FILE__ . ":" . __LINE__);
|
||||
|
||||
function bool2string($var)
|
||||
{
|
||||
@ -41,7 +41,19 @@ function mktopic($device)
|
||||
return $device->topic . "/" . $device->friendlyName;
|
||||
}
|
||||
|
||||
logger(DEBUG, _("signal handling"), false);
|
||||
function getValue($fn, $property)
|
||||
{
|
||||
global $indexDevices;
|
||||
return $indexDevices[$fn]->$property["value"];
|
||||
}
|
||||
|
||||
function setValue($fn, $property, $value)
|
||||
{
|
||||
global $indexDevices;
|
||||
$indexDevices(RDC_SALON_MVMT2)->occupancy["value"] = $value;
|
||||
}
|
||||
|
||||
logger(DEBUG, _("signal handling"), __FILE__ . ":" . __LINE__, false);
|
||||
//signal handling
|
||||
function signalHandler($signal)
|
||||
{
|
||||
|
@ -20,13 +20,13 @@ function askWebServer($read)
|
||||
|
||||
if ( stream_select( $read, $array, $array, 0 ))
|
||||
{
|
||||
logger(DEBUG,_("socket ready to read"));
|
||||
logger(DEBUG, _("socket ready to read"), __FILE__ . ":" . __LINE__);
|
||||
$spawn = stream_socket_accept($read[0]);
|
||||
if ($spawn !== false)
|
||||
{
|
||||
logger(DEBUG,_("socket accepted"));
|
||||
logger(DEBUG, _("socket accepted"), __FILE__ . ":" . __LINE__);
|
||||
$input = fgets($spawn, 4096);
|
||||
logger(DEBUG, $input);
|
||||
logger(DEBUG, $input, __FILE__ . ":" . __LINE__);
|
||||
if (!empty($input))
|
||||
{
|
||||
$input = substr($input,5);
|
||||
@ -34,17 +34,18 @@ function askWebServer($read)
|
||||
$argTmp = explode("&", $input[0]);
|
||||
foreach($argTmp as $tmp)
|
||||
{
|
||||
logger(DEBUG, $tmp);
|
||||
logger(DEBUG, $tmp, __FILE__ . ":" . __LINE__);
|
||||
$array = explode("=", $tmp);
|
||||
print_r($array);
|
||||
//print_r($array);
|
||||
if (isset($array[1])) $argList[$array[0]] = $array[1];
|
||||
}
|
||||
if(array_key_exists("cmd", $argList))
|
||||
{
|
||||
switch(strtolower($argList["cmd"]))
|
||||
$command = strtolower($argList["cmd"]);
|
||||
switch($command)
|
||||
{
|
||||
case "get":
|
||||
logger(DEBUG, "get reached");
|
||||
logger(DEBUG, _("GET reached"), __FILE__ . ":" . __LINE__);
|
||||
if(empty($argList["device"]))
|
||||
{
|
||||
$response = "<html><header><body>get passed</body></header><html>";
|
||||
@ -52,12 +53,13 @@ function askWebServer($read)
|
||||
fwrite($spawn, $response);
|
||||
break;
|
||||
case "set":
|
||||
logger(DEBUG, "set reached");
|
||||
logger(DEBUG, _("SET reached"), __FILE__ . ":" . __LINE__);
|
||||
$response = "<html><header><body>set passed</body></header><html>";
|
||||
fwrite($spawn, $response);
|
||||
break;
|
||||
case "dump":
|
||||
case "print":
|
||||
logger(DEBUG, "print reached");
|
||||
logger(DEBUG, $command . _(" reached"), __FILE__ . ":" . __LINE__);
|
||||
$var = $GLOBALS[$argList["object"]];
|
||||
if (isset($argList["topic"]))
|
||||
{
|
||||
@ -78,7 +80,12 @@ function askWebServer($read)
|
||||
}
|
||||
}else
|
||||
{
|
||||
logger(ERROR, _("topic is not defining: add &topic=zigbee2mqtt to the resquest"));
|
||||
$str = _("topic is not defining: add &topic=\nThese topics are availables: ");
|
||||
foreach($topics as $key => $value)
|
||||
{
|
||||
$str .= $key . EOL;
|
||||
}
|
||||
logger(ERROR, $str, __FILE__ . ":" . __LINE__);
|
||||
}
|
||||
}
|
||||
$error = error_get_last();
|
||||
@ -86,12 +93,19 @@ function askWebServer($read)
|
||||
{
|
||||
$response = "<html><header><body>" . $error["message"] . " file: " . $error["file"] . " line: " . $error["line"] . "</body></header><html>";
|
||||
}
|
||||
$response = "<html><header><body>" . print_r($var, true) . "</body></header><html>";
|
||||
if ($command === "print")
|
||||
{
|
||||
$response = print_r($var, true);
|
||||
}elseif($command === "dump")
|
||||
{
|
||||
$response = "Dump" . EOL;
|
||||
$response .= var_export($var, true);
|
||||
}
|
||||
fwrite($spawn, $response);
|
||||
break;
|
||||
default:
|
||||
logger(DEBUG, "not understanding command");
|
||||
fwrite($spawn, "not understanding command");
|
||||
logger(DEBUG, _("unknown command"), __FILE__ . ":" . __LINE__);
|
||||
fwrite($spawn, _("unknown command"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user