Plugwise ohne Server direkt auslesen/schalten

Hallo

nachdem paresy (dankeschön) auf die Seite maartendamen hingewiesen hat, hab ich mal schnell versucht auf den Stick und die Circle über eine Registervariable ohne den Plugwise Server, zuzugreifen und es funktioniert.

Die Verbindung mit dem Stick war nach dem Studium der oben genannten Seite schnell hergestellt und der Stick initialisert, nur das Auslesen wollte nicht funktionieren, da man mit anderen Adressen natürlich auch einen anderen CRC hat und den musst ich erstmal rausbekommen.
Nach einigem Suchen im Netz hab ich dann die Lösung gefunden und will sie euch natürlich nicht vorenthalten.

<?

// this function is used to calculate the (common) crc16c for an entire buffer
function calculate_common_crc16c($buffer)
{
    $crc16c = 0x0000;  // the crc initial value laut www.maartendamen.com
    $buffer_length = strlen($buffer);
    for ($i = 0; $i < $buffer_length; $i++)
    {
        $ch = ord($buffer[$i]);
        $crc16c = update_common_crc16c($ch, $crc16c);
    }
    return $crc16c;
}
// this function is used to calculate the (common) crc16c byte by byte
// $ch is the next byte and $crc16c is the result from the last call, or 0xffff initially
function update_common_crc16c($ch, $crc16c)
{
    $crc16c_polynomial = 0x11021;   //auch laut maartendamen
    // This comment was in the code from
    // http://www.joegeluso.com/software/articles/ccitt.htm
    // Why are they shifting this byte left by 8 bits??
    // How do the low bits of the poly ever see it?
    $ch <<= 8;
    for($i = 0; $i < 8; $i++)
    {
        if (($crc16c ^ $ch) & 0x8000)
        {
            $xor_flag = true;
        }
        else
        {
            $xor_flag = false;
        }
        $crc16c = $crc16c << 1;
        if ($xor_flag)
        {
            $crc16c = $crc16c ^ $crc16c_polynomial;
        }
        $ch = $ch << 1;
    }
    // mask off (zero out) the upper two bytes
    $crc16c = $crc16c & 0x0000ffff;
    return $crc16c;
}


// init
$befehl="000A";
$mac="";

// abfrage Verbrauch
//$befehl = '0012';
//$mac = '000Dxx0000D3xxxB'; //Adresse des Circle




// abfrage device
//$befehl = '0023';
//$mac = '000Dxx0000D3xxxB';

// schalten
//$befehl = '0017';
//$mac = '000Dxx0000D3xxxB01';   //01 bzw. 00 hinten schaltet ein bzw. aus



$text=$befehl.$mac;
$ausgabe=dechex(calculate_common_crc16c($text));
$ausgabe = str_pad($ausgabe, 4 ,'0', STR_PAD_LEFT); //mit nullen auffüllen
$text.= $ausgabe;


RegVar_SendText(54511 /*[Test neu\Plugwise\Register Plugwise]*/,"\x05\x05\x03\x03".$text."\x0D\x0A");


?>

Als erstes muss man den Stick initialiseren mit

$befehl="000A";
$mac="";

So sieht es in der Registervariable aus 000Ab43c und das ist die Antwort des Sticks bei mir.

00003E1300C1CA7D
00113E13000Dxx0000CxxxE0101610Dxx0000B1Dxxxxx1FF64D3
ƒ

0011 ist die Antwort auf 000A (Die Antwort ist anscheinend immer eins größer als die Anfrage)
3E13 ist die fortlaufende Nummer der Anfragen.
000Dxx0000 ist die Adresse des Plugwise Netzwerk jetzt noch die Adresse(Die auf dem Aufkleber) des Circles dahinter und Ihr könnt die Circle auslesen.
0101 die erste 01 ist noch unbekannt, die hintere 01 zeigt an ob der Circle+ online ist.
Dahinter sind dann nochmal Netzwerk Infos.

Als nächstes kann man mit

$befehl = '0023';
$mac = '000Dxx0000D3xxxB';

Infos über den Circle auslesen.
Nähere Infos zum Protokol siehe dieses Pdf.

Mit dem Befehl „0012“ kann man den Verbrauch auslesen. Der wird als Pulse pro Sekunde, Pulse pro 8 Sekunden und gesamte Pulse ausgegeben. Die muss man dann noch irgendwie mit einer Korrektur die man einmal aus dem Circle auslesen muss (Befehl 0026) verrechnen(hab mich da noch nicht eingelesen) und schon soll man den Verbrauch haben.

Die Circle schalten geht auch mit

$befehl = '0017';
$mac = '000Dxx0000D3xxxB01';   //01 bzw. 00 hinten schaltet ein bzw. aus

Mit dem Befehl 0023 bekommt man die Uhrzeit, ob ein oder aus, ob 50Hz oder 60Hz(wers braucht), Hard und Software version des Circle raus.

Auch Uhrzeitstellen (0016), den Speicher der Circle auslesen (0048) geht.

Jetzt muss man „nur“ noch die Antworten der Registervarible auswerten aber das sollte für das Forum doch ein klacks sein und dann braucht man den Server von Plugwise nicht mehr.

Das wollte ich nur kurz präsentieren damit sich auch andere ans Programmieren machen können. (

So das ganze ist nur quick&dirty erstellt um zu schauen ob es geht und jetzt könnt Ihr loslegen.

Gruß Jannis

Hallo Jannis!

Vielen Dank für deine Mühe. Ich wollte eigentlich mal ein paar Funktionen dafür schreiben, allerdings scheitere ich schon an den Basics. Den Port kann ich öffnen, die Registervariable ist angelegt & dein Init-Script ausgeführt. Im Debug-Fenster sehe ich auch die Antwort des Circles, aber wie bekomme ich die in mein PHP-Script? $_IPS[‚VALUE‘] im RegVarParser-Script bringt nichts verwertbares…

Kannst du mir mal dein Beispielscript schicken, mit dem du auf deine Antworten gekommen bist?

Danke,
Markus

…also ich habe es auch probiert…kann es sein, dass dies mit der aktuellen Firmware garnicht mehr funktioniert? Ich komme nämlich auch auf keine vernünftigen Werte in der RegVar…

Grüße
Grebi

Morgen

wenn Plugwise heute Nacht nicht gerade ein Update rausgebracht hat, warte kurz ich schau nach… ne bin noch auf dem neuesten Stand sollte es eigentlich klappen. :stuck_out_tongue:

(Bevor ich mich dran mach und sowas teste, versuche ich eigentlich auf dem neuesten Stand zu sein. Alles andere wäre rausgeworfene Zeit.

Was Du mit keine „vernünftige“ Werte meinst weiß ich jetzt gerade nicht, aber klar ist das die Registervariable nicht rauswirft „Circle PC verbaucht gerade soundsoviel W und ist online“. Sondern
00003E2400C16349ƒ
00133E24000Dxx000Dxxxxx000C005C000004EFFFFFFDD300013D12

Das muss man dann halt erstmal in seine Einzelteile zerlegen um an die Infos ranzukommen, aber da steht genau das gleiche drin wie oben.

Aber jetzt gehen wir mal der Reihe nach.

Ihr habt eine Registervariable, Serialport angelegt und verbunden mit eurem Stick.

Dann schauen wir mal was Ihr bei der Registervariable rausbekommt. Dazu Doppelklick auf die Registervariable und dann auf Debug klicken.

Wenn ihr jetzt den Behfel 000A und keine MAC adresse schickt sollte es so aussehen(oben Text-, unten HEXansicht erstmal nur die oberen beiden Zeilen):

um 9:31:02 wurde 000A gesendet die 4 „Vierecke“ davor sind wie man unten bei der Hex Ansicht siehte die Steuerungszeichen 05 <ENQ> Enquiry und 03 <ETX> End of Text(Jeweils 2 mal).
Damit fängt immer eine Anfrage bzw. auch die Antwort an.
Danach kommt der Befehl 000A und danach die CRC Cecksumme b43c.
Am schluss noch 0D <CR> Carriage Return und 0A <LF> Line Feed.

Als Erstes kommt immer erst die Antwort vom Stick das er den Befehl empfangen hat und weiterleitet. Danach kommt dann erst die richtige Antwort vom Circle, wenn er denn noch da/erreichbar ist.

Die Antwort 9:31:02 Recieved Data fängt auch mit 2x<ENQ> und 2x<ENT> an.
0000 Ist die Antwort vom Stick das er die Anfrage bekommen hat
3E25 Ist die Anfragenummer
00C1 Bedeutet das der Befehl erfolgreich war
C918 Ist die Checksumme CRC
Danach kommt ein <CR> und <LF> wieder 2x<ENQ> und 2x<ENT>
0011 ist die Antwort auf den Befehl 000A
3E25 Die Anfragenummer (siehe oben)
000Dxx0000Cxxxxx Die Mac adresse des Sticks
01 ??
01 Circle+ ist online
61 ??
0Dxx0000Bxxxxx MAC Adresse des Circle+
Axxx Soll ne kurze Netzwerk ID sein
FF
C3FA CRC Checksumme

Jetzt ist der Stick Initialisert(irgendwo im Netz stand zwar das man das nicht unbedingt braucht aber schaden tuts sicher nicht).

Mit dem Befehl 0012 und der Mac Adresse eines Circle, siehe
9:31:42, sollte als Antwort erst 00003E2600C127CA (siehe oben) vom Stick kommen das er die Anfrage bekommen hat und weiterschickt.
Je nachdem welchen Circle ihr abfragt dauert es kurz(je nach erreichbarkeit) bis die Antwort des Circle kommt.

Dann endlich was wir wollen
0013 Antwort auf 0012
3E26 Abfrage Nr
00
0Dxx0000Dxxxxx die MAC Adresse des Circle
000B Anzahl der Pulse pro s
0057 Anzahl der Pulse pro 8s
00001053 Totale Anzahl der Pulse
FFFF soll was mit Energieerzeugung zu tun haben (soll man anscheiend mit Plugwise auch messen können)
FDD3 soll was mit Energieerzeugung zu tun haben
0007 soll was mit Energieerzeugung zu tun haben
3D6F CRC Checksumme

So versucht doch mal ob ihr auch solche Werte rausbekommt. Oder zeigt mal was bei euch rauskommt. Bei mir hats Stunden gedauert bis ich überhaupt mal was anderes als immer die gleiche Antwort/Fehler vom Stick zurückbekommen hab, lag halt an der blöden CRC Summe.

Um das Umrechenen bzw. die integration in IPS können wir uns dann immernoch kümmern wenn es bei euch erstmal soweit klappt.

Gruß Jannis

Hallo

Hab gerade nen kleinen Fehler beim CRC umrechnen gefunden.
Führende Nullen werden beim dechex natürlich verschluckt.

Wenn der CRC z.B.: 03b3 ist gibt die dechex funktion leider nur 3b3 aus und ist somit natürlich falsch.

War bei mir jetzt bei einem von 10 Circlen.

Daher muss noch das eingefügt werden.

$ausgabe = str_pad($ausgabe, 4 ,'0', STR_PAD_LEFT);

Habs oben mal abgeändert.

Vielleicht war ja das einer der Fehler bei euch.

Gruß Jannis

Hi Jannis,

vielen Dank für deine Mühe - bei mir kommt aber noch immer Schrott:

So öffne ich den Port:

In der Hex-Ansicht kann ich durchaus Parallelen erkennen, wobei die Antworten viel zu kurz sind… na mal sehen - ich forsche weiter :slight_smile:

Gruß,
Markus

plugwise_regvar.jpg

serial_port.jpg

Okay erstes Problem gefunden.
Baud ist 115200

Na das war doch einfach :wink:

tja - kaum macht man es richtig, klappt’s auch :rolleyes:…
wie gut, dass das Problem wie so oft VOR dem PC saß :wink:

Viele Grüße & vielen Dank,
Markus
:loveips:

Super ein Problem weniger.

Wollte eigentlich noch mein Auslesescript online stellen, aber der PC zuhause ist abgestürtzt und ich bekomm ihn vom Geschäfft nicht wieder an.
Aber heute Abend stell ichs online.

Damit werden schonmal die wichtigsten Infos(in HEX) ausgegeben.
Fürs umrechnen von den Pulsen in Watt brauch ich dann aber die Integer bzw. Float Werte, aber da bin ich dran.

Gruß Jannis

Hallo Markus,
Hallo Jannis,

es wird Licht :slight_smile: Das Entscheidende bei mir war die Baudrate! Jetzt können wir gemeinsam weiter entwickeln…

Grüße
Grebi

So hat leider länger gedauert als gedacht, aber dafür bin ich jetzt soweit die Kalibrierung und den aktuellen Verbrauch auszulesen und von Pulsen in Watt umzurechnen.
Hab es an drei Circlen nachgemessen und bis jetzt hat die Rechnung immer gestimmt.
Auch das schalten geht und die Rückmeldungen welcher Circle geschalten bzw. den Befehl erhalten hat funktioniert.
Wenn der Circle nicht antwortet kommt ein Fehler vom Stick zurück, den man aber erst noch zuordnen müsste.

!!!ACHTUNG vorab !!

Finger weg von 0001 und 0004 Befehlen.
Ich hab rausgefunden das man mit dem Befehl 0001 und 0004 vorsichtig sein muss.
Der sollte eigentlich beim Neuanlernen wichtig sein, aber mir hats beim rumspielen mein Plugwise Netzwerk „zerschossen“ Anscheinend vergibt man ne neue Netzid und die muss man den Ciclen mitteilen.
Danach musste ich ALLE Circle in den Werkszustand zurücksetzten. (Irgendwie 3x Jeweils 3s ein und ausstecken dann 10s ein und ausstecken und nochmal 3s ein und ausstecken.)
Macht keinen Spass an die ganzen Circle erstmal wieder ranzukommen. :stuck_out_tongue:
War aber nur beim Ausprobieren von den 0001 0004 Befehlen passiert.

Also nicht verunsichern lassen die bekomme ich auch noch eingearbeitet wenn ich wieder zeit hab.

Zur Zeit gehen also die Befehle

000A = Init des Sticks (kann man auch weglassen)
0012+Adresse = Abfrage des Verbrauches in Pulsen
0017+Adresse+01/00 Ein/Ausschalten eines Circle
0018+Adresse des „Circle+“ + 01,02,03 Abfragen der Adresse der angehängten Circle am Circle+
0023+Adresse = Auslesen von Infos des Circle auch der Logadresse
0026+Adresse = Kalibrierungsdaten auslesen(nur einmal pro Circle notwendig)
0048+Adresse+Logadresse = auslesen des Circlelogs (Hab ich noch nicht umgesetzt)

Zum ausprobieren müsst ihr noch ne Cutter Instanz nach den Serialport hängen mit Linke trennzeichen 05 05 03 03 und Rechte Trennzeichen 0D

Darauf die Registervariable zugreifen lassen und als Auswerte Script das hier nehmen:

$id_Register = 56849 /*[Test neu\Plugwise\Register Variable Cutter Plug]*/;
function bintofloat($in)
{
	$in=hexdec($in);
  	$binary = str_pad(decbin($in),32,"0", STR_PAD_LEFT);
	$fb = $binary[0];
	$exp = bindec(substr($binary, 1, 8));
	$m = bindec(substr($binary, 9, 23));
	return pow(-1,$fb) * (1+$m/(pow(2,23))) * pow(2,$exp-127);
}



if ($IPS_SENDER == "RegisterVariable")

$buf = $IPS_VALUE;
switch ((substr($buf,0,4)))
	{
	case "0000":         //Befehl vom Stick empfangen
		switch ((substr($buf,8,4)))
	   	{
   		case "00C1":  //Schauen ob alles empfangen wurde
    			print "Befehl von Stick empfangen";
			break;
			case "00D8":  //eingeschaltet
    			print "Eingeschaltet MAC".substr($buf,12,16);
			break;
         case "00DE":  //ausgeschaltet
    			print "Ausgeschaltet MAC".substr($buf,12,16);
			break;
			case "00E1":  //ausgeschaltet
    			print "Achtung Befehl nicht vom Circle bestätigt";
			break;
         default:
			print "Fehler von Stick";  //bei allem anderen
      	}
   break;

	case "0011":  // Init
         print "Die Sequenznr: ".substr($buf,4,4)."
";
	      print "MC Adresse: ".substr($buf,8,16);
	break;
	
	case "0013":   //Verbrauch
         print "Die Sequenznr: ".substr($buf,4,4)."
";
	      print "MC Adresse: ".substr($buf,8,16)."
";
         print "Pulse/s : ".substr($buf,24,4)."
";
         print "Pulse/8s: ".substr($buf,28,4)."
";
         print "Pulse gesamt: ".substr($buf,32,8)."
";
         
         
         $gaina = getvaluefloat(21413 /*[Test neu\Plugwise\Geckos\gaina]*/);
			$gainb = getvaluefloat(37221 /*[Test neu\Plugwise\Geckos\gainb]*/);
			$offot= 	getvaluefloat(15337 /*[Test neu\Plugwise\Geckos\offtot]*/);
			$offruis=getvaluefloat(42895 /*[Test neu\Plugwise\Geckos\offruis]*/);
			$pulse = substr($buf,28,4);

			$value = hexdec($pulse)/8;
			$out = (pow(($value+$offruis),2)*$gainb)+(($value+$offruis)*$gaina)+$offot;
			$kw = (($out ) / 468.9385193)*1000;
         setvaluefloat(20342 /*[Test neu\Plugwise\Geckos\Watt]*/,$kw);
         
         
         
	break;
	

	case "0019":   //Adressen abfragen
         print "Die Sequenznr: ".substr($buf,4,4)."
";
	      print "MC Circle+: ".substr($buf,8,16)."
";
         print "MAC Circle : ".substr($buf,24,16)."
";
         print "Node ID: ".substr($buf,40,2)."
";
         

	break;
	case "0024":   //Info
         print "Die Sequenznr: ".substr($buf,4,4)."
";
	      print "MC Adresse: ".substr($buf,8,16)."
";
         print "Jahr : ".substr($buf,24,2)."
";
         print "Monat: ".substr($buf,26,2)."
";
         print "Minuten : ".substr($buf,28,4)."
";
         print "log Adresse: ".substr($buf,32,8)."
";
         print "An/aus: ".substr($buf,40,2)."
";
         print "Herz (85=50H): ".substr($buf,42,2)."
";
		   print "Hardwareversion: ".substr($buf,44,12)."
";
		   print "Softwareversion: ".substr($buf,56,8)."
";
		   print "Stick 00,Cir+ 01 Cir 02: ".substr($buf,64,2)."
";





	break;
	
	case "0027":   //Kalibrierung
         print "Die Sequenznr: ".substr($buf,4,4)."
";
	      print "MC Adresse: ".substr($buf,8,16)."
";
         print "gaina : ".substr($buf,24,8)."
";
         print "gainb: ".substr($buf,32,8)."
";
         print "offtot : ".substr($buf,40,8)."
";
         print "offnoise: ".substr($buf,48,8)."
";
         
         
        
			setvaluefloat(21413 /*[Test neu\Plugwise\Geckos\gaina]*/,bintofloat(substr($buf,24,8)));
			setvaluefloat(37221 /*[Test neu\Plugwise\Geckos\gainb]*/,bintofloat(substr($buf,32,8)));
			setvaluefloat(15337 /*[Test neu\Plugwise\Geckos\offtot]*/,bintofloat(substr($buf,40,8)));
			if (substr($buf,48,8)=="00000000")
				setvaluefloat(42895 /*[Test neu\Plugwise\Geckos\offruis]*/,0);
			else
				setvaluefloat(42895 /*[Test neu\Plugwise\Geckos\offruis]*/,bintofloat(substr($buf,48,8)));


	break;
	case "0049":
	
	
	break;
	
	
	}
	


Ich geb die ankommenden Infos zur Zeit nur mit Print aus, bzw. schreibe ich die Kallibrierungsdaten und die W in Variablen zum Testen. Müsst ihr also noch anpassen.

So jetzt muss ich weg und hoffe ihr kommt damit zurecht.

Gruß Jannis

Jannis - das ist toll! Habe bei mir schon viel nachvollziehen können, kann schalten und aktuellen Verbrauch in Watt auslesen.

Ich versuche dann mal daraus ein Skript zu basteln, welches die Variablen für die Circles automatisch anlegt (Vebrauch und Status) und natürlich schaltbar macht. Kann aber dauern…

Gibt’s schon eine Lösung, um den Gesamtverbrauch zu lesen?

Danke & Gruß,
Axel

Bin gestern extrem weit gekommen: pro circle muß nur eine Kategorie angelegt werden und die 6-stellige ID in der Beschreibung abgelegt werden. Dann werden Variablen State und Watt pro Circle automatisch angelegt und befüllt. Circles lassen sich dann über’s Webfront schalten, Feedback ob Befehl erfolgreich durchgeführt wurde wird auch ausgewertet.

Das ganze ist in lediglich einem Skript realisiert. Um den Spannungsbogen zu halten werde ich es am WE posten, da ich erst mal bis Freitag auf Dienstreise bin :frowning: Bin noch nicht ganz fertig mit dem Anlegen von Kalibrierungs-Variablen. Aber wenn’s fertig ist, dann sollte es sehr einfach zu installieren sein :slight_smile:

Hat jemand eine Idee, wie man die vollständige Adresse eines beliebgen Circles auslesen? Oder an die Liste aller Circles kommt? Brauche zumindest einen zur Kalibrierung. Init des Sticks (000A) liefert mir die id des Sticks, die dafür wohl nicht genommen werden kann. Reicht die einmalige Kalibrierung und gilt das dann für alle Circles?

Und welche Infos ausser Status und Watt wären noch interessant? Gesamtzähler ist noch nicht realisiert, sollte auch einfach zu lesen sein.

Danke & Gruß,
Axel

Coool :slight_smile: Ich freu mich aufs WE :smiley:

DANKE !!!

Hat jemand eine Idee wie der Gesamtverbrauch zu interpretieren ist? Genau wie der aktuelle?

Morgen Alex und die anderen

Als erstes ein kurzer Bericht über 2 Wochen Plugwise nur mit Ip-symcon.
Zum Einrichten braucht man wohl auch in Zukunft noch die Orginalsoftware aber seitdem hab ich sie nicht mehr gestartet.

Den Verbrauch frage ich seit 2 Wochen alle 2 min ab und bis auf ein paar kleine Empfangsprobleme/Funkaussetzer und am Anfang Wattzahlen über 17000W obwohl der Circle ausgeschaltet war(ist jetzt aber behoben) sehe ich kein Problem mehr Plugwise direkt aus IP-Symcon abzufragen, bzw. zu schalten.

Das Schalten aus dem Webfront heraus und mit Rückmeldung ob der Circle wirklich an/aus ist klappt einwandfrei.
Die Rückmeldung vom Circle ob er sich ein/aus geschalten wird ausgewertet.
Was mir beim Schalten noch fehlt ist das Automatische nochmal senden wenn der Circle den Befehl nicht empfangen hat. Die Idee wie ich das mache ist schon da nur zur Umsetzung bin ich noch nicht gekommen.

Das ein Befehl nicht ankommt passiert bei mir nur noch sehr selten aber ich hab einen Circle im Obergeschoss da ist es kritisch ob der Befehl ankommt(ich denke einer von hundert befehlen kommt nicht an. Wird dann abervom Stick mitgeteilt das der Befehl nicht ankam bzw. die Rückmeldung ausgeblieben ist). Zum Vergleich ich frage ja alle 2 min 22 Circle ab, schalte noch ein paarmal und es kam in der letzten Stunde nur 2 mal die Meldung das ein Circle nichts zurückgemeldet hat.

Die Uhrzeit der Circle abfragen geht und auch das stellen funktioniert schon, muss aber noch ausreifen.

Die Circle selber speichern auch den Verbrauch von 4 Stunden und das der letzten 16 Stunden. Hier bin ich aber auch noch auf der Suche nach einem Muster das ich was gescheites rausbekomme.

So das war erstmal der überblick was zur Zeit geht.

Alex nimm statt der 6 stelligen ID lieber die gesamte Adresse, bei mir haben 6 Plugs eine 7stellige Nummer. Scheinen also schon jede Menge an Plugs verkauft zu haben wenn ihnen 6 Stellen nicht mehr ausreichen.

Zum Abfragen der Adressen muss man „nur“ 0018 +Adresse des Circle + Nummer des Node (Also von 00 bis FF je nachdem wieviele Plugs man hat) senden

Als Antwort 0019 bekommt man die Adresse des Circle+ und die Adresse des Circle zurück, bzw. FFFFFFFFFFFFFFFF falls da kein Circle dahinter steckt.
(siehe mein Empfangsscript weiter unten)

Wie schon geschrieben hatte ich ein Paar falsche Wattzahlen wenn der Circle ganz aus war bzw. wirklich nichts angeschlossen war.

Das erste Problem war, das wenn der Circle 0000 Pulse verbraucht hat hat die Funktion trotzdem etwas zurückgegeben, wegen der Kalibrierung. Also die Abfrage wenn 0000 dann kw = 0 eingebaut.

Aber immernoch bekam ich Watt jenseits von 17000W und hab dann rausbekommen das der Circle statt 0000 gerne mal FFFF schickt was aber nicht gerade warscheinlich ist(ausser ihr habt den Circle wirklich bis zum Maximum ausgereizt). Also auch diesen Fall ausgeklammert und seit ner Woche keine falschen Werte mehr gefunden.

Der Gesamtverbrauch ist „nur“ der Verbrauch seit Beginn der aktuellen Stunde, kann aber ansonsten wie die Pulse pro s bzw. 8 Sek ausgewertet werden.

Zum Anlegen der einzelnen Circle hab ich mir ein Script geschrieben das mir ne Kategorie anlegt, der Kategorie den Ident der Macadresse zuweist und darin verschiedene Variablen anlegt auch wieder mit den dazugehörigen Ident.
Das Script muss man halt für jeden Circle anpassen und einmal ausführen. Achtung hab noch keine Überprüfung eingebaut ob die Kategorie/Variablen/Ident schon da sind.

Den oberen Teil müsst ihr halt noch anpassen (soll eigentlich auch nur zeigen was mit Plugwise geht und euch auf die Sprünge helfen, bzw. ihr könnt mir tips geben was man einfacher, besser, anders machen kann).

<?

//kategorie anlegen
$cid="1A400C9";
$Katname = "Drucker ".$cid;
$Plugwiseid = 48691 /*[Test neu\Plugwise]*/;
$Archiveid = 33828 /*[Archive Handler]*/;
$schaltscript = 39141 /*[Test neu\Plugwise\Plugschalten Webfront]*/;

// ********************************************
      $KatID = IPS_CreateCategory();       // Kategorie anlegen
		IPS_SetName($KatID, $Katname); // Kategorie benennen
      IPS_SetParent($KatID, $Plugwiseid);  //Kategorie euerer Plugwise
      $MAC="000D6F000".$cid;

IPS_SetIdent($KatID, $MAC);

//Gaina anlegen
	$type = 2;
	$name = "Gaina";
	
     $VarID = IPS_CreateVariable($type);
    IPS_SetName($VarID, $name);
	 IPS_SetIdent($VarID, $name);                             // Kategorie benennen
    IPS_SetParent($VarID, $KatID);            // Variable einordnen


//Gainb anlegen
	$type = 2;
	$name = "Gainb";

     $VarID = IPS_CreateVariable($type);
    IPS_SetName($VarID, $name);
	 IPS_SetIdent($VarID, $name);                             // Kategorie benennen
    IPS_SetParent($VarID, $KatID);            // Variable einordnen
//Offot anlegen
	$type = 2;
	$name = "Offot";

     $VarID = IPS_CreateVariable($type);
    IPS_SetName($VarID, $name);
	 IPS_SetIdent($VarID, $name);                             // Kategorie benennen
    IPS_SetParent($VarID, $KatID);            // Variable einordnen
    

//offruis anlegen
	$type = 2;
	$name = "Offruis";

     $VarID = IPS_CreateVariable($type);
    IPS_SetName($VarID, $name);
	 IPS_SetIdent($VarID, $name);                             // Kategorie benennen
    IPS_SetParent($VarID, $KatID);            // Variable einordnen


//Watt anlegen
	$type = 2;
	$name = "Watt";

     $VarID = IPS_CreateVariable($type);
    IPS_SetName($VarID, $name);
	 IPS_SetIdent($VarID, $name);                             // Kategorie benennen
    IPS_SetParent($VarID, $KatID);            // Variable einordnen
    IPS_SetVariableCustomProfile($VarID, "~Watt.3680");
     AC_SetLoggingStatus($Archiveid , $VarID, true);
     IPS_ApplyChanges($Archiveid);

//Pulsegesamt anlegen
	$type = 2;
	$name = "Pulsegesamt";

     $VarID = IPS_CreateVariable($type);
    IPS_SetName($VarID, $name);
	 IPS_SetIdent($VarID, $name);                             // Kategorie benennen
    IPS_SetParent($VarID, $KatID);            // Variable einordnen

//Wh anlegen
	$type = 2;
	$name = "Wh";

     $VarID = IPS_CreateVariable($type);
    IPS_SetName($VarID, $name);
	 IPS_SetIdent($VarID, $name);                             // Kategorie benennen
    IPS_SetParent($VarID, $KatID);            // Variable einordnen
    IPS_SetVariableCustomProfile($VarID, "~Watt.3680");
     AC_SetLoggingStatus($Archiveid , $VarID, true);
     IPS_ApplyChanges($Archiveid);


		$type = 0;
	$name = "Status";

     $VarID = IPS_CreateVariable($type);
    IPS_SetName($VarID, $name);
	 IPS_SetIdent($VarID, $name);                             // Kategorie benennen
    IPS_SetParent($VarID, $KatID);            // Variable einordnen
		IPS_SetVariableCustomAction($VarID,schaltscript);
		IPS_SetVariableCustomProfile($VarID,"~Switch");


	$type = 0;
	$name = "Schalten gesperrt";
	$ident ="gesperrt";
     $VarID = IPS_CreateVariable($type);
    IPS_SetName($VarID, $name);
	 IPS_SetIdent($VarID, $ident);                             // Kategorie benennen
    IPS_SetParent($VarID, $KatID);            // Variable einordnen




?>

Mein Auslese Script ist dann das hier

<?

$Plugwisekat = 48691 /*[Test neu\Plugwise]*/;


function bintofloat($in)
{
	$in=hexdec($in);
  	$binary = str_pad(decbin($in),32,"0", STR_PAD_LEFT);
	$fb = $binary[0];
	$exp = bindec(substr($binary, 1, 8));
	$m = bindec(substr($binary, 9, 23));
	return pow(-1,$fb) * (1+$m/(pow(2,23))) * pow(2,$exp-127);
}
function pulsetowatt($pu,$s,$ga,$gb,$offr,$offo) //Pulse,Sekunden,gaina,b,offruis,offtot
{
	if (($pu>0))
		{
		$va = $pu/$s;
		$out = (pow(($va+$offr),2)*$gb)+(($va+$offr)*$ga)+$offo;
		$kw = (($out ) / 468.9385193)*1000;
		}
	else
	   $kw=0;
	return $kw;
}



if ($IPS_SENDER == "RegisterVariable")

$buf = $IPS_VALUE;
switch ((substr($buf,0,4)))
	{
	case "0000":         //Befehl vom Stick empfangen
		switch ((substr($buf,8,4)))
	   	{
   		case "00C1":  //alles empfangen
			    			print "Befehl von Stick empfangen";
			break;
			case "00D8":  //eingeschaltet
    			print "Eingeschaltet MAC".substr($buf,12,16);
    			$KatID = IPS_GetObjectIDByIdent(substr($buf,12,16),$Plugwisekat);
         	setvalueboolean(IPS_GetObjectIDByIdent("Status",$KatID),true);
				//IPS_RunScript(54091 /*[Test neu\Plugwise\Plug Strom auslesen lassen]*/);
			break;
         case "00DE":  //ausgeschaltet
    			print "Ausgeschaltet MAC".substr($buf,12,16);
    			$KatID = IPS_GetObjectIDByIdent(substr($buf,12,16),$Plugwisekat);
         	setvalueboolean(IPS_GetObjectIDByIdent("Status",$KatID),false);
        	
				//IPS_RunScript(54091 /*[Test neu\Plugwise\Plug Strom auslesen lassen]*/);
			break;
			case "00E1":  //Befehl nicht am Circle angekommen
    			print "Achtung Befehl nicht vom Circle bestätigt";
			break;
         default:
			print "Fehler von Stick";  //bei allem anderen
      	}
   break;

	case "0011":  // Init
         print "Die Sequenznr: ".substr($buf,4,4)."
";
	      print "MC Adresse: ".substr($buf,8,16);
	break;
	
	case "0013":   //Verbrauch
       //  print "Die Sequenznr: ".substr($buf,4,4)."
";
	    //  print "MC Adresse: ".substr($buf,8,16)."
";
       //  print "Pulse/s : ".substr($buf,24,4)."
";
         print "Pulse/8s: ".substr($buf,28,4)."
";
         print "Pulse gesamt: ".substr($buf,32,8)."
";
         
         
        $KatID = IPS_GetObjectIDByIdent(substr($buf,8,16),$Plugwisekat);
           $gaina = getvaluefloat(IPS_GetObjectIDByIdent("Gaina",$KatID));
			$gainb = getvaluefloat(IPS_GetObjectIDByIdent("Gainb",$KatID));
			$offot= 	getvaluefloat(IPS_GetObjectIDByIdent("Offot",$KatID));
			$offruis=getvaluefloat(IPS_GetObjectIDByIdent("Offruis",$KatID));
			$pulse = hexdec(substr($buf,28,4));
			if ($pulse==65535 /*[Objekt #65535 existiert nicht]*/)
     		   $kw=0;
      	else
				$kw= pulsetowatt($pulse,8,$gaina,$gainb,$offruis,$offot);
			setvaluefloat(IPS_GetObjectIDByIdent("Watt",$KatID),$kw);
			$pulsegesamt = hexdec(substr($buf,32,8));
         setvaluefloat(IPS_GetObjectIDByIdent("Pulsegesamt",$KatID),$pulsegesamt);
         $kwh= pulsetowatt($pulsegesamt,3600,$gaina,$gainb,$offruis,$offot);
			setvaluefloat(IPS_GetObjectIDByIdent("Wh",$KatID),$kwh);
			
			if ($kw>1000)     //WEnn mehr als 1000W dann ins log schreiben
			   {
				$zustand = date("d.m.y H:i ").$buf." Pulse/8s".substr($buf,28,4)." Watt ".$kw."
";
				IPS_RunScriptEx(33144 /*[Diverse\Hilfsprogramme\Log schreiben]*/, Array("log" => "Plugwise.txt" , "daten" => $zustand ));
				}
         
         
         
	break;
	
	
	case "0019":   //Auslesen der MAC adressen
         print "Die Sequenznr: ".substr($buf,4,4)."
";
	      print "MC Circle+: ".substr($buf,8,16)."
";
         print "MAC Circle : ".substr($buf,24,16)."
";
         print "Node ID: ".substr($buf,40,2)."
";
         

	break;
	case "0024":   //Info
         print "Die Sequenznr: ".substr($buf,4,4)."
";
	      print "MC Adresse: ".substr($buf,8,16)."
";
         print "Jahr : ".substr($buf,24,2)."
";
         print "Monat: ".substr($buf,26,2)."
";
         print "Minuten : ".substr($buf,28,4)."
";
        $logAddress = ((hexdec(substr($buf, 32, 8)) - 278528) / 32);
         print "log Adresse: ".$logAddress."
";
         print "An/aus: ".substr($buf,40,2)."
";
         print "Herz (85=50H): ".substr($buf,42,2)."
";
		   print "Hardwareversion: ".substr($buf,44,12)."
";
		   print "Softwareversion: ".substr($buf,56,8)."
";
		   print "Stick 00,Cir+ 01 Cir 02: ".substr($buf,64,2)."
";


			$KatID = IPS_GetObjectIDByIdent(substr($buf,8,16),$Plugwisekat);
      	if(substr($buf,40,2)=="01")               //gerät an/aus
         setvalueboolean(IPS_GetObjectIDByIdent("Status",$KatID),true);
         else
         setvalueboolean(IPS_GetObjectIDByIdent("Status",$KatID),false);


	break;
	
	case "0027":   //Kalibrierung
         print "Die Sequenznr: ".substr($buf,4,4)."
";
	      print "MC Adresse: ".substr($buf,8,16)."
";
         print "gaina : ".substr($buf,24,8)."
";
         print "gainb: ".substr($buf,32,8)."
";
         print "offtot : ".substr($buf,40,8)."
";
         print "offnoise: ".substr($buf,48,8)."
";
         
         $KatID = IPS_GetObjectIDByIdent(substr($buf,8,16),$Plugwisekat);

        
			setvaluefloat(IPS_GetObjectIDByIdent("Gaina",$KatID),bintofloat(substr($buf,24,8)));
			setvaluefloat(IPS_GetObjectIDByIdent("Gainb",$KatID),bintofloat(substr($buf,32,8)));
			setvaluefloat(IPS_GetObjectIDByIdent("Offot",$KatID),bintofloat(substr($buf,40,8)));
			if (substr($buf,48,8)=="00000000")
				setvaluefloat(IPS_GetObjectIDByIdent("Offruis",$KatID),0);
			else
				setvaluefloat(IPS_GetObjectIDByIdent("Offruis",$KatID),bintofloat(substr($buf,48,8)));


	break;
	case "0049":		//Logauslesen

		print "Die Sequenznr: ".substr($buf,4,4)."
";
      print "MC Adresse: ".substr($buf,8,16)."
";
      
      print "logdate1: ".substr($buf,24,8)."
";
      print "logvalue1 : ".substr($buf,32,8)."
";
      print "logdate2: ".substr($buf,40,8)."
";
      print "logvalue2 : ".substr($buf,48,8)."
";
      print "logdate3: ".substr($buf,56,8)."
";
      print "logvalue3 : ".substr($buf,64,8)."
";
      print "logdate4: ".substr($buf,72,8)."
";
      print "logvalue4 : ".substr($buf,80,8)."
";
      print "Logadresse: ".substr($buf,88,8)."
";
	break;

	case "003F":         //Uhrzeit auslesen
      print $buf."
";
		print "Die Sequenznr: ".substr($buf,4,4)."
";
      print "MC Adresse: ".substr($buf,8,16)."
";
      print "Stunde : ".substr($buf,24,2)."
";
      print "Min: ".substr($buf,26,2)."
";
      print "Sek : ".substr($buf,28,2)."
";
      print "Tag der Woche: ".substr($buf,30,2)."
";
      print "Rest : ".substr($buf,32,2)."
";
      print "Rest2: ".substr($buf,34,4)."
";
	break;
	
	}

?>

Zum schalten der Circle hab ich mir noch ne Variable angelegt mit der ich den Circle sperren kann, ansonsten könnte ausversehen der Kühlschrank oder ein auch ein gesamter Raum ausgeschaltet werden.

Fürs schalten aus dem Webfront heraus hab ich das Script hier, wurde beim anlegen der Circle als $schaltscript hinterlegt.

<?



if ($IPS_SENDER=="WebFront")
	{

	$array = (IPS_GetObject($IPS_VARIABLE));
	$idgesperrt=IPS_GetObjectIDByIdent("gesperrt",$array['ParentID']);
	if (!getvalue($idgesperrt))
		{
		   IPS_RunScriptEx(20458 /*[Test neu\Plugwise\Plugwise schalten]*/, Array("id" => $IPS_VARIABLE , "an" => $IPS_VALUE ));

	   	//setvalue($IPS_VARIABLE,$IPS_VALUE);
			//$mac=IPS_GetObject("
		}
	else
		echo "Gesperrt";
	}
 

 
?>

Das schaltscript ist dann das hier

<?

// this function is used to calculate the (common) crc16c for an entire buffer
function calculate_common_crc16c($buffer)
{
    $crc16c = 0x0000;  // the crc initial value laut www.maartendamen.com
    $buffer_length = strlen($buffer);
    for ($i = 0; $i < $buffer_length; $i++)
    {
        $ch = ord($buffer[$i]);
        $crc16c = update_common_crc16c($ch, $crc16c);
    }
    return $crc16c;
}
// this function is used to calculate the (common) crc16c byte by byte
// $ch is the next byte and $crc16c is the result from the last call, or 0xffff initially
 function makeCrcCheckSum($string)
 {
        $crc = 0x0000;
        for ($i = 0, $j = strlen($string); $i < $j; $i++) {
            $x = (($crc >> 8) ^ ord($string[$i])) & 0xFF;
            $x ^= $x >> 4;
            $crc = (($crc << 8) ^ ($x << 12) ^ ($x << 5) ^ $x) & 0xFFFF;
        }
         //$ausgabe = str_pad($ausgabe, 4 ,'0', STR_PAD_LEFT); //Mit Nullen auffüllen

        return str_pad(strtoupper(dechex($crc)), 4 ,'0', STR_PAD_LEFT);
}

$array = (IPS_GetObject($id));
($macarray=IPS_GetObject($array['ParentID']));
 $mac=$macarray['ObjectIdent'];
$befehl = "0017";
if ($an)
	$mac.="01";
else
   $mac.="00";



$text=$befehl.$mac;
$ausgabe=makeCrcCheckSum($text);
$text.= $ausgabe;


RegVar_SendText(56849 /*[Test neu\Plugwise\Register Variable Cutter Plug]*/,"\x05\x05\x03\x03".$text."\x0D\x0A");


?>

aufruf mit

IPS_RunScriptEx(20458 /*[Test neu\Plugwise\Plugwise schalten]*/, Array("id" => $IPS_VARIABLE , "an" => $IPS_VALUE ));

Und hier mein Script zum anfragen des Verbrauches

<?

// this function is used to calculate the (common) crc16c for an entire buffer
function calculate_common_crc16c($buffer)
{
    $crc16c = 0x0000;  // the crc initial value laut www.maartendamen.com
    $buffer_length = strlen($buffer);
    for ($i = 0; $i < $buffer_length; $i++)
    {
        $ch = ord($buffer[$i]);
        $crc16c = update_common_crc16c($ch, $crc16c);
    }
    return $crc16c;
}
// this function is used to calculate the (common) crc16c byte by byte
// $ch is the next byte and $crc16c is the result from the last call, or 0xffff initially
 function makeCrcCheckSum($string)
 {
        $crc = 0x0000;
        for ($i = 0, $j = strlen($string); $i < $j; $i++) {
            $x = (($crc >> 8) ^ ord($string[$i])) & 0xFF;
            $x ^= $x >> 4;
            $crc = (($crc << 8) ^ ($x << 12) ^ ($x << 5) ^ $x) & 0xFFFF;
        }
         //$ausgabe = str_pad($ausgabe, 4 ,'0', STR_PAD_LEFT); //Mit Nullen auffüllen

        return str_pad(strtoupper(dechex($crc)), 4 ,'0', STR_PAD_LEFT);
}



// init
//$befehl="000A";
//$mac="";

$anfang="000D6F000";

$id_array=array(	"0B1D99F",
						"0Dxxx5",
						"0Dxxxx8",
						"0DxxxxC",
						"0DxxxxB",
						"0Dxxxx6",
						"0DxxxxB",
						"0Dxxxx0",
						"0Dxxxx5",
						"0Dxxxx7",
						"1Axxxx6",
						"1Axxxx8",
						//"0DxxxxA",
						"1Axxxx6",
						//"1Axxxx4",
						"1AxxxxA",
						"0Dxxxx6",
						//"1Axxxx8",
						"1Axxxx9",
						//"0DxxxxE",
						"0BxxxxA");

$anzahl = count($id_array);

for ($i=0;$i<$anzahl;$i++)
	{

	$mac=$anfang.$id_array[$i];
	$befehl = "0012";//Verbrauch auslesen
   //$befehl = "0026"; //Kalibrierung auslesen
	//$befehl="0023";//Infos auslesen

	$text=$befehl.$mac;
	$ausgabe=makeCrcCheckSum($text);
	$text.= $ausgabe;

	IPS_sleep(300);
	RegVar_SendText(56849 /*[Test neu\Plugwise\Register Variable Cutter Plug]*/,"\x05\x05\x03\x03".$text."\x0D\x0A");

	}
?>

Die Adressen der einzlnen Circle könnte man natürlich auch jedesmal aus den Ident der Kategorien auslesen lassen aber ich denke hier schreibt man lieber einmal alle Adressen rein und gut ist.

Jetzt habt Ihr was zum ausprobieren.

Und Alex, ich bin gespannt auf dein Script also immer her damit.

Gruß Jannis

Für mich käme die plugwise Variante nur ohne den Server Teil in frage, also dass IPS direkt die Daten ausliest und steuert.

Mit der ServerSoftware werden regelmässig massig Daten zu plugwise hochgeladen :frowning:

Plugwise makes a big mistake…

Hallo gdfde

Das ist ja genau das was ich mit diesen Scripts mache. (War zwar nicht deswegen sonder einfach um eine Software weniger auf dem Rechner zu haben, um aktuelle Daten auszulesen und nicht den Umweg IP-Symcon fragt bei der Software nach die irgendwann in den letzten Minuten mal die Circle abgefragt hat und man kann jetzt selber bestimmen wie oft die Daten ausgelesen werden sollen, zwecks Funkverkehr etc.) (Unds das wichtigste :stuck_out_tongue: es hat mal wieder Spass gemacht rumzutüfteln wie,wo,was ich da eigentlich gerade auslese)

Zum Einrichten(geht ohne Internetverbindung) braucht man halt einmal die Plugwise Software. Auch um eventuell Updates auf die Circle zu installieren braucht man die Software(dazu brauchst du natürlich auch Internet aber im schlimmsten fall kann die Software die Daten der letzten 16 Stunden der Circle weiterleiten mehr kann man eigentlich nicht aus den Circlen auslesen. und natürlich die Namen die man in der Software vergibt aber die brauchst du nicht zu vergeben da das in meinen Scripten keine Rolle spielt, die werden nirgends auf den Circlen gespeichert).

Aber wenn die Circle einmal angelernt sind brauchts du die Software nicht mehr. Macht alles IP-Symcon.

Gruß Jannis
P.S.: Es gibt bei Plugwise Source auch die Option keine Daten zu senden. Inwieweit das natürlich Vertrauenswürdig ist kann ja jeder mit seinem Firewall rausfinden

So, ich hab mir auf Basis von Jannis Erkenntnissen mal ein Skript zusammengelötet, welches sämtliche Circles verwalten kann. Die einzelnen Circles legt man als Dummy Module an und man gibt ihnen die Plugwise Adresse mit in die Beschreibung. Variablen werden dann automatisch angelegt.

Zum Einrichten von Plugwise braucht man die Orginalsoftware „Source“, aber danach nur noch bei Systemänderungen. Über IPS kann geschaltet und Verbrauch ermittelt werden.

Installation:

  1. Serial Port anlegen
    Com Port, Baud rate: 115200, Data bits: 8, Stop bits: 1, Parity: none

  2. Cutter anlegen und mit Serial Port verbinden
    Linke Trennzeichen: „05 05 03 03“ (Hex)
    Rechte Trennzeichen: „0D“ (Hex)

  3. Kategorie „Plugwise“ nach belieben im Objektbaum anlegen

  4. Skript anbei in Kategorie „Plugwise“ anlegen. Variable $REGVAR oben im Skript anpassen.

  5. Registervariable in Kategorie Plugwise anlegen, als Ziel das Skript angeben und als übergeordnete Instanz den Cutter

  6. Skript ein mal ausführen.
    Es wird eine Kategorie „Circles“ angelegt.

  7. In der Kategorie Circles für jeden echten Circle ein Dummy Modul (oder Kategorie) anlegen und die 6-Stellige Adresse des Circles (z.B. B1B8D7) in die Beschreibung eintragen.

  8. Skript noch mal ausführen. Jetzt werden Kaibrierungsdaten abgerufen und als Variable für jede Circle angelegt.

  9. Unterhalb des Skripts ein Ereignis anlegen, so dass Skript alle X Minuten ausgeführt wird (Anfangs eine Minute zum testen, ich hab’s im Betrieb auf alle 5 Minuten stehen).

Wenn alles geklappt hat, dann werden nach erster Auslösung des Ereignis die Variablen Watt und State in die Kategorien der Circles geschrieben.

Jetzt kann man nach belieben Links im Webfront/iFront aufbauen bzw. Variablen loggen und Graphen zeichnen lassen…

Nach jeder Systemänderung in Plugwise einfach entsprechend Dummy Module anpassen (Adresse in Beschreibung!) und noch ein mal das Skript ausführen.

Ich hoffe es klappt auch bei euch. Schalten geht stabil - ich hatte bisher noch keinen Aussetzer.

TODO:

  • Gesamtverbrauch ermitteln (Befehl 0048). Ich hätte das gerne als Zählervariable…
  • Schalten über Variablen ermöglichen

Gruß,
Axel

Geräte.GIF

Baum.GIF

Plugwise-0.2.txt (11.9 KB)

Moin Alex :0)

musste heute morgen natürlich gleich mal dein Scripts ausprobieren.
Leider klappt das mir nicht :0(

  1. Frage: In der RegisterVariable gebe ich doch als übergeordnete Instanz den Cutter an oder ???

  2. Script läuft ohne Fehler durch nur steht unter Meldungen in IPS - Achtung Befehl nicht vom Circle bestätigt. Anlegen tut sich darauf hin auch nichts :0(

Hast ne idee?

MFG

Andreas