Washing machine power optimizer
My solar panels generate more power that we consume for 6 months of the year. And the cheapes power is the power you do not have to buy from the grid. So running our machines when I produce an excess is the most efficient solution. But how do I know when to turn on my machines? Most of them are not ‘smart’ and only have a delayed start. So how do I know at what time to program this delayed start? And what are these fun little repurposed epaper price tags I have laying around?…
Components
I need a few components to pull this off.
Miele W 5933
My washing machine is a 15 year old Miele W 5933. Still perfectly happy with it, but it can only be controlled by its own buttons.
Yes, I could rewire those, but meh…
It has a delayed start, however. I can specify at what time (by 15 minute increments) the program should start after preparing the machine. Great! Now how do I get the optimal time?
OpenEpaperLink
OpenEpaperLink is an alternative firmware and protocol for Electronic Shelf Labels. It can be used to set up E-Paper tags and supply them with content.
Tags
The tags are repurposed Solum ST-GR29000 tags. They have a 298x128 pixel epaper display with white, black and red colors. the (0, 0) coordinate is in the top-left corner.
Controller
The tags are controlled by a Mini-AP-v4 OpenEpaperLink gateway made by Nic Limper. It is a WiFi to 802.15.4 gateway, based on an ESP32-C6 with an integrated tag programmer.
Image taken from OpenEpaperLink site.
Home Assistant
Home Assistant runs most of my home automation. It is the glue between sensors, events and actuators. It has lots of very usefull integrations (plugins) to add more functionality to the system.
Forecast.Solar Integration
Forecast.Solar is an integration that provides the expected solar power generation of the day, based on my location, roof angle and wattage of panels. It is pretty accurate. It not only generates a nice graph in your energy dashboard, it also performs some calculations on the peak time + expected power. This peak time I want to use to time my devices.
OpenEpaperLink Integration
OpenEpaperLink is also an integration for Home Assistant. You can install it via HACS or manually, as described on the project page.
Automation
Finally we need some automation to get the time of the peek of self-generated power, create a layout with these values and send it to the display. This automation is run every hour of the day, since I want to display the offset of the current time to the peek time (in hours).
- type: text
value: >-
Wasmachine starten met
x: 10
y: 5
size: 20
color: black
- type: text
value: >-
maximaal eigen opwek.
x: 10
y: 35
size: 20
color: black
- type: icon
value: mdi:white-balance-sunny
x: 181
y: 32
size: 24
color: black
- type: line
x_start: 10
x_end: 286
y_start: 64
width: 1
- type: text
value: >-
Vandaag over {{
(as_local(as_datetime(states('sensor.power_highest_peak_time_today'))).hour
- now().hour) }} uur ({{
as_local(as_datetime(states('sensor.power_highest_peak_time_today'))).strftime('%H:%M')
}})
x: 10
y: 75
size: 20
color: >-
{{ 'red' if
(as_local(as_datetime(states('sensor.power_highest_peak_time_today'))).hour
- now().hour) < 0 else 'black' }}
- type: text
value: >-
Morgen over {{
(24 - now().hour) + (as_local(as_datetime(states('sensor.power_highest_peak_time_tomorrow'))).hour)
}} uur ({{
as_local(as_datetime(states('sensor.power_highest_peak_time_tomorrow'))).strftime('%H:%M')
}})
x: 10
y: 105
size: 20
color: black
The most interesting part is the template-code for formatting the time values and conditional coloring of the content.
value: >-
Vandaag over {{
(as_local(as_datetime(states('sensor.power_highest_peak_time_today'))).hour
- now().hour) }} uur ({{
as_local(as_datetime(states('sensor.power_highest_peak_time_today'))).strftime('%H:%M')
}})
Get the value of the peak time sensor sensor.power_highest_peak_time_today
with states()
. Convert this to a datetime object with as_datetime()
and adjust it to the current timezone with as_local()
. Now I have the hour of the day where the peak will occur.
Subtract the current hour now().hour
from the peak time and now I have the hours till peak time occurs. This is the ##-part of the text “Vandaag over ## uur”. (see the picture at the top of this page).
The second part of the template-code displays the peak time as the hour of the day. It follows a similar logic as the calculation above.
Get the value of the peak time sensor sensor.power_highest_peak_time_today
with states()
. Convert this to a datetime object with as_datetime()
, adjust it to the current timezone with as_local()
and format it I as HH:MM with the .strftime('%H:%M')
property. Now I have the time at which hour the peak will occur.
Now for the coloring.
color: >-
{{ 'red' if
(as_local(as_datetime(states('sensor.power_highest_peak_time_today'))).hour
- now().hour) < 0 else 'black' }}
Color 'red'
if the peak hour as_local(as_datetime(states('sensor.power_highest_peak_time_today'))).hour
minus the current hour now().hour
is smaller than zero, else color 'black'
. This means if the peak hour lies in the past, the text is colored red.