Ich befürchte aber, er steuert gerade das Tor, welches einen Impuls erwartet, mit einem Dauersignal an.
Gruß Xel66
Moderator: Co-Administratoren
Ich befürchte aber, er steuert gerade das Tor, welches einen Impuls erwartet, mit einem Dauersignal an.
Code: Alles auswählen
string sTimer= 'tclsh /usr/local/timerschedule.tcl -c -d -g "Safety LEVEL 4 1.0"';
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State(sTimer);
Code: Alles auswählen
Oct 10 07:55:17 homematic-raspi user.debug TIME_Scheduler_V13: [BidCos-RF.....:1.LEVEL erfolgreich auf 1.0 ]
Oct 10 07:55:21 homematic-raspi user.debug TIME_Scheduler_V13: [BidCos-RF.... :1.LEVEL erfolgreich auf 1.0 ]
Oct 10 07:55:25 homematic-raspi user.debug TIME_Scheduler_V13: [ID (24473) Fehler beim Versuch Wert (1.0)]
Oct 10 07:55:29 homematic-raspi user.debug TIME_Scheduler_V13: [ID (24501) Fehler beim Versuch Wert (1.0)]
Code: Alles auswählen
#!/bin/tclsh
# Zeitverzögertes setzen von Datenpunkten aus einem HM script heraus.
# Michael Thelen aka Black in November 2018 / Oktober 2019
#
# bekannterweise gibt es keine sinnig vorhandene Methode, um zeitverzögert Datenpunkte zu setzen (Grund Funkdisziplin)
# Abhilfe: Dieses TCL Script
# Aufruf:bitte über CUxD.Exec, nich tüber system Exec. mit der & option hab ichs mit System Exec nicht stabil zum Laufen bekommen
# Syntax
# tclsh /usr/local/timeschedule.tcl [-c] [-d] "ID1 T1 V1 (ED)[, ID2 T2 V2 (ED2)]"
# hierbei bedeutet ID1: ID des zu setzenden Datenpunktes (es wird testet, ob der DP Systemvariable oder Datenpunkt vom Kanal ist
# T1 : Verzögerungszeit in Sekunden
# V1 : neuer Wert
# ID1 T1 und V1 jeweils getrennt durch Leerzeichen
# bei mehreren Werten, komma, dann ID2 T2 und V2 gemäß wie oben
#
# Aufruf mit Option -g in dem Moment läuft die Routine über ein Gewerk der CCU
# tclsh /opt/usr/timeschedule.tcl -g "GewerkID StateName T1 V1 (ED)"
# hierbei wird durch alle Kanäle des Gewerks Iteriert und dabei Zeitverögert die Einzelnen Datenpunkte auf den Werte V1 gesetzt
#
# Aufruf mit der Option -r in dem Moment läuft die Routine über einen Raum der CCU
# tclsh /opt/usr/timeschedule.tcl -r "RaumID StateName T1 V1 (ED)"
# hierbei wird durch alle Kanäle des Raumes Iteriert und dabei Zeitverögert die Einzelnen Datenpunkte auf den Werte V1 gesetzt
#
# Aufruf mit der Option -f in dem Moment läuft die Routine über einen Favoriten der CCU
# tclsh /opt/usr/timeschedule.tcl -f "FavoritenID StateName T1 V1 (ED)"
# hierbei wird durch alle Kanäle des Favoriten Iteriert und dabei Zeitverögert die Einzelnen Datenpunkte auf den Werte V1 gesetzt
#
# V1.1 Ergänzung Optionaler Parameter ED (Einschaltdauer)
# Wird dieser Parameter mitgegeben, wird überprüft, ob dieser Channel einen Datenpunkt ON_TIME besitzt,
# Wenn ja, wird dieser Datenpunkt mit der voreingestellten Zeit beschrieben,bevor der Schaltdatenpunkt gesetzt wird
#
# V1.2 Ergängung -s bei Gewerk,Raum,Favorit
# Wenn als Datenpunkt Level angegeben wurde, wird bei -s geprüft.
# gibt es keinen Datenpunkt Level, wird Versucht, den Datenpunkt "State" zu erreichen.
# gibt es diesen Datenpunkt, so wird bei Level >=0 der Wert State 1 eingetragen, wei Wert Level=0 der Wert State =0 eingetragen
# tclsh /usr/local/timeschedule.tcl -g -s "GwerkID StateName T1 V1 (ED)"
# Beispiel für Aufruf -c -g -s "Licht LEVEL 1.0 0.0"
# Script läuft durch das Gewerk Licht, Sucht alle Datenpunkte Level und setzt diese auf den Wert 0, so er nicht nicht den Wert 0 hat.
# Hat der Channel keinen Datenpunkt Level,
# so wird der Datenpunkt State (Option -s) genommen. bei Wert V1= 0.0 wird State = false gesetzt, bei V1 <> 0.0 wird State auf true gesetzt
#
# V1.3 Ergängung -z bei Gewerk, Raum, Favorit (Szene) noch nicht implementiert
# es wird iteriert und dabei aus
# Szene: Liest
# ##################################################################################################################################
load tclrega.so
proc option {_argv name {_var ""}} {
upvar 1 $_argv argv $_var var
set pos [lsearch -regexp $argv ^$name]
if {$pos>=0} {
if {$_var != ""} {
set var 1
}
set argv [lreplace $argv $pos $pos]
incr ::argc -1
return 1
}
return 0
}
set blackversion "TIME_Scheduler_V13B"
# option compare: macht nur setstate wenn value <> neuem Wert ist
set compare [option argv -c]
# option debug: gibt über logger aus, wenn über hm script datenpunkt gesetzt wird
set debug [option argv -d]
# option gewerk: läuft über ein Gewerk
set gewerk [option argv -g]
# option Raum: läuft über einen Raum
set raum [option argv -r]
# option favorit: läuft über einen Favoriten
set favorit [option argv -f]
set iteration 0
if {$gewerk} {
set scriptid "ID_FUNCTIONS"
set scriptname "Gewerk"
set iteration 1
}
if ($raum) {
set scriptid "ID_ROOMS"
set scriptname "Raum"
set iteration 1
}
if ($favorit) {
set scriptid "ID_FAVORITES"
set scriptname "Favorit"
set iteration 1
}
# nur aktualisieren (es wird keinenuer wert zugewiesen sondern der alte Wert
# führt dazu, das ein Trigger auf aktualisierung erkannt wird ohne Wertänderung
# bei actual wird das compare Flag ignotiert
set actual [option argv -a]
# -s
# Wenn als Datenpunkt Level angegeben wurde, wird bei -s geprüft.
# gibt es keinen Datenpunkt Level, wird Versucht, den Datenpunkt "State" zu erreichen.
# gibt es diesen Datenpunkt, so wird bei Level >=0 der Wert State 1 eingetragen, wei Wert Level=0 der Wert State =0 eingetragen
set lstate [option argv -s]
#puts $actual
if { $argc < 1 } {
puts "$blackversion by Black in November 2018"
puts "Aufruf tclsh timeschedule.tcl \[-c\] \[-d\] \[-g\] \[-s\] \[-s\]\"COMMANDO\""
exit 1
}
if {$iteration} {
# Es ist eine Iteration, dann erstmal den Code für Iteration abarbeiten
set ts [split [lindex $argv 0] " "]
set duration [lindex $ts 4]
# wenn duration gültig, diese mit in den String einbinden, ansonsten EInfügestring = Leerstring
if {[string is double $duration] && ($duration> 0)} {
set sed " $duration"
} else {
set sed ""
}
append cmd "string sID;string sTCL=\"\";string sTime=\"0.0\";object oFunc= dom.GetObject ($scriptid).Get(\"[lindex $ts 0]\");"
append cmd "if (oFunc)\{foreach (sID,oFunc.EnumUsedIDs() ) \{"
set dp [string toupper [lindex $ts 1]]
puts $dp
append cmd "object oID= dom.GetObject (sID).DPByHssDP (\"$dp\");"
append cmd "if (oID) \{"
append cmd "if (sTCL != \"\") \{sTCL = sTCL # \",\";\}"
append cmd "sTCL= sTCL # oID.ID () # \" \" # sTime # \" [lindex $ts 3]$sed\";sTime=\"[lindex $ts 2]\";\}"
if {$lstate} {
if {[string compare $dp "LEVEL"]==0} {
# Der Original DP ist ein LEVEL
set newval [lindex $ts 3]
set stateval "true"
if {[string compare $newval "0.0"]==0} {
set stateval "false"
}
# Hier nun probieren, obs dort den Datenpunkte State gibt und diesen setzen
append cmd " else \{"
append cmd "oID= dom.GetObject (sID).DPByHssDP (\"STATE\");"
append cmd "if (oID) \{"
append cmd "if (sTCL != \"\") \{sTCL = sTCL # \",\";\}"
append cmd "sTCL= sTCL # oID.ID () # \" \" # sTime # \" $stateval$sed\";sTime=\"[lindex $ts 2]\";\}"
# das ist die klammer vom else
append cmd "\}"
# puts $stateval
}
}
# Dies ist die Klammer von foreach
append cmd "\}"
# Dies ist die Klammer von if (oFunc)
append cmd "\}"
# puts $cmd
array set values [rega_script $cmd]
unset cmd
if { [info exists values(sTCL)]} {
set x $values(sTCL)
set para [split $x ","]
} else {
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
exec logger -t $blackversion -p user.debug \[Error in HMScript $scriptname\]
exit 1
}
} else {
# Keine Iteration, damit die liste aus argv holen und splitten
set para [split [lindex $argv 0] ","]
}
# Ab hier läuft das Hauptprogramm
#puts $para
set params [llength $para]
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
exec logger -t $blackversion -p user.debug \[Start Scheduler mit \($params\) State\(s\) - Black in November 2018\]
# durch die Anzahl an Datenpunkten durchlaufen
foreach lData $para {
set ts [split $lData " "]
set id [lindex $ts 0]
set delay [lindex $ts 1]
set value [lindex $ts 2]
set duration [lindex $ts 3]
# Warten nur wenn delay sinnige eingabe ist
if {[string is double $delay] && ($delay> 0)} {
set wait_in_ms [expr $delay * 1000 + 1]
after [expr int($wait_in_ms)]
}
# Warten zuende
if {[string is double $duration] && ($duration> 0)} {
append sdur "object oChan= dom.GetObject (o1.Channel());if ((oChan) && (o1.Type()==OT_HSSDP)) \{"
append sdur "object oDur=oChan.DPByHssDP (\"ON_TIME\");if (oDur) \{"
append sdur "oDur.State ($duration);retDur= $duration;\}\}"
} else {
append sdur ""
}
append cmd "string retID=\"\";string retDur=\"\";object o1= dom.GetObject (\"$id\");if (o1)\{"
append cmd "if ((o1.Type()==OT_HSSDP)||(o1.Type()==OT_VARDP)) \{"
if { $compare && !$actual} {
append cmd "if (o1.Value()!=$value) \{"
}
# Zuweisung Schreiben
# Bei actual ist es der eigene Wert und es wird dabei auch keine Einschaltdauer geschrieben
if { $actual } {
append cmd "o1.State (o1.Value () ); "
set value "alten Wert aktualisiert"
} else {
append cmd "$sdur o1.State (\"$value\");"
}
# Name in Rückgabe
# Änderung 10.10.2019
# Zuerst die Klammer zu, ansonsten keine Rückgabe
if { $compare && !$actual} {
append cmd "\}"
}
append cmd "retID=o1.Name();"
append cmd "\} \}"
#puts $cmd
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
array set values [rega_script $cmd]
# Die reale zeitverzögerung Analysieren
if { [info exists values(retDur)] && ($values(retDur) != "")} {
set duration $values(retDur)
set durtext "mit Einschaltdauer $duration s"
} else {
set durtext ""
}
# Erfolg oder Misserfolg Parameter setzen
if { [info exists values(retID)] && ($values(retID) != "")} {
set x $values(retID)
if { $debug } {
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
exec logger -t $blackversion -p user.debug \[$x erfolgreich auf $value $durtext\]
#puts "Erfolgreich"
}
} else {
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
exec logger -t $blackversion -p user.debug \[ID \($id\) Fehler beim Versuch Wert \($value\)\]
#puts "Nicht erfolgreich"
}
unset cmd
unset sdur
}
Code: Alles auswählen
string sTimer = 'tclsh /usr/local/timerschedule.tcl -d "4592 60 HUHU"';
WriteLine(sTimer);
dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State(sTimer);
Code: Alles auswählen
homematic-raspi daemon.info cuxd[26059]: system(tclsh /usr/local/timerschedule.tcl -d "4592 60 HUHU") exit(1) 0s
Genau. Was ich mich aber noch in Verbindung mit CUxD frage, ist, wann der Verzögerungswert an CUxD übergeben wird. Sprich, wenn zwischenzeitlich die ReGaHSS abstürzt, führt CUxD den verzögerten Befehl dann trotzdem noch aus, oder wird er dann gar nicht weitergeleitet?