Saturday, January 27, 2024

Washer and [updated] Dryer Notifications

 


This article will cover how I implemented voice notifications for my washer and dryer using Home Assistant.  Originally implemented over three years ago, I recently upgraded the sensors for the dryer notifications to provide better reliability.  This article will cover the original washer notification and the updated dryer version.

You can see a video of the original washer and dryer notification process.  The washer notification is unchanged and I'll cover that original process here as well. 


But the dryer sensors and ESPHome processes have since changed.  This is also covered in an update video and I'll only be covering the new dryer process in this article:


Background


One of my earliest automations, yet still one of my wife's favorites, are voice notifications for both the washer and dryer.  Since the laundry is located on the main floor, the buzzers from the machines that indicated a cycle was complete could not be heard upstairs or when spending time in our finished basement.  My wife was constantly heading up or down the stairs to check on the laundry.  So not long after first implementing Home Assistant, I saw an opportunity for major WAF (Wife Approval/Acceptance Factor) points if I could have an announcement made that could be heard throughout the house when either the washer or dryer completed its cycle.  The success of this project paved the way for many other automations that followed.

These processes and notifications are based on a standard U.S.110 VAC washer and a 220 VAC electric dryer.  If you are only interested in the updated dryer portion, you can skip over the washer notification section.

Note on YAML shown:  While the YAML I include here would likely need to be modified for your particular Home Assistant/ESPHome installation, if you do wish to copy/paste any code, it is highly recommended that you do that from the Github repository and not directly from this article.  There is a high probability that spacing and indentation would not copy correctly if copied directly from here.

Washer Notifications


The washer notification has pretty much remained unchanged since I originally created it.  But since I did not create a written guide when I released the original video, I'll go over the washer notification in this section.  As always, let's start with the parts list... which is pretty short for the washer side.

Parts List


Note: All you really need for the washer notifications is an energy-monitoring smart plug or outlet that can integrate into Home Assistant.  There are many options, including Zigbee smart plugs and others, that can provide local energy readings.  As long as you can get real-time wattage (or amps) from the outlet into Home Assistant, the automations listed below will work.  I'm listing the parts I used, including the necessary components to flash Tasmota (or ESPHome).

QTY

Item

Notes

 

Smart Plug Used in the Article

 

-

Sonoff S31 WiFi Smart Plug

With energy monitoring

 

 

 

 

Parts needed for flashing firmware

 

 

USB-to-Serial Flasher (only one needed)

 

1

CP2102 USB-to-TTL

Most common or

1

FTL232RL USB-to-Serial

Alternate version

 

 

 

 

Jig and Connection Options

 

1

Sonoff S31 3D Printed Jig

This is a Thingiverse link

-

Pogo Pins for 3D Printed Jig

 

-

Test Lead Hook Clips

Alternate to jig

-

Dupont Jumper Wires

 

1

USB Extension Cable

Optional but recommended

 

 

 

Some of these links may be Amazon affiliate links.  Use of these links will not affect your pricing, but as an affiliate this channel may earn a small commission if you make a purchase.

Flashing Tasmota or ESPHome


Replacing your device's default firmware is optional if it already has an integration in Home Assistant.  But if your device can be flashed (not all can), replacing the default manufacturer's cloud-based firmware removes dependency on the Internet and also protects your data.  You can achieve this same result using something like a Zigbee, Z-Wave or Matter smart plug.  The end result is that you want to see real-time energy monitoring in Home Assistant:


As long as you can see the amps and/or watts from the smart plug, then you are good to move ahead.

Assure that any smart plug you select is rated to handle the amp load from your washer! A 15 amp rating on the smart plug is recommended.

However, if you are interested in flashing Tasmota or ESPHome to your smart plug, I have both a video and written article that provides step-by-step instructions for flashing the Sonoff S31:


Installation


Configure your smart plug or outlet per the manufacturer's or custom firmware's instructions.  This includes joining the device to your WiFi and completing any other setup or calibration processes.


The actual installation couldn't be any easier.  Unplug the washer from its current outlet, plug in the energy-monitoring smart plug and plug the washer into the smart plug.  That's it!

Home Assistant Integration


If your smart plug has a native Home Assistant integration, it should show up automatically as a newly discovered device.  If you are using Tasmota, you will need to first install the Tasmota integration.  Follow the device's documentation or the appropriate Home Assistant integration instructions for adding your device to Home Assistant.  Links to both the official Tasmota and ESPHome sites are listed at the end of this article.

When complete, you should see a switch and the associated energy readings in your Home Assistant entities.  You normally want the switch turned "ON" since the washer will not receive power and cannot be started when the switch is "OFF".  However, you can use the switch to cut power to the washer to stop 'phantom' power draw... which you'll see in my washer energy readings next.

If you want to change the name of any of the Home Assistant entities, now is the time to do so.

Home Assistant Automation


Before creating the actual automations in Home Assistant, you'll need to get some energy readings from the smart plug as the washer runs through its cycle.  These readings will be used to determine when the washer starts and completes.  In my case, I recorded the peak and minimum wattage values for the various stages of the cycle for three or four loads, then averaged these values:

You could substitute amps for watts if desired

For my washer, it draws 1 watt when idle. This is what I was mentioning as 'phantom' power draw.. this is probably a bit of power to keep the front control panel energized.  I could stop that draw by switching the smart plug off, but then it would have to be turned back on any time the wash needed to be done... leading to a low WAF... so I leave the smart plug in an on state at all times.

In my case, as soon as the washer starts its cycle, the power jump to 12 watts and doesn't drop below this value until the cycle is complete, where it returns to the starting value of 1 watt.  So I can use a value of 5 watts as the trigger for my automations.  Any time the power rises above 5 watts, the cycle has started and when it drops below 5 watts, the cycle is complete.

If in your case the soak cycle drops the power down to near or equal the idle power, then you need to determine the maximum time that the washer remains in the soak portion and include that in your automation trigger.  For example, if my washer dropped to 1 watt during the soak cycle, but the longest soak cycle was three minutes, then my trigger would look for the watts to drop below 1 watt for greater than three minutes (e.g. four or five minutes).  This will slightly delay the notification by that length of time... but it will still work.

With the trigger determined, the first automation that determines that the washer has started a cycle can be created.  I'll show both the YAML and a screen shot of the corresponding steps using the Home Assistant UI editor.  You can see the full YAML automation in a single file in this Github repository

MQTT vs. Input Text Helper

For my washer state, I'm using MQTT to publish and show the current state of the washer as "Washing" or "Idle" on a dashboard.  


This is also the trigger that is used for voice notifications.  However, you can use a simple text input helper in lieu of MQTT, and I'll show the use of this text helper in the examples here.  This requires the creation of a text input helper (mine will be called text_input.washer_state).  This can be done via YAML or via the UI editor.  If you want to see how I am using MQTT, see the Github repo of my full automation.  If you wish to skip both the MQTT and input_text helper options, you can simply move the voice notification actions under the 'washer complete' automation.

Washer Start Automation
Trigger

YAML
automation:
  # ===============================
  #  Washing Machine Start/Finish
  # ===============================
  - alias: 'Washer State - Start'
    trigger:
      platform: numeric_state
      entity_id: sensor.washer_watts
      above: 5

UI Editor



Any time the measured power from the smart plug rises above 5 watts, this automation will fire.

Conditions

YAML
    # Make sure washer isn't already running - don't re-trigger
    condition:
      condition: template
      value_template: "{{ not is_state(input_text.washer_state), 'Washing' }}"

UI Editor


The condition is optional.  I'm simply checking to see if the washer is already in running... or in a state of 'Washing'.  It if is, then the automation stops and the actions are not executed.

Actions

YAML
    action:
     - service: input_text.set_value
       target:
         entity_id: input_text.washer_state
       data:
         value: "Washing"    

UI Editor

All the action is doing here is setting the value of the text input helper so the status can be displayed on a dashboard.  But it will also serve as the trigger for the voice notification below.  

Washer Finished Automation
I'm only going to show the YAML here, because the automation is almost identical to the one above, except we are looking for the power to drop below 5 watts and are setting the text input helper to 'Idle'.

  - alias: 'Washer State - Idle'
    trigger:
      platform: numeric_state
      entity_id: sensor.washer_watts
      below: 5
      for:
        minutes: 1
    condition:
      condition: template
      value_template: "{{is_state(sensor.washer_state), 'Washing'}}"
    action:
     - service: input_text.set_value
       target:
         entity_id: input_text.washer_state
       data:
         value: "Idle"    

The finished automation trigger does add a 'time check' on the watts.  This is to assure the trigger doesn't fire if the watts just quickly dips below 5 but then rises again (meaning the cycle isn't really complete).  This is where you would adjust the 'for' clause if your washer enters a soak cycle that results in the power dropping below the threshold for a few minutes.  Just adjust the number of minutes accordingly.

The condition this time is just checking that the washer is currently in a cycle and the action is setting the text input helper value back to 'Idle'.

Voice Notification Automation

I opt to split my voice notifications out into their own automation so that I can 'snooze' or disable the voice notifications but still see the state of the washer on a dashboard.

  - alias: 'Washer Finished'
    trigger:
      platform: state
      entity_id: input_text.washer_state
      from: 'Washing'
      to: 'Idle'
    condition:
      - condition: state
        entity_id: input_boolean.notify_washer
        state: 'on'
    action:
      - service: tts.google_say
        entity_id:
          - media_player.all_home_devices
        data_template:
           message: "The washer has completed its cycle."

For my voice notification, I'm simply watching for the value of my input text helper to change from 'Washing' to 'Idle', indicating that the washer cycle is complete.  I'm adding a conditional check to see if voice notifications are enabled via an input boolean that can be toggled on the dashboard.  An announcement is made, in my case to a group of Google speakers, that the washer has finished.  You could substitute a push notification or other action for the voice notifications if desired.

If you want to know more about how I snooze and set a night mode "do-not-disturb" for all my voice notifications, I have two YouTube videos that cover it in detail:

Home Assistant 101: Managing Voice Notifications (older version that focus on YAML)

You can also review the full YAML for my washer, including the YAML that implements the snooze feature, in this Github repository.

Dryer Notifications


Background


Dryer notification can be a bit trickier for an electric dryer in the U.S. as you can't just use a simple smart plug since most operate off of 220 VAC.  There are many alternatives however.  You can use CT clamps to measure the amperage by placing one over one of the supply lines inside the dryer.  If you have a digital control panel, you can often find DC voltage inside and can key off of signals inside the panel.. such as a buzzer indicating the cycle end.  Both of these methods, however, usually require some sort of disassembly of the dryer... an option that may not have a high spouse approval factor!  In fact, my wife instructed me that she'd love to have dryer notifications, but I had to find a way to do it without any disassembly of the dryer.

Another common option is the use of a vibration sensor that can detect when the dryer is tumbling and when it stops.  This is a pretty easy option and there are a number of sensors that integrate natively into Home Assistant. 


In this case, the automations are very similar to the washer... watch for vibration to start to indicate the dryer has started and watch for the vibrations to stop to indicate the cycle is complete.  Unfortunately for me, my front loading washer causes so much vibration during its spin cycle, any sort of sensor on the dryer would be tripped every time the washer ran.

Fortunately, my dryer has indicator lights on the front panel that indicate the various stages of the cycle.


The sensing indicator lights up anytime the dryer is started and the cycle complete indicator lights whenever the dryer is finished.  I just needed to create sensor that could detect these lights and report back to Home Assistant.  Note that you could adapt this same process to any device that has indicator lights, like a dishwasher, to create automations based on the device state.

My first version used a standard photoresistor, connected to 3.3V and the analog pin on a Wemos D1 Mini to measure voltage changes due to variances in the photoresistor, based on the light level.  


The photoresistor was placed right on top of the LED indicator and this worked pretty well... for a while.  But over time, the resistance/voltage would drift over time, requiring constant changes to the automation triggers.  Eventually, the voltage range between 'light and no light' would become small enough that the automations were inconsistent as well.  Twice, I rebuilt the sensors using new components and the would return to 'normal' operation for 6 months or so.  I'm still unsure why this occurs. Photoresistors shouldn't lose sensitivity, but the analog pin on an ESP8266 can be flaky as well. I decided it was time to change to a different sensor and light detection method.  The remainder of this article describes the build and use of this new sensor.

Parts List


These are the parts I used, but you may need, or can choose, to substitute as your project requires. The quantities listed are to build two sensors... one for the start cycle sensor and one for the end cycle sensor.

QTY

Item

Notes

2

GY-302 BH1750 Illuminance Module

 

2

Wemos D1 Mini (ESP8266)

ESP32 could be used as well

1

Long MicroUSB cable

Long enough to reach from wall wort/power supply to splitter

1

USB Female to Male Spitter Cable

So 2 sensors can be powered from one USB cable

1

USB wall wort (or other 5V USB power source)

Any standard phone charger type AC adapter will work.

-

24 gauge stranded wire

22 gauge can also be used

 

Double-sided Gorilla tape

 

2

3D Printed enclosures

Thingiverse link to .stl files

 

 

 

Some of these links may be Amazon affiliate links.  Use of these links will not affect your pricing, but as an affiliate this channel may earn a small commission if you make a purchase.

The BH1750 Illuminance Sensor


Instead of a photoresistor, this updated version will use an illuminance sensor.

Top side on left... bottom side on right

The BH1750 is an IC with 16-bit resolution with an onboard illuminance to lux converter, meaning it can report lux values from 0 to 65,535. The one I am using is mounted on a GY-302 break-out board, which is pretty small in size.

The board is approx. 19.25mm x 14.4 mm

The board will operate on 3.3 VDC or 5 VDC (VCC) meaning you can use either the 5V pin or 3V3 pin on the ESP to power it.

It is also an I2C device, meaning I won't have to rely on the inconsistent analog pin or the ADC of the ESP8266.  It has a default I2C address of 0x23 when the ADDR pin is not connected or if connected to ground.  However, you can connect the ADDR pin to VCC to give it an address of 0x5C.  This means you could connect two of these devices to a single ESP8266 if desired. I opted to maintain two separate devices because it was easier for me to swap these out for the older two sensors.

Wiring and Bench Testing


My first step when using any new component is a basic bench test.  The wiring is very simple in this case.

Click to enlarge

VCC is connected to the 3V3 (3.3V) pin of the D1 Mini and ground is connected to ground.  The I2C clock (SCL) and data (SDA) pins are connected to pins D1 and D2 respectively, which are the I2C pins for the D1 Mini.  If you really want to use an ESP32, you would just use the I2C pins on the ESP32, which are GPIO22 (SCL) and GPIO21 (SDA) by default.  
The D1 Mini will be powered via USB.


I simply created this circuit on a breadboard.  I also created a separately powered LED that was button operated so I could simulate the dryer's indicators.  But to test this, I first had to put some basic test ESPHome code on the D1 Mini.  

I just added the following to a new standard ESPHome node:

i2c:
  scan: true

sensor:
  - platform: bh1750
    name: "BH1750 Bench Test"
    id: "BH1750_test"
    internal: true
    address: 0x23
    update_interval: 1s

I did not initially integrate this into Home Assistant when prompted, as I knew I was going to make additional changes.  For the bench test, I could use the ESPHome logs to see the sensor lux values.  For the test, I have the sensor taking a reading once per second.

Click to enlarge

When just exposed to some ambient light, the sensor consistently reported around 39-40 lux and was stable.  When I covered the sensor with my hand, lux dropped to near zero and when exposed to the LED, the lux jumped to over 2,000 lux.  Definitely a broad enough range to use for automations!  I'll cover the full ESPHome code I used for the final sensor below.

Enclosure and Assembly


With a successful bench test, I had to come up with an enclosure to hold the GY-302 board, the D1 Mini and the wiring.  I wanted to try to keep the size of the enclosure about the same as before (to assist with the WAF).


I ended up with the same basic "box" excepted I had to increase the size of the sensor area so that I could slot the GY-302 board into an opening where the BH1750 sensor would align with a hole on the bottom.  This will be placed directly over the dryer LED sensor... just like with the previous photoresistor version.


Using very short runs of 24 gauge stranded wire, the four connections from the GY-302 to the D1 Mini were made per the wiring diagram above by using the through holes on both boards.


The GY-302 was 'slotted' into place and the D1 Mini simply sits on top with the microUSB port opposite the sensor.

Original version on top - New version on bottom

Other than the expanded area for the GY-302 board, the base footprint is the same as the original.  In fact, I was able to reuse the lids from the old sensors for the new sensors.

Of course, I needed separate sensors for both the start and end cycle indicators so I had to repeat the above process for the second sensor.

Dryer start cycle and end cycle sensors

I repeated the bench testing for both sensors.  The good news that when in the enclosure and placed face down (as in the above photo) under normal ambient lighting conditions, both sensors reported a lux value of 0.  But exposure to my test LED still resulted in lux values well in excess of 1,000.  This means that turning the lights on or off in the laundry room won't have an impact on any automations or cause false triggers.

With the physical build complete and ready for installation, it was time to move on to creating the final ESPHome code and the Home Assistant automations.

ESPHome Code


While it would have been entirely possible to just use the test code and the lux values from the sensor as triggers for Home Assistant automations (basically in the same manner as voltage was used from the old photoresistor version), I opted to 'fancy-up' my ESPHome a bit.  Instead of using the raw lux value, I create a binary sensor that is either 'on' or 'off' depending upon whether the measured lux value is above or below a threshold value, which I can set via the Home Assistant front end via an input number helper.

Here are the pertinent sections of my ESPHome code for the dryer cycle start sensor.  I'll describe each section below:

i2c:
  scan: true   #include I2C and scan for device

# Virtual Binary Sensor based on Illuminance above/below threshold
binary_sensor:
  - platform: template
    name: "Dryer Start Cycle Indicator"
    id: start_cycle_light
    device_class: light

This is the virtual binary sensor that will indicate if the measured lux is above or below a threshold value.

sensor:
# Import Home Assistant Input Number Threshold
  - platform: homeassistant
    name: "Dryer Start Cycle Threshold"
    id: "start_threshold"
    entity_id: input_number.dryer_start_cycle_threshold

The first sensor is an input number helper imported from Home Assistant.  This is used to set the threshold lux value that will determine if the binary sensor is off/on.

  - platform: bh1750
    name: "Dryer Start Cycle Illuminance"
    id: "BH1750_start_lx"
    address: 0x23
    internal: true    #optional
    update_interval: 5s
    filters:
      - lambda: !lambda |-
          if (x <= id(start_threshold).state ) {
            if (id(start_cycle_light).state == false) {
              //Light is already off
              return x;
            }
            //Light from on to off
            id(start_cycle_light).publish_state(false);
            return x;
          } else {
            if (id(start_cycle_light).state == true) {
            //Light is already on
            return x;
            }
            id(start_cycle_light).publish_state(true);
            return x;
          }

The next sensor is the BH1750 illuminance sensor.  The internal flag is optional, but if included and set to 'true', the lux values will not be reported to Home Assistant.  They are not needed since the automations will be based on the state of the binary sensor.  But if you wish to include lux values in Home Assistant, you can remove this line.  If you do, you may also want to exclude this entity from your Home Assistant recorder, since it is going to report a value every 5 seconds.  Tracking history of the lux sensor is probably not meaningful since it will be either a consistent low value when the dryer is stopped and briefly at a high value when the associated indicator is on.  But that's ultimately your decision.

The lambda filter for this sensor takes the current reading (x) and determines if it is above or below the threshold value and sets the binary sensor to true (on) or false (off) as appropriate.  The binary sensor is only updated if the threshold is crossed.

My full YAML, which you can find in this Github repository, also contains a last boot sensor and a restart/reboot button.  I include those in all my ESPHome devices, so they really aren't pertinent to this particular project.

The dryer cycle complete ESPHome code is identical, except that the entity names and IDs are changed from "start" to "end"... e.g. "Dryer End Cycle Indicator".

Once the updated ESPHome code has been uploaded or flashed to the sensor, it can be integrated into Home Assistant from the Devices and Integrations page.  If you haven't yet adopted it, you'll likely receive a notification in Home Assistant that a new device has been discovered.

Home Assistant Entities


As described under the ESPHome section above, two input number helpers are required to set the threshold values.  These can be created via YAML or the Helper UI:

YAML
input_number:
  #Threshold values for illuminance sensor (BH1750)
  dryer_start_cycle_threshold:
    min: 0
    max: 1000
    step: 10
    
  dryer_end_cycle_threshold:
    min: 0
    max: 1000
    step: 10

UI Editor
Repeat for the End Cycle Threshold



In this Home Assistant dashboard mock-up, you can see all the entities created from the two sensors:

Click to enlarge

The end cycle indicator (binary sensor) is on because the measured lux of the end cycle sensor (2,090) is above the threshold of 200.   Similarly, the start cycle indicator is off because its measured lux (0) is below its threshold.  For this example, I removed the 'internal' flag on the ESPHome BH1750 sensor so that I could display the lux values. The end cycle light indicates the dryer has finished its cycle, shown as the current state.  The state setting is handled via automation, which is what I'll cover next.  But there is one more entity that needs to be creating if you are not using MQTT.

In my full example (which you can find in the Github repository), I'm using MQTT to set and get the state of the dryer... much like I do for the washer.  But if you are not using MQTT or prefer not to use it for these automations, you can substitute a simple text input helper to hold the current state value.  But you must manually create this input text helper via YAML or the UI editor:

YAML
input_text:
  dryer_state

UI Editor


I'll use this input text helper in my automation examples below, but if you want to see the MQTT version, see the Github link above.

In my case, I also need a timer helper due to a particular quirk in how my dryer indicates stages.  I'll describe that below, but for now, here is the YAML to create that timer via YAML and the UI helper:

YAML
timer:
  dryer_cycle:

UI Editor


I'm not specifying a default time for the timer, as I'll do that in the automations.

Home Assistant Automations


The automations are actually pretty basic and very similar to the washer automations except the states of the two binary sensor indicators are used as triggers instead of a wattage value.  But there are a couple small caveats that must be accounted for in my case.


As you can see above, the 'Sensing' indicator, where the start cycle sensor will be placed, always illuminates any time the dryer starts.  And the 'Cycle Complete' indicator, where the end cycle sensor will be placed, illuminates whenever the dryer completes.  In between these events, a number of other indicator lights illuminate.  This means there is a period during the cycle when neither of the start or end cycle indicators are lit.  If the cycle is stopped before completion (e.g. clothes are removed during the 'cool down' period), then the cycle end indicator will never light up and the dryer will be left in a state of 'Drying'.  This is why I need the timer helper and you'll see how that is used in the automations.

If the dryer does complete the cycle, the end cycle indicator remains on until the dryer door is opened, at which point it turns off.  This event will also be used to set the dryer state back to 'Idle'.

I'm only going to show the YAML here, but you could easily use the UI editor to create the same triggers, conditions and actions.  If you need some pointers on how to do this, you can use the washer automations above as and example or you can watch the following YouTube video: Recreate a YAML automation using the UI Automation Editor

# -------------------
#  AUTOMATIONS
# -------------------
automation: 
  # Dryer Start Cycle
  - alias: "Dryer Start"
    trigger: 
      platform: state
      entity_id: binary_sensor.dryer_cycle_start_indicator
      from: 'off'
      to: 'on'
    condition:
      condition: template
      value_template: "{{not is_state('sensor.dryer_state', 'Drying')}}"
    action:
      - service: input_text.set_value
        target:
          entity_id: input_text.dryer_state
        data:
          value: "Drying"    
     # Start 1 hour timer in case cycle stopped before complete
      - service: timer.start
        data:
          entity_id: timer.dryer_cycle
          duration: '01:00:00'

The automation is triggered when the start cycle binary sensor goes from a state of off to on, which means that the LED indicator light on the dryer has lit up.

I add a condition to check that the state of the dryer isn't already "Drying".  This really shouldn't happen, so the condition could probably be eliminated but it doesn't hurt to have it as a double-check.

For the actions, I'm setting the value (state) of the input text helper to 'Drying' (when using MQTT, I'm publishing a message with a payload of 'Drying').  I am then starting that timer and giving it a duration of one hour.  One hour is longer than any normal dryer cycle and if the timer expires, it likely means someone manually stopped the dryer before the cycle completed.  I'll handle that case in another automation.

  # Dryer End Cycle
  - alias: "Dryer Finished"
    trigger:
      platform: state
      entity_id: binary_sensor.dryer_cycle_end_indicator
      from: "off"
      to: "on"
    condition:
      condition: template
      value_template: "{{is_state('sensor.dryer_state', 'Drying') }}"
    action:
      - service: input_text.set_value
        target:
          entity_id: input_text.dryer_state
        data:
          value: "Finished"    

For the end of the cycle, the end cycle indicator switches from off to on which serves as the trigger.  The condition checks that the dryer currently has a state of drying (probably not needed) then sets the text input dryer state value to 'Finished'.  Recall that the indicator light will remain on in my case until the dryer door is opened.

I could include additional services under the actions, such as voice or other notifications here if desired.  But as described under the washer automations, I like to split out my voice notifications so that they can be snoozed or set to a nighttime 'do-not-disturb' mode.  I'll show my notification automation after I finish up the dryer state automations.

  - alias: "Dryer Idle"
    # Default to Idle status if neither indicator on
    # and state <> drying. This would normally fire when the
    # dryer door is opened after the cycle is complete and the 
    # cycle complete indicator turns off.
    trigger: 
      platform: state
      entity_id: binary_sensor.dryer_cycle_end_indicator
      from: "on"
      to: "off"
    condition:
      - condition: state
        entity_id: binary_sensor.dryer_cycle_start_indicator
        state: "off"
      - condition: template
        value_template: "{{not is_state('sensor.dryer_state', 'Drying')}}"
    action:
      - service: input_text.set_value
        target:
          entity_id: input_text.dryer_state
        data:
          value: "Idle"    

This automation would normally fire after the cycle is complete and the dryer door is opened, causing the end cycle indicator to turn off.  It checks a couple of conditions to assure the start indicator isn't on (which might be the case if the cycle was just restarted without removing the load) and that the dryer isn't already in a drying state (basically redundant... but it's possible that the start light is only on briefly if a cycle restarts, so this provides a double-check).

Then it just sets the dryer status to 'Idle' where it will remain until the dryer is restarted at some later point.

There is one final situation to account for... and that's if the dryer cycle is manually stopped before it completes.  This is where that timer comes into play.

  - alias: "Dryer Cycle Time Expired"
    # If manually stopped, reset status to Idle after max time
    trigger:
      - platform: event
        event_type: timer.finished
        event_data:
          entity_id: timer.dryer_cycle
    action:
      - service: input_text.set_value
        target:
          entity_id: input_text.dryer_state
        data:
          value: "Idle"    

In this case, the timer (which I set to one hour in dryer start cycle automation) has expired.  Since this is longer than any normal dryer cycle, it just sets the dryer state back to 'Idle'.

Voice Notifications

As mentioned, you could include any type of desired notification(s) under the dryer complete automation above.  Personally, I like to spilt mine out so that I can snooze or silence voice notifications without affecting the state or status of the dryer.  Also note that you aren't limited to voice notifications.  You could substitute actions to send a push notification to a phone, turn on a light, etc. either in this automation or under the dryer complete automation.  I'll just show my basic voice notification:

  - alias: "Dryer Announce"
    trigger:
      platform: state
      entity_id: text_input.dryer_state   
      from: 'Drying'
      to: 'Finished'
    condition:
      # Check that voice notification isn't snoozed or in night mode
      - condition: state
        entity_id: input_boolean.notify_dryer
        state: 'on'
    action:
      - service: tts.google_say
        entity_id:
          - media_player.all_home_devices
        data_template:
           message: "Your clothes are dry. Whoop! whoop!"

For the notification, I'm simply watching the state (input text helper above... or the MQTT topic if using MQTT) for it to change from 'Drying' to 'Finished'.  I then check an input boolean to be sure my voice notifications are enabled and then send a message to a media player group.  In my case, this group is a number of Google speakers spread throughout the house (and even in the garage) so the notification can be heard regardless of where you might be in the house.  Score major WAF points!

Final Installation, Results and Thoughts


Installation was just like the previous sensors.


Double-sided Gorilla tape was affixed to the flat bottom of the sensor, leaving an opening for the actual sensor.


The sensors were then attached to the front of the dryer's panel, centering the opening for the sensor directly over the LED indicator light.  This did take me a try or two to get it in exactly the right place to get maximum lux value as it was a bit more difficult than the photoresistor version due to the larger enclosure section that goes over the LED.

But at least for the first couple of months of use, the system has worked perfectly.  And even though I haven't had to use them yet (the lux readings between "on" and "off" have been very consistent), I like having the thresholds adjustments that I can use to tweak the light values between on/off without reflashing the D1 Mini with updated ESPHome code or changing any automations.  Only time will tell if these hold up better/longer than the photoresistor version, but I suspect they will.

It isn't the most attractive final install... but the trade-off for dryer notifications gets an acceptable Wife Approval Factor.  If I had been permitted to open up the control panel, I'm sure there is DC voltage present for the panel that I could have used not only to power an ESP, but likely could have used the circuitry to either the LEDs or the buzzer to create a sensor that would have been completely invisible.  And since the panel cover is plastic instead of metal, WiFi reception would have probably been OK too.  But alas.. that wasn't an option.

I also really like the BH1750 illuminance sensor.  I will definitely consider this for any future projects where I need to know light level as opposed to using a photoresistor and the not-so-reliable analog/ADC pin on the ESP.

As always, thanks for reading and let me know in the comments if you have any questions or additional thoughts.

Links and Additional Information



While I enjoy creating and sharing new projects, the process of making videos, writing blog articles and creating Github repositories is a time-consuming endeavor. 

If you'd like to support future content on this blog and the related YouTube channel, or just say thanks for something that helped you out, you can add your support by buying me a one-off cup of coffee at:

No comments:

Post a Comment

To help eliminate spam and to keep all conversations civil, submitted comments are moderated. Therefore your post may not show up immediately. Please be patient as most reviews are completed within a few hours.