Seite 3 von 4

Re: Bewegungsmelder oder dauer an

Verfasst: 6. Jul 2020 15:35
von SIDE22
die zeiten soll die selbe sein auch von 17 bis 23 hatte dies nur als beispiel erstellt

die rule dass das licht um 17uhr angeht und 23uhr aus habe ich schon angelegt

weis halt nur nicht wie ich die lampe nun dort mit reinbekomme in der rule bewegung habe ich es drin ist dies funktioniert auch
allerdings scheitert es bei dem dauer an wenn man schaltet

Re: Bewegungsmelder oder dauer an

Verfasst: 6. Jul 2020 16:03
von udo1toni
Na ja, das Einfachste ist, dass Du das Licht Treppe_Licht3 mit einem anderen Namen versiehst, nämlich Treppe_LichtNacht (eben passend zum anderen Licht, was sich so verhalten soll) und dann werden die Rules alle so angepasst, dass das Verhalten sich auf beide Lampen auswirkt:

Code: Alles auswählen

var Timer tFlur = null
var Timer tTreppe = null
var Boolean bNacht = false

val Integer iZeit = 45
val Integer iNacht = 1

rule "Bewegung erkennen"
when
    Member of gMelder received update ON
then
    val licht = triggeringItem.name.split("_").get(0)                       // "Flur" oder "Treppe"
    val Licht = gLichter.members.filter[i|i.name.contains(licht)].head      // gLichtFlur oder gLichtTreppe
    if(Licht.state != 100) {                                                // Licht nicht in Dauerbetrieb
        if(licht == "Treppe") {                                             // falls Treppe, Treppentimer
            gLichtTreppe.sendCommand(60)                                    // entsprechendes Licht auf 60%
            tTreppe?.cancel                                                 // Timer abbrechen
            tTreppe = createTimer(now.plusSeconds(iZeit),[|                 // Timer anlegen
                gLichtTreppe.members.forEach[i|                             // Für jedes Licht
                    i.sendCommand(if(                                       // Sende Befehl
                        i.name.contains("Nacht") &&                         // Falls der Name "1" enthält
                        bNacht                                              // und Zeitbedingung erfüllt
                    )iNacht else 0)                                         // 30, ansonsten 0
                ]
            ])
        } else if(dunkel.state == ON) {                                     // falls nicht Treppe und dunkel
            gLichtFlur.sendCommand(60)                                      // entsprechendes Licht auf 60%
            tFlur?.cancel                                                   // Timer abbrechen
            tFlur = createTimer(now.plusSeconds(iZeit),[|                   // Timer anlegen
                gLichtFlur.members.forEach[i|                               // Für jedes Licht
                    i.sendCommand(if(                                       // Sende Befehl
                        i.name.contains("Nacht") &&                         // Falls der Name "1" enthält
                        bNacht                                              // und Zeitbedingung erfüllt
                    )iNacht else 0)                                         // 30, ansonsten 0
                ]
            ])
        }
    }
end


rule "Dauerbetrieb"
when
    Member of gSwitches changed
then
    val licht = triggeringItem.name.split("_")get(0)
    val Licht = gLichter.members.filter[i|i.name.contains(licht)].head
    if(licht == "Flur") tFlur?.cancel
    if(licht == "Treppe") tTreppe?.cancel
    Licht.sendCommand(if(triggeringItem.state == ON) 100 else 0)
    if(bNacht && triggeringItem.state == OFF)
        gLichter.allMembers.filter[i|i.name == licht + "_LichtNacht"].head.sendCommand(iNacht)
end

rule "Nachtlicht an"
when
    Time cron "0 0 18 * * ?"
then
    bNacht = true
    gLichter.allMembers.filter[i|i.name.contains("LichtNacht")].forEach[j|
        if(j.state == 0) j.sendCommand(iNacht)
    ]
end

rule "Nachtlicht an"
when
    Time cron "0 0 1 * * ?"
then
    bNacht = false
    gLichter.allMembers.filter[i|i.name.contains("LichtNacht")].forEach[j|
        if(j.state == iNacht) j.sendCommand(0)
    ]
end
Das sind die gleichen Rules, mit ein paar kleinen Änderungen.
Zum einen habe ich eine Variable bNacht eingeführt. Diese wird durch die Time cron Rules umgeschaltet, so dass nun an anderer Stelle nicht mehr mit den Zeiten gearbeitet werden muss.
Dann habe ich noch eine Konstante iNacht eingeführt, welche den gewünschten Level für das Nachtlicht vorgibt.
Und dann habe ich den Code so angepasst, dass nun alle Lampen, in deren Name "LichtNacht" vorkommt, entsprechend geschaltet werden. Zu beachten ist hier, dass ich die Gruppe mit allMembers anspreche, also auch die Kindeskinder mit einbeziehe.
Die Gruppen und deren Verwendung in der DSL sind extrem mächtig :)

Re: Bewegungsmelder oder dauer an

Verfasst: 6. Jul 2020 17:14
von SIDE22
so habe die rule mal soweit übernommen
allerdings wenn die lampen sich in Time cron befinden und ich den schalter EIN und wieder Ausschalte gehen die lampen aus und bleiben aus
da sollte doch eigendlich die lampe mit Time cron wieder zurückspringen

bei der rule müsste ich allerdings was ändern

Code: Alles auswählen

rule "Dauerbetrieb"
when
    Member of gSwitches changed
then
    val licht = triggeringItem.name.split("_")get(0)
    val Licht = gLichter.members.filter[i|i.name.contains(licht)].head
    if(licht == "Flur") tFlur?.cancel
    if(licht == "Treppe") tTreppe?.cancel
    Licht.sendCommand(if(triggeringItem.state == ON) 100 else 0)
    if(bNacht && triggeringItem.state == OFF)
        gLichter.allMembers.filter[i|i.name == licht + "_LichtNacht"].head.sendCommand(30)
end
wenn die zeitsteuerung EIN ist und man den schalter wieder auf AUS macht sollen die lampen _LichtNacht ja wieder den zustand der steuerung nehmen
ich müsste die lampe (Flur_LichtNacht) auf einer anderen helligkeit haben den das ist eine die mehr lm hab und demnach zu hell ist nur bei der jetztigen rule weis ich noch nicht wie ich dies ändern kann
und bevor ich jetzt stunden/tage lang testen und probiere frage ich lieber kurz ..

lg
florian

Re: Bewegungsmelder oder dauer an

Verfasst: 6. Jul 2020 22:44
von udo1toni
Dass nach dem Dauer Einschalten und wieder Ausschalten das Licht wieder auf 60% geht (für den Fall, dass es vorher an war) ist nicht so ohne weiteres realisierbar. Das Licht muss dann ja auch wieder ausgeschaltet werden. Aber Bewegung sollte erkannt werden und das Licht dann auch wieder einschalten.
Unterschiedliche Helligkeitsstufen für die beiden Nachtlichter sind natürlich etwas ungünstig, denn Sinn des Codes ist es ja gerade, dass sich beide Schaltungen gleich verhalten. Gibt es einen besonderen Grund, warum gerade die einzige Lampe, die heller als der Rest strahlt, für das Nachtlicht zuständig ist? (Du könntest die Lampe ja vielleicht auch in eine andere Leuchte einbauen oder alternativ eine andere Lampe einschalten lassen).
Man könnte das aber auch über unterschiedliche Werte realisieren. Wenn man zwei default Werte definiert, müssen natürlich auch die Rules entsprechend angepasst werden...

Code: Alles auswählen

var Timer tFlur = null
var Timer tTreppe = null
var Boolean bNacht = false

val Integer iZeit = 45
val Integer iNachtFlur = 30
val Integer iNachtTreppe = 25

rule "Bewegung erkennen"
when
    Member of gMelder received update ON
then
    val licht = triggeringItem.name.split("_").get(0)                       // "Flur" oder "Treppe"
    val Licht = gLichter.members.filter[i|i.name.contains(licht)].head      // gLichtFlur oder gLichtTreppe
    if(Licht.state != 100) {                                                // Licht nicht in Dauerbetrieb
        if(licht == "Treppe") {                                             // falls Treppe, Treppentimer
            gLichtTreppe.sendCommand(60)                                    // entsprechendes Licht auf 60%
            tTreppe?.cancel                                                 // Timer abbrechen
            tTreppe = createTimer(now.plusSeconds(iZeit),[|                 // Timer anlegen
                gLichtTreppe.members.forEach[i|                             // Für jedes Licht
                    i.sendCommand(if(                                       // Sende Befehl
                        i.name.contains("Nacht") &&                         // Falls der Name "1" enthält
                        bNacht                                              // und Zeitbedingung erfüllt
                    )iNachtTreppe else 0)                                   // iNachtTreppe, ansonsten 0
                ]
            ])
        } else if(dunkel.state == ON) {                                     // falls nicht Treppe und dunkel
            gLichtFlur.sendCommand(60)                                      // entsprechendes Licht auf 60%
            tFlur?.cancel                                                   // Timer abbrechen
            tFlur = createTimer(now.plusSeconds(iZeit),[|                   // Timer anlegen
                gLichtFlur.members.forEach[i|                               // Für jedes Licht
                    i.sendCommand(if(                                       // Sende Befehl
                        i.name.contains("Nacht") &&                         // Falls der Name "1" enthält
                        bNacht                                              // und Zeitbedingung erfüllt
                    )iNachtFlur else 0)                                     // iNachtFlur, ansonsten 0
                ]
            ])
        }
    }
end


rule "Dauerbetrieb"
when
    Member of gSwitches changed
then
    val licht = triggeringItem.name.split("_")get(0)
    val Licht = gLichter.members.filter[i|i.name.contains(licht)].head
    if(licht == "Flur") tFlur?.cancel
    if(licht == "Treppe") tTreppe?.cancel
    var Integer bri = 100 
    if(triggeringItem.state == OFF)
        bri = 0
    Licht.forEach[i|
        if(i.name.contains("Nacht") && bNacht && bri == 0) 
            bri = if(i.name.contains("Flur")) iNachtFlur else iNachtTreppe
        sendCommand(bri)
    ]
end

rule "Nachtlicht an"
when
    Time cron "0 0 18 * * ?"
then
    bNacht = true
    gLichter.allMembers.filter[i|i.name.contains("LichtNacht")].forEach[j|
        if(j.state == 0) j.sendCommand(if(j.name.contains("Flur")) iNachtFlur else iNachtTreppe)
    ]
end

rule "Nachtlicht an"
when
    Time cron "0 0 1 * * ?"
then
    bNacht = false
    gLichter.allMembers.filter[i|i.name.contains("LichtNacht")].forEach[j|
        if(j.state == if(j.name.contains("Flur")) iNachtFlur else iNachtTreppe) j.sendCommand(0)
    ]
end

Re: Bewegungsmelder oder dauer an

Verfasst: 7. Jul 2020 12:36
von SIDE22
aktuell sind das die ikea lampen die über die HUE Bridge laufen
und die 3 "nachtlichter" sind stehlampen leider habe ich mich mal vergriffen und die 1 lampe hat 1000ml die anderen nur 600 ml
und wie ich die 1000ml lampe auf den selben wert dimme wie die anderen wird diese natürlich heller ^^ aber ja werde diese heute noch austauschen muss eh in die stadt kann dann gleich bei ikea halten und einmal die selbe holen ^^

mit der funktion wenn man den schalter EIN und wieder AUS schaltet ging in der allerersten variante die du mir gegeben hattest
da lief das ganze ja noch über

Code: Alles auswählen

if((now.getHourOfDay < 1 || now.getHourOfDay > 14) && triggeringItem.state == OFF && licht = "Flur") 
        Flur_LichtNacht.sendCommand(30)
dies ging ja nur im flur und wollte ja gerne auch Treppe dazu haben

habe auch aktuell die rule angepasst das bewegung nur geht wenn helligkeit höher ist als 50 dies funktioniert recht gut und den wert gibt der bewegungsmelder raus

Re: Bewegungsmelder oder dauer an

Verfasst: 7. Jul 2020 13:14
von SIDE22
so habe das ganze mal übernommen bekomme auch gleich 9 fehler in VSCode

Unbenannt.PNG

hier einmal die betroffende rule mit zeilennummern

Code: Alles auswählen

43 rule "Dauerbetrieb"
44 when
45     Member of gSwitches changed
46 then
47     val licht = triggeringItem.name.split("_").get(0)
48     val Licht = gLichter.members.filter[i|i.name.contains(licht)].head
49     if(licht == "Flur") tFlur?.cancel
50     if(licht == "Treppe") tTreppe?.cancel
51     var Integer bri = 100 
52     if(triggeringItem.state == OFF)
53         bri = 0
54     Licht.forEach[i|
55         if(i.name.contains("Nacht") && bNacht && bri == 0) 
56             bri = if(i.name.contains("Flur")) iNachtFlur else iNachtTreppe
57         sendCommand(bri)
58     ]
59 end

habe die lampe ja nun getauscht demnach kann sie auch den selben wert haben wie die anderen sollte von der rule hereinfacher sein ^^


lg

Re: Bewegungsmelder oder dauer an

Verfasst: 8. Jul 2020 00:19
von udo1toni
Oh, ja, da fehlt noch ein members in Zeile 54... sollte so aussehen;

Code: Alles auswählen

Licht.members.forEach[i|
Licht ist ja eines von zwei Gruppenitems

Re: Bewegungsmelder oder dauer an

Verfasst: 11. Jul 2020 00:45
von SIDE22
Hey muss das thema nochmal rausholen ^^
habe mal ne frage wegen dem bNacht

Code: Alles auswählen

var Boolean bNacht = false

rule "Dauerbetrieb"
when
    Member of gSwitches changed
then
    val licht = triggeringItem.name.split("_").get(0)
    val Licht = gLichter.members.filter[i|i.name.contains(licht)].head
    if(licht == "Flur") tFlur?.cancel
    if(licht == "Treppe") tTreppe?.cancel
    Licht.sendCommand(if(triggeringItem.state == ON) 100 else 0)
    if(bNacht && triggeringItem.state == OFF)
        gLichter.allMembers.filter[i|i.name == licht + "_LichtNacht"].head.sendCommand(10)
end

müsste man unten aus dem

Code: Alles auswählen

bNacht
nicht

Code: Alles auswählen

bNacht.state = true
machen wegen der zeit regelung ?

Code: Alles auswählen

rule "Nachtlicht an"
when
    Time cron "0 0 21 * * ?"
then
    bNacht = true
    gLichter.allMembers.filter[i|i.name.contains("LichtNacht")].forEach[j|
        if(j.state == 0) j.sendCommand(10)
    ]
end


rule "Nachtlicht aus"
when
    Time cron "0 0 1 * * ?"
then
    bNacht = false
    gLichter.allMembers.filter[i|i.name.contains("LichtNacht")].forEach[j|
        if(j.state == 10) j.sendCommand(0)
    ]
end
oder wie muss ich das verstehen?
mit den rules selber komme ich mittlerweile klar
nur noch nicht mit diesen funktion die am anfang stehen also dieses "var" zb.

lg
Florian

Bewegungsmelder oder dauer an

Verfasst: 11. Jul 2020 14:23
von udo1toni
Nein, bNacht ist eine global definierte Variable (die erste Zeile... var Boolean bNacht = false)

Es handelt sich also NICHT um ein Item. Da bNacht ausdrücklich als Typ Boolean definiert ist, kennt es nur die Zustände true und false. Das hat den Vorteil, dass man an Stellen, an denen man exakt diese beiden Zustände braucht, ohne weiteres Drumherum auskommt, also if(bNacht) bzw. if(!bNacht), das macht im Code schon einen erheblichen Unterschied.
Der Nachteil: Man kann den Zustand von bNacht nicht in einer Sitemap anzeigen lassen, da es sich ja nicht um ein Item handelt. Auch eine Persistence ist dafür nicht möglich. Da der Zustand der Variablen sich aber ohnehin nur sicher über die Kenntnis der Schaltzeiten festlegen lässt, müsste man bNacht sowieso über eine separate Rule berechnen lassen, wenn das System neu gestartet wird - das hatte ich glatt unterschlagen... geht so:

Code: Alles auswählen

rule “System wird gestartet“
when
    System started
then
    if(now.getHourOfDay < 1 || now.getHourOfDay > 16) 
        bNacht = true
end
Damit wird bNacht beim Systemstart von false auf true umgeschaltet, falls es vor 1 Uhr oder nach 17 Uhr ist.

Achtung, die Anführungszeichen sind die falschen... iPad sei Dank...
Gesendet von iPad mit Tapatalk

Re: Bewegungsmelder oder dauer an

Verfasst: 11. Jul 2020 14:39
von SIDE22
ah ok habe das ganze mal hinzugefügt und auf meine zeiten angepasst werde es dann heute abend mal testen wenn die zeiten passen :)

danke dir

lg
Florian