undokumentierte Skript-Befehle

Problemlösungen und Hinweise von allgemeinem Interesse zur Haussteuerung mit HomeMatic

Moderator: Co-Administratoren

MichaelN
Beiträge: 9635
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 697 Mal
Danksagung erhalten: 1614 Mal

undokumentierte Skript-Befehle

Beitrag von MichaelN » 31.05.2020, 12:53

Da ich auf 1-2 undokumentierte Befehle gestoßen bin (zumindest nicht von EQ-3 offiziell dokumentiert), habe ich mir gedacht es wäre für alle (Einsteiger) hilfreich diese an einer Stelle zu sammeln. Würde mich freuen, wenn dieser Thread von den "Wissenden" dafür genutzt wird. Danke!

>>>> Bitte auch den Beitrag zum Debugging beachten. <<<<

korrektes Referenzieren einer Systemvariablen (zur Vermeidung von falschen Objekt-Referenzen durch doppelte Vergabe von Namen)

Code: Alles auswählen

! System-Variable auslesen
var Daten = dom.GetObject(ID_SYSTEM_VARIABLES).Get("sysvarname").Value();
! System-Variable beschreiben
dom.GetObject(ID_SYSTEM_VARIABLES).Get("sysvarname").State(Daten);

! falls man nicht sicher sein kann, das die Systemvariable auch existiert:
object SV;
SV = dom.GetObject(ID_SYSTEM_VARIABLES).Get("sysvarname");
if (SV) { SV.State(Daten); }
Hinweis: man kann Systemvariablen auch mit .Variable() auslesen und beschreiben. Aber die Ausgabe erfolgt immer als Datentyp String und das Beschreiben löst keine Triggerung aus!

Datenpunkte

Wie man Datenpunkte identifiziert und ausliest hat alchy ausführlich beschrieben :
viewtopic.php?f=31&t=30127

Unterschied .State() und .Value() und .Variable()

.State() fragt die Geräte aktiv ab, d.h. netzversorgte Geräte werden über Funk abgefragt
.Value() nimmt immer den letzten übermittelten Wert; nur Read, Write löst RuntimeError aus
.Variable() Write führt nicht zum Triggern! Ergebnis bei Read ist immer vom Typ String!


State-Methode kann mit Verzögerung und mit/ohne Abbruch einer laufenden Verzögerung ausgeführt werden (wie in der WebUI)

ab Rega R1.00.0388.0220 auch auf Kanäle (OT_CHANNEL) und Programme (OT_PROGRAM) anwendbar

ACHTUNG: ein State(x) bricht keine laufende Verzögerung ab (im Gegensatz zur WebUI)
siehe auch viewtopic.php?f=19&t=61630&start=10

Code: Alles auswählen

! State() mit Verzögerung
! State(var Value,{integer Delay in ms[0]},{boolean Retrigger[true]})
! Value = Wert der geschrieben wird
! Delay = Verzögerung in ms (optional, Standard 0)
! Retrigger = bisheriger Delay wird abgebrochen/überschrieben (optional, Standard true)
! darf nicht auf Kanäle angewendet werden, bei Geräten muss der Datenpunkt angesprochen werden

! setzt Automatik nach 60000 Millisekunden auf TRUE
dom.GetObject(ID_SYSTEM_VARIABLES).Get("Automatik").State(1, 60000);
dom.GetObject("Steckdose Lampe:3").DPByHssDP("STATE").State(true,60000);
! setzt Automatik nach 120000 Millsekunden auf TRUE, laufende Verzögerung wird nicht unterbrochen
! ACHTUNG: die Verzögerung zählt ab dem absetzen des Befehls, nicht nach Ablauf des vorherigen!
dom.GetObject(ID_SYSTEM_VARIABLES).Get("Automatik").State(1, 120000, false);
dom.GetObject("Steckdose Lampe:3").DPByHssDP("STATE").State(true, 120000, false);
Einschaltdauer setzen und einschalten

Code: Alles auswählen

(dom.GetObject(ID_CHANNELS).Get("KANALNAME")).DPByHssDP("ON_TIME").State(dauer);
(dom.GetObject(ID_CHANNELS).Get("KANALNAME")).DPByHssDP("STATE").State(true);
ValueName-Methode gibt den symbolischen Wert einer booleschen Systemvariablen aus

Code: Alles auswählen

! dp.ValueName()
object oSysvar = dom.GetObject(ID_SYSTEM_VARIABLES).Get("SysVarName");
WriteLine("ValueName: "#oSysvar.ValueName()); ! "was auch immer man für true/false definiert hat"
! im Gegensatz zu
WriteLine("Value: "#oSysvar.Value()); ! true oder false
CreateObject / DeleteObject

hier geht es ans Eingemachte - siehe Erläuterungen von Black

Code: Alles auswählen

! [object]= dom.CreateObject ([OT_TYPE],[opt OBJ_NAME],[opt OBJ_ID]);
! [boolean] =dom.DeleteObject (ID [int,string, object])
Substr - Längenangabe optional

Entgegen der offiziellen Doku ist der Längen-Parameter optional. Ohne Angabe der Länge wird die verbleibende Rest-Länge angenommen:

Code: Alles auswählen

! string string.Substr(integer index {,integer length});

string s = "Hallo Welt!";
string world = s.Substr(6); ! world = "Welt"
foreach, while Ablaufsteuerung

Code: Alles auswählen

break; ! bricht die Schleife ab
continue; ! überspringt das aktuelle Element
GenerateEnum - Werteliste generieren

Code: Alles auswählen

! system.GenerateEnum(min [integer], max [integer])
! erzeugt eine durch Tab getrennte Werteliste von min bis max

var test = system.GenerateEnum(1,10);
WriteLine(test); ! 1	2	3	4	5	6	7	8	9	10

! Hilfreich für eine Foreach-Schleife:
string index;
foreach(index,system.GenerateEnum(1,10))
{
 WriteLine (index);
}
Arbeiten mit Systemvariable vom Typ Werteliste

alle Werte der Werteliste auflisten

Code: Alles auswählen

! alle Werte der Werteliste auflisten
string sSysvar = "Status";
string itemID; integer i = 0;
var Liste = dom.GetObject(ID_SYSTEM_VARIABLES).Get(sSysvar).ValueList();
WriteLine("Index: Wert");
foreach(itemID, Liste.Split(";"))
{
WriteLine(i#": "#itemID);
i = i + 1;
}                
einen bestimmten Wert der Liste ausgeben

Code: Alles auswählen

! einen bestimmten Wert der Liste ausgeben
string sSysvar = "Status";
integer iValue = 1; ! Welchen Wert?  - beginnend mit 0
WriteLine( web.webGetValueFromList((dom.GetObject(ID_SYSTEM_VARIABLES).Get(sSysvar)).ValueList(), iValue) );
Index des gültigen Wertes / gültigen Wert ausgeben

Code: Alles auswählen

string sSysvar = "Status";
! Index des gültigen Wertes
WriteLine(dom.GetObject(ID_SYSTEM_VARIABLES).Get(sSysvar).Value());
! Klartext des gültigen Wert ausgeben
WriteLine( web.webGetValueFromList((dom.GetObject(ID_SYSTEM_VARIABLES).Get(sSysvar)).ValueList(), (dom.GetObject(ID_SYSTEM_VARIABLES).Get(sSysvar)).Value()) );
! oder
WriteLine( (dom.GetObject(ID_SYSTEM_VARIABLES).Get(sSysvar).ValueList() ).StrValueByIndex(";",dom.GetObject(ID_SYSTEM_VARIABLES).Get(sSysvar).Value()) );
! oder
object oList = dom.GetObject (ID_SYSTEM_VARIABLES).Get (sSysvar);
WriteLine( web.webGetValueFromList(oList.ValueList(), oList.Value()) );

Code: Alles auswählen

! Anzahl der Elemente in einer Liste ermitteln
! Liste muss String mit ; getrennt sein
string liste = "A;B;C";
var n = web.webGetValueListCount(liste) ;
WriteLine(n);
Sonnenwinkel berechnen

Code: Alles auswählen

! SunAzimuth({time}) / SunAltitude({time})  optional: Angabe eines Zeitstempel für die Berechnung, Standard aktuelle Zeit
system.SunAzimuth(); ! gibt Azimutwinkel für aktuelle Uhrzeit und in der Systemeinstellung definierte Position aus
system.SunAltitude(); ! gibt Elevationswinkel für aktuelle Uhrzeit und in der Systemeinstellung definierte Position aus
system.SunAzimuth (@08:00@); ! gibt Azimut für heute 8 Uhr aus
system.SunAltitude (@2020-01-01 06:00:00@); ! Sonnenhöhe am 01.01.2020 um 06:00 Uhr

! das geht auch mit einem Zeitstempel als Integerwert
! system.SunAltitude (integer Timestamp);
integer iZeit = system.Date("%F %T").ToTime().ToInteger();
iZeit = iZeit + 6000;
WriteLine(system.SunAltitude (iZeit));
Sonnenauf/untergang
Mit %H, %M, %S gibt man an, ob man Stunden, Minuten, Sekunden haben möchte. Ohne Parameter wird Datum und Uhrzeit ausgegeben.

Code: Alles auswählen

var auf = system.SunriseTime("%H:%M:%S"); ! Sonnenaufgangszeit in Stunden:Minuten:Sekunden
var ab = system.SunsetTime("%H:%M"); ! Sonnenuntergangszeit in Stunden:Minuten 
in der Systemsteuerung festgelegte Geo-Koordinaten

Code: Alles auswählen

system.Longitude();
system.Latitude();
Anwendungsbeispiel Uhrzeit zu einer bestimmten Sonnenhöhe berechnen und CuxD-Timer stellen

Code: Alles auswählen

!- Uhrzeit zu einer gegebenen Sonnenhöhe berechnen V1.0 MN
real Sollwert = -6; !- gegebene Sonnenhöhe
integer Genauigkeit = 5; !- Schrittweite in Minuten (nur Ganzzahlen,>0)
string SV_Aufgang = "Aufgangszeit";    !- Namen der Systemvariablen in der das Ergebnis abgelegt wird
string SV_Untergang ="Untergangszeit";

integer AktuelleZeit =  system.Date("%F").ToTime().ToInteger();
integer NeueZeit;
real IstElevation = -100.0;
object SV;


   !- Morgendämmerung berechnen
   NeueZeit = AktuelleZeit + ( 10800 - ( Genauigkeit * 60)); !- um 3 Uhr starten
   while ( IstElevation < Sollwert ) {
         NeueZeit = ( NeueZeit + ( Genauigkeit * 60)) ; !- x Minuten hinzu
         IstElevation =  system.SunAltitude(NeueZeit); !- Elevation zur neuen Zeit berechnen
   }
   WriteLine("Ergebnis Morgendämmerung: " #NeueZeit.ToTime().Format("%T"));
   SV = dom.GetObject(ID_SYSTEM_VARIABLES).Get(SV_Aufgang);
   if ( SV ) {SV.State(NeueZeit.ToTime().Format("%T"));}

   !- Abenddämmerung berechnen
   IstElevation = 100.0;
   NeueZeit = AktuelleZeit + ( 54000 - ( Genauigkeit * 60)); !- um 15 Uhr starten
   while ( IstElevation > Sollwert ) {
         NeueZeit = ( NeueZeit + ( Genauigkeit * 60)) ; !- x Minuten hinzu
         IstElevation =  system.SunAltitude(NeueZeit); !- Elevation zur neuen Zeit berechnen
   }
   WriteLine("Ergebnis Abenddämmerung: " #NeueZeit.ToTime().Format("%T"));
   SV = dom.GetObject(ID_SYSTEM_VARIABLES).Get(SV_Untergang);
   if ( SV ) {SV.State(NeueZeit.ToTime().Format("%T"));}
Das Ergebnis steht in "NeueZeit" und kann dann genauso zur Programmierung des CUxD Timer verwendet werden:

Code: Alles auswählen

dom.GetObject("RolladenZP").State(NeueZeit);
dom.GetObject("CUxD.CUX2800001:1.TIMER_SET").State(NeueZeit);
Rechnen mit Zeiten

Im Gegensatz zum dokumentierten system.Date(), welches die aktuelle Zeit als String liefert, liefert das undokumentierte localtime die aktuelle Zeit als Time-Datentyp. Und damit lässt sich einfacher rechnen:

Code: Alles auswählen

! Aktuelle Zeit plus 5 Minuten
WriteLine((localtime+300).Format("%H:%M"));
! versus
WriteLine((system.Date().ToTime().ToInteger()+300).ToTime().Format("%H:%M "));     
Include

mit #inc können externe Skripte aus externen Dateien eingebunden werden
siehe Beschreibung von Black

ProgramExecute()

Führt ein anderes WebUI Programm aus. Allerdings ohne Prüfung der Bedingungen. Es wird immer das erste DANN ausgeführt. Die Ausführung erfolgt erst wenn das aufrufende Skript beendet ist.

Der Nutzen ist also begrenzt. Nicht nur aus dem Grund rate ich von der Benutzung ab. Siehe auch viewtopic.php?f=26&t=75299&start=10#p730346

wget über system.Exec nutzen

ruft eine URL auf bzw. Daten ab ohne die CCU zu blockieren

Code: Alles auswählen

! hhtp per exec senden
string send_data = "http://......";
string stdout; string stderr;
system.Exec("wget --timeout=10 -q -O - '"#send_data#"'", &stdout, &stderr);

! hhtp per exec senden, wenn man gar keine Rückmeldung braucht
string send_data = "http://......";
system.Exec("timeout 10 wget --timeout=10 -q -O /dev/null '"#send_data#"' &");
getestet mit CCU FW 3.51.6 / ReGaHss Logikengine R1.00.0388.0215
Zuletzt geändert von MichaelN am 07.12.2023, 19:34, insgesamt 40-mal geändert.
LG, Michael.

Wenn du eine App zur Bedienung brauchst, dann hast du kein Smarthome.

Wettervorhersage über AccuWeather oder OpenWeatherMap+++ Rollladensteuerung 2.0 +++ JSON-API-Ausgaben auswerten +++ undokumentierte Skript-Befehle und Debugging-Tipps +++

MichaelN
Beiträge: 9635
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 697 Mal
Danksagung erhalten: 1614 Mal

Re: undokumentierte Skript-Befehle

Beitrag von MichaelN » 10.06.2020, 08:46

Hier ein Link zu einem alten Beitrag über undokumentierte Befehle
viewtopic.php?f=43&t=2606&hilit=SunriseTime
LG, Michael.

Wenn du eine App zur Bedienung brauchst, dann hast du kein Smarthome.

Wettervorhersage über AccuWeather oder OpenWeatherMap+++ Rollladensteuerung 2.0 +++ JSON-API-Ausgaben auswerten +++ undokumentierte Skript-Befehle und Debugging-Tipps +++

Benutzeravatar
Black
Beiträge: 5469
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 419 Mal
Danksagung erhalten: 1070 Mal
Kontaktdaten:

Re: undokumentierte Skript-Befehle

Beitrag von Black » 10.06.2020, 10:09

Es gibt einen ganzen haufen undokumentierter Methoden und konstanten. Ich müsste nachgucken... etwas über 900 müssten das sein.

Eigentlich kommt da auch jeder dran.
Mit nem hexeditor die rega anschauen, da kommt man schon auf vieles. Wer die Möglichkeit hat und mit dem IDApro disassembler/Decompiler von hexware umgehen kann... mit den entsprechenden tables über den verwendeten compiler etc gefüttert wirft dieser dann schon sehr vieles aus. Es hilft dann aber auch wenn man x86 assembler lesen und verstehen kann.

Die Informationen daraus hab ich in mein Programm einfließen lassen, die sind aber auch nicht geheim, mit den entsprechenden kurztasten über die verschiedenen vervollständigen wirft der sdv diese Listen auch aus.mit dem Wissen über die Methodennamen lässt man dann einen wordwrapper über die Firmware laufen und findet so die verwendungsstellen und kann damit Rückschlüsse über die Anwendung der Methode ziehen.

Die Seite wikimatik gibt auch noch Informationen über Methoden.

Dann gibt es noch einen ehemaligen User hier der eine wohl vollständige methodendoku erstellt hat, aber er und noch ein bekannter aber ungenannte Forenuser Hüten dieses "Geheimnis" wie die Startcodes von Atomraketen. Nun denn, Wenn's glücklich macht :wink: :wink:

Da aber diese listen auf dem oben beschriebenen Weg bekannt sind... wird sich, wenn dich das wissen verbreitet, auch der einzug in allgemeine verwendung nicht mehr aufhalten lassen. Meine Software unterstützt dabei ja auch.

Ich halte nämlich rein gar nichts von monopolisiertem Wissen.

Black
Zuletzt geändert von Black am 10.06.2020, 18:55, insgesamt 1-mal geändert.
Wenn das Fernsehprogramm immer mehr durch nervende Werbung unterbrochen wird und der Radiomoderator nur noch Müll erzählt, ist es besser, die Zeit für sinnvolle Dinge zu nutzen -
mal aufs Klo zu gehen, ein Bier zu holen oder einfach mal den roten AUS-Knopf zu drücken. Klick - und weg

Script Time Scheduler V1.3
AstroSteuerung über Zeitmodul flexibel mit Offset / spätestens, frühestens
SDV 5.03.01 Das umfassende Entwicklungs und Diagnosetool für Homematik
Selektive Backups - Nützliche Dinge, die die WebUI nicht kann

Intel NUC6 Celeron 16GB mit 512GB SSD unter Proxxmox mit insgesamt 5 VM: 2 x bloatwarebefreiter Raspberrymatik, 2 x IOBroker als Middleware und einer MariaDB zur Archivierung. Verbrauch: 6W

technical contribution against annoying advertising

MichaelN
Beiträge: 9635
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 697 Mal
Danksagung erhalten: 1614 Mal

Re: undokumentierte Skript-Befehle

Beitrag von MichaelN » 10.06.2020, 11:54

Allein den Namen einer Methode zu kennen, hilft ja nicht unbedingt weiter.
LG, Michael.

Wenn du eine App zur Bedienung brauchst, dann hast du kein Smarthome.

Wettervorhersage über AccuWeather oder OpenWeatherMap+++ Rollladensteuerung 2.0 +++ JSON-API-Ausgaben auswerten +++ undokumentierte Skript-Befehle und Debugging-Tipps +++

dtp
Beiträge: 10658
Registriert: 21.09.2012, 08:09
System: CCU
Wohnort: Stuttgart
Hat sich bedankt: 320 Mal
Danksagung erhalten: 501 Mal

Re: undokumentierte Skript-Befehle

Beitrag von dtp » 15.06.2020, 08:15

Übrigens, "break" und "continue" sind in der aktuellen Version 2.3 der Sprachbeschreibung enthalten.
CCU3 mit stets aktueller FW und den Addons "CUxD" und "Programmedrucken", ioBroker auf Synology DiskStation DS718+ im Docker-Container;
einige Projekte: zentrales Push-Nachrichten-Programm zPNP, DoorPi-Videotürsprechanlage, An- und Abwesenheitsdetektion per Haustürschloss, zentrales Programm zur Steuerung von Beschattungsgeräten zBSP.

MichaelN
Beiträge: 9635
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 697 Mal
Danksagung erhalten: 1614 Mal

Re: undokumentierte Skript-Befehle

Beitrag von MichaelN » 15.06.2020, 09:15

Was kann man eigentlich mit dem Datentyp idarray anfangen? Dazu habe ich nichts gefunden.
LG, Michael.

Wenn du eine App zur Bedienung brauchst, dann hast du kein Smarthome.

Wettervorhersage über AccuWeather oder OpenWeatherMap+++ Rollladensteuerung 2.0 +++ JSON-API-Ausgaben auswerten +++ undokumentierte Skript-Befehle und Debugging-Tipps +++

Benutzeravatar
Black
Beiträge: 5469
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 419 Mal
Danksagung erhalten: 1070 Mal
Kontaktdaten:

Re: undokumentierte Skript-Befehle

Beitrag von Black » 16.06.2020, 18:57

Ein idarray ist der aufbewahrungsort von aufzählungen von Objekten. Typische Beispiele ist das channels() im device objekt bzw das DPs im Channel objekt. Auf ein idarray kannst du Methoden wie Add , Remove, removeall, sortbyname, moveto etc anwenden. Ein idarray kannst du zwar im Script anlegen, allerdings referenziert das ins Nirvana. Jens wollte da mal gucken, das sich da auch eine ordnungsgemäße Initialisierung einfindet.

Ein idarray verhält sich jetzt wie ein Pointer. Zuweisung idarray ifeld= Gerät.channels() geht. Auch ein ifeld.removeall() geht. Bloß hat dann dein Gerät keine Kanäle mehr :wink: :wink:

Black
Wenn das Fernsehprogramm immer mehr durch nervende Werbung unterbrochen wird und der Radiomoderator nur noch Müll erzählt, ist es besser, die Zeit für sinnvolle Dinge zu nutzen -
mal aufs Klo zu gehen, ein Bier zu holen oder einfach mal den roten AUS-Knopf zu drücken. Klick - und weg

Script Time Scheduler V1.3
AstroSteuerung über Zeitmodul flexibel mit Offset / spätestens, frühestens
SDV 5.03.01 Das umfassende Entwicklungs und Diagnosetool für Homematik
Selektive Backups - Nützliche Dinge, die die WebUI nicht kann

Intel NUC6 Celeron 16GB mit 512GB SSD unter Proxxmox mit insgesamt 5 VM: 2 x bloatwarebefreiter Raspberrymatik, 2 x IOBroker als Middleware und einer MariaDB zur Archivierung. Verbrauch: 6W

technical contribution against annoying advertising

Belly
Beiträge: 22
Registriert: 24.06.2020, 08:07
System: CCU
Hat sich bedankt: 1 Mal

Re: undokumentierte Skript-Befehle

Beitrag von Belly » 04.07.2020, 18:35

Vielleicht nur eine Kleinigkeit, aber ich habe entdeckt, dass der zweite Parameter der Methode `Substr` optional ist. Ohne wird einfach der String ab der bestimmten Stelle zurückgegeben (wie das bei substr üblich ist).

Code: Alles auswählen

string s = "Hallo Welt!";
string world = s.Substr(4); ! world = "o Welt!"
Auszug aus der Doku:
Bildschirmfoto 2020-07-04 um 18.30.40.png

alchy
Beiträge: 10754
Registriert: 24.02.2011, 01:34
System: CCU
Hat sich bedankt: 65 Mal
Danksagung erhalten: 673 Mal

Re: undokumentierte Skript-Befehle

Beitrag von alchy » 04.07.2020, 22:27

der Parameter ist optional - richtig erkannt. BadenPower hat das schon vor Jahren dokumentiert.
BP_Substr.jpg
Und noch mehr (z.B. bezüglich negativer Werte), wie du im Bild lesen kannst.

Alchy

Blacklist................... almost full
Ignoranz ist die Summe aller Maßnahmen die man ergreift, um bestehende Tatsachen nicht sehen zu müssen.

© Sandra Pulsfort (*1974)

Lies bitte die Logik von WebUI Programmen und die Tipps und Tricks für Anfänger.

Wichtig auch CUxD ersetzt System.exec. Die HM Script Doku (Downloadart Skripte) hilft auch weiter.
Zum Testen von Scripten den >> HomeMatic Script Executor << von Anli benutzen.

MichaelN
Beiträge: 9635
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 697 Mal
Danksagung erhalten: 1614 Mal

Re: undokumentierte Skript-Befehle

Beitrag von MichaelN » 05.07.2020, 11:43

Belly hat geschrieben:
04.07.2020, 18:35
Vielleicht nur eine Kleinigkeit, aber ich habe entdeckt, dass der zweite Parameter der Methode `Substr` optional ist. Ohne wird einfach der String ab der bestimmten Stelle zurückgegeben (wie das bei substr üblich ist).
Richtig. Length wird dann automatisch mit der restlichen Länge angenommen. Nutze ich auch, sehr praktisch, da man sich damit die Schritte zur Ermittlung der Rest-Länge spart. Nehme ich mal in Beitrag 1 auf.
LG, Michael.

Wenn du eine App zur Bedienung brauchst, dann hast du kein Smarthome.

Wettervorhersage über AccuWeather oder OpenWeatherMap+++ Rollladensteuerung 2.0 +++ JSON-API-Ausgaben auswerten +++ undokumentierte Skript-Befehle und Debugging-Tipps +++

Antworten

Zurück zu „HomeMatic Tipps & Tricks - keine Fragen!“