- openHAB I: Heimautomatisierung mit openHAB
- openHAB II: Grundkonfiguration
- openHAB III: Fritz!Box-Einbindung
- openHAB IV: Temperatur, Heizung und Raumklima mit Homematic IP
- openHAB V: Müllkalender per ical einbinden
- openHAB VI: Beleuchtung mit Philips Hue
- openHAB VII: Waschmaschine und Trockner melden sich, wenn sie fertig sind
- openHAB VIII: Update auf openHAB 3.0
- openHAB IX: Fritz!Box und OH 3.0
- openHAB X: Endlich die korrekte Uhrzeit
In unserem Haus stehen Waschmaschine und Trockner im Keller. Möchte ich wissen, ob eines der Geräte fertig ist, muss ich also in den Keller laufen. Das ist unpraktisch. Da muss es doch etwas besseres geben.
Natürlich gibt es etwas besseres. Es gibt dieses tolle Tutorial.
Tag 1: Installation, Items, Regeln
Das Konzept ist relativ simpel. Ich schließe die Waschmaschine und den Trockner jeweils an eine Steckdose, die den Verbrauch messen kann. Wenn der Verbrauch von einer hohen Last auf eine sehr niedrige Last fällt, muss der Waschgang fertig sein. Dann bekomme ich eine Nachricht.
Ich installiere an Waschmaschine und Trockner jeweils eine Schalt-Mess-Steckdose von Homematic IP, HmIP-PSM.1Bei amazon für 44,99€ pro Stück gekauft. Anschließend definiere ich die Items in homematic.items
:
// Waschkeller // HmIP-PSM_Waschmaschine Number SteckdoseWaschmaschine_Power "Waschmaschine Verbrauch [%.1f W]" {channel="homematic:HMIP-PSM:3014F711A0001F9A499D1959:0001DBE9913DBB:6#POWER" } Number Waschmaschine_Status "Waschmaschine [%d]" // HmIP-PSM_Trockner Number SteckdoseTrockner_Power "Trockner Verbrauch [%.1f W]" {channel="homematic:HMIP-PSM:3014F711A0001F9A499D1959:0001DA49A3492E:6#POWER" } Number Trockner_Status "Trockner [%d]"
Es folgt die waschen.rules
:
import java.util.concurrent.locks.ReentrantLock val Number MODE_OFF = 0 val Number MODE_STANDBY = 1 val Number MODE_ACTIVE = 2 val Number MODE_FINISHED = 3 val ReentrantLock Waschmaschine_lock = new ReentrantLock() val ReentrantLock Trockner_lock = new ReentrantLock() rule "Status Waschmaschine" when Item SteckdoseWaschmaschine_Power changed then if (SteckdoseWaschmaschine_Power.state < 0.5) Waschmaschine_Status.postUpdate(MODE_OFF) else if (SteckdoseWaschmaschine_Power.state > 10) Waschmaschine_Status.postUpdate(MODE_ACTIVE) else if (SteckdoseWaschmaschine_Power.state < 4.5) { if (Waschmaschine_Status.state == MODE_OFF) Waschmaschine_Status.postUpdate(MODE_STANDBY) else if (Waschmaschine_Status.state == MODE_ACTIVE) { Waschmaschine_lock.lock() try { Thread::sleep(10000) // Debounce for 10 seconds if (SteckdoseWaschmaschine_Power.state < 4.5) { Waschmaschine_Status.postUpdate(MODE_FINISHED) sendNotification("mail@dresse", "Waschmaschine ist fertig!") } } finally { Waschmaschine_lock.unlock() } } } end rule "Status Trockner" when Item SteckdoseTrockner_Power changed then if (SteckdoseTrockner_Power.state < 0.5) Trockner_Status.postUpdate(MODE_OFF) else if (SteckdoseTrockner_Power.state > 10) Trockner_Status.postUpdate(MODE_ACTIVE) else if (SteckdoseTrockner_Power.state < 4.5) { if (Trockner_Status.state == MODE_OFF) Trockner_Status.postUpdate(MODE_STANDBY) else if (Trockner_Status.state == MODE_ACTIVE) { Trockner_lock.lock() try { Thread::sleep(10000) // Debounce for 10 seconds if (SteckdoseTrockner_Power.state < 4.5) { Trockner_Status.postUpdate(MODE_FINISHED) sendNotification("mail@dresse", "Trockner ist fertig!") } } finally { Trockner_lock.unlock() } } } end
Diese rules-datei ist im Prinzip copy-paste von obiger Anleitung. Okay, ich habe die entsprechende Regel verdoppelt, weil ich ja Waschmaschine und Trockner habe. Ansonsten habe ich nur noch das Lock verändert, indem ich den Import an den Anfang der Datei gesetzt habe. Das war nötig, weil ich sonst folgenden Fehler erhalten hatte:
[WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'waschen.rules' has errors, therefore ignoring it: [6,1]: missing EOF at 'import'
Zum Schluss noch die default.sitemap
:
Frame label="Waschküche" { Text item=Waschmaschine_Status icon="whitegood" label="Waschmaschine" Text item=Trockner_Status icon="whitegood" label="Trockner" }
Und dann schauen wir mal, ob es funktioniert.
Tag 2: Feinschliff
Es funktioniert.
Öh. Es funktioniert zu gut. Das sid zu viele Nachrichten. Ich muss die Grenzen, an denen sich der Status ändert, etwas anpassen. So sieht die waschen.rules
jetzt aus:
import java.util.concurrent.locks.ReentrantLock val Number MODE_OFF = 0 val Number MODE_STANDBY = 1 val Number MODE_ACTIVE = 2 val Number MODE_FINISHED = 3 val ReentrantLock Waschmaschine_lock = new ReentrantLock() val ReentrantLock Trockner_lock = new ReentrantLock() rule "Status Waschmaschine" when Item SteckdoseWaschmaschine_Power changed then if (SteckdoseWaschmaschine_Power.state < 0.5) Waschmaschine_Status.postUpdate(MODE_OFF) else if (SteckdoseWaschmaschine_Power.state > 200) Waschmaschine_Status.postUpdate(MODE_ACTIVE) else if (SteckdoseWaschmaschine_Power.state < 2.2) { if (Waschmaschine_Status.state == MODE_OFF) Waschmaschine_Status.postUpdate(MODE_STANDBY) else if (Waschmaschine_Status.state == MODE_ACTIVE) { Waschmaschine_lock.lock() try { Thread::sleep(100000) // Debounce for 100 seconds if (SteckdoseWaschmaschine_Power.state < 2.2) { Waschmaschine_Status.postUpdate(MODE_FINISHED) sendNotification("andreas@kolmer.one", "Waschmaschine ist fertig!") } } finally { Waschmaschine_lock.unlock() } } } end rule "Status Trockner" when Item SteckdoseTrockner_Power changed then if (SteckdoseTrockner_Power.state < 0.5) Trockner_Status.postUpdate(MODE_OFF) else if (SteckdoseTrockner_Power.state > 200) Trockner_Status.postUpdate(MODE_ACTIVE) else if (SteckdoseTrockner_Power.state < 200) { if (Trockner_Status.state == MODE_OFF) Trockner_Status.postUpdate(MODE_STANDBY) else if (Trockner_Status.state == MODE_ACTIVE) { Trockner_lock.lock() try { Thread::sleep(10000) // Debounce for 10 seconds if (SteckdoseTrockner_Power.state < 200) { Trockner_Status.postUpdate(MODE_FINISHED) sendNotification("andreas@kolmer.one", "Trockner ist fertig!") } } finally { Trockner_lock.unlock() } } } end
Das hat geklappt, jetzt kriege ich nur noch eine Nachricht, wenn die Waschmaschine fertig ist.
Nächster Punkt: Die Sitemap ist noch nicht ganz perfekt. Da steht jetzt für die Waschmaschine eine Zahl als Status, also entweder 0, 1, 2 oder 3. Ich möchte aber viel lieber, dass da "Aus" oder "Standby" steht. Da es wie immer tolle Anleitungen gibt, hoffe ich, dass dieser Schritt einfach ist.
Ich bearbeite also meine homematicip.items
:
// Waschkeller // HmIP-PSM_Waschmaschine Number SteckdoseWaschmaschine_Power "Waschmaschine Verbrauch [%.1f W]" {channel="homematic:HMIP-PSM:3014F711A0001F9A499D1959:0001DBE9913DBB:6#POWER" } Number Waschmaschine_Status "Waschmaschine [%d]" String Waschmaschine_Anzeige "[MAP(waschen.map):%s]" // HmIP-PSM_Trockner Number SteckdoseTrockner_Power "Trockner Verbrauch [%.1f W]" {channel="homematic:HMIP-PSM:3014F711A0001F9A499D1959:0001DA49A3492E:6#POWER" } Number Trockner_Status "Trockner [%d]" String Trockner_Anzeige "[MAP(waschen.map):%s]"
Und dann erstelle ich noch eine transform/waschen.map
:
0=Aus 1=Standby 2=Läuft 3=Fertig -=- undefined=- uninitialized=- NULL=-
Und schon erhalte ich einen Fehler in den Logs:
[WARN ] [rest.core.item.EnrichedItemDTOMapper] - Failed transforming the state 'NULL' on item 'Waschmaschine_Anzeige' with pattern 'MAP(waschen.map):%s': Couldn't transform value because transformation service of type 'MAP' is not available. [WARN ] [ui.internal.items.ItemUIRegistryImpl] - couldn't transform value in label because transformationService of type 'MAP' is unavailable [WARN ] [rest.core.item.EnrichedItemDTOMapper] - Failed transforming the state 'NULL' on item 'Trockner_Anzeige' with pattern 'MAP(waschen.map):%s': Couldn't transform value because transformation service of type 'MAP' is not available. [WARN ] [ui.internal.items.ItemUIRegistryImpl] - couldn't transform value in label because transformationService of type 'MAP' is unavailable
Tja, das wäre auch zu einfach gewesen. Aber auch für dieses Problem gibt es eine Lösung: Ich muss das Addon "MAP" installieren. Sonst geht das nicht. Also wähle ich in der PaperUI Addons > Transformations das Addon Map Transformation (transformation-map - 2.5.3). Und schon gibt es keine Fehlermeldungen mehr.
Okay, noch schnell die default.sitemap
überarbeiten:
Frame label="Waschküche" { Text item=Waschmaschine_Anzeige icon="whitegood" label="Waschmaschine" Text item=Trockner_Anzeige icon="whitegood" label="Trockner" }
Sollte klappen, oder? Nein, leider nicht. Die Anzeige funktioniert nicht. Keine Ahnung, woran dies liegt. Da muss ich noch etwas basteln.