Anbindung von Plugwise Stretch 2.0

Hallo Zusammen,

ich habe gestern einen Plugwise Stretch 2.0 erhalten. Der bisherige Plugwise USB-Stick wandert in den Stretch und der ist über LAN oder WLAN erreichbar und kann damit besser zentral im Plugwise-Netzwerk plaziert werden.

Hier meine Frage: Hat schon jemand Erfahrungen mit der der Anbindung eines Stretch 2.0 an IP-Symcon?

Bisher habe ich den Plugwise-Stick über einen seriellen Port angebunden und Scripte ähnlich zu den hier im Forum geposteten genutzt.

Für den Stretch gibt es eine REST-API die ich nutzen möchte. Leider habe ich bisher wenig Ahnung und Erfahrung mit den REST-WebServices. Eine weitere Problematik ist leider auch, dass ich nur einen Plugwise-Stick habe und meine 48 Plugwise-Steckdosen schnellstmöglich wieder funktionieren sollten. Ich werde also stundenweise programmieren und testen und dann den Stick wieder wie bisher im Keller am IP-Symcon-Server betreiben.

Für einen Start-Anstoss oder Tipps in Sachen REST und Plugwise wäre ich sehr dankbar. Die bisherige Suche zu Stretch im Forum und bei Google hat bisher natürlich wenig ergeben, da das Gerät sehr neu ist. Kennt jemand ein gutes REST-Tutorial zum Einlesen in das Thema?

Zunächst wäre es aussreichend von IP-Symcon die Verbindung zum Stretch herzustellen und einzelne Module ein- bzw. auszuschalten. Der Rest (Energiemessung) ist erstmal zweitrangig, das wüde ich später mit der API-Doku alleine hinbringen. Wie gesagt es mir mir um eine Anschubhilfe für den den ganzen schnellen Einstieg. Danke.

Viele Grüße aus dem Unterallgäu
Harry

Hallo Harry,

wir hatten auch gerade diesbezüglich Kontakt zu Plugwise.
Voraussichtlich im Herbst werden wir das Gateway „Stretch“ in IP-Symcon integrieren.
(Stretch miniREST v2 API)

Viele Grüße von der Ostsee ins Allgäu
MST

Hallo Herr Steiner,

das habe ich vom Plugwise-Mitarbeiter in München auch schon gehört - er hat mir auch die API-Doku zur Verfügung gestellt. :wink:
Herr V. hat mir auch ein Smile P0 zum „Testpreis“ angeboten. WIrd das auch in IPS integriert?
Gerne unterstütze ich Sie und paresy beim Testen vorab.

Was kann ich tun, damit ich das Gerät bereits jetzt nutzen kann und nicht bis in den Herbst warten muss. :cool:
Gibt es vielleicht einen Tipp zur Einbindung (Client-Socket anlegen?) oder 1-2 Zeilen PHP-Code zum Testen vorab?

Viele Grüße aus dem sonnigen Unterallgäu an die Küste
Harry Kellner

Gibt’s hier schon Neuigkeiten - und ist „Herbst“ noch „Herbst“ :slight_smile:

Grüße,
Martin

Gibt’s hierzu Updates?

Ich sitze gerade in Australien & hatte eine Situation, in der ein IPS-Unabhängiger Eingriff in das Plugwise-Netz sinnvoll gewesen wäre… Ich erhoffe mir durch die Nutzung des Strech den Zugriff sowohl über IPS als auch direkt über den Strech - mit allen damit verbunden Vor- und ggf. auch Nachteilen.

Unabhängig davon ist mir eine native Unterstützung seitens IP-Symcon natürlich ebenfalls lieber, als die bisherige unsupportete (sowohl seitens IPS als auch seitens Plugwise) Lösungen die hier im Forum herumgeistern.

Alternativ: Gibt es eventuell kleine Code-Schnippsel wie ggf. ein Zugriff über die offizielle Plugwise-API auf den Strech aussehen könnte? Da mir kein Strech vorliegt, kann ich das leider nicht testen… und nur auf gut Glück werde ich mir das Teil sicherlich nicht kaufen :slight_smile:

Viele Grüße aus Sydney,
Markus

Hallo Markus,

zunächst viele Grüße nach Australien.

Ich habe die Versuche mit der PLUGWISE API und Stretch eingestellt. Firmware und Weboberfläche sind noch immer so buggy dass es keinen Spaß bringt damit zu arbeiten. Nach wie vor kann man keine statische IP vergeben, aber nicht weil es nicht vorgesehen wäre, sondern weil das Webformular fehlerhaft ist. Auch die massenhaften Schreibfehler zeugen nicht von einer professionellen Softwareentwicklung. Rückfragen beim Support bzw. bei Herrn V. habe ich aufgegeben. Auch gibt es keine automatischen Updates, sondern werden diese einzeln fürs jeweilige Gerät freigeschalten. Eigenartige Praxis.

Auf die angekündigte IPS-Unterstützung im Herbst warte ich auch noch, bis dahin ruhen alle „Stretch“-Aktivitäten.

Aktuell sind panStamp und MAX! meine IPS-Baustellen.

Viele Grüße (auch an K.) aus Augsburg
Harry

Sent from my iPhone using Tapatalk

Hallo Harry,

Hmm, hab schon vermutet das sich bei dir der Status noch nicht weiter verändert hat… Meine Hoffnung war eher, den Thread mal wieder aus der Vergessenheit zu holen & doch ein Statement von unseren lieben IP-Symcon Entwicklern zu bekommen :-)… Aber wer weiß, Herbst ist ja ein Dehnbarer begriff… und wenn die Zusammenarbeit IPS<->Plugwise ähnlich funktioniert wie die Zusammenarbeit zwischen Dir und Mr. V kann sich das noch ziehen.

Schade das ein eigentlich so gutes & zuverlässiges Produkt wie Plugwise nicht sinnvoll weiter gebracht wird…

Ich habe bei mir zu Hause halt das Problem, dass ein Teil der Automatisierung auf Plugwise beruht und aktuell somit ein IPS-Ausfall fatal ist. Lichter gehen dann nicht mehr, Steckdosen sind ausgeschaltet… Um das ganze etwas fehlertoleranter zu gestallten, hatte ich auf die Strech-Lösung mit Webinterface gehofft.

Alternativ muss ich mir sonst wenigstens mal 1 oder 2 Plugwise-Schalter besorgen, um ein „IPS-Unabhängiges“ Schalten der Plugwisekomponenten zu ermöglichen.

Viele Grüße aus Sydney,
Markus

P.S.: Die Grüße an die Regierung werden beim nächsten Telefonat ausgerichtet, und unsere Homeautomatisierungs-Telko nach meiner Rückkehr wieder eingeführt :smiley:

Hallo Markus,

vor einem Einsatz der Plugwise-Schalter (Switch) würde ich überlegen, ob es keine bessere Lösung gibt.

1.) sind die masslos überteuert und b.) qualitativ sehr windig. Ich habe einen aus Testzwecken im Einsatz und bin genauso wenig überzeugt wie vom Plugwise Sense (auch viel zu teuer, billiges Plastik und aufgrund des nicht offen gelegten Protokolls schwer in IPS einzubinden) - den habe ich mittlerweile in der Bucht weitervermittelt. Wie gesagt mäßige Plastikausführung und unpräziser Druckpunkt beim Schalten - man muss manchmal mehrfach drücken bis der Switch reagiert. Schade eigentlich, da die Circles genial sind. Hätten sie eine direkte, manuelle Bedienmöglichkeit und eine Status-LED wären Sie unschlagbar gut. Und hier ist auch der Preis akzeptabel.

Ich schalte einen Teil meiner Plugwise Circles mit HomeMatic-Fernbedienungen, falls Du Deine CCU noch in Betrieb hast eine Alternative, allerdings auch nicht unabhängig vom IPS-Rechner :frowning:

Kommst Du mit Plugwise Source nicht an die Geräte oder blockiert die IPS-Instanz den Port?

Am Ende bleibt wohl nur ein Original-Plugwise-Schalter für die direkte Bedienung?

Viele Grüße aus der Tretmühle in München
Harry

Hallo Harry,

Genau die Homematic-Lösung läuft bei uns (die große Homematic-Fernbedienung), und ist auch total beliebt :-). Aber du weißt ja wie es ist: Man(n) ist mal nicht erreichbar, hat kein Internet, zeitgleich geht die Welt unter, die Regierung ist aber zu Hause… dann kommt genau was eigentlich nie passieren sollte: IPS stürzt ab, Windoof macht Updates, settings.json ist leer… oder sonst irgend etwas unvorhergesehenes.

Und jetzt frage ich mich halt: Wie bekommt Frau K. die Plugwise-Stecker wieder eingeschaltet? Meine Idee war, eine Art eingeschränkten Notbetrieb auch ohne IPS aufrecht zu erhalten… Und wenn das über das Webfront vom Stretch bzw. über die Android-App von Plugwise gelöst wäre :slight_smile:

Der Zugriff über Plugwise Source ist nicht möglich, so lange unter IPS der Port geöffnet ist.

Am Liebsten wäre mir daher die Strech-Lösung, aber diese lässt sich wohl erst umsetzen, wenn eine halbwegs funktionierende IPS-Integration möglich ist.

Viele Grüße,
Markus (der jetzt auf dem Weg in den Feierabend ist :stuck_out_tongue: )

Hallo Markus,

da wäre der Stretch schon die Lösung.

Die zugehörige App funktioniert in meinem Plugwise-Testnetz (Stretch, Cirlce+, 1x Circle) und die Circles lassen sich schalten. Auf meine große Plugwise-Installation habe ich den Stretch noch nicht losgelassen.

Für den aktuellen Stand der Firmware ist der Stretch definitv zu teuer. Versuch doch mal in München anzurufen und den aktuellen Stand zu erfahren und/oder ein „Test-Kit“ auszuhandeln.

Viele Grüße (noch aus der Tretmühle)
Harry

wird wohl doch eher „April“ werden

:D:D:D

Das erklärt es doch, ohne dem IPS Team zu unterstellen nicht up to date zu sein. Ausserdem zitierst Du einen post der 6 Monate alt ist und der letzte Eintrag des Threads ist 4 Monate alt.

Bist Du denn mit den Geräten weiter gekommen, oder warum postest Du plötzlich hier?

Hallo zusammen,

ich habe vor 10 Tagen bei Plugwise Deutschland nachgefragt. Aktuell gibt es zwar eine neuere Firmware, aber man stellt sie noch nicht bereit. Man will mich informieren, wenn ich die neue Version downloaden kann. Bis dahin stelle ich weitere Versuche ein.

Der Thread ist also noch aktuell und dass bei Steiner & Co. nichts weiter vorangeht scheint verständlich.

Viele Grüße aus dem Unterallgäu
Harry

Gesendet von iPad mit Tapatalk

Hallo zusammen,

wenns nur um zentrale Position geht, man kann den Stick auch mit einem Silex o.ä. ins LAN / WLAN bringen. Funktioniert bei mir seit Jahren ohne Probleme.

Wg der „billigen“ Schalter, Sensoren …

Irgend wo hatten die glaube 1.Q 2013 auch mal eine Schnittstelle zu Enocean angekündigt. Auf Nachfrage in 11/2014 habe ich folgende Antwort bekommen:

„vielen Dank an Ihrem Interesse unserer Produkte. Wir haben ein Produkte Namens Stealth ZE (Stealth mit Zigbee & EnOcean) entwickelt welches als Brücke dient. Über dieses Modul können an das Zigbee Netzwerk bis zu 8 EnOcean Sensoren eingebunden und verarbeitet werden wie z.B. der Batterielose EnOcean Schalter etc. . Das Modul befindet sich derzeit im Testbetrieb und wir hoffen dies so bald als möglich freigeben zu können. Einen genauen Termin kann ich Ihnen jedoch leider derzeit noch nicht nennen.“

Damit könnte man dann die batterielosen Schalter und vieles andere von EON nehmen, und zum Schalten dann die „preiswerten“ Plugwise Circles.

Eigentlich hatte ich gehofft, dass die die EON Brücke in den neuen Stretch 2.0 integrieren. Schade.

Mal sehn wie sich das weiter entwickelt.

Hallo IPS-Gemeinde,

diese Woche habe ich Stretch und Desktop-Software aktualisiert.
Die Stretch-Firmware hat nun die Version 2.3.9 und der Desktop 1.7.63.
Endlich sind die gröbsten Bugs wohl behoben und abgesehen von ein paar Rechtschreibfehlern habe ich nichts gefunden.

Die nächsten Tage werde ich mich mit der Stretch-API befassen und versuchen den Stretch in IPS einzubinden.
Aktuell nutze ich noch immer den USB-Stick und bevor der Stretch nicht sauber funktioniert werde ich nicht auf den Stretch umstellen, denn ich habe fast 50 Steckdosen im Einsatz.

Vielleicht hat ja jemand bereits „Stretch-Erfahrung“ und postet etwas dazu.

Viele Grüße aus dem Unterallgäu
Harry

Hallo Zusammen,

der Stretch funktioniert. Hier der Code um einen Circle ein- („on“) oder auszuschalten („off“).


<?
// Stretch 2.0 Setup
$StretchIP = "192.168.1.1";   // die IP-Adresse des Stretch
$StretchPort = 80;   // Standard-Port des Stretch
$StretchID = "abcdefgh";   // die 8 Buchstaben der Stretch-ID
$ApplianceID = "c0b67fe32ea8444ab2b2a9b4e4d9e9db";   // die ApplianceID des Circles, abfragen über http://[StretchIP]/minirest/appliances
$MAC_Address = "000D6F0000D12345";   // die MAC-Adresse des Circles, abfragen über http://[StretchIP]/minirest/modules
$CircleID = "0D12345";
$SwitchStatus = "on";   // "on" oder "off"
$AuthBase64 = base64_encode("stretch:".$StretchID);

// Socket öffnen
$HTTP_Handle = fsockopen($StretchIP, $StretchPort, $ErrorNo, $ErrorStr);

if (!$HTTP_Handle) {
	echo "Socket-Fehler: ".$ErrorStr." (".$ErrorNo.")
";
} else {
	// HTTP-Request zusammenbauen
	$data  = "POST /minirest/modules;mac_address=000D6F000".$CircleID."/power_state=".$SwitchStatus." HTTP/1.1
";
	$data .= "Host: ".$StretchIP."
";
	$data .= "Authorization: Basic ".$AuthBase64."
";
	$data .= "
";
	fwrite($HTTP_Handle, $data);
	// HTTP-Antwort
	$answer =  fread($HTTP_Handle, 255);
	// Socket schliessen
	fclose($HTTP_Handle);
	//echo $answer."
";
	if (substr($answer, 0, 15)=="HTTP/1.1 200 OK") {
		echo "Befehl OK";
	}
}
?>

Weitere Details seht ihr in den Code-Kommentaren und in der Plugwise-Minirest-API(V2).pdf.

Viele Grüße aus dem Unterallgäu
Harry

Hallo Harry,

ich habe mittlerweile auch die gesamte Kommunikation auf den Stretch 2.0 umgestellt, und ziehe in diesem Zug Schritt-für-Schritt alles auf den Banana-Pi um…

Ich hänge dir einfach mal meine Schalt-Funktionen rund um die Plugwise-Kommunikation an - wenn ich was vergessen / übersehen habe, einfach melden :-). Ansonsten können wir uns gerne bei der weiteren Einbindung zusammen tun und gemeinsam weiter entwickeln…

Viele Grüße vom Bodensee,
Markus

<?
IF (GetValueBoolean(47322 /*[_System\ Global Config\System\IPS_Plugwise_Enable]*/ ) == FALSE)
{
  exit;
}
/**
Plugwise Circle schalten

Verwendung:     PlugwiseSwitchCircle("005512A5", "on")
                PlugwiseSwitchCircle("005512A5", "off")
**/

if (!function_exists('PlugwiseSwitchCircle'))
{
    function PlugwiseSwitchCircle($CircleID, $STATE)
    {
		  /*********************** Config-START ***********************/
		  global $_IPS;
		  $s = IPS_GetScript(get_module_config_include_ID("Plugwise"));
		  include($s['ScriptFile']);
		  /*********************** Config-ENDE ***********************/

        // Switch setup (circle)
        $ApplianceID = get_plugwise_variable("Appliance_ID", $CircleID);
        $ApplianceName = get_plugwise_variable("Appliance_Name", $CircleID);
        $SwitchStatus = $STATE; // on/off

        // Kernel
        $AuthBase64 = base64_encode($pw_username.":".$pw_password);
        $Postdata = "<relay><state>".$SwitchStatus."</state></relay>";
        if ($pw_EnableLogging==TRUE)
	     {
          IPSUtils_Include ("IPSLogger.inc.php", "IPSLibrary::app::core::IPSLogger");
          $LogContext = "Plugwise";
          $LogMessage = "Switch_Circle ".$CircleID." (".$ApplianceName."): ... Verbindung zu Plugwise-Gateway aufbauen ...";
          IPSLogger_Not($LogContext, $LogMessage);
		  }

        $HTTPHandle = fsockopen($pw_ip, 80, $errno, $errstr, 30);
        if (!$HTTPHandle) {
            if ($pw_EnableLogging==TRUE)
	         {
            	IPSUtils_Include ("IPSLogger.inc.php", "IPSLibrary::app::core::IPSLogger");
            	$LogContext = "Plugwise";
            	$LogMessage = "Switch_Circle ".$CircleID." (".$ApplianceName."): $errstr ($errno)";
            	IPSLogger_Err($LogContext, $LogMessage);
				}
        } else {
            $Data = "POST /core/appliances;id=".$ApplianceID."/relay HTTP/1.1
";
            $Data .= "Host: ".$pw_ip."
";
            $Data .= "Content-Type: application/xml
";
            $Data .= "Content-length: ".strlen($Postdata)."
";
            $Data .= "Authorization: Basic ".$AuthBase64."
";
            $Data .= "Connection: Close

";
            $Data .= $Postdata;

            fwrite($HTTPHandle, $Data);
            while (!feof($HTTPHandle)) {
                echo fgets($HTTPHandle, 128);
            }
            fclose($HTTPHandle);

            if ($pw_EnableLogging==TRUE)
	         {
              IPSUtils_Include ("IPSLogger.inc.php", "IPSLibrary::app::core::IPSLogger");
              $LogContext = "Plugwise";
              $LogMessage = "Switch_Circle ".$CircleID." (".$ApplianceName."): ".$STATE;
              IPSLogger_Not($LogContext, $LogMessage);
            }
        }
    }
}
?>

Der Status wird durch folgendes Script synchronisiert:

<?php
IF (GetValueBoolean(47322 /*[_System\ Global Config\System\IPS_Plugwise_Enable]*/ ) == FALSE)
{
  exit;
}
/**
  sync_plugwise_device
  Ersteller: Markus Kromberg
  Version 1.0.0

  Aufgabe:
     Dieses Script
      - registriert automatisch neue Plugwise-Circles im IP-Symcon
      - legt nötige Variablen, Scripte und Events an
      - aktualisiert die Messwerte
      - bei Bedarf kann auch nur ein einzelner Circle aktualisiert werden

  Updates:
  05.12.2014: initiale Erstellung des Scriptes
**/

if (!function_exists('sync_plugwise_state'))
{
    function sync_plugwise_state($IPS_SCRIPT_ID, $pw_ip, $pw_username, $pw_password, $pw_circle_root, $pw_UpdateCircleDetails, $pw_CircleID="" )
    {
      /*********************** Config-START ***********************/
      global $_IPS;
      $s = IPS_GetScript(get_module_config_include_ID("Plugwise"));
      include($s['ScriptFile']);
      /*********************** Config-ENDE ***********************/

      /**
      CACHING-STATUS prüfen
      **/

        // Cache-Status noch Okay, kein Refresh nötig
        $OpenCURL = FALSE;
        $output = GetValueString($PW_CacheModulesID);
        $oXML = new SimpleXMLElement($output);

		  /* Globale Variablen - Circle-Unabhängig */
		  $glob_powerusage = 0.0;
        for($i = 0;$i < count($oXML);$i ++)
        {
           /* Variablen initialisieren */
           $devid = "";
           $mac_adr = "";
           $lastseendate = "";
           $powerstate = "";
           $powerusage = 0.0;
           $appliance_id = "";
           $CatID = 0;
           $pid_id = 0;
           $apl_id = 0;
           $ana_id = 0;
           $pmc_id = 0;
           $lsd_id = 0;
           $pst_id = 0;
           $pss_id = 0;
           $pus_id = 0;
           $plugwise_type = 0;
           $ApplianceName = "";
           $View_PowerstateLabel = "";

            /* Variablen auslesen / erzeugen */
            $devid         = strval($oXML->module[$i]->name);
            $plugwise_type = intval($oXML->module[$i]->type);
            $mac_adr       = strval($oXML->module[$i]->mac_address);
            $powerstate    = strval($oXML->module[$i]->power_state);
            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;
            $powerusage    = floatval($oXML->module[$i]->current_power_usage);

            // Nur Circles / Stealth an dieser Stelle abarbeiten:
            IF ($plugwise_type == 1 OR $plugwise_type == 2)
            {
                // Appliance-Attribute auslesen
                if (isset($oXML->module[$i]))
                {
                    if (isset($oXML->module[$i]->appliance))
                    {
                            foreach($oXML->module[$i]->appliance->attributes() as $a => $b) {
                                if ($a == "id") $appliance_id = strval($b);
                            }
                    }
                }

                IF (($pw_circle_root == 0) OR (!ISSET($pw_circle_root)))
                {
						exit;
					 }
                IF (($pw_view_root == 0) OR (!ISSET($pw_view_root)))
                {
						exit;
					 }
                // Anlegen einer neuen Kategorie mit dem Plugwise-Namen
                $CatID     = create_plugwise_category($devid, $pw_circle_root);

                IF (($CatID == 0) OR (!ISSET($CatID)))
                {
						exit;
					 }

                // Anlegen der Variablen
                /* powerstate          */ $pst_id = create_plugwise_device($CatID,         "powerstate",           0, $powerstate_bool, "~Switch", $devid, $devid, 1);
                /* powerusage          */ $pus_id = create_plugwise_device($CatID,         "powerusage",           2, $powerusage,   "~Watt.3680",     "", $devid, 1);
            }
        }
    }
}
?>

Dazu habe ich mir einige Hilfs-Funktionen geschrieben:

<?
/**
  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 ***********************/
global $_IPS;
$s = IPS_GetScript(get_module_config_include_ID("Plugwise"));
include($s['ScriptFile']);
/*********************** Config-ENDE ***********************/

        // Circles finden
        $CircleID = @IPS_GetObjectIDByName(trim(strval($pwid)), intval($pw_circle_root));
        if ($CircleID === false)
            echo "Error, Circle:".trim(strval($pwid))." in Root:".$pw_circle_root." nicht gefunden";
        else
        {
            $VariableID = @IPS_GetObjectIDByName($variablename, $CircleID);
            if ($VariableID === false)
                echo "Error (varname:*".$variablename."*, CircleID:*".$CircleID."*";
            else
            {
                return GetValue($VariableID);
            }
        }
    }
}

?>

<?
IF (GetValueBoolean(47322 /*[_System\ Global Config\System\IPS_Plugwise_Enable]*/ ) == FALSE)
{
  exit;
}
/**
  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, $ApplianceId, $CircleId, $doupdate = 1, $devlocked_bool = FALSE)
    {
		/*********************** Config-START ***********************/
		global $_IPS;
		$s = IPS_GetScript(get_module_config_include_ID("Plugwise"));
		include($s['ScriptFile']);
		/*********************** Config-ENDE ***********************/
		
        /*********************** Config-START ***********************/
        $IPS_INCLUDE_SYNC_CIRCLE_ID = get_plugwise_include_id("sync_circle", $gPlugwise_Root);
        $IPS_INCLUDE_SWITCH_CIRCLE_ID = get_plugwise_include_id("switch_circle", $gPlugwise_Root);
        /*********************** Config-ENDE ***********************/

        // 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 $pw_MasterScriptID;
                $ScriptTEXT_switch =  '
                <?php
                  /* Dieses Script wurde automatisch durch Script "'.$pw_MasterScriptID.'" erzeugt.
                     Es dient zum Schalten der Circles sowie zur Überwachung des erfolgreichen
                     Schaltvorgangs */

                  /* START Konfiguration */
                  $CircleID = "'.$CircleId.'";
                  $ApplianceID = "'.$ApplianceId.'";
                  $pw_ip = "'.$pw_ip.'";
                  $pw_username = "'.$pw_username.'";
                  $pw_password = "'.$pw_password.'";
                  $pw_circle_root = '.$pw_circle_root.';
                  $pw_MasterScriptID = "'.$pw_MasterScriptID.'";
                  /* ENDE Konfiguration*/

                  $s = IPS_GetScript('.$IPS_INCLUDE_SWITCH_CIRCLE_ID.');
                  include($s["ScriptFile"]);
                ?>';
                $script_switch = CreateScriptByName("switch_circle", $VarID_ID, $ScriptTEXT_switch);

                $eid = IPS_CreateEvent(0);                        //Ausgelöstes Ereignis
                IPS_SetEventTrigger($eid, 0, $VarID_ID);          //Bei Änderung von Variable mit ID 15754
                IPS_SetEventTriggerValue($eid, false);            //Nur bei "TRUE" auslösen
                IPS_SetParent($eid, $script_switch);              //Ereignis zuordnen
                IPS_SetEventActive($eid, true);                   //Ereignis aktivieren
            }

            /* Nach Variablen-Neuanlage Wert immer übernehmen */
            $doupdate = 1;
        }

        /* Wert übernehmen */
        if ($doupdate != 0)
        {

            /* ggf. Appliance-Name abfragen */
            if ($name == "Appliance_Name")
            {
              /**
              CACHING-STATUS prüfen
              **/
              IF (get_plugwise_cachevar_stateOK("Appliances", $PW_Master_ID) == TRUE)
              {
                // Cache-Status noch Okay, kein Refresh nötig
                $PW_CacheVarID = get_plugwise_cachevar_id("Appliances", $PW_Master_ID);
                $output = GetValueString($PW_CacheVarID);
              } else
              {
                if ($pw_EnableLogging==TRUE)
	             {
                  IPSUtils_Include ("IPSLogger.inc.php", "IPSLibrary::app::core::IPSLogger");
                  $LogContext = "Plugwise";
                  $LogMessage = "Create_Plugwise_Device: ... Verbindung zu Plugwise-Gateway aufbauen ...";
                  IPSLogger_Not($LogContext, $LogMessage);
					 }
                $chname = curl_init();
                curl_setopt($chname, CURLOPT_URL, "http://".$pw_ip."/minirest/appliances");
                curl_setopt($chname, CURLOPT_USERPWD, $pw_username . ":" . $pw_password);
                curl_setopt($chname, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($chname, CURLOPT_HEADER, 0);
                $output = curl_exec($chname);

                /**
                CACHING: Wenn kein Filter aktiv, dann Array-Inhalt in Variable zwischenspeichern
                **/
                set_plugwise_cachevar("Appliances", $PW_Master_ID, $output);
                curl_close($chname);
              }
              $tmpXML = new SimpleXMLElement($output);
              $oXML = $tmpXML->xpath("//*[@id='".$ApplianceId."']");
              $value = strval(convertToUTF8($oXML[0]->name));
            }

            switch ($type)
            {

            case 0:
                if (is_bool($value) == true)
                {
                    if (GetValueBoolean($VarID_ID) != $value)
                          {
                             SetValueBoolean($VarID_ID, $value);        // Wert übernehmen
                             if ($pw_EnableLogging==TRUE)
	                          {
									    IPSUtils_Include ("IPSLogger.inc.php", "IPSLibrary::app::core::IPSLogger");
                               $LogContext = "Plugwise";
                               $LogMessage = "Create_Plugwise_Device: Update Variable ".IPS_GetName(IPS_GetParent($VarID_ID))."[".IPS_GetName($VarID_ID)."]: ".var_export($value, true);
                               IPSLogger_Not($LogContext, $LogMessage);
                             }
                          }
                }
                break;

            case 1:
                if (GetValueInteger($VarID_ID) != $value)         SetValueInteger($VarID_ID, $value);        // Wert übernehmen
                break;

            case 2:
                if (GetValueFloat($VarID_ID) != $value)         SetValueFloat($VarID_ID, $value);        // Wert übernehmen
                break;

            case 3:
                if (GetValueString($VarID_ID) != $value)         SetValueString($VarID_ID, $value);        // Wert übernehmen
                break;
            }
        }
        return $VarID_ID;
    }
}
?>

<?
/**
  get_plugwise_cachevar_id
  Ersteller: Markus Kromberg
  Version 1.0.1

  Aufgabe:
     Diese Funktion liefert die ID einer Caching-Variable zurück

  Parameter:
    $variablename:    Name der Variable
    $pwid:            Plugwise-Master-ID

  Historie:
    09.12.2014: initiale Erstellung der Funktion
**/

if (!function_exists('get_plugwise_cachevar_id'))
{
    function get_plugwise_cachevar_id($variablename, $pwid)
    {
/*********************** Config-START ***********************/
global $_IPS;
$s = IPS_GetScript(get_module_config_include_ID("Plugwise"));
include($s['ScriptFile']);
/*********************** Config-ENDE ***********************/

		// Circles finden
		$CircleCacheFolderID = @IPS_GetObjectIDByName("Caching", $pw_circle_root);
		if ($CircleCacheFolderID === false)
			echo "Error, CacheFolder *Caching* not found!";
		else
		{
			$VariableID = @IPS_GetObjectIDByName($variablename, $CircleCacheFolderID);
			if ($VariableID === false)
				echo "CacheVariable *".$variablename."* not found!";
			else
			{
				return $VariableID;
			}
		}
    }
}

?>

<?
/**
  get_plugwise_cachevar_stateOK
  Ersteller: Markus Kromberg
  Version 1.0.1

  Aufgabe:
     Diese Funktion liefert den Cache-Status einer Caching-Variable zurück

  Parameter:
    $variablename:    Name der Variable
    $pwid:            Plugwise-Master-ID

  Historie:
    09.12.2014: initiale Erstellung der Funktion
**/

if (!function_exists('get_plugwise_cachevar_stateOK'))
{
    function get_plugwise_cachevar_stateOK($variablename, $pwid)
    {
/*********************** Config-START ***********************/
global $_IPS;
$s = IPS_GetScript(get_module_config_include_ID("Plugwise"));
include($s['ScriptFile']);
/*********************** Config-ENDE ***********************/

		// Circles finden
		$CircleCacheFolderID = @IPS_GetObjectIDByName("Caching", $pw_circle_root);
		if ($CircleCacheFolderID === false)
			return FALSE;
		else
		{
			$VariableID = @IPS_GetObjectIDByName($variablename, $CircleCacheFolderID);
			if ($VariableID === false)
				return FALSE;
			else
			{
				$Variable = IPS_GetVariable($VariableID);
				$VariableTimeStamp = $Variable["VariableUpdated"];
				$VariableAge = time()-$VariableTimeStamp;
				$PW_MaxAgeID = get_plugwise_configvar_id("Cache_MaxAge", $pw_circle_root);
				$PW_ForceUpdateID = get_plugwise_configvar_id("Update_CircleCache", $pw_circle_root);
				$PW_ForceUpdate = GetValueBoolean($PW_ForceUpdateID);
				$PW_MaxAge = GetValueInteger($PW_MaxAgeID);

				/**
				Variable auf MaxAge prüfen, alternativ Update Forcen wenn $PW_ForceUpdate=TRUE.
				Ausnahme: letztes Update wurde vor weniger als 2 Sekunden durchgeführt, dann kein Update (Denial of Service-Schutz)
				**/
				IF (($VariableAge <= $PW_MaxAge AND $PW_ForceUpdate==FALSE) OR $VariableAge <= 10)
				{
					return TRUE;
				} else
				{
					return FALSE;
				}
			}
		}
    }
}

?>

<?
/**
  set_plugwise_cachevar
  Ersteller: Markus Kromberg
  Version 1.0.1

  Aufgabe:
     Diese Funktion schreibt eine Plugwise Cache-Variable & legt diese sowie
	 alle Child-Variablen notfalls automatisch an

  Parameter:
    $variablename:    Name der Variable
    $pwid:            Plugwise-Master-ID
	$content:		  Inhalt der geschrieben werden soll

  Historie:
    09.12.2014: initiale Erstellung der Funktion
**/

if (!function_exists('set_plugwise_cachevar'))
{
    function set_plugwise_cachevar($variablename, $pwid, $content)
    {
        $pw_circle_root = $pwid;

		// Cache-Variable finden
		$CircleCacheFolderID = @IPS_GetObjectIDByName("Caching", $pw_circle_root);
		if ($CircleCacheFolderID === false)
			echo "Error!";
		else
		{
			$VariableID = CreateVariableByName($CircleCacheFolderID, $variablename, 3, $profile = "", $icon = "", $pos = 0, $hidden=true);
			SetValueString($VariableID, $content);
			return $VariableID;
		}
    }
}

?>

Include-Scripte:

<?php
  /** SWITCH_CIRCLE **/

  // max. Scriptlaufzeit definieren
  ini_set('max_execution_time', get_module_configvar("Plugwise", "SYS_max_execution_time_switch_circle"));

IF (get_module_configvar("Plugwise", "000_Enable") == FALSE)
{
  Echo "Aborting update_modules";
  exit;
}

/*********************** Config-START ***********************/
global $_IPS;
$s = IPS_GetScript(get_module_config_include_ID("Plugwise"));
include($s['ScriptFile']);
/*********************** Config-ENDE ***********************/

/*********************** Functions-START ***********************/
/* Include eines Scriptes über die IPS-ID */
if (!function_exists('includeScript'))
{
function includeScript($scriptID)
{
  $s = IPS_GetScript($scriptID);
  include($s['ScriptFile']);
}
}
/*********************** Functions-ENDE ***********************/

/*********************** Includes Einbinden-START ***********************/
/* Kategorien laden */
$funct_arr = IPS_GetChildrenIDs($pw_MasterFunctionID);
for($j=0; $j < count($funct_arr); $j++)
{
	includeScript($funct_arr[$j]);
}
/*********************** Includes Einbinden-ENDE ***********************/
  $SyncRefreshInt  = get_module_configvar("Plugwise", "Sync_Refresh_Interval", $GetID=FALSE);
  $SyncSwitchInt   = get_module_configvar("Plugwise", "Sync_Switch_Interval", $GetID=FALSE);
  $SyncMaxRetry    = get_module_configvar("Plugwise", "Sync_Max_Retry", $GetID=FALSE);

  $PowerState      = get_plugwise_variable("powerstate", $CircleID);
  $SetPowerState   = get_plugwise_variable("powerstate_set", $CircleID);
  $ApplianceName   = get_plugwise_variable("Appliance_Name", $CircleID);
  $ErrorCountID    = CreateVariableByName($_IPS["SELF"], "error_count", 1, $profile = "", $icon = "", $pos = 0, $hidden=true);

  $UpdateNameID    = CreateVariableByName($_IPS["SELF"], "update_name", 0, $profile = "", $icon = "", $pos = 0, $hidden=true);
  $UpdateName      = GetValueBoolean($UpdateNameID);
  $SetPowerStateID = get_plugwise_variable_id("powerstate_set", $CircleID);
  $ErrorCount      = GetValueInteger($ErrorCountID);

  // Schalt-Anforderung auf jeden Fall an Plugwise übertragen
  IF ($SetPowerState == TRUE)
  {
	PlugwiseSwitchCircle($CircleID, "on");
  }
  else
  {
	PlugwiseSwitchCircle($CircleID, "off");
  }

  IF ($PowerState == $SetPowerState)
  {
	SetValueInteger($ErrorCountID, 0);
	if ($pw_EnableLogging==TRUE)
	{
     IPSUtils_Include ("IPSLogger.inc.php", "IPSLibrary::app::core::IPSLogger");
     $LogContext = "Plugwise";
     $LogMessage = "switch_circle: $ApplianceName Powerstate passt, keine Aktion nötig ($CircleID)";
     IPSLogger_Dbg($LogContext, $LogMessage);
   }

	//Timer ausschalten
	IPS_SetScriptTimer($_IPS['SELF'], 0);
  }

  IF (($PowerState != $SetPowerState) AND ($ErrorCount <= $SyncMaxRetry))
  {
	IF ($SetPowerState == TRUE)
	{
		if ($pw_EnableLogging==TRUE)
	   {
	     IPSUtils_Include ("IPSLogger.inc.php", "IPSLibrary::app::core::IPSLogger");
	     $LogContext = "Plugwise";
	     $LogMessage = "switch_circle: $ApplianceName Powerstate fehlerhaft, $CircleID einschalten";
	     IPSLogger_Dbg($LogContext, $LogMessage);
	   }
   }
	IF ($SetPowerState == FALSE)
	{
	   if ($pw_EnableLogging==TRUE)
	   {
	     IPSUtils_Include ("IPSLogger.inc.php", "IPSLibrary::app::core::IPSLogger");
	     $LogContext = "Plugwise";
	     $LogMessage = "switch_circle: $ApplianceName Powerstate fehlerhaft, $CircleID ausschalten";
	     IPSLogger_Dbg($LogContext, $LogMessage);
	   }
	}

	$ErrorCount = $ErrorCount+1;
	SetValueInteger($ErrorCountID, $ErrorCount);
	IPS_SetScriptTimer($_IPS['SELF'], $SyncSwitchInt);
  }

includeScript(22155 /*[_System\ Global Includes\include_footer]*/ );
?>

Was mir negativ aufgefallen ist:

[ul]
[li] Teilweise dauert das Abrufen der XML-Seite vom Stretch 2.0 relativ lange, aus diesem Grunde speicher ich mir die Seiten in einer Caching-Variable zwischen, die zyklisch automatisch aktualisiert wird. Dadurch können selbst mehrere parallele Script-Aufrufe relativ gut abgearbeitet werden (z.B. bei vielen Schaltaktionen durch Wechsel Anwesenheit)
[/li][li] Wir bekommen keine aktive Benachrichtigung über Status-Wechsel, der Circle-Status muss jederzeit aktiv angefragt werden
[/li][/ul]

Hallo Markus,

schön von Dir zu hören, hast viel um die Ohren? Ich habe heute Heimarbeitstag und mir die Tour nach München gespart.

Was mir negativ aufgefallen ist:

Teilweise dauert das Abrufen der XML-Seite vom Stretch 2.0 relativ lange, aus diesem Grunde speicher ich mir die Seiten in einer Caching-Variable zwischen, die zyklisch automatisch aktualisiert wird. Dadurch können selbst mehrere parallele Script-Aufrufe relativ gut abgearbeitet werden (z.B. bei vielen Schaltaktionen durch Wechsel Anwesenheit)
Wir bekommen keine aktive Benachrichtigung über Status-Wechsel, der Circle-Status muss jederzeit aktiv angefragt werden

Da kann ich nur zustimmen und ich überlege ob ich wirklich auf den Stretch umsteige, da mein momentaner USB-Zugriff zuverlässig und schnell funktioniert. :confused:

Den Vorteil des Stretch sehe ich im Moment nicht so, außerdem habe ich noch nicht erkannt, wie ich den Umstieg meines vorhandenen Plugwise-Netzes mit fast 50 Circles auf den Stretch realisieren soll. Ein Austausch von USB-Stick und Circle+ alleine reicht nicht. Auch die Neuinstallation des Stretch führte nicht zum Ziel - der Stretch erkennt den anderen Circle+ einfach nicht und bleibt hartnäckig bei seinem eigenen Circle+.

Weißt Du wo Plugwise die Netzwerk-Infrastrukur ablegt - im Circle+ oder im Stick?

Also für mich die Frage: lohnt der Umstieg auf den Stretch? Wo siehst Du den Vorteil des Stretch?

Deine Skripte werde ich mal testen - sind ja sehr umfangreich. :cool:

Viele Güße aus dem Unterallgäu
Harry

Hallo Harry,

Jep - hab mal wieder (wie immer) ziemlich viel um die Ohren, derzeit arbeite ich an einem großen Automatisierungs-Projekt das Ende des Jahres in USA in Betrieb genommen wird… 15 Roboter verteilt auf mehrere Fertigungs-Linien, da wird’s sooo schnell nicht langweilig :-).

Da kann ich nur zustimmen und ich überlege ob ich wirklich auf den Stretch umsteige, da mein momentaner USB-Zugriff zuverlässig und schnell funktioniert.

Hmm, die Windows-Only-Lösung hatte schon charme und war mittlerweile auch recht stabil - aber da ich langfristig von Windows weg möchte, war für mich persönlich der Schritt unumgänglich. Ich möchte es ähnlich wie in der Automatisierungs-Technik aufbauen: Ein minimales IPS auf einem stabilen Unix-System für die Basis-Funktionen (Schalten & verknüpfen von Geräten), mit dem Ziel eine möglichst hohe Stabilität zu gewährleisten. Dieses Basis-IPS soll dann auch nicht mehr Bestandteil von Tests und Spielereien werden… Ein Backup-BananaPi / RasPi sowie Backup-SD-Karten sind ja überhaupt kein Problem - was das Thema Verfügbarkeit auch noch mal deutlich verbessert.
Darauf aufbauend gibt’s das „alte“ Windows-IPS, welches sich zukünftig nur noch um Komfort-Funktionen und Visualisierung kümmern soll, hier kann dann auch nach belieben gespielt & getestet werden. Die Synchronisation bzw. die „Kommunikations-API“ möchte ich über die JSON-RPC API umsetzen (Datenaustausch — IP-Symcon :: Automatisierungssoftware).

Also vereinfacht gesagt:
Ich möchte Visualisierung / GUI & Komfort auslagern und über eine weitere „API“ an die Schalt-Logik anbinden (3-Schichten-Modell). Ich habe dann die Hoffnung, zukünftig einzelne Bereiche Ändern zu können (z.B. bei Systemwechsel) ohne jedes Mal auch Komfort-Funkionen und Visualisierung anpassen zu müssen. Diese kommunizieren dann über statische Kommunikations-Variablen, die per RPC im Raspberry dann den eigentlichen Schalt-Befehl auslösen…
Ist dir hier schon mal ein Thread zu einer Mehr-Schicht-Architektur untergekommen? Aktuell suche ich noch ein bissl Inspiration, wie sowas zuverlässig, komfortabel und flexibel umgesetzt werden könnte…

Wir Zwei liebäugeln gerade mit dem Thema Eigenheim und planen in den nächsten 2-3 Jahren zu bauen… da möchte ich damit so langsam mein IPS in die richtige Richtung bringen… und du weißt ja wie aufwändig es ist, ein Haus halbwegs sinnvoll an IPS anzubinden :slight_smile:

Den Vorteil des Stretch sehe ich im Moment nicht so, außerdem habe ich noch nicht erkannt, wie ich den Umstieg meines vorhandenen Plugwise-Netzes mit fast 50 Circles auf den Stretch realisieren soll. Ein Austausch von USB-Stick und Circle+ alleine reicht nicht. Auch die Neuinstallation des Stretch führte nicht zum Ziel - der Stretch erkennt den anderen Circle+ einfach nicht und bleibt hartnäckig bei seinem eigenen Circle+.

Weißt Du wo Plugwise die Netzwerk-Infrastrukur ablegt - im Circle+ oder im Stick?

Uff, gute Frage. Soweit ich Informiert bin, ist Daten-Master der Circle+. Dieser verwaltet sowohl die Netzwerkstruktur der Circles untereinander, sowie die aktuellen Messwerte (inklusive einer längeren Messwert-Historie). Sämtliche Circles müssen am Circle+ registriert werden, damit diese in das Netz des Circle+ aufgenommen werden. Des Weiteren habe ich (glaube ich) irgendwo gelesen, dass durch die Umstellung auf den Stretch sich in der Kommunikation etwas ändert. Ich musste sämtliche Circles resetten und das Plugwise-Netz komplett neu aufbauen lassen… Prinzipiell bei meiner Circle-Anzahl kein Problem, bei dir wird’s schon schwieriger.
Ich hatte mir in IPS ein Schaltscript gebastelt, dass den Reset-Schalt-Code für mich an einem Circle schaltet… und mit dem bin ich dann durch die Wohnung gewandert :slight_smile:

Also für mich die Frage: lohnt der Umstieg auf den Stretch? Wo siehst Du den Vorteil des Stretch?

Hmm, wenn du an deiner Architektur nichts ändern möchtest und alles beim Alten belassen möchtest, würde ich erst mal nicht switchen. Aktuell ist bedingt durch die langsamen Warte- und Schaltzeiten die Umstellung noch nicht unbedingt vorteilhaft… Plugwise muss erst mal an der Firmware arbeiten und vor allem die Performance optimieren - dann könnte es Interessant werden.
Möchtest du allerdings Windows-Unabhängig werden (z.B. Backup über Raspi etc), dann wird dir wohl nichts anderes übrig bleiben :-/.

Deine Skripte werde ich mal testen - sind ja sehr umfangreich.

Mach das! Ziemlich sicher habe ich irgend welche Hilfsfunktionen vergessen, hab mir mittlerweile ne ganze Library an Helferlein gebastelt, die automatisch von IPS angezogen werden… Wenn was fehlt, du Fehler findest oder etwas besser gelöst hast - freue ich mich natürlich über jeden Input :-).

Viele Grüße von der Front,
Markus

P.S.: Wird mal wieder Zeit für ne Telko, oder?

Hallo Markus,

das mit der Aufteilung auf 2x IPS mache ich auch gerade:

Das IPS auf dem RaspberryPi soll die Automatik-Funktionen für Rollo (EIB), Licht (EIB) und die EIB-Steckdosen managen, also vor allem die regelmäßigen tägichen Funktionen, aber bisher eben nur EIB. Da wäre es schon gut auch Plugwise dort abzuhandeln.

Das „Windows-IPS“ bleibt für die Visualisierung, die Komfort-Funktionen und den Rest. Momenan habe ich nach 5 Jahren auch endlich mal das Dashboard in Angriff genommen.

TelKo jederzeit, aber nur übers Festnetz, Handy hat zu Hause keinen Empfang. Abends ab ca. 19:00 Uhr geht fast immer. :rolleyes:

Viele Grüße aus dem Unterallgäu
Harry

PS Jetzt bin ich mal kurz weg - Mittagspause.