Notification when washing machine or dryer are finished, with openHAB
As part of my home automation project, I wanted the washing machine and the dryer to send notifications when they are finished. Both machines are in a separate room, and their alarm beeps are hard to hear in the other parts of the flat. Also because of the noise both machines make during operation, the door is usually closed.
After checking several options how to interact with the washing machine and the dryer (from listening to the audio signals to having light sensors glued over the status led, open the frame and install something inside, and a small cam with picture recognition), I settled with measuring the power consumption. Next step: find the right kit.
After another round of investigation, I settled with adding FRITZ!DECT 210 devices to the already existing FRITZ!Box. The "Smart Home" extensions send their data to the FRITZ!Box, which in turn provides the data using the "avmfritz" binding. Add the extension, again in Ansible:
- name: Get list of available and installed extensions
uri:
url: "http://{{ ansible_host }}:8080/rest/extensions"
register: oh2_extensions
changed_when: false
- name: Install extensions
uri:
url: "http://{{ ansible_host }}:8080/rest/extensions/{{ item }}/install"
method: POST
when: "not (oh2_extensions.json|byattr('id', item))[0].installed"
with_items:
- binding-avmfritz
register: oh2_install_extensions
Auto-approve the new Items:
- name: Get inbox
uri:
url: "http://{{ ansible_host }}:8080/rest/inbox"
register: oh2_inbox
changed_when: false
- name: Auto-approve certain inbox items
uri:
url: "{{ oh2_inbox.url }}/{{ item.thingUID }}/approve"
method: POST
when: item.flag == "NEW" and
(item.thingTypeUID[0:20] == "avmfritz:FRITZ_DECT_")
loop: "{{ oh2_inbox.json }}"
The Play above will work with both the older FRITZ!DECT 200 and the newer FRITZ!DECT 210 adapters.
The "210" adapters provide Channels for total power consumption, current power consumption and the temperature. For now all I need is the current power consumption, but nevertheless I add Items for both the power consumption and the temperature. Everything goes into an .items file in /etc/openhab2/items:
Number Washingmachine_Power "Washing machine power [%.2f W]" <washingmachine> (Energy) {channel="avmfritz:FRITZ_DECT_210:*:*:power"}
Number Washingmachine_State "Washing machine state [MAP(washingmachine.map):%s]" <washingmachine> (Energy)
Number Temperature_1 "Temperature 1 [%f°C]" <temperature> (Temperature) {channel="avmfritz:FRITZ_DECT_210:*:*:temperature"}
Number Dryer_Power "Dryer power [%.2f W]" <dryer> (Energy) {channel="avmfritz:FRITZ_DECT_210:*:*:power"}
Number Dryer_State "Dryer state [MAP(washingmachine.map):%s]" <dryer> (Energy)
Number Temperature_2 "Temperature 2 [%f°C]" <temperature> (Temperature) {channel="avmfritz:FRITZ_DECT_210:*:*:temperature"}
The FRITZ!Box IP-address and the adapter UID are part of the channel name, but masked out in the example above.
The "washingmachine.map" file, in /etc/openhab2/transform:
0=Off
1=Standby
2=Running
3=Finished
NULL=Unknown
Now the rule for the washing machine, relatively straightforward:
val Number MODE_OFF = 0
val Number MODE_STANDBY = 1
val Number MODE_ACTIVE = 2
val Number MODE_FINISHED = 3
rule "Washing machine Status"
when
Item Washingmachine_Power received update
then
// < 1.0 off
// 1.0 - 5.0 standby
// > 5.0 active
if (Washingmachine_State.state == NULL) {
// initial setup
postUpdate(Washingmachine_State, MODE_OFF)
}
if (Washingmachine_Power.state < 1.0) {
postUpdate(Washingmachine_State, MODE_OFF)
} else if (Washingmachine_Power.state > 5.0) {
postUpdate(Washingmachine_State, MODE_ACTIVE)
} else if (Washingmachine_Power.state <= 5.0) {
if (Washingmachine_State.state == MODE_OFF) {
postUpdate(Washingmachine_State, MODE_STANDBY)
} else if (Washingmachine_State.state == MODE_ACTIVE) {
postUpdate(Washingmachine_State, MODE_FINISHED)
logInfo("Washing machine", "Washing machine is finished")
// SEND NOTIFICATION HERE
}
}
end
Everything above 5 watt of power consumption is considered active, everything below is either off or standby. Notification goes out when the state changes from active to finished.
The dryer is more complicated. The anti-crease program will turn on the dryer occasionally, and from a power consumption perspective there is no difference between a regular run and the anti-crease program. Afer carefully watching the openHAB logfile, I figured out that the anti-crease program turns the dryer on for about 2 minutes. I settled with adding another flag for the program, and a timer which fires after 3 minutes (to allow for openHAB delays):
var Timer anti_crease_timer = null
var Boolean anti_crease_program = null
rule "Dryer Status"
when
Item Dryer_Power received update
then
// < 1.0 off
// 1.0 - 5.0 standby
// > 5.0 active
if (Dryer_State.state == NULL) {
// initial setup
postUpdate(Dryer_State, MODE_OFF)
anti_crease_program = false
}
if (Dryer_Power.state < 1.0) {
postUpdate(Dryer_State, MODE_OFF)
} else if (Dryer_Power.state > 5.0) {
postUpdate(Dryer_State, MODE_ACTIVE)
anti_crease_program = true
// occasionally the dryer, when in standby, turns on again
// to prevent the clothes from crasing
// this process lasts about 2 minutes
anti_crease_timer = createTimer(now.plusSeconds(180)) [|
if (Dryer_State.state == MODE_ACTIVE) {
// if the dryer is still running after 3 minutes, it's the full program,
// not just the anti crease program
anti_crease_program = false
}
]
} else if (Dryer_Power.state <= 5.0) {
if (Dryer_State.state == MODE_OFF) {
postUpdate(Dryer_State, MODE_STANDBY)
anti_crease_program = false
} else if (Dryer_State.state == MODE_ACTIVE) {
postUpdate(Dryer_State, MODE_FINISHED)
// this flag is reset after 180 seconds,
// only send a notification if the flag is 'false'
// else it's just a short power-up from the anti-crease program
if (anti_crease_program == false) {
logInfo("Dryer", "Dryer is finished")
// SEND NOTIFICATION HERE
}
}
}
end
The timer fires when the power consumption goes up (active mode), and will check the power consumption after 3 minutes. Also when the power consumption goes up, the anti-crease program flag is set. If the power consumption is still high after the timer ended, it's not the anti-crease program - the flag is reset.
The important part is that the notification is only send when the flag is false - this avoids repeating the "is finished" message.
All in all that's a nice setup and I like the notification part.
Comments
Display comments as Linear | Threaded