Volkszaehler Anbindung

Hallo :loveips:-Forum

anbei ein kleines Skript, mit dem sich alle per volkszaehler.org - home erfassten Kanäle in IPS anzeigen lassen.

Skript muss nur irgendwo in IPS rumgammeln, MYSQL Passwörter etc. sind natürlich anzupassen.

<?
// max Ausführungszeit für Script in Sekunden
ini_set("max_execution_time", 60);

$link = mysql_connect(host, 'vz', *****);
if (!$link) {
    die('Verbindung nicht möglich : ' . mysql_error());
}
$linhkdb = mysql_select_db('volkszaehler', $link);
if (!$linhkdb) {
    die ('Kann foo nicht benutzen : ' . mysql_error());
	}

$sql='SELECT entities.uuid, (SELECT properties.value FROM properties WHERE (((properties.pkey)="resolution") AND ((properties.entity_id)=entities.id))) AS Ausdr1 FROM entities;';
$result=mysql_query($sql,$link);
if (!$result) {
    die ('Kann foo nicht benutzen : ' . mysql_error());
	}
while ($row = mysql_fetch_row($result)){
	$subsql='SELECT entities.uuid, data.timestamp, data.value, properties.value, entities.type, UNIX_TIMESTAMP()-data.timestamp/1000 FROM (data INNER JOIN entities ON data.channel_id = entities.id) LEFT JOIN properties ON entities.id = properties.entity_id WHERE (((entities.uuid)="'.$row[0].'") AND ((properties.pkey)="title")) ORDER BY data.timestamp DESC LIMIT 2;';
	$result2=mysql_query($subsql,$link);
/*	echo $row[0]." ".mysql_numrows($result2).chr(10); */
	if (mysql_numrows($result2)>0){
		if (!$result2) {
		    die ('Kann foo nicht benutzen : ' . mysql_error());
			}
	   $row2 = mysql_fetch_row($result2);

		if (!($subitem=@IPS_GetObjectIDByName($row[0],$IPS_SELF)))
		{
			echo "Neue uuid=$row[0] anlegen";
			$subitem=IPS_CreateCategory();
		   IPS_SetName($subitem, $row[0]);
		   IPS_SetParent($subitem, $IPS_SELF);
		}
		if (!($subsubitem=@IPS_GetObjectIDByName("title",$subitem)))
		{
			$subsubitem=IPS_CreateVariable(3);
		   IPS_SetName($subsubitem, "title");
		   IPS_SetParent($subsubitem, $subitem);
		}
		setvaluestring($subsubitem,$row2[3]);
		if (!($subsubitem=@IPS_GetObjectIDByName("timestamp",$subitem)))
		{
			$subsubitem=IPS_CreateVariable(3);
		   IPS_SetName($subsubitem, "timestamp");
		   IPS_SetParent($subsubitem, $subitem);
		}
		$t0=floatval($row2[1]);
		setvaluestring($subsubitem,$row2[1]);

		if (!($subsubitem=@IPS_GetObjectIDByName("value",$subitem)))
		{
			$subsubitem=IPS_CreateVariable(2);
		   IPS_SetName($subsubitem, "value");
		   IPS_SetParent($subsubitem, $subitem);
		}
		setvaluefloat($subsubitem,floatval($row2[2]));
		if (!($subsubitem=@IPS_GetObjectIDByName("type",$subitem)))
		{
			$subsubitem=IPS_CreateVariable(3);
		   IPS_SetName($subsubitem, "type");
		   IPS_SetParent($subsubitem, $subitem);
		}
		setvaluestring($subsubitem,$row2[4]);
		if (!($subsubitem=@IPS_GetObjectIDByName("resolution",$subitem)))
		{
			$subsubitem=IPS_CreateVariable(1);
		   IPS_SetName($subsubitem, "resolution");
		   IPS_SetParent($subsubitem, $subitem);
		}
		$res=intval($row[1]);
		if ($res==0) $res=1;
		setvalueinteger($subsubitem,$res);
		if (!($subsubitem=@IPS_GetObjectIDByName("age",$subitem)))
		{
			$subsubitem=IPS_CreateVariable(2);
		   IPS_SetName($subsubitem, "age");
		   IPS_SetParent($subsubitem, $subitem);
		}
		$a0=floatval($row2[5]);
		setvaluefloat($subsubitem,$a0);
		if (mysql_numrows($result2)>1){
	  	   $row2 = mysql_fetch_row($result2);
			if (!($subsubitem=@IPS_GetObjectIDByName("preage",$subitem)))
			{
				$subsubitem=IPS_CreateVariable(2);
			   IPS_SetName($subsubitem, "preage");
			   IPS_SetParent($subsubitem, $subitem);
			}
			$a1=($t0-floatval($row2[1]))/1000;
			setvaluefloat($subsubitem,$a1);
		}
		if (!($subsubitem=@IPS_GetObjectIDByName("current",$subitem)))
		{
			$subsubitem=IPS_CreateVariable(2);
		   IPS_SetName($subsubitem, "current");
		   IPS_SetParent($subsubitem, $subitem);
		}
		$curr=round(3600*1000/$res/max($a0,$a1));
		setvaluefloat($subsubitem,$curr);
	}
}
?>

Hallo,

Danke für dieses Script, ich wüürde es gerne in mein IP-Symcon einbind, allerdings ist die Version des Scriptes leicht veraltet. mysql_ wird nun ja nicht mehr unterstütz.
Bevor ich anfange alles umzuwerkeln wollte ich freundlich fragen, ob sich jemand schon die mühe gemacht hat dieses alles anzupassen?

Grüße
D

Ja, das habe ich tatsächlich.

<?
include('vz.inc.php');
// middleware.php/data.json?uuid[]=0b439dd7-1145-eee2-e6c7-12bef0b84e1b.json&from=now

if(!IPS_SemaphoreEnter("Volkszaehler", 10 /* sehr kurz warten */)) {
 return; //Läuft bereits
}

function getuuid($data,&$uuidarr){
if (array_key_exists("children",$data)){
	 if (is_array($data["children"])){
		foreach ($data["children"] as $childk=>$childv){
		   getuuid($childv,$uuidarr);
		}
	}
}
else{
	$uuidarr[]=$data;
	}
}

function ObjectIDByUUID($uuid){
	$uuidarr=IPS_GetChildrenIDs (19204);
	foreach ($uuidarr as $k=>$v){
		if (strpos(IPS_GetObject($v)["ObjectName"],$uuid)===0) return $v;
	}
}

$linhkdb = mysqli_connect(VZ_HOST, VZ_USER, VZ_PASSWORD,'Volkszaehler');

if (!$linhkdb) {
    die ('Kann foo nicht benutzen : ' . mysql_error());
	}

$result=mysqli_query($linhkdb,'SELECT UNIX_TIMESTAMP() AS TS');
if (!$result) {
    die ('Kann foo nicht benutzen : ' . mysql_error());
	}

$row = mysqli_fetch_row($result);
$vzts=$row[0];
mysqli_close($linhkdb);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://".VZ_HOST.VZ_MIDDLEWARE."group/00ead2e0-9ca4-11e9-bdf8-a74aea206369.json");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = json_decode(curl_exec($ch),true);
$uuidarr=array();$uuids="";
getuuid($output["entity"],$uuidarr);$vzarr=array();

foreach($uuidarr as $uuid){
	$uuids.="&uuid[]=".$uuid["uuid"]."&from=now";
//	$vzarr[$uuid["uuid"]]=array("title"=>$uuid["title"],"type"=>$uuid["type"],"resolution"=>$uuid["resolution"]);
	$vzarr[$uuid["uuid"]]=$uuid;
	unset($vzarr[$uuid["uuid"]]["uuid"]);
}

//echo "http://".VZ_HOST.VZ_MIDDLEWARE."data.json?".substr($uuids,1);die("lmaa");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://".VZ_HOST.VZ_MIDDLEWARE."data.json?".substr($uuids,1));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = json_decode(curl_exec($ch),true);

foreach($output["data"] as $key=>$value){
	if (array_key_exists("tuples",$value)){
		@$vzarr[$value["uuid"]]["current"]=$value["tuples"][(count($value["tuples"])-1)][1];
		@$vzarr[$value["uuid"]]["current_ts"]=(int)($value["tuples"][(count($value["tuples"])-1)][0]/1000);
	}
}

foreach($vzarr as $uuid=>$uuidarr){
	if (!($subitem=@IPS_GetObjectIDByName($uuid." ".utf8_decode($uuidarr["title"]),$_IPS['SELF'])))
	   {
		if (!($subitem=ObjectIDByUUID($uuid)))
		{
			$subitem=IPS_CreateCategory();
		   IPS_SetName($subitem, $uuid." ".utf8_decode($uuidarr["title"]));
		   IPS_SetParent($subitem, $_IPS['SELF']);
		}
		else
		{
		   IPS_SetName($subitem, $uuid." ".utf8_decode($uuidarr["title"]));
		}
	}
	if (!($subsubitem=@IPS_GetObjectIDByName("current_ts",$subitem)))
	{
		$subsubitem=IPS_CreateVariable(1);
	   IPS_SetName($subsubitem, "current_ts");
	   IPS_SetParent($subsubitem, $subitem);
	}
//	echo $uuid." ".$uuidarr["title"]." ".$uuidarr["current_ts"]."
";
	unset($curid);
	if (array_key_exists ("current_ts",$uuidarr)){
		if ($uuidarr["current_ts"]>=IPS_GetVariable($subsubitem)["VariableUpdated"]){
	 		setvalueinteger($subsubitem,$uuidarr["current_ts"]);
			if (!($subsubitem=@IPS_GetObjectIDByName("current",$subitem)))
			{

				$subsubitem=IPS_CreateVariable(2);
			   IPS_SetName($subsubitem, "current");
			   IPS_SetParent($subsubitem, $subitem);
			}
			setvaluefloat($subsubitem,floatval($uuidarr["current"]));
			$curid=$subsubitem;
		}
	}
	if (!($subsubitem=@IPS_GetObjectIDByName("type",$subitem)))
	{

		$subsubitem=IPS_CreateVariable(3);
	   IPS_SetName($subsubitem, "type");
	   IPS_SetParent($subsubitem, $subitem);
	}
	setvaluestring($subsubitem,$uuidarr["type"]);
//	if ($uuid=="1ed195ee-6347-e49e-ef41-810129fe8dee") print_r($uuidarr);

	if ($uuidarr["type"]=="power"){
		if (!($subsubitem=@IPS_GetObjectIDByName("current_extrapol",$subitem)))
		{
			$subsubitem=IPS_CreateVariable(1);
		   IPS_SetName($subsubitem, "current_extrapol");
		   IPS_SetParent($subsubitem, $subitem);
		}
	   @IPS_SetVariableCustomProfile($subsubitem,"Watt");
//	   echo $vzts." ".time()." ".$uuidarr["current_ts"]." ".round(3600/($vzts-$uuidarr["current_ts"])*1000/$uuidarr["resolution"],0)." vs ".(int)$uuidarr["current"]."
";
		if ($vzts>$uuidarr["current_ts"]){
	 		@setvalueinteger($subsubitem,min(round(3600/($vzts-$uuidarr["current_ts"])*1000/$uuidarr["resolution"],0),(int)$uuidarr["current"]));
	 		}
		else{
	 		@setvalueinteger($subsubitem,(int)$uuidarr["current"]);
		}
	}

	if (isset($curid)){
		if (in_array($uuidarr["type"],array("power","powersensor","electric meter"))){
		   IPS_SetVariableCustomProfile($curid,"~Watt.14490");
		}
		elseif (in_array($uuidarr["type"],array("temperature"))){
		   IPS_SetVariableCustomProfile($curid,"~Temperature");
		}
	}
	$arr=IPS_GetChildrenIDs($subitem);
	foreach($arr as $k=>$v){
		if (strpos(IPS_GetObject($v)["ObjectName"],"from=")===0){
			echo "http://".VZ_HOST.VZ_MIDDLEWARE."data/".$uuid.".json?".IPS_GetObject($v)["ObjectName"]."&tuples=1";
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL, "http://".VZ_HOST.VZ_MIDDLEWARE."data/".$uuid.".json?".IPS_GetObject($v)["ObjectName"]."&tuples=1");
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			$output = json_decode(curl_exec($ch),true);
			print_r($output);
			if (@$c=$output["data"]["consumption"]){
			   if (IPS_GetVariable($v)['VariableCustomProfile']=='Kubikmeter'){
					setvalue($v,$c);
			   }
			   else{
					setvalue($v,$c);
//					setvalue($v,round($c/1000,0));
     		   }
			}
	   }
	}
}

//Aufräumen. Falls das Skript vorher stirbt, gibt es eine weitere Fehlermeldung, aber die Semaphore wird trotzdem aufgeräumt!
IPS_SemaphoreLeave("Volkszaehler");

?>

Die Zugangsdaten habe ich in Konstanten in der vz.inc.php definiert, so in etwa:


<?
// Wird an diversen Stellen includiert, um mit dem Volkszaehler zu sprechen
define("VZ_HOST", "127.0.0.1");
define("VZ_MIDDLEWARE", "/volkszaehler.org/htdocs/middleware.php/");
define("VZ_USER","*****");
define("VZ_PASSWORD","*****");
?>

es setzt voraus, dass alles unter einer Gruppe in VZ struckturiert ist. Zeile 45 musst du also entsprechend anpassen.

Dann mnüssten beim ersten Aufruf unter dem Script alle uuids dieser Gruppe auftauchen.

Hi TomW…

danke für das Script…

Ich habe es noch ein bisschen für meine Bedürfnisse anpassen müssen, aber es läuft jetzt sauber…

Herzlichen Dank…

Grüße
Pfiff