undokumentierte Skript-Befehle

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

Moderator: Co-Administratoren

MichaelN
Beiträge: 2205
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 173 Mal
Danksagung erhalten: 287 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); }
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);
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

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;
}                

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) );

Code: Alles auswählen

string sSysvar = "Status";
! Index des gültigen Wertes
WriteLine(dom.GetObject(ID_SYSTEM_VARIABLES).Get(sSysvar).Value());
! 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()) );

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);
Include

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


getestet mit CCU FW 3.51.6 / ReGaHss Logikengine R1.00.0388.0215
Zuletzt geändert von MichaelN am 10.05.2021, 14:07, insgesamt 26-mal geändert.

MichaelN
Beiträge: 2205
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 173 Mal
Danksagung erhalten: 287 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

Benutzeravatar
Black
Beiträge: 3888
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 115 Mal
Danksagung erhalten: 421 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

technical contribution against annoying advertising

MichaelN
Beiträge: 2205
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 173 Mal
Danksagung erhalten: 287 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.

dtp
Beiträge: 9757
Registriert: 21.09.2012, 08:09
System: CCU
Wohnort: Stuttgart
Hat sich bedankt: 173 Mal
Danksagung erhalten: 348 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: 2205
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 173 Mal
Danksagung erhalten: 287 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.

Benutzeravatar
Black
Beiträge: 3888
Registriert: 12.09.2015, 22:31
System: Alternative CCU (auf Basis OCCU)
Wohnort: Wegberg
Hat sich bedankt: 115 Mal
Danksagung erhalten: 421 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

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: 10265
Registriert: 24.02.2011, 01:34
System: CCU
Hat sich bedankt: 45 Mal
Danksagung erhalten: 429 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..................... be crowded
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: 2205
Registriert: 27.04.2020, 10:34
System: CCU
Hat sich bedankt: 173 Mal
Danksagung erhalten: 287 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.

Antworten

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