Seite 1 von 1

Probleme mit HSB Farbwechsel Script

Verfasst: 13. Okt 2023 09:26
von retai
Hallo zusammen,

ich versuche mich gerade mit einem Script für einen automatischen HSB Farbwechsel. Bei dem Farbwechsel soll das Item mauerfarbe (vom Typ hsb mit 3 werten) alle 2 Sekunden beim Wert hue um eins erhöht werden. Dabei bekomme ich 2 Fehler:

1. der Script wird in der Regel nicht gefunden
2. der Script wird nicht richtig ausgeführt

Ich bekomme folgende 2 Fehlermeldungen:
1: [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'script-1' failed: Script 'huefade' cannot be found. in script

2: [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'huefade' failed: <eval>:1:27 Expected ; but found as
var hsb = mauerfarbe.state as HSBType
^ in <eval> at line number 1 at column number 27

OH ist 3.4.2.
Die Regel wurde in einer Textdatei namens scripts.rules erstellt.
die Regel ist so erstellt:

Code: Alles auswählen

rule "Partytime"
when Time cron "*/2 * * * * ?"
then
 if (partymodus.state == ON) { 
	callScript("huefade");
 }
 end
Den Script habe ich in der UI als ECMA Script unter name und ID huefade erstellt. Name Der Script sieht so aus:

Code: Alles auswählen

var hsb = mauerfarbe.state as HSBType
var DecimalType hue = new DecimalType(hsb.hue.intValue % 360 + 1)
var PercentType sat = new PercentType(hsb.saturation.intValue)
var brightValue = 65;                                                     
var PercentType bright = new PercentType(brightValue)
var HSBType newHsb = new HSBType(hue, sat, bright)

mauerfarbe.sendCommand(newHsb);
Sieht jemand von euch das Problem bzw. hat einen alternativen Lösungsvorschlag?

danke

Re: Probleme mit HSB Farbwechsel Script

Verfasst: 13. Okt 2023 21:25
von udo1toni
Die Action callScript() kann nur DSL Scripte starten, und diese dürfen nicht über die UI erzeugt werden, stattdessen müssen sie im Verzteichnis $OPENHAB_CONF/scripts/ abgespeichert werden, mit der Endung .script (die nicht mit angegeben werden darf)

Kannst Du hier nachlesen: https://www.openhab.org/docs/configurat ... em-actions

Warum überhaupt indirekt über ein Script?

Code: Alles auswählen

// Globale Variablen in der rules Datei vor der ersten Rule definieren!
var Timer tColorchange = null // Timer für Farbwechsel

rule "farbtest"
when
    Item partymode changed                                                             // Partymodus aktiviert oder deaktiviert
then
    tColorchange?.cancel                                                               // entferne laufende Timer
    if(newState != ON)                                                                 // Falls nicht ON
        return;                                                                        // Rule beenden

    tColorchange = createTimer(now.plus(500, java.time.temporal.ChronoUnit.MILLIS), [| // erzeuge Timer in einer halben Sekunde
        val oldHSB = mauerfarbe.state as HSBType                                       // hole aktuellen Status  als HSB
        val    hue = new DecimalType((oldHSB.hue + 1).intValue % 360)                  // wähle nächste Stufe
        val    sat = oldHSB.saturation                                                 // wähle eingestellte Sättigung
        val    bri = oldHSB.brightness                                                 // wähle aktuelle Helligkeit
        val newHSB = new HSBType(hue, sat, bri)                                        // erzeuge neuen HSB-Wert
        mauerfarbe.sendCommand(newHSB.toString)                                        // Schreibe Wert in Item
        tColorchange.reschedule(now.plus(500, java.time.temporal.ChronoUnit.MILLIS))   // plane den nächsten Timeraufruf
    ])
end
Erst mal ist es sinnvoller, einen Timer zu verwenden. Damit wird die Rule nur dann ausgeführt, wenn der Schalter umgeschaltet wird.
Als erstes wird bei einem Wechsel der Schalterstellung ein eventuell laufender Timer abgebrochen (das ? bedeutet: Falls die Variable nicht null ist)
Ist der neue Status nicht ON, so wird die Rule abgebrochen.

Ist der Status aber ON, so wird die nächste Zeile ausgeführt, die einen Timer anlegt.
Der Timer wird in 500 Millisekunden ausgeführt - die Schreibweise ist etwas umständlich, leider gehört ChronoUnit nicht zu den Standard Imports.
Alternativ könnte man auch .plusNanos(500000000) schreiben.
Falls Du tatsächlich einen Farbwechsel alle 2 Sekunden willst, geht natürlich auch .plusSeconds(2)

Innerhalb des Timer Lambdas läuftg der Code in ähnlicher Form, wie von Dir vorgesehen:
Die Variable oldHSB wird mit dem aktuellen HSB Wert geladen
Die lokale Konstante hue wird mit dem nächsten Farbwert geladen. Dabei wird der neue Wert Modulo 360 genommen, der Modulo Operator steht nur für Integer zur Verfügung, allerdings wird hue als DecimalType gebraucht.
Die zwei Werte saturation und brightness werden in lokale Konstanten übernommen
der neue HSB-Wert wird in der lokalen Konstanten newHSB gespeichert.
newHSB wird als String als Befehl ans Item gesendet.
Abschließend wird der Timer neu eingeplant.

Den Code habe ich unter openHAB4.0.3 getestet, er sollte aber exakt so auch unter 3.x laufen.

Re: Probleme mit HSB Farbwechsel Script

Verfasst: 15. Okt 2023 14:16
von retai
Hallo Udo,

danke, deine Regel funktioniert einwandfrei. Wenn ich mir dann aber die Logs ansehe, bekomme ich noch die Fehlermeldung:

2023-10-15 14:12:08.596 [WARN ] [d4j.internal.RRD4jPersistenceService] - Failed to open rrd4j database 'mauerfarbe' to store data (java.lang.IllegalStateException: request interrupted for file:///C:/openhab31/userdata/persistence/rrd4j/mauerfarbe.rrd)

Was ich verstanden habe ist, dass man in einer rrd4j persistence nur number speichern kann und deswegen der Fehler kommt.
Ich dachte, na gut, dann passe ich bei
mauerfarbe.sendCommand(newHSB.toString) den String auf Number an, das funktioniert aber nicht, da es wahrscheinlich drei Number Werte mit Trennung sind.
Kann man diesen Fehler noch umgehen oder muss man damit leben? Er schreibt halt dann die Log Datei voll.

Danke

Re: Probleme mit HSB Farbwechsel Script

Verfasst: 16. Okt 2023 00:40
von udo1toni
Du kannst das Item von der Persistence ausklammern.
Leider arbeitet openHAB seit Version 3 unsauber, um neuen Usern das Leben einfacher zu machen, und die Kehrseite der Medaille sind solche Fehlermeldungen.

Um die Meldungen loszuwerden, musst Du definieren, welche Items persistiert werden sollen. In der Folge werden dann nur noch diese Items persistiert und alle übrigen nicht mehr.
Einfache Variante: Du definierst ein Group Item (z.B. gRrd4jPersist) und weist alle Items, die Du persistieren möchtest dieser Gruppe zu. Die Gruppe sollte kein Bestandteil des Semantic Model sein.
Anschließend definierst Du, dass alle Member dieser Gruppe mit der gewünschten Stategy persistiert werden (everyUpdate, everyMinute).
Dazu legst Du entweder eine passende Datei an
$OPENHAB_CONF/persistence/rrd4j.persist mit dem Inhalt:

Code: Alles auswählen

Strategies {
        // for rrd4j, we need a cron strategy
        everyMinute : "0 * * * * ?"
}

Items {
        // let's store Wheater_Chart values in rrd4j
        gRrd4jPersist*                  : strategy = everyMinute, everyUpdate
}
Das Sternchen nach dem Itemnamen bedeutet, dass nicht das ITem selbst persistiert wird, sondern dessen unmittelbare Member. Es handelt sich NICHT um einen Joker!
Alternativ kannst Du ab openHAB4 diese Einstellung auch über die UI erledigen, openHAB Main UI -> Adminstration -> Einstellungen -> Add-Ons -> Other Add-Ons -> Persistence Services -> RRD4J Persistence -> anklicken, um in die Detailansicht zu kommen -> winzig kleines blaues Zahnrad rechts neben dem REMOVE Knopf klicken -> Blauen Schriftzug Persistence Configuration klicken.
Im folgendne Dialog Add Configuration klicken und dort das Group Item auswählen, sowie die Strategies everyMinute und everyUpdate auswählen.
everyMinute ist NICHT optional, diese Strategy ist systembedingt bei rrd4j obligatorisch.

Du kannst statt der Gruppe auch jedes Item einzeln angeben :) was bei der Variante über die UI zu einer Klick-Orgie ausarten könnte.

Wenn man keinerlei Konfiguration angelegt hat, gilt eine Default Regel, welche mit dem * ALLE Items einschließt und mit everyMinute, everyUpdate persistiert.

Re: Probleme mit HSB Farbwechsel Script

Verfasst: 16. Okt 2023 22:04
von retai
Habe mir jetzt das Group Item gRrd4jPersist mit dem member mauerfarbe angelegt, die Warnmeldung kommt aber immer noch.
Hatte dann das Group Item durch das Item direkt ersetzt, aber das bringt auch die gleiche Fehlermeldung.

Code: Alles auswählen

Strategies {
        // for rrd4j, we need a cron strategy
        everyMinute : "0 * * * * ?"
}

Items {
        // let's store Wheater_Chart values in rrd4j
        mauerfarbe                  : strategy = everyMinute, everyUpdate
}
Kann es sein, dass ich das item mauerfarbe irgenwie davor aus der rrd4j database löschen muss? Weil im Ordner C:\openhab31\userdata\persistence\rrd4j ist die mauerfarbe.rrd noch vorhanden.

Re: Probleme mit HSB Farbwechsel Script

Verfasst: 17. Okt 2023 10:15
von udo1toni
Nein, mauerfarbe darfst Du ja eben NICHT persistieren, das ist ja das Item, welches keine (einzelne) Zahl enthält. Leider kann man nicht gezielt Items aus der Persistence ausklammern, stattdessen musst Du alle anderen Items (bis auf das eine) in die Persistence einbeziehen,

Re: Probleme mit HSB Farbwechsel Script

Verfasst: 20. Okt 2023 09:55
von retai
ich bekomme es leider nicht zum laufen, weder mit dem RRD4 wo ich aus der gruppe die mauerfarbe ausklammere noch mit einer zweiten persistence.
habe mir jetzt mal eine mapdb.persist gebastelt und wollte da explizit die mauerfarbe als item in der gruppe gmapdb anführen. auch in der UI habe ich mapdb als standart service ausgefählt. dann habe ich noch die mauerfarbe.rrd gelöscht, das ganze system neu gestartet und sobald das system geladen ist, ist die mauerfarbe.rrd wieder im rrd4j ordner vorhanden und die fehlermeldung da.

Code: Alles auswählen

Strategies {
        // for rrd4j, we need a cron strategy
        everyHour : "0 0 * * * ?"
	default = everyChange
}

Items {
        // let's store Wheater_Chart values in rrd4j
        gmapdb* : strategy = everyChange, restoreOnStartup
}
hat noch jemand eine idee wo ich den fehler mache?

Re: Probleme mit HSB Farbwechsel Script

Verfasst: 20. Okt 2023 11:22
von udo1toni
Warum legst Du eine mapdb.persist an, wo Du doch eine rrd4j.persist brauchst?

Deine rrd4j.persist muss so aussehen:

Code: Alles auswählen

Strategies {
    // for rrd4j, we need a cron strategy
    everyMinute : "0 * * * * ?"
}
Items {
        grrd4j* : strategy = everyMinute, everyUpdate
}
Damit wird in rrd4j nur persistiert, was unmittelbar zur Gruppe grrd4j gehört.
Entsprechend musst Du alle Items zu dieser Gruppe zuordnen, bis auf das Item mauerfarbe.

MapDB kann das Item mauerfarbe problemlos persistieren, MapDB kennt keine Einschränkungen des Datentyps - genau wie die jdbc Persistence, die ihre Daten an eine externe SQL-Datenbank sendet. Voraussetzung ist dann natürlich eine laufende SQL-Datenbank wie z.B. MariaDB oder PostgreSQL.

Re: Probleme mit HSB Farbwechsel Script

Verfasst: 22. Okt 2023 09:10
von retai
Ich hatte die mapdb.persist angelegt, da ich mit der rrd4j.persist keinen Erfolg hatte.
Mein Gedanke war folgender. Das Item mauerfarbe ist ein String item welches nicht mit rrd4j persistiert werden kann (nur Number items). Daher habe ich zuerst versucht alle Items bis auf mauerfarbe mit der von dir vorgeschlagenen rrd4j.persist zu persistieren. Das funktionierte bei mir aber nicht. Deswegen bin ich dann den Weg gegangen die mapdb.perist zu erstellen welche String items persistieren kann. Hier führte ich dann speziell nur die mauerfarbe an, leider wiederum ohne Erfolg, da egal was ich mache, Openhab versucht das Item mauerfarbe in rrd4 zu persistieren :)

Re: Probleme mit HSB Farbwechsel Script

Verfasst: 22. Okt 2023 12:27
von udo1toni
retai hat geschrieben: 22. Okt 2023 09:10 egal was ich mache, Openhab versucht das Item mauerfarbe in rrd4 zu persistieren
Nein, definitiv nicht, dann hast Du einfach einen Fehler in der rrd4j.persist Datei.

Man kann jedes Item mit jedem Persistence Service gleichzeitig persistieren, das explizite persistieren mit einem bestimmten Service verhindert also nicht, dass ein anderer Persitence Service das Item ebenfalls persistiert. Stattdessen musst Du das Item aktiv ausklammern, was aber nicht vorgesehen ist.

Eventuell wäre es sinnvoll, dazu einen Issue aufzumachen (zum einen: Persistence Services sollten Items ignorieren, die sie nicht sinnvoll persistieren können; zum zweiten: Man sollte gezielt Items konfigurieren können, welche nicht persistiert werden sollen, obwohl die Regeln dieses Item berücksichtigen (z.B. ein vorangestelltes !, oder eine explizite Strategy none, so dass man mit * alle Items einschließen kann, aber solche mit Strategy none werden wieder entfernt).