making compatibility with mqtt's friendly names
This commit is contained in:
		@@ -8,37 +8,63 @@ function storeDB($db, $filepath)
 | 
			
		||||
    fclose($fp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function mkDevicesDB($topic, $json)
 | 
			
		||||
function deviceTree(string $topic, array $fnTree, array &$device)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function mkDevicesDB($topic, $json, $group=false)
 | 
			
		||||
{
 | 
			
		||||
	global $devices, $listProperties, $indexDevices, $dbInit, $logFh;
 | 
			
		||||
	foreach ($json as $device)
 | 
			
		||||
	if (!isset($devices[$topic]))   $devices[$topic]= array();
 | 
			
		||||
	foreach ($json as $jsonDevice)
 | 
			
		||||
	{
 | 
			
		||||
		//print_r($device);
 | 
			
		||||
		$fn = $device->friendly_name;
 | 
			
		||||
		$devices[$topic][$fn] = new device;
 | 
			
		||||
		$devices[$topic][$fn]->topic = $topic;
 | 
			
		||||
		$devices[$topic][$fn]->device = $device;
 | 
			
		||||
		$devices[$topic][$fn]->type = $device->type;
 | 
			
		||||
		$devices[$topic][$fn]->ieeeAddress = $device->ieee_address;
 | 
			
		||||
		$devices[$topic][$fn]->friendlyName = $device->friendly_name;
 | 
			
		||||
		if ( !empty($devices[$topic][$fn]->powerSource ) )
 | 
			
		||||
		$fn = $jsonDevice->friendly_name;
 | 
			
		||||
		$fnTree = explode("/", $fn);
 | 
			
		||||
		$device = & $devices[$topic];
 | 
			
		||||
		foreach($fnTree as $fnPart)
 | 
			
		||||
		{
 | 
			
		||||
			$devices[$topic][$fn]->powerSource = $device->power_source;
 | 
			
		||||
			$device[$fnPart] = array();
 | 
			
		||||
			$device = & $device[$fnPart];
 | 
			
		||||
		}
 | 
			
		||||
		if ($device->definition != null)
 | 
			
		||||
 | 
			
		||||
		$device["device"] = new device;
 | 
			
		||||
		$device["device"]->topic = $topic;
 | 
			
		||||
		//$device["device"]->device = $jsonDevice;
 | 
			
		||||
		$device["device"]->friendlyName = $jsonDevice->friendly_name;
 | 
			
		||||
		if ($group)
 | 
			
		||||
		{
 | 
			
		||||
			$devices[$topic][$fn]->description = $device->definition->description;
 | 
			
		||||
			//print_r($device);
 | 
			
		||||
			$device["device"]->groupID = $jsonDevice->id;
 | 
			
		||||
			$indexDevices[$device["device"]->groupID] = $jsonDevice->friendly_name;
 | 
			
		||||
		}else
 | 
			
		||||
		{
 | 
			
		||||
			$device["device"]->type = $jsonDevice->type;
 | 
			
		||||
			$device["device"]->ieeeAddress = $jsonDevice->ieee_address;
 | 
			
		||||
			if ( !empty($jsonDevice->power_source ) )
 | 
			
		||||
			{
 | 
			
		||||
				$device["device"]->powerSource = $jsonDevice->power_source;
 | 
			
		||||
			}
 | 
			
		||||
			if ($jsonDevice->definition != null)
 | 
			
		||||
			{
 | 
			
		||||
				$device["device"]->description = $jsonDevice->definition->description;
 | 
			
		||||
			}
 | 
			
		||||
			//searchProperty($fn, $device["device"], $jsonDevice, $listProperties);
 | 
			
		||||
			$indexDevices[$device["device"]->ieeeAddress] = & $device["device"];
 | 
			
		||||
			//print_r($device);
 | 
			
		||||
		}
 | 
			
		||||
		searchProperty($fn, $devices[$topic][$fn], $device, $listProperties);
 | 
			
		||||
		$indexDevices[$device->ieee_address] = $device->friendly_name;
 | 
			
		||||
	}
 | 
			
		||||
	$dbInit = true;
 | 
			
		||||
	fwrite($logFh, "################################START##################################################");
 | 
			
		||||
	fwrite($logFh, print_r($devices, true));
 | 
			
		||||
	fwrite($logFh, "################################END##################################################");
 | 
			
		||||
 | 
			
		||||
	echo "Devices DB made" .EOL;
 | 
			
		||||
	//print_r($devices);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function searchProperty($fn, $device, $object, $listProperties)
 | 
			
		||||
function searchProperty($fn, &$device, $object, $listProperties)
 | 
			
		||||
{
 | 
			
		||||
	$objectArray = (array)$object;
 | 
			
		||||
	foreach($listProperties as $key => $value)
 | 
			
		||||
@@ -52,17 +78,43 @@ function searchProperty($fn, $device, $object, $listProperties)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function changeDevice($topic, $fn, $device)
 | 
			
		||||
function changeDevice($topic, $fn, &$device, $json)
 | 
			
		||||
{
 | 
			
		||||
	//print_r($device);
 | 
			
		||||
	iterateDevice($topic, $fn, $device, $device->json);
 | 
			
		||||
	/*foreach($fnTree as $fn)
 | 
			
		||||
	{
 | 
			
		||||
		//print_r($device);
 | 
			
		||||
		if (!isset($device[$fn]))
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		$device = & $device[$fn];
 | 
			
		||||
	}*/
 | 
			
		||||
 | 
			
		||||
	//print_r($json);
 | 
			
		||||
	$fnTree = explode("/", $fn);
 | 
			
		||||
	print_r($json);
 | 
			
		||||
	if ( ($jsonDevice = json_decode($json)) === null )
 | 
			
		||||
	{
 | 
			
		||||
		echo "json ========>>>>>>> " . print_r($json,true) . EOL;
 | 
			
		||||
		if (!isset($device->value))
 | 
			
		||||
		{
 | 
			
		||||
			$device->{"value"} = $json;
 | 
			
		||||
			$device->type = true;			//set this as parameter and not device
 | 
			
		||||
		}
 | 
			
		||||
		print_r($device);
 | 
			
		||||
	}else
 | 
			
		||||
	{
 | 
			
		||||
		iterateDevice($topic, $fn, $device, $jsonDevice);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function iterateDevice($topic, $fn, $device, $object)
 | 
			
		||||
function iterateDevice($topic, $fn, &$device, $json)
 | 
			
		||||
{
 | 
			
		||||
	global $changed;
 | 
			
		||||
 | 
			
		||||
	//echo "device =>";print_r($device);echo EOL;
 | 
			
		||||
	foreach($object as $key => $value)
 | 
			
		||||
	foreach($json as $key => $value)
 | 
			
		||||
	{
 | 
			
		||||
		$oldValue = 0;
 | 
			
		||||
		//echo "key =>"; print_r($key); echo EOL;
 | 
			
		||||
@@ -95,14 +147,14 @@ function iterateDevice($topic, $fn, $device, $object)
 | 
			
		||||
					$changed[$fn]["value"] = $value;
 | 
			
		||||
 | 
			
		||||
					//echo "oldvalue => " . print_r($oldValue, true) . EOL;
 | 
			
		||||
					if (empty($oldValue))
 | 
			
		||||
					/*if (empty($oldValue))
 | 
			
		||||
					{
 | 
			
		||||
						echo "Initializing " . $key;
 | 
			
		||||
					}else
 | 
			
		||||
					{
 | 
			
		||||
						echo "changed " . $key . " value " . $oldValue;;
 | 
			
		||||
					}
 | 
			
		||||
					echo  " to " . $value . EOL;
 | 
			
		||||
					echo  " to " . $value . EOL;*/
 | 
			
		||||
				}
 | 
			
		||||
				//print_r($device->functions);
 | 
			
		||||
				if (!empty($device->functions))
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								events.php
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								events.php
									
									
									
									
									
								
							@@ -3,15 +3,16 @@
 | 
			
		||||
function checkEvents()
 | 
			
		||||
{
 | 
			
		||||
	global $events, $indexDevices, $devices;
 | 
			
		||||
	echo "===========> checking events" . EOL;
 | 
			
		||||
	//echo "===========> checking events" . EOL;
 | 
			
		||||
	foreach ($events as $key => $event)
 | 
			
		||||
	{
 | 
			
		||||
		if ($event->dateTimeEvent <= now())
 | 
			
		||||
		if (!empty($event->dateTimeEvent) and $event->dateTimeEvent <= now())
 | 
			
		||||
		{
 | 
			
		||||
				echo "---->sending command" . EOL;
 | 
			
		||||
				//echo "---->sending command" . EOL;
 | 
			
		||||
				publish($devices[$event->topic][$indexDevices[$event->ieeeAddress]], array($event->param => $event->value), "set", $key);
 | 
			
		||||
				//$event->published = now();
 | 
			
		||||
				unset($key);
 | 
			
		||||
				//echo "#################################\nUnsetting event $key \n###########################" . EOL;
 | 
			
		||||
				unset($events[$key]);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	//print_r($events);
 | 
			
		||||
@@ -69,15 +70,15 @@ function searchEvent($device, $param , $value)
 | 
			
		||||
	global $events;
 | 
			
		||||
	echo "searching event" . EOL;
 | 
			
		||||
	//$keys = array_keys($events, $device->ieeeAddress);
 | 
			
		||||
	echo "ieee_address =>" . $device->ieeeAddress . EOL;
 | 
			
		||||
	print_r($events);
 | 
			
		||||
	//echo "ieee_address =>" . $device->ieeeAddress . EOL;
 | 
			
		||||
	//print_r($events);
 | 
			
		||||
	foreach($events as $key => $event)
 | 
			
		||||
	{
 | 
			
		||||
		//echo "Event : $event => $value" . EOL;
 | 
			
		||||
		echo "===>";print_r($event); echo EOL;
 | 
			
		||||
		//echo "===>";print_r($event); echo EOL;
 | 
			
		||||
		if($event->topic == $device->topic and $event->param == $param and $event->value == $value and $event->ieeeAddress == $device->ieeeAddress)
 | 
			
		||||
		{
 | 
			
		||||
			echo "==============================\nfound " . $key . "\n=================================" . EOL;
 | 
			
		||||
			//echo "==============================\nfound " . $key . "\n=================================" . EOL;
 | 
			
		||||
			return $key;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -87,7 +88,7 @@ function deleteEvent($eventKey)
 | 
			
		||||
{
 | 
			
		||||
	global $events;
 | 
			
		||||
	unset ($events[$eventKey]);
 | 
			
		||||
	echo "delete event " . $eventKey . EOL;
 | 
			
		||||
	//echo "delete event " . $eventKey . EOL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								moha.php
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								moha.php
									
									
									
									
									
								
							@@ -35,12 +35,13 @@ class topic {
 | 
			
		||||
 | 
			
		||||
class device
 | 
			
		||||
{
 | 
			
		||||
	public $method;    //auto or manual
 | 
			
		||||
	public $topic;
 | 
			
		||||
	public $device;
 | 
			
		||||
	public $json;
 | 
			
		||||
	public $ieeeAddress;
 | 
			
		||||
	public $groupID;
 | 
			
		||||
	public $friendlyName;
 | 
			
		||||
	public $type;
 | 
			
		||||
	public $type;					// if true then not a device but parameter of device(eg. topic/FRIENDLYNAME/PARAMETER
 | 
			
		||||
	public $powerSource;
 | 
			
		||||
	public $description;
 | 
			
		||||
	public $functions;
 | 
			
		||||
@@ -50,6 +51,11 @@ class device
 | 
			
		||||
	{
 | 
			
		||||
		publish($this, $this->payload, "set", $event);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function get()
 | 
			
		||||
	{
 | 
			
		||||
		publish($this, $this->payload, "get", $event);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class event
 | 
			
		||||
@@ -136,15 +142,14 @@ $topics["zigbee2mqtt"] = new topic;
 | 
			
		||||
bindtextdomain("moha", "./locale");
 | 
			
		||||
textdomain("moha");
 | 
			
		||||
 | 
			
		||||
//signal handling
 | 
			
		||||
pcntl_signal(SIGTERM, 'signalHandler');// Termination ('kill' was called)
 | 
			
		||||
pcntl_signal(SIGHUP, 'signalHandler'); // Terminal log-out
 | 
			
		||||
pcntl_signal(SIGINT, 'signalHandler');
 | 
			
		||||
 | 
			
		||||
if (!init()) exit(1);
 | 
			
		||||
 | 
			
		||||
require "mqtt_functions.php";
 | 
			
		||||
require "utils.php";
 | 
			
		||||
require "events.php";
 | 
			
		||||
require "db_functions.php";
 | 
			
		||||
 | 
			
		||||
$client = new Mosquitto\Client();
 | 
			
		||||
if (!init()) exit(1);
 | 
			
		||||
$client->onConnect('connectResponse');
 | 
			
		||||
$client->onDisconnect('disconnectResponse');
 | 
			
		||||
$client->onSubscribe('subscribeResponse');
 | 
			
		||||
@@ -152,8 +157,16 @@ $client->onMessage('message');
 | 
			
		||||
$client->onLog('logger');
 | 
			
		||||
$client->onPublish('publishResponse');
 | 
			
		||||
 | 
			
		||||
$include 'mqtt_functions.php';
 | 
			
		||||
 | 
			
		||||
//signal handling
 | 
			
		||||
pcntl_signal(SIGTERM, 'signalHandler');// Termination ('kill' was called)
 | 
			
		||||
pcntl_signal(SIGHUP, 'signalHandler'); // Terminal log-out
 | 
			
		||||
pcntl_signal(SIGINT, 'signalHandler');
 | 
			
		||||
 | 
			
		||||
// Program start
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
$client->connect("192.168.1.253", 1883, 5);
 | 
			
		||||
foreach($topics as $name => $topic)
 | 
			
		||||
{
 | 
			
		||||
	//echo $name;
 | 
			
		||||
@@ -178,6 +191,10 @@ while (true)
 | 
			
		||||
	}elseif($dbInit and $included)
 | 
			
		||||
	{
 | 
			
		||||
		checkEvents();
 | 
			
		||||
		if (empty($flag))
 | 
			
		||||
		{
 | 
			
		||||
			$flag = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -187,7 +204,7 @@ function init()
 | 
			
		||||
{
 | 
			
		||||
	global $logFh, $client;
 | 
			
		||||
	date_default_timezone_set('Europe/Paris');
 | 
			
		||||
	$client->connect("192.168.1.253", 1883, 5);
 | 
			
		||||
 | 
			
		||||
	if (! $logFh = fopen("moha.log", "w") )
 | 
			
		||||
	{
 | 
			
		||||
		echo _("error opening log file");
 | 
			
		||||
@@ -211,7 +228,7 @@ function loadHooks($dir)
 | 
			
		||||
			if (is_dir($file))
 | 
			
		||||
			{
 | 
			
		||||
				//echo "directory" . EOL;
 | 
			
		||||
				listHooks($dir . '/' . $file);
 | 
			
		||||
				loadHooks($dir . '/' . $file);
 | 
			
		||||
			}else
 | 
			
		||||
			{
 | 
			
		||||
				//echo "file" . EOL;
 | 
			
		||||
@@ -234,14 +251,15 @@ function endMoha()
 | 
			
		||||
	{
 | 
			
		||||
		if ($object->status)
 | 
			
		||||
		{
 | 
			
		||||
			$client->unsubscribe($topic);
 | 
			
		||||
			$mid = $client->unsubscribe($topic);
 | 
			
		||||
			$mids[$mid] = $topic;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while ($nSubscribed != 0)
 | 
			
		||||
	{
 | 
			
		||||
		//echo $nSubscribed;0x00124b0022ebac5c
 | 
			
		||||
		if ( $x++ > 30) exit (0);
 | 
			
		||||
		if ( $x++ > 60) exit (0);
 | 
			
		||||
		$client->loop();
 | 
			
		||||
	}
 | 
			
		||||
	$client->disconnect();
 | 
			
		||||
 
 | 
			
		||||
@@ -13,12 +13,12 @@ function message($message)
 | 
			
		||||
				break;
 | 
			
		||||
			case "devices":
 | 
			
		||||
				$topics[$topic[0]]->devices = json_decode($message->payload);
 | 
			
		||||
				mkDevicesDB($topic[0], $topics[$topic[0]]->devices);
 | 
			
		||||
				fwrite($logFh, print_r($topics[$topic[0]]->devices, true));
 | 
			
		||||
				mkDevicesDB($topic[0], $topics[$topic[0]]->devices);
 | 
			
		||||
				break;
 | 
			
		||||
			case "groups":
 | 
			
		||||
				$topics[$topic[0]]->groups = json_decode($message->payload);
 | 
			
		||||
				mkDevicesDB($topic[0], $topics[$topic[0]]->groups);
 | 
			
		||||
				mkDevicesDB($topic[0], $topics[$topic[0]]->groups, true);
 | 
			
		||||
				break;
 | 
			
		||||
			case "extensions":
 | 
			
		||||
				$topics[$topic[0]]->extensions = json_decode($message->payload);
 | 
			
		||||
@@ -37,11 +37,23 @@ function message($message)
 | 
			
		||||
		};
 | 
			
		||||
	}elseif (($topic[array_key_last($topic)]) != "get" and ($topic[array_key_last($topic)]) != "set")
 | 
			
		||||
	{
 | 
			
		||||
		$topic = explode ("/", $message->topic, 2);
 | 
			
		||||
 | 
			
		||||
		$topic = explode ("/", $message->topic, 2);   	// get topic name
 | 
			
		||||
		$fnTree = explode ("/" , $topic[1]); 				// get friendlyname
 | 
			
		||||
		echo $topic[0] . " => " . $topic[1] . EOL;
 | 
			
		||||
		$devices[$topic[0]][$topic[1]]->json = json_decode($message->payload);
 | 
			
		||||
		changeDevice($topic[0], $topic[1], $devices[$topic[0]][$topic[1]]);
 | 
			
		||||
		//$devices[$topic[0]][$fnTree[0]]->json = json_decode($message->payload);
 | 
			
		||||
		$device = & $devices[$topic[0]];
 | 
			
		||||
		foreach($fnTree as $fn)
 | 
			
		||||
		{
 | 
			
		||||
			//print_r($device) ;
 | 
			
		||||
			if (!isset($device[$fn]))
 | 
			
		||||
			{
 | 
			
		||||
				logger(LOG_INFO, $logFh, "init of " . $fn .EOL);
 | 
			
		||||
				$device[$fn] = array();
 | 
			
		||||
				$device[$fn]["device"] = new device;
 | 
			
		||||
			}
 | 
			
		||||
			$device = & $device[$fn];
 | 
			
		||||
		}
 | 
			
		||||
		changeDevice($topic[0], $topic[1], $device["device"], $message->payload);
 | 
			
		||||
		//fwrite($logFh, print_r($msg, true));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -52,17 +64,19 @@ function message($message)
 | 
			
		||||
function publish($device, $payload, $commande="set", $eventKey)
 | 
			
		||||
{
 | 
			
		||||
	global $client, $mids, $logFh;
 | 
			
		||||
	print_r($payload);
 | 
			
		||||
	//print_r($payload);
 | 
			
		||||
	$string = $device->topic . "/" . $device->friendlyName . "/" . $commande;
 | 
			
		||||
	$mid = $client->publish($string, json_encode($payload) , 2);
 | 
			
		||||
	if ($mids[$mid])
 | 
			
		||||
	if (isset($mids[$mid]))
 | 
			
		||||
	{
 | 
			
		||||
		//echo "unsetting mids" .EOL;
 | 
			
		||||
		unset ($mids[$mid]);
 | 
			
		||||
	}else
 | 
			
		||||
	{
 | 
			
		||||
		//echo "setting mids" .EOL;
 | 
			
		||||
		$mids[$mid] = true;
 | 
			
		||||
	}
 | 
			
		||||
	echo $string . " =>>>>>> " . json_encode($payload) . EOL;
 | 
			
		||||
	//echo $string . " =>>>>>> " . json_encode($payload) . EOL;
 | 
			
		||||
	logger(LOG_INFO, $logFh, "Publishing " . $string . " with payload => " . json_encode($payload));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -127,9 +141,11 @@ function publishResponse($mid)
 | 
			
		||||
	logger(LOG_INFO, "Event with mid = " . $mid . " published by MQTT broker");
 | 
			
		||||
	if (isset($mids[$mid]))
 | 
			
		||||
	{
 | 
			
		||||
		//echo "unsetting mids" . EOL;
 | 
			
		||||
		unset ($mids[$mid]);
 | 
			
		||||
	}else
 | 
			
		||||
	{
 | 
			
		||||
		//echo "setting mids" . EOL;
 | 
			
		||||
		$mids[$mid] = true;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,8 @@
 | 
			
		||||
	$rdcPanneau = function($topic, $fn, $param, $value)
 | 
			
		||||
	{
 | 
			
		||||
		global $devices, $indexDevices;
 | 
			
		||||
		$delay = 20;
 | 
			
		||||
		$timeUnit = "sec";
 | 
			
		||||
		$delay = 3;
 | 
			
		||||
		$timeUnit = "min";
 | 
			
		||||
		switch($param)
 | 
			
		||||
		{
 | 
			
		||||
			case "occupancy":
 | 
			
		||||
@@ -14,16 +14,19 @@
 | 
			
		||||
				{
 | 
			
		||||
					$msg = array("state" => "ON");
 | 
			
		||||
					$device = $devices[Z2M][$indexDevices["0x588e81fffe343e8f"]];
 | 
			
		||||
					$device->set($msg);
 | 
			
		||||
					setDelay($device, $delay, $timeUnit, $param, "OFF", true);
 | 
			
		||||
					$device->payload = $msg;
 | 
			
		||||
					$device->set(null);
 | 
			
		||||
					setDelay($device, $delay, $timeUnit, "state", "OFF", true);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
		echo _("notification received from MQTT") . EOL;
 | 
			
		||||
		echo $param . "=> " . $value . EOL;
 | 
			
		||||
		//echo $param . "=> " . $value . EOL;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	//assignation of the function to the devices
 | 
			
		||||
	$devices[Z2M][$indexDevices["0x00124b0022ebac5c"]]->functions[] = $rdcPanneau;
 | 
			
		||||
	$devices[Z2M][$indexDevices["0x588e81fffe2cf695"]]->functions[] = $rdcPanneau;
 | 
			
		||||
	//assignation of the function to the sensors devices
 | 
			
		||||
	$indexDevices["0x00124b0022ebac5c"]->functions[] = $rdcPanneau;
 | 
			
		||||
	$indexDevices["0x588e81fffe2cf695"]->functions[] = $rdcPanneau;
 | 
			
		||||
	$indexDevices["0x04cf8cdf3c78aff0"]->functions[] = $rdcPanneau;
 | 
			
		||||
 | 
			
		||||
?>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user