Hallo liebe IPS’ler,
heute möchte ich auch mal was zur Community beitragen und mein Plugwise-IPS-Integrations-Script veröffentlichen :-). Aber erst mal kurz die Grundlagen: was ist Plugwise überhaupt?
Plugwise ist eine Firma, die nette kleine Zwischenstecker herstellt die
- geschaltet werden können
- und nebenbei noch den Stromverbrauch messen.
Diese Zwischenstecker kommunizieren untereinander über ein Zigbee-Netz, mit den gleichen Vor- und Nachteilen. Ein wesentlicher Nachteil ist sicherlich die geringe maximale Reichweite die zwischen den einzelnen Circles möglich ist. Einzelheiten findet ihr aber zu genüge auf der Plugwise-Homepage (z.B. hier: Wie funktioniert das Plugwise System? | Plugwise), da muss ich sicherlich nicht weiter drauf eingehen.
Plugwise selber benötigt einen USB-Stick (Bestandteil des Home-Start-Sets), dieser sowie eine Client-Software stellen das Interface für IP-Symcon zur Verfügung. Folge: Stick muss immer verbunden sein, die Software (es gibt auch einen Server-Part) muss laufen.
Idee / Motivation der Scripte:
Weder Plugwise noch IP-Symcon bieten eine echte Integration, neue Circles müssen von Hand in IP-Symcon eingebunden werden, die Variablen angelegt werden, Schaltscripte angelegt & ggf. Links für’s Webfront erzeugt werden. Mit meinem Plugwise-Script habe ich alle anfallenden Aufgaben automatisiert, jetzt müssen nur noch die Circles in der Plugwise-Software (Plugwise Source) angelegt werden, diese werden dann beim nächsten Script-Lauf automatisch in IP-Symcon übernommen & die nötigen Variablen / Scripte / Links automatisch angelegt.
Doku des Scripts / der Funktionen
Die öfters geforderte Doku des Scripts bzw. der Funktionen ist in Arbeit, ich ergänze diese in absehbarer Zeit.
Bis dahin bleibt euch wohl nur übrig, einen Blick in die Scripte zu werfen - ich denke sie sind einigermaßen klar geschrieben & sollten ohne weiteres verständlich sein
IP-Symcon Hilfsfunktionen
In meinen Scripten / Funktionen verwende ich immer mal wieder Hilfsfunktionen aus meiner persönlichen Funktionsbibliothek. Diese kleinen Helferlein machen mir das Scripten etwas leichter & nehmen nervige, wiederkehrende Aufgaben ab.
Hier eine hoffentlich vollständige Übersicht der Hilfsfunktionen die in meinen Plugwise-Scripten verwendet werden: http://www.ip-symcon.de/forum/f53/plugwise-integration-ip-symcon-17330/#post152234
Nach der Installation aktiviert man den Webserver in der Software und legt folgende Scripte im Webserver-Pfad von Plugwise an:
ipsymcon.xml
<items type="array">
<% foreach Plugwise.Rooms %>
<%$room = .Name %>
<% foreach .Appliances %>
<%
if (.Module == null)
continue;
/if
if (.Room == null)
echo "No Room";
/if
$state=.StatusImageName.Replace("_locked","");
$state=$state.SubString($state.LastIndexOf("_")+1);
%>
<appliance>
<id><%=.Id%></id>
<device><%=.Name%></device>
<devicetype><%=.TypeText%></devicetype>
<locked><%=.DoNotSwitchOff%></locked>
<realstate><%=$state%></realstate>
<powerstate><%=.PowerState%></powerstate>
<powerusage><%=.PowerUsage%></powerusage>
<totalusage><%=.TotalUsage%></totalusage>
<moduleid><%=.Module.Id%></moduleid>
<moduleid_bc><%=.module%></moduleid_bc>
<macaddr><%=.Module.MacAddress%></macaddr>
<moduletype><%=.Module.TypeText%></moduletype>
<room><%=$room%></room>
<totalusagetoday><%=.TotalUsageToday%></totalusagetoday>
<isonline><%=.IsOnline%></isonline>
<lastseendate><%=.LastSeenDate%></lastseendate>
<lastseenseconds><%=.LastSeenSeconds%></lastseenseconds>
<firstseendate><%=.FirstSeenDate%></firstseendate>
</appliance>
<% /foreach %>
<% /foreach %>
</items>
cc.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<? header("HTTP/1.0 204 No Content"); ?>
<html>
<head>
<title>Bwired Plugwise example</title>
</head>
<body>
<%
//Response.Status = "204 no content"
$cmd=Request.get.containsKey("cmd")?Request.get["cmd"]:""
$applid=Request.get.containsKey("applid")?Request.get["applid"]:0
$modid=Request.get.containsKey("modid")?Request.get["modid"]:0
if ($applid>0)
With Appliance($applid)
//echo "<br>",.Name,": "
if $cmd=="on"
.SwitchOn()
//echo " ingeschakeld"
elseif $cmd=="off"
.SwitchOff()
//echo " uitgeschakeld"
/if
/With
/if
if ($modid>0)
With Module($modid)
//echo "<br>",.Name,": "
if $cmd=="on"
.CloseRelay()
//echo " ingeschakeld"
elseif $cmd=="off"
.OpenRelay()
//echo " uitgeschakeld"
/if
/With
/if
echo "<hr>"
foreach Plugwise.Appliances
//echo '<br>',.Name,': <a href="?applid=',.Id,'&cmd=on">Aan</a> <a href="?applid=',.Id,'&cmd=off">Uit</a>'
/foreach
//echo "<hr>"
foreach Plugwise.Modules
//echo '<br>',.Name,': <a href="?modid=',.Id,'&cmd=on">Aan</a> <a href="?modid=',.Id,'&cmd=off">Uit</a>'
/foreach
%>
</body>
</html>
So, nun aber zum eigentlichen interessanten Teil: die Integration in IP-Symcon. Der Plugwise-Webserver stellt uns nun zwei Interfaces zur Verfügung: eins zum Auslesen der Verbrauchswerte, und eins zum Schalten der Stecker. Um jetzt eine möglichst gute Integration in IP-Symcon hin zu bekommen, hab ich mir (als Quick-and-Dirty-Lösung) folgendes Script zusammen gebastelt:
create_update_circles
<?php
/**
create_update_circles
Ersteller: Markus Kromberg
Version 1.0.2
Aufgabe:
Dieses Script
- registriert automatisch neue Plugwise-Circles im IP-Symcon
- legt nötige Variablen, Scripte und Events an
- aktualisiert die Messwerte
Trigger:
Dieses Script sollte autmatisch per Timer-Event alle 5 Minuten getriggert werden.
Bei jedem Lauf werden dann die Circle-Stati sowie die Verbrauchswerte ausgelesen und in IP-Symcon übernommen.
Öfters Triggern (also unter 1 Minute) macht meistens keinen Sinn, da sich die Circles im Schnitt alle 60 Sekunden beim Circle+ / Source melden.
Nachteil: Sollten auch Schaltsysteme von Plugwise zum Einsatz kommen, wird ein manuelles Schalten erst nach 5 Minuten erkannt.
Updates:
15.02.2012: Config-Block um einige Parameter erweitert
14.02.2012: Zeichensatz-Konvertierung der Device- und Raumnamen
02.05.2011: initiale Erstellung des Scriptes
**/
/*********************** Config-START ***********************/
$Steckdosen_OnOff_Link_ID = 37370; // Eltern-Element, unter dem der Link angelegt wird
$Power_State_Link_ID = 42209; // Eltern-Element, unter dem der Link angelegt wird
$IPS_SCRIPT_ID = 24267; // IP-Symcon ID dieses Scripts
$pw_ip = "127.0.0.1"; // IP-Adresse zum Plugwise-Server
$pw_port = "8080"; // Webserver-Port des Plugwise-Servers
$pw_username = GetValueString(23880); // Username, falls das Plugwise-Webfront geschützt ist
$pw_password = GetValueString(30828); // Passwort, falls das Plugwise-Webfront geschützt ist
$pw_room_root = 45206; // Hier werden von Plugwise die Raum-Kategorien automatisch angelegt
$pw_health = 27555; // Boolean-Variable, enthält eine Vermutung ob das Plugwise-System läuft (Werte vom Plugwise Webfront)
$pw_akt_verbrauch = 28707; // Float-Variable, enthält den aktuellen Verbrauch aller Circles
$pw_ges_verbrauch = 39620; // Float-Variable, enthält den Tages-Verbrauch aller Circles
$pw_wft_detail_script = 30269; // Script-ID welches aus dem Webfront aufgerufen kann & zur Detail-Seite verlinkt. Der Script-Namen wird immer in den aktuellen Verbrauch umbenannt
/*********************** Config-ENDE ***********************/
if ($pw_username <> "") $var_loginstr = $pw_username.":".$pw_password."@";
$xml_source = file_get_contents('http://'.$var_loginstr.$pw_ip.':'.$pw_port.'/ipsymcon.xml');
$xml = simplexml_load_string($xml_source);
$c = 0;
$akt_gesamtverbrauch = 0;
$insg_gesamtverbrauch = 0;
$check_socket = 0;
while(isset($xml->appliance[$c]))
{
/* Variablen auslesen / erzeugen */
$devid = intval($xml->appliance[$c]->id);
$modid = strval($xml->appliance[$c]->moduleid_bc);
$device = strval($xml->appliance[$c]->device);
$device = iconv('UTF-8', 'ISO-8859-1', $device);
$lastseendate = strval($xml->appliance[$c]->lastseendate);
$lastseenseconds = intval($xml->appliance[$c]->lastseenseconds);
$powerstate = $xml->appliance[$c]->powerstate;
if ($powerstate == "on") $powerstate_bool = TRUE;
if ($powerstate == "off") $powerstate_bool = FALSE;
if ($powerstate == "unknown") $powerstate_bool = FALSE;
if ($powerstate_bool == TRUE) $check_socket = 1;
$devlocked = $xml->appliance[$c]->locked;
if ($devlocked == "True") $devlocked_bool = TRUE;
if ($devlocked == "False") $devlocked_bool = FALSE;
$powerusage = floatval($xml->appliance[$c]->powerusage);
$totalusagetoday = floatval($xml->appliance[$c]->totalusagetoday);
$room = strval($xml->appliance[$c]->room);
$room = iconv('UTF-8', 'ISO-8859-1', $room);
$isonline = $xml->appliance[$c]->isonline;
if ($isonline == "True") $isonline_bool = TRUE;
if ($isonline == "False") $isonline_bool = FALSE;
// Plugwise Modul-ID auslesen
$modid = substr($modid, -8, 6);
// Gesamtverbrauch berechnen
$akt_gesamtverbrauch = $akt_gesamtverbrauch + $powerusage;
$insg_gesamtverbrauch = $insg_gesamtverbrauch + $totalusagetoday;
// Verbrauch des Raumes berechnen
if (isset($arr_verbrauch["$room"]))
{
$arr_verbrauch["$room"]["akt_gesamtverbrauch"] = floatval($arr_verbrauch["$room"]["akt_gesamtverbrauch"])+$powerusage;
$arr_verbrauch["$room"]["insg_gesamtverbrauch"] = floatval($arr_verbrauch["$room"]["insg_gesamtverbrauch"])+$totalusagetoday;
}
else
{
$arr_verbrauch["$room"]["akt_gesamtverbrauch"] = $powerusage;
$arr_verbrauch["$room"]["insg_gesamtverbrauch"] = $totalusagetoday;
}
// Anlegen einer neuen Kategorie mit dem Raum-Namen für die Devices
$RoomID = create_plugwise_category($room, $pw_room_root);
// Anlegen einer neuen Kategorie mit dem Plugwise-Namen
$CatID = create_plugwise_category($device, $RoomID);
// Variablen zurücksetzen
$pss_id = 0;
$psl_id = 0;
$pslsync_id = 0;
// Anlegen der Variablen
/* ID */ $pid_id = create_plugwise_device($CatID, "ID", 1, $devid, "", "", 1, $devlocked_bool);
/* module ID */ $mod_id = create_plugwise_device($CatID, "moduleid", 3, $modid, "", "", "", $devlocked_bool);
/* lastseendate */ $lsd_id = create_plugwise_device($CatID, "lastseendate", 3, $lastseendate, "", "", 1, $devlocked_bool);
/* lastseenseconds */ $lss_id = create_plugwise_device($CatID, "lastseenseconds", 1, $lastseenseconds, "Seconds", "", 1, $devlocked_bool);
/* locked */ $lck_id = create_plugwise_device($CatID, "locked", 0, $devlocked_bool, "", "", 1, $devlocked_bool);
/* powerstate */ $pst_id = create_plugwise_device($CatID, "powerstate", 0, $powerstate_bool, "~Switch", $devid, 1, $devlocked_bool);
/* powerstate_set */ $pss_id = create_plugwise_device($CatID, "powerstate_set", 0, $powerstate_bool, "~Switch", $modid, 0, $devlocked_bool);
/* powerstate_set_lnk */ $psl_id = create_link($pss_id, $room.": ".$device, 0, $Steckdosen_OnOff_Link_ID);
/* powerstate_set_sync */ if ($devlocked_bool == FALSE) $pslsync_id = sync_plugwise_powerstate($pst_id, $pss_id);
/* powerusage */ $pus_id = create_plugwise_device($CatID, "powerusage", 2, $powerusage, "~Watt.3680", "", 1, $devlocked_bool);
/* powerusage_room */ $pus_room_id = create_plugwise_device($RoomID, "powerusage", 2, $powerusage, "~Watt.3680", "", 0, $devlocked_bool);
/* powerusage_lnk */ $pul_id = create_link($pus_id, $room.": ".$device, 0, $Power_State_Link_ID);
/* totalusagetoday */ $tut_id = create_plugwise_device($CatID, "totalusagetoday", 2, $totalusagetoday, "~Electricity", "", 1, $devlocked_bool);
/* totalusagetoday_room*/ $tut_room_id = create_plugwise_device($RoomID, "totalusagetoday", 2, $totalusagetoday, "~Electricity", "", 0, $devlocked_bool);
/* $threshold */ $tsh_id = create_plugwise_device($CatID, "threshold", 1, 0, "", "", 0, $devlocked_bool);
/* room */ $rom_id = create_plugwise_device($CatID, "room", 3, $room, "", "", 1, $devlocked_bool);
/* isonline */ $onl_id = create_plugwise_device($CatID, "isonline", 0, $isonline_bool, "HM_online_offline", "", 1, $devlocked_bool);
/* akm_anw */ $akmanw_id = create_plugwise_device($CatID, "akm_anw", 1, TRUE, "AKM", $modid, 0, $devlocked_bool);
/* akm_abw */ $akmabw_id = create_plugwise_device($CatID, "akm_abw", 1, TRUE, "AKM", $modid, 0, $devlocked_bool);
//Stromverbrauch-Links ausgeschalteter Geräte ausblenden
if ($powerstate == "off") { IPS_SetHidden($pul_id, true); }
if ($powerstate == "on") { IPS_SetHidden($pul_id, false); }
// Statusvariablen gelockter Geräte ausblenden
if ($devlocked == "True") { IPS_SetHidden($psl_id, true); }
if ($devlocked == "False") { IPS_SetHidden($psl_id, false); }
//Stromverbrauch-Links & Statusvariablen nicht erreichbarer Geräte ausblenden
if ($isonline == "False") { IPS_SetHidden($pul_id, true); }
if ($isonline == "False") { IPS_SetHidden($psl_id, true); }
//Datenbank-Logging einschalten
ipssql_logging($pus_id /* powerusage */, TRUE, 0);
ipssql_logging($pus_room_id /* powerusage_room */, TRUE, 0);
ipssql_logging($tut_id /* totalusagetoday */, TRUE, 1);
ipssql_logging($tut_room_id /* totalusagetoday_room*/, TRUE, 1);
ipssql_logging($onl_id /* isonline */, TRUE, 0);
$c++;
}
// Socket-Status speichern
if ($check_socket == 0) SetValueBoolean($pw_health, FALSE);
if ($check_socket == 1) SetValueBoolean($pw_health, TRUE);
// Gesamtverbrauch speichern
SetValueFloat($pw_akt_verbrauch,$akt_gesamtverbrauch);
$var_filename = "akt. Stromverbr.: ".$akt_gesamtverbrauch."W";
IPS_SetName ($pw_wft_detail_script, $var_filename);
SetValueFloat($pw_ges_verbrauch,$insg_gesamtverbrauch);
// Gesamtverbrauch der Räume speichern
$plugwiseraeume = IPS_GetChildrenIDs($pw_room_root);
$anzahl_raeume = count($plugwiseraeume);
for ($ir = 0; $ir < $anzahl_raeume; $ir++) {
$VarID = @IPS_GetVariableIDByName("powerusage", $plugwiseraeume[$ir]);
if ($VarID === false)
{}
else
{
$var_room = IPS_GetName($plugwiseraeume[$ir]);
SetValueFloat($VarID,floatval($arr_verbrauch["$var_room"]["akt_gesamtverbrauch"]));
}
}
for ($ir = 0; $ir < $anzahl_raeume; $ir++) {
$VarID = @IPS_GetVariableIDByName("totalusagetoday", $plugwiseraeume[$ir]);
if ($VarID === false)
{}
else
{
$var_room = IPS_GetName($plugwiseraeume[$ir]);
SetValueFloat($VarID,floatval($arr_verbrauch["$var_room"]["insg_gesamtverbrauch"]));
}
}
?>
Zusätzlich werden noch einige Funktionen benötigt, die ich bei mir in eine eigene Funktions-Bibliothek ausgelagert habe:
create_plugwise_category
<?
/**
create_plugwise_category
Ersteller: Markus Kromberg
Version 1.0.1
Aufgabe:
Diese Funktion erstellt Kategorien für das Plugwise-System, allerdings nur
wenn diese Kategorie noch nicht existiert.
Trigger:
Diese Funktion wird getriggert, sobald neue Kategorien (beim Hinzufügen von neuen Circles)
angelegt werden sollen.
Parameter:
$name: Name der Kategorie
$Master_ID: "Mutter"-Kategorie, unter der die neue Kategorie angelegt werden soll
Historie:
15.02.2012: Kommentar-Block
02.05.2011: initiale Erstellung der Funktion
**/
if (!function_exists('create_plugwise_category'))
{
function create_plugwise_category($name, $Master_ID)
{
/* prüfen ob Kategorie existiert */
$does_exist = "FALSE";
$ips_children = IPS_GetChildrenIDs($Master_ID);
for($i=0; $i < count($ips_children); $i++)
{
$var_name = IPS_GetName($ips_children[$i]);
if ($var_name == $name)
{
$does_exist = "TRUE";
$CatID = intval($ips_children[$i]);
}
}
/* ggf. Kategorie anlegen */
if ($does_exist == "FALSE")
{
/* Kategorie anlegen */
$CatID = IPS_CreateCategory(); // Kategorie anlegen
IPS_SetName($CatID, $name); // Kategorie benennen
IPS_SetParent($CatID, $Master_ID); // Kategorie einordnen
}
return $CatID;
}
}
?>
create_plugwise_device
<?
/**
create_plugwise_device
Ersteller: Markus Kromberg
Version 1.0.1
Aufgabe:
Diese Funktion
- registriert neue Plugwise-Geräte in IP-Symcon & erzeugt die nötigen Variablen
- Prüft die dem Gerät zugehörigen Variablen auf Vollständigkeit, und legt ggf. fehlende Variablen an
- übernimmt die neuen Werte von Plugwise Source in die IPS-Variablen
Trigger:
Diese Funktion sollte auf Grund der großen Anzahl an Parametern nur vom Hauptscript aus getriggert werden
Parameter:
$category_id: Kategorie-ID
$name: Name der Variable
$typ=0: Variablen-Typ: Boolean
$typ=1: Variablen-Typ: Integer
$typ=2: Variablen-Typ: Float
$typ=3: Variablen-Typ: String
$value: Wert
$profilename: Profil, welches auf die Variable angewendet werden soll
$pwid: Plugwise-ID
$doupdate: Soll der Wert gleich von Plugwise-Source übernommen werden?
$devlocked_bool: Ist das Gerät gesperrt?
Historie:
15.02.2012: Kommentar-Block
02.05.2011: initiale Erstellung der Funktion
**/
if (!function_exists('create_plugwise_device'))
{
function create_plugwise_device($category_id, $name, $type, $value, $profilename, $pwid, $doupdate = 1, $devlocked_bool = FALSE)
{
// Pre-Checks
if ($name == "moduleid")
{
$name = "PWID".$value;
$value = $value;
}
/* prüfen ob Variable existiert */
$does_exist = "FALSE";
$ips_children = IPS_GetChildrenIDs($category_id);
for($i=0; $i < count($ips_children); $i++)
{
$var_name = IPS_GetName($ips_children[$i]);
if ($var_name == $name)
{
$does_exist = "TRUE";
$VarID_ID = intval($ips_children[$i]);
}
}
/* ggf. Variable anlegen */
if ($does_exist == "FALSE")
{
/* Variable anlegen */
$VarID_ID = IPS_CreateVariable($type);
IPS_SetName($VarID_ID, $name); // Kategorie benennen
IPS_SetParent($VarID_ID, $category_id); // Variable einordnen
if ($profilename <> "") IPS_SetVariableCustomProfile($VarID_ID, $profilename);
/* ggf. Trigger-Script anlegen */
if ($name == "powerstate_set")
{
global $IPS_SCRIPT_ID;
/* Switch-Script */
$ScriptTEXT = '<?php switch_plugwise_device(4, "PWID'.$pwid.'"); ?>';
$on_script = CreateScriptByName("switch_device", $VarID_ID, $ScriptTEXT);
$eid = IPS_CreateEvent(0); //Ausgelöstes Ereignis
IPS_SetEventTrigger($eid, 0, $VarID_ID); //Bei Änderung von Variable mit ID 15754
IPS_SetParent($eid, $on_script); //Ereignis zuordnen
IPS_SetEventActive($eid, true); //Ereignis aktivieren
$ScriptTEXT = '<?php switch_plugwise_device(3, "PWID'.$pwid.'"); ?>';
$toggle_script = CreateScriptByName("toggle_device", $VarID_ID, $ScriptTEXT);
IPS_SetVariableCustomAction($VarID_ID, $toggle_script);
$ScriptTEXT_on = '<?php switch_plugwise_device(1, "PWID'.$pwid.'"); ?>';
$script_on = CreateScriptByName("switch_on", $VarID_ID, $ScriptTEXT_on);
$ScriptTEXT_off = '<?php switch_plugwise_device(2, "PWID'.$pwid.'"); ?>';
$script_off = CreateScriptByName("switch_off", $VarID_ID, $ScriptTEXT_off);
}
}
/* Wert übernehmen */
if ($doupdate != 0)
{
if ($type == 0 AND is_bool($value) == true) SetValueBoolean($VarID_ID, $value); // Wert übernehmen
if ($type == 1) SetValueInteger($VarID_ID, $value); // Wert übernehmen
if ($type == 2) SetValueFloat($VarID_ID, $value); // Wert übernehmen
if ($type == 3) SetValueString($VarID_ID, $value); // Wert übernehmen
}
return $VarID_ID;
}
}
?>
get_plugwise_variable
<?
/**
get_plugwise_variable
Ersteller: Markus Kromberg
Version 1.0.1
Aufgabe:
Diese Funktion liefert den Wert einer Plugwise-Variable, ohne das man die genaue IPS-ID kennen muss
Parameter:
$variablename: Name der Variable
$pwid: Plugwise-ID
Historie:
15.02.2012: Kommentar-Block
02.05.2011: initiale Erstellung der Funktion
**/
if (!function_exists('get_plugwise_variable'))
{
function get_plugwise_variable($variablename, $pwid)
{
/*********************** Config-START ***********************/
$pw_room_root = 45206; // Hier werden von Plugwise die Raum-Kategorien automatisch angelegt
/*********************** Config-ENDE ***********************/
// Räume finden
$plugwiseraeume = IPS_GetChildrenIDs($pw_room_root);
$anzahl_raeume = count($plugwiseraeume);
for ($ir = 0; $ir < $anzahl_raeume; $ir++) {
// Devices finden
$plugwisedevices = IPS_GetChildrenIDs($plugwiseraeume[$ir]);
$anzahl_devices = count($plugwisedevices);
for ($iv = 0; $iv < $anzahl_devices; $iv++) {
// Variablen finden
$plugwisevariables = IPS_GetChildrenIDs($plugwisedevices[$iv]);
$anzahl_variables = count($plugwisevariables);
$VarID = @IPS_GetVariableIDByName($pwid, $plugwisedevices[$iv]);
if ($VarID === false)
$nf = 0;
else
{
$VarID2 = @IPS_GetVariableIDByName($variablename, $plugwisedevices[$iv]);
if ($VarID2 === false)
$nf = 0;
else
{
return GetValue($VarID2);
}
}
}
}
}
}
?>
get_plugwise_variable_id
<?
/**
get_plugwise_variable_id
Ersteller: Markus Kromberg
Version 1.0.1
Aufgabe:
Diese Funktion liefert die IPS-ID einer Plugwise-Variable, ohne das man die genaue IPS-ID kennen muss
Parameter:
$variablename: Name der Variable
$pwid: Plugwise-ID
Historie:
15.02.2012: Kommentar-Block
02.05.2011: initiale Erstellung der Funktion
**/
if (!function_exists('get_plugwise_variable_id'))
{
function get_plugwise_variable_id($variablename, $pwid)
{
/*********************** Config-START ***********************/
$pw_room_root = 45206; // Hier werden von Plugwise die Raum-Kategorien automatisch angelegt
/*********************** Config-ENDE ***********************/
// Räume finden
$plugwiseraeume = IPS_GetChildrenIDs($pw_room_root);
$anzahl_raeume = count($plugwiseraeume);
for ($ir = 0; $ir < $anzahl_raeume; $ir++) {
// Devices finden
$plugwisedevices = IPS_GetChildrenIDs($plugwiseraeume[$ir]);
$anzahl_devices = count($plugwisedevices);
for ($iv = 0; $iv < $anzahl_devices; $iv++) {
// Variablen finden
$plugwisevariables = IPS_GetChildrenIDs($plugwisedevices[$iv]);
$anzahl_variables = count($plugwisevariables);
$VarID = @IPS_GetVariableIDByName($pwid, $plugwisedevices[$iv]);
if ($VarID === false)
$nf = 0;
else
{
$VarID2 = @IPS_GetVariableIDByName($variablename, $plugwisedevices[$iv]);
if ($VarID2 === false)
$nf = 0;
else
{
return $VarID2;
}
}
}
}
}
}
?>
switch_plugwise_device
<?
/**
switch_plugwise_device
Ersteller: Markus Kromberg
Version 1.0.1
Aufgabe:
Diese Funktion schaltet Plugwise-Circles.
Über Parameter kann man dabei mehrere Schalt-Arten auswählen, diese sind im Kommentarblock "Parameter" näher aufgeführt.
ToDo:
Auswerten, ob der Schaltvorgang erfolgreich durchgeführt wurde. Der Plugwise Webserver quittiert soweit ich weiß
den Schaltvorgang mit OK oder mit Fehler, dieser könnte noch ausgewertet werden.
Trigger:
Diese Funktion wird über die Aktions-Scripte der "powerstate_set"-Variablen aufgerufen
Parameter:
$pwid: Plugwise-ID
$state = 1: ON
$state = 2: OFF
$state = 3: TOGGLE
$state = 4: gemäß "powerstate_set"
Historie:
15.02.2012: Kommentar-Block
02.05.2011: initiale Erstellung der Funktion
**/
if (!function_exists('switch_plugwise_device'))
{
function switch_plugwise_device($state, $pwid)
{
/*********************** Config-START ***********************/
$IPS_SCRIPT_ID = 24267; // IP-Symcon ID des Haupt-Scripts "create_update_circles"
$pw_ip = "127.0.0.1"; // IP-Adresse zum Plugwise-Server
$pw_port = "8080"; // Webserver-Port des Plugwise-Servers
$pw_username = GetValueString(23880); // Username, falls das Plugwise-Webfront geschützt ist
$pw_password = GetValueString(30828); // Passwort, falls das Plugwise-Webfront geschützt ist
/*********************** Config-ENDE ***********************/
if ($state == "") $state = 3;
$switchdev = TRUE;
$current_state = get_plugwise_variable("powerstate", $pwid);
$powerstate_set = get_plugwise_variable("powerstate_set", $pwid);
$current_power = get_plugwise_variable("powerusage", $pwid);
$threshold = get_plugwise_variable("threshold", $pwid);
$locked = get_plugwise_variable("locked", $pwid);
$deviceid = get_plugwise_variable("ID", $pwid);
if ($state == 1) $state_bool = TRUE;
if ($state == 2) $state_bool = FALSE;
if ($state == 3 AND $current_state == FALSE) $state_bool = TRUE;
if ($state == 3 AND $current_state == TRUE) $state_bool = FALSE;
if ($state == 4) $state_bool = $powerstate_set;
if ($deviceid <> "" AND $current_state != $state_bool)
{
if ($threshold == 0) $threshold = 1000;
if ($threshold < $current_power) $switchdev = FALSE;
if ($locked == TRUE) $switchdev = FALSE;
if ($switchdev == TRUE)
{
if ($state == 1) $setstate = "on";
if ($state == 2) $setstate = "off";
if ($state == 3 AND $current_state == TRUE) $setstate = "off";
if ($state == 3 AND $current_state == FALSE) $setstate = "on";
if ($state == 4 AND $powerstate_set == TRUE) $setstate = "on";
if ($state == 4 AND $powerstate_set == FALSE) $setstate = "off";
if ($setstate == "off") $setstate_bool = false;
if ($setstate == "on" ) $setstate_bool = true;
$powerstate_setvar = get_plugwise_variable_id("powerstate_set", $pwid);
if ($pw_username <> "") $var_loginstr = $pw_username.":".$pw_password."@";
if (GetValueBoolean($powerstate_setvar) <> $setstate_bool) SetValueBoolean($powerstate_setvar,$setstate_bool);
file_get_contents('http://'.$var_loginstr.$pw_ip.':'.$pw_port.'/cc.html?applid='.$deviceid.'&cmd='.$setstate);
sleep(1); // Sicherheitshalber den Schaltbefehlt nochmal schicken, wird aber normalerweise nicht benötigt
file_get_contents('http://'.$var_loginstr.$pw_ip.':'.$pw_port.'/cc.html?applid='.$deviceid.'&cmd='.$setstate);
IPS_RunScript($IPS_SCRIPT_ID); // "create_update_circles" starten, um die geänderten Werte wieder zu bekommen
SetScriptRun($IPS_SCRIPT_ID, time() + 30); // Nach 30 Sekunden erneut starten, um den neuen Stromverbrauch zu bekommen
}
}
}
}
?>
sync_plugwise_powerstate
<?
/**
sync_plugwise_powerstate
Ersteller: Markus Kromberg
Version 1.0.1
Aufgabe:
Diese Funktion synchronisiert den Schaltzustand der Plugwise-Circles.
Im Objektbaum befindet sich unter dem jeweiligen Device eine "Powerstate" und eine "Powerstate_Set" Variable.
Powerstate_Set enthält den Zustand (TRUE / FALSE) wie ihn die IPS-Scripte vorgeben. Wird allerdings auf Grund eines
Stromausfalls oder "ausstecken & einstecken" der Zustand ausserhalb von IP-Symcon verändert, weicht der Inhalt
der beiden Variablen ab. Durch einen Aufruf dieser Funktion wird der Zustand synchronisiert & den Inhalt von Powerstate_Set
übernommen.
Trigger:
Diese Funktion kann manuell aufgerufen werden, ist aber fester Bestandteil des Hauptscripts "create_update_circles".
Ein zusätzlicher, manueller Aufruf sollte normalerweise nicht nötig sein.
Parameter:
$powerstate_id: IPS-ID der Variable "powerstate"
$powerset_id: IPS-ID der Variable "powerstate_set"
Historie:
15.02.2012: Kommentar-Block
02.05.2011: initiale Erstellung der Funktion
**/
if (!function_exists('sync_plugwise_powerstate'))
{
function sync_plugwise_powerstate($powerstate_id, $powerset_id)
{
if (GetValueBoolean($powerstate_id) <> GetValueBoolean($powerset_id))
{
$upd_powerstate_arr = IPS_GetVariable($powerstate_id);
$upd_powerstate = $upd_powerstate_arr["VariableUpdated"];
$upd_powerset_arr = IPS_GetVariable($powerset_id);
$upd_powerset = $upd_powerset_arr["VariableUpdated"];
if ($upd_powerstate <= $upd_powerset) SetValueBoolean($powerstate_id, GetValueBoolean($powerset_id));
else if ($upd_powerstate >= $upd_powerset) SetValueBoolean($powerset_id, GetValueBoolean($powerstate_id));
}
}
}
?>
akm_switch_plugwise
<?
/**
akm_switch_plugwise
Ersteller: Markus Kromberg
Version 1.0.1
Aufgabe:
Diese Funktion wird bei Statusänderung der Anwesenheit ausgeführt.
Sie geht den kompletten Plugwise-Baum durch, analaysiert die Variablen "akm_abw" und "akm_anw"
und führt ggf. die gewünschte Schaltaktion aus
Trigger:
Diese Funktion wird durch ein Script bei AKM-Statusänderung (anwesend / abwesend) getriggert
Parameter:
$var_anw_abw = "abw": Abwesend, die Wohnung ist leer
$var_anw_abw = "anw": Anwesend, es ist jemand zu Hause
Historie:
15.02.2012: Kommentar-Block
02.05.2011: initiale Erstellung der Funktion
**/
if (!function_exists('akm_switch_plugwise'))
{
function akm_switch_plugwise($var_anw_abw)
{
/*********************** Config-START ***********************/
$pw_room_root = 45206; // Hier werden von Plugwise die Raum-Kategorien automatisch angelegt
/*********************** Config-ENDE ***********************/
// Räume finden
$plugwiseraeume = IPS_GetChildrenIDs($pw_room_root);
$anzahl_raeume = count($plugwiseraeume);
for ($ir = 0; $ir < $anzahl_raeume; $ir++) {
// Devices finden
$plugwisedevices = IPS_GetChildrenIDs($plugwiseraeume[$ir]);
$anzahl_devices = count($plugwisedevices);
for ($iv = 0; $iv < $anzahl_devices; $iv++)
{
/* akm_abw finden */
$AKM_VarID = @IPS_GetVariableIDByName("akm_".$var_anw_abw, $plugwisedevices[$iv]);
$PW_VarID = @IPS_GetVariableIDByName("powerstate", $plugwisedevices[$iv]);
$PWS_VarID = @IPS_GetVariableIDByName("powerstate_set", $plugwisedevices[$iv]);
if ($AKM_VarID != false)
{
$PWS_StatusID = "";
switch (GetValueInteger($AKM_VarID))
{
case 0:
break;
case 1:
$PWS_StatusID = TRUE;
SetValueBoolean($PWS_VarID, TRUE);
break;
case 2:
$PWS_StatusID = FALSE;
SetValueBoolean($PWS_VarID, FALSE);
break;
}
}
}
}
}
}
?>
CreateRoomPower
Mit dieser Funktion können aus dem Webfront Highcharts-Graphen erzeugt werden, die alle Verbraucher des gewählten Raumes beinhalten. Wird in Plugwise Source ein neuer Verbraucher einem Raum hinzugefügt, legt mein IPS-Script den Verbraucher an & die unten stehende Funktion erzeugt beim nächsten Aufruf den aktualisierten Graphen im Webfront.
der Aufruf im Webfront geht über ein Script (Script welches im Webfront angeklickt / gestartet werden kann) mit folgendem Inhalt:
<?
$var_room = "Wohnzimmer";
echo CreateRoomPower($var_room, $_IPS['SELF'], $_IPS['SENDER']);
?>
so, aber nun zur Funktion:
<?php
if (!function_exists('CreateRoomPower'))
{
function CreateRoomPower($var_room, $_IPS_self, $_IPS_sender)
{
// => ab V1.0004, damit kann der Script auch von anderen Scripten aufgerufen werden und bereits mit CfgDaten vorkonfiguriert werden
Global $CfgDaten; //$CfgDaten = array();
// Überschriften
$CfgDaten["Title"]= $var_room;
$CfgDaten["SubTitle"]= ""; // "" = Automatisch über Zeitraum
// IPS Variablen ID´s
$CfgDaten["ArchiveHandlerId"]= 13860 /*[Archive Handler]*/; // Archive Handler
$CfgDaten["ContentVarableId"]= 50446 /*[_System\Interfaces\Highcharts\content]*/; // ID der Content-Variable
$CfgDaten["HighChartScriptId"]= 37206 /*[_System\Interfaces\Highcharts\Highcharts]*/; // ID des Highcharts Scripts
// Zeitraum welcher dargestellt werden soll
$CfgDaten["StartTime"] = mktime(0,0,0, date("m", time()), date("d",time()), date("Y",time())); // ab heute 00:00 Uhr
$CfgDaten["EndTime"] = mktime(date("G", time()),59,59, date("m", time()), date("d",time()), date("Y",time())); // ab heute 23:59 Uhr, oder //$CfgDaten["EndTime"] = time(); // = bis jetzt
// => ab V1.0003
$CfgDaten["RunMode"]= "files"; //oder script
// => ab V1.0003
// Serienübergreifende Einstellung für das Laden von Werten
$CfgDaten["AggregatedValues"]["HourValues"] = 3; // ist der Zeitraum größer als X Tage werden Stundenwerte geladen
$CfgDaten["AggregatedValues"]["DayValues"] = 14; // ist der Zeitraum größer als X Tage werden Tageswerte geladen
$CfgDaten["AggregatedValues"]["NoLoggedValues"] = 60; // ist der Zeitraum größer als X Tage werden keine Boolean Werte mehr geladen, diese werden zuvor immer als Einzelwerte geladen
$CfgDaten["AggregatedValues"]["MixedMode"] = false; // alle Zeitraumbedingungen werden kombiniert
// Die Parameter für die einzelnen Chart Serien (Achtung! unbedingt auf Groß-Kleinschreibung achten)
// Name: Name der Kurve (Anzeige in Legende und Tooltip)
// Unit: NULL = Einheit wird aus Suffix des eingestellten Profils übernommen
// "string" = string wird als Einheit eingetragen
// array(0=>'String für 0',1=>'String für 1', usw.) = Ist der Wert 0 wird 'Strung für 0' im Tooltip angezeigt, usw
// ReplaceValues: false = Werte werden wie geloggt übernommen
// array(0=>0.2,1=>10, usw.) = der Wert 0 wird in 0.2 geändert, der Wert 1 wird in 10 geändert
// das macht für die Darstellung von Boolean Werte Sinn, oder für Drehgriffkontakte (Werte 0,1,2) Sinn
// Param: Einstellungen der Kurve (hier können werden exakt Einstellungen aus Higcharts.com eingegeben) hier ein paar Beispiele
// type: Art der Kurve: Sinn machen [area, areaspline, line, spline, pie], noch nicht sinnvoll dargestellt werden [scatter, bar, column]
// step: true oder false - jeder Werte bildet eine Stufe (sinnvoll für Heizungsteller, oder Sollwertvorgaben)
// yAxis: Nummer welche Y-Achse verwendet werden soll (ab 0)
// shadow: true oder false - Darstellung mit oder ohne Schatten
// lineWidth: Linienstärke
// alles weitere bitte aus der Higcharts-Referenz entnehmen -> http://www.highcharts.com/ref/
// und so könnte für eine Achse seperate Einstellungen für die AggregattedValues getroffen werden
//$AggregatedValuesForSeries["HourValues"] = 3;
//$AggregatedValuesForSeries["DayValues"] = 2;
//$AggregatedValuesForSeries["DayValues"] = 2;
//$AggregatedValuesForSeries["Combined"] = true;
//,"AggregatedValues"=>$AggregatedValuesForSeries
// Plugwise Raum finden
$plw_room = @IPS_GetObjectIDByName($var_room, 45206 /*[_System\Aktoren & Geräte\Plugwise\Räume]*/);
// Plugwise Devices finden
$plugwisedevices = IPS_GetChildrenIDs($plw_room);
$anzahl_devices = count($plugwisedevices);
for ($iv = 0; $iv < $anzahl_devices; $iv++)
{
$plw_powerusage = @IPS_GetObjectIDByName("powerusage", $plugwisedevices[$iv]);
$plw_devname = IPS_GetName($plugwisedevices[$iv]);
$CfgDaten["Series"][] = array("Id"=>$plw_powerusage, "Name" =>$plw_devname, "Unit"=>"Watt", "ReplaceValues"=>false,
"Param" =>"type:'line', step:true, yAxis: 0, shadow: true,lineWidth: 1 , states: {hover:{lineWidth: 2}}, marker: { enabled: false, states: { hover: { enabled: true, radius: 4}}}");
}
$plw_powerusage_room = @IPS_GetObjectIDByName("powerusage", $plw_room);
$CfgDaten["Series"][] = array("Id"=>$plw_powerusage_room, "Name" =>"gesamt", "Unit"=>"Watt", "ReplaceValues"=>false,
"Param" =>"type:'area', step:true, yAxis: 0, shadow: true,lineWidth: 1 , states: {hover:{lineWidth: 2}}, marker: { enabled: false, states: { hover: { enabled: true, radius: 4}}}");
// Y-Achsen
$CfgDaten["yAxis"][0] = array("Name" =>"Stromverbrauch", "Unit"=>" W","Opposite"=>false);
//oder direkt den String für die Achsen übergeben $CfgDaten["yAxis"][] = "title: { text: 'Heizungssteller / Luftfeuchte' }, min:0";
// X-Achse ist autom. Time-Format
// => ab V1.0002
// HighchartConfig String
$CfgDaten["HighChartCfg"]= false; // false = default String wird verwendet
$CfgDaten["HighChart"]["Theme"]="ips.js"; // von Highcharts mitgeliefert: dark-green.js, dark-blue.js, gray.js, grid.js
// Abmessungen des erzeugten Charts
$CfgDaten["HighChart"]["Width"] = 0; // in px, 0 = 100%
$CfgDaten["HighChart"]["Height"] = 500; // in px
// und jetzt los ......
$s=IPS_GetScript($CfgDaten["HighChartScriptId"]); // Id des Highcharts-Scripts
include($s['ScriptFile']);
// => ab V1.0003
// hier werden die CfgDaten geprüft und bei Bedarf vervollständigt
$CfgDaten = CheckCfgDaten($CfgDaten);
// => ab V1.0003
if (isset($CfgDaten["RunMode"]) && $CfgDaten["RunMode"] == "script")
{
// Variante1: Übergabe der ScriptId. Daten werden beim Aufruf der PHP Seite erzeugt und direakt übergeben. Dadurch kann eine autom. Aktualisierung der Anzeige erfolgen
if ($_IPS['SENDER'] != "WebInterface")
{
WriteContentWithScriptId ($CfgDaten, $_IPS['SELF']); // und jetzt noch die ContentTextbox
return; // Ende, weil durch die Zuweisung des Script sowieso nochmals aufgerufen wird
}
$sConfig = CreateConfigString($CfgDaten); // erzeugen und zurückgeben des Config Strings
}
else
{
//Variante2: Übergabe des Textfiles. Daten werden in tmp-File gespeichert. Eine automatische Aktualisierung beim Anzigen der Content-Textbox erfolgt nicht
$sConfig = CreateConfigString($CfgDaten); // erzeugen und zurückgeben des Config Strings
$tmpFilename = CreateConfigFile($sConfig, $_IPS['SELF']); // und ab damit ins tmp-Files
if ($_IPS['SENDER'] != "WebInterface")
{
WriteContentWithFilename ($CfgDaten, $tmpFilename); // und jetzt noch die ContentTextbox
}
}
return GetValueString($CfgDaten["ContentVarableId"]);
}
}
?>
Ich weiß das diese Scripte ziemlich quick-and-dirty dahin geschrieben sind und das die fest codierten IPS-ID’s nicht wirklich einem guten Programmier-Stil entsprechen… :rolleyes:
Letztendlich denke ich aber doch, dass es sicherlich für den einen oder andere eine gute Inspiration ist & eventuell Anregungen für eine möglichst gute Integration in IP-Symcon bietet.
Wenn jemand an den Scripten arbeitet & sie verbessert / optimiert würde ich mich über eine Veröffentlichung hier im Thread freuen - damit die ganze Community davon profitieren kann.
Viele Grüße & viel Spaß mit den Script-Bausteinen,
Markus
Versionshistorie
006 2012-02-15: File-Header mit Versionshistorie, Kurzbeschreibung, Trigger- und Parameterübersicht bei allen Files hinzugefügt
005 2012-02-15: create_update_circles: Config-Block, zur einfacheren Anpassung an bestehende Systeme
004 2012-02-15: create_update_circles: Namenskonvertierung / Charset-Konvertierung beim Anlegen der Circles (äöü etc)
003 2012-02-14: Ergänzung CreateRoomPower (Verbrauchs-Graphen im Webfront mit HighCharts)
002 2012-02-14: Ergänzung akm_switch_plugwise (Schaltvorgänge bei An- und Abwesenheit)
001 2012-02-14: Initiale Veröffentlichung der Scripte