Das Upgrade sollte jederzeit problemlos möglich sein, solange man in der 2er Reihe bleibt. Es ist immer möglich, dass sich Konfigurationsdetails geändert haben, es kann also notwendig sein, die Konfiguration anzupassen, aber grundsätzlich sollte das Upgrade immer funktionieren.
Die Geschwindigkeit des Sticks (oder auch der SD-Karte) spielt eine untergeordnete Rolle. Das Hauptproblem des Raspberry ist - neben Stromversorgung - dass durch die große Menge an Daten, die weggeschrieben werden, die SD-Karten zum Wearout neigen. Dieses Problem tritt aber genauso mit USB Sticks auf. Mit dem aktuellen openHABian kommt ein Tool mit, welches den Großteil der Schreibzugriffe in eine Ramdisk verlagert. Bei 4GByte Arbeitsspeicher spielt das keine Rolle (also wegen Platzbedarf), sorgt aber dafür, dass die Speicherkarte nicht durch häufiges Schreiben belastet wird. Nachteil: Bei Stromausfall sind alle so gesicherten Daten weg. Wenn man hingegen den Raspberry geordnet herunter fährt (das ist ohnehin Pflicht! niemals einfach den Strom abklemmen, immer geordnet herunter fahren!), werden die Daten auf die SD-Karte kopiert, bevor sich der Raspberry abschaltet. Da hier nur einmalig geschrieben wird, gibt es keine Probleme mit Wearout.
openHAB unter Windows funktioniert genauso wie unter GNU/Linux, es gibt halt im Detail Unterschiede, sobald man auf das Dateisystem zugreift. Das ist allerdings nicht unbedingt nötig (jetzt mal abgesehen von Konfigurationsarbeiten), und wenn, dann gibt es ohnehin erhebliche Unterschiede. Wenn man z.B. mittels exec Binding eine Batchdatei aufruft, wird diese Batchdatei unter Windows komplett anders aussehen, als unter GNU/Linux. Das sollte Dich aber nicht davon abhalten, unter Windows zu testen!
Was angeschlossene Hardware betrifft, gilt natürlich das gleiche. Ohne Zugang zum entsprechenden Bus kann ein Binding nicht funktionieren. Wenn der Zugang aber z.B. über Web erfolgt, spielt es keine Rolle, ob ein GNU/Linux System sich per IP mit einem Device verbindet, oder ob das ein Windows System macht. Einen Conbee Stick kannst Du natürlich jederzeit auch an einen Windows PC anschließen. Wenn Du einen Raspberry als Testsystem (zusätzlich) einrichtest, hast Du das gleiche Problem. Entweder, Du schaffst Dir einen 2. Stick an, oder Du schließt kurzfristig den Stick aus dem Produktivsystem an das Testsystem an.
Meist muss es aber gar nicht die echte Hardware sein, die man anspricht, z.B. um Regeln zu testen, reicht es, in der UI die Schaltvorgänge zu sehen, oder auch im Log nachzuverfolgen, was passiert. die fertige Rule kann dann nach der Testphase unverändert ins Produktivsystem übernommen werden, sofern die Items gleich angelegt wurden.
openHAB lief schon auf einem Raspberry Pi 1A mit 256MByte RAM (machte allerdings keinen Spaß...), ab dem Raspberry Pi 2 ließ sich gut damit arbeiten. Sofern der Raspberry Pi 4 keinen Hardwaredefekt hat, ist er mehr als ausreichend für openHAB. Meine VM z.B. hat "nur" 1GByte RAM und nur einen (virtuellen) Prozessorkern, trotzdem sehe ich keinerlei Probleme durch die "schwache" (virtuelle) Hardware.
Ja, die Rule war ich noch schuldig geblieben: (Achtung! Kommentare außerhalb des Fensters. horizontal scrollen!)
Code: Alles auswählen
// globale Variablen werden immer zu Beginn der Datei definiert, in der sie verwendet werden
var Timer tWecker = null // definiere einen Timer
var Integer iDim = 0 // setze iDim auf 0
rule "Wecker"
when
System started or // System wurde gestartet/ Datei wurde gespeichert
Time cron "15 0 0 * * ?" or // täglich um 00:00:15 Uhr
RDO61_WECKER_M changed or // Minute wurde geändert
RDO61_WECKER_H changed or // Stunde wurde geändert
wakeup_on changed // Wecker wurde aktiviert/deaktiviert
then
if(!((RDO61_WECKER_M.state instanceof Number) && (RDO61_WECKER_H.state instanceof Number))) { // enthalten die Items eine gültige Zahl?
logWarn("wecker","Keine gültige Startzeit!") // Fehlermeldung, falls nicht
return; // und Rule abbrechen
}
tWecker?.cancel // Timer löschen, falls existient
if (wakeup_on.state == ON) { // Falls Wecker aktiviert
var Integer iTime = (RDO61_WECKER_M.state as Number) + (RDO61_WECKER_H.state as Number) * 60 // Sollzeit in Minuten seit 0:00 Uhr
tWecker = createTimer(now.withTimeAtStartOfDay.plusMinutes(iTime).plusDays(if(iTime > now.getMinuteOfDay) 0 else 1),[| // Plane einen Wecker
iDim += 1 // erhöhe iDim um 1
if(iDim < 101) { // falls iDim kleiner 101
Licht_2_Dimmer.sendCommand(iDim) // setze Dimmer 1 auf Wert
Licht_3_Dimmer.sendCommand(iDim) // etze Dimmer 2 auf Wert
tWecker.reschedule(now.plusSeconds(4)) // plane den Wecker in 4 Sekunden
} else { // ansonsten
iDim = 0 // setze iDim auf 0
tWecker = null // entferne den Wecker
}
])
}
end
Die Zeile
Code: Alles auswählen
tWecker = createTimer(now.withTimeAtStartOfDay.plusMinutes(iTime).plusDays(if(iTime > now.getMinuteOfDay) 0 else 1),[|
Bedarf eventuell etwas Erläuterung
Die global definierte Timer-Variable wird mit eienm Timer befüllt. (genauer: es wird ein Zeiger gesetzt, der auf den Timer verweist).
now -> der aktuelle Zeitpunkt (auf die Nanosekunde genau, mit Zeit, Datum, Zeitzone...)
.withTimeAtStartOfDay -> zurück zu 0:00:00 Uhr des aktuellen Tags (dabei iwird auch eine evtl. Zeitumstellung berücksichtigt.)
.plusMinutes -> zähle Minuten hinzu
.plusDays -> zähle Tage hinzu
if(...) 0 else 1 -> ternärer Operator. Falls die Bedingung zutrifft, nimmm den 1. Wert, sonst den 2. Wert.
iTime > now.getMinuteOfDay -> Der Weckzeitpunkt liegt heute in der Zukunft.
Die Rule triggert immer, wenn eines der beteiligten Items sich ändert, Mitternacht gerade durch ist oder das System neu gestartet wurde.
Zunächst prüft die Rule, ob die Items gültige Zahlen enthalten (z.B. bei Systemstart wichtig), gegebenenfalls wird die Rule abgebrochen.
Anschließend wird ein evtl. vorhandener Timer entfernt.
Ist der Wecker aktiv geschaltet, so wird der Timer neu angelegt. Dabei wird der Zeitpunkt über die Anzahl Minuten seit Mitternacht angegeben. Falls der Weckzeitpunkt heute schon vorüber ist, wird der Wecker auf morgen geplant (streng genommen unnötig, aber man könnte die Rule noch etwas verfeinern und auf den Trigger um Mitternacht verzichten,)
Nach dem Anlegen des Timers ist die Rule zuende. Zu diesem Zeitpunkt hat das System ca. 5 Millisekunden Rechenzeit genutzt.
Der Timer liegt nun im Scheduler. Wenn der gewählte Zeitpunkt erreicht ist, wird der hinterlegte Code ausgeführt.
Zunächst wird die Variable iDim hochgezählt. Ist sie anschließend kleiner als 101, wird der Wert in die Dimmer geschrieben und anschließend der Timer erneut gestartet, diesmal allerdings schon in 4 Sekunden. Zu diesem Zeitpunkt hat das System wiederum ca. 5 Millisekunden für den Code benötigt.
Das Spiel wiederholt sich solange, bis iDim die magische Grenze überschreitet (100) Nun reinitialisiert der Code die Variable und löscht anschließend den Timer. Alternativ könnte man hier den Code so anpassen, dass der Timer wieder für die Zukunft gesetzt wird (analog zur ursprünglichen createTimer-Anweiseung, nun aber als reschedule)
Die Rule benötigt grob geschätzt ca. 1 Sekunde Rechenzeit (insgesamt!) gegenüber 400 Sekunden, die einzelnen Schritte benötigen nur wenige Millisekunden, danach steht der jeweilige Thread sofort wieder zur Verfügung.
Natürlich könnte man iDim auch in 5er Schritten erhöhen und dafür jeweils 20 Sekunden pausieren, aber mit feiner Abstufung ist der Dimmvorgang hübscher
