🧽 Detect and monitor the status of an appliance based on its power consumption - Updated V1.0.1

Important notice! :rotating_light:

:new: The code has been updated

  1. Version 1.0.1 of 05/16/2022 - [FIX!] Fixes the error of the ‘idle’ state which was not working correctly. :man_facepalming:

The entire post was updated, you are going to get the latest version.

Note: If you are installing the blueprint for the first time, you can discard this message.
More details at the end of the post.


Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

This is my simple automation to control the most power-hungry appliances in my house. I use this for my dishwasher and washing machine.

So far the results have been great! And my family :heart: it. I hope you’ll find this useful as well.

:clipboard: Features

I took inspiration from this automation here and decided to make my version of it.

This is what’s different:

  • Set your own custom actions for each of the following states:
    • On Start
    • On Finish
    • On Resume After Overload
    • On Powered Again After Overload
  • The appliance has its own State Machine
    • You can tell if it’s in one of the following states:
      • unplugged
      • idle
      • paused
      • job_ongoing
      • job_completed
    • Note: Each state transition is handled automatically, you just have to provide the initial configuration!
  • More triggers: more control, even after Home Assistant reboots
    • This automation is set to run on each power read, the starting/finishing thresholds comparison is done in the actions section. This allows more granular control over what’s happening. There might be a better way of doing this. If you know one, feel free to share it!
  • Faster machine start-finish detection: one of the problems that I always face is timing. What if you want to measure how long it took for your appliance to complete its job? The automation has to be very reactive. This logic should solve that problem for you.

:ballot_box_with_check: What is needed to run this:

Premise

Please consider that this blueprint is shared “as it is”, and even it fits my use case, it might not be the same for you.

To achieve this level of control, the socket has to have some basic features, like:

  • power monitoring (polling rate of a maximum of 60 sec for best results)
  • ON/OFF control over HASSIO
  • status reporting

Mine is a Meross MSS310EU.

To get the pause state to work properly, you also need another automation that can detect an overload. I’m not the author of that automation (which you can find here).
I have not tested my blueprint without this value, so can’t tell you if it would still work without it.

1. The State Machine entries (input_select)

You need to create the input_select for our appliance.
To do that, head over to configuration.yaml and edit it by creating this:

input_select:
  <your_appliance_name>_state_machine:
    name: <Your Appliance Name> - State Machine
    options:
      - unplugged
      - idle
      - paused
      - job_ongoing
      - job_completed
    icon: mdi:<your_appliance_icon>

Please make sure to edit <your_appliance_name>, <Your Appliance Name> and <your_appliance_icon> accordingly.

For example, my appliance is a washing machine, so I’ll do the following:

<your_appliance_name> = washing_machine
<Your Appliance Name> = Washing Machine
<your_appliance_icon> = washing-machine (taken from here https://materialdesignicons.com/)

The result:

input_select:
  washing_machine_state_machine:
    name: Washing Machine - State Machine
    options:
      - unplugged
      - idle
      - paused
      - job_ongoing
      - job_completed
    icon: mdi:washing-machine

2. The Job Cycle indicator (input_boolean)

input_boolean:
  <your_appliance_name>_job_cycle:
    name: <Your Appliance Name> - Job Cycle
    icon: mdi:<your_appliance_icon>

Please make sure to edit <your_appliance_name>, <Your Appliance Name> and <your_appliance_icon> accordingly. The variables are the same as before.

Congratulations! Your appliance is now smarter :brain:

Okay, done… but now, please reboot Home Assistant (at this page → Verify & if okay, Reboot)

  1. Add the automation blueprint to your Home Assistant Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.
  2. Create a new automation from that blueprint
  3. Configure the variables as indicated inside of the blueprint’s UI

You should now see that there is a new pair of entities:

Have fun!


Important notice! :rotating_light:

:new: The code has been updated

  1. Version 1.0.1 of 05/16/2022 - [FIX!] Fixes the error of the ‘idle’ state which was not working correctly. :man_facepalming:

    If you are installing the blueprint for the first time, you can discard the update procedure.

    To update:

    • open this page Open your Home Assistant instance and show your blueprints. (just click the link, it’s magical) and scroll till you find “Monitor the status of an appliance - by leofabri”. Delete it by clicking on the thrash bin :wastebasket:. Don’t worry, we’ll add it right back in a few sec, you can leave the automation as it is.
    • add the blueprint again Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled. and reload home assistant.

The code (V1.0.1 - latest):

# Earlier -> initial release.
# Update of 05/16/2022 - V1.0.1 -> Fixed 'idle' state not entering

blueprint:
  name: Monitor the status of an appliance - by leofabri
  description: 'This automation helps you to keep an eye on the status of an appliance
    such as a dishwasher, a washing machine, etc.<br> By using this, you''ll be able
    to tell if an appliance is performing a job (job_ongoing state) or if it''s done
    (job_completed state).

    It also incorporates a simple state machine that allows Home Assistant to know
    if the appliance had a pending job that was suspended because it caused a power
    overload on the line.'
  domain: automation
  input:
    appliance_socket:
      name: Smart appliance socket
      description: 'The socket is used to control this appliance.

        To exercise this level of control, the socket has to have some basic features,
        like power monitoring (polling rate of a maximum of 60 sec for best results),
        ON/OFF control over HASSIO, and status reporting. Mine is a Meross MSS310EU.'
      default: []
      selector:
        entity:
          domain: switch
          # multiple: false
    appliance_power_sensor:
      name: Power Sensor
      description: The power entity can tell how much power is currently being absorbed
        by the appliance.
      default: []
      selector:
        entity:
          domain: sensor
          # multiple: false
    appliance_job_cycle:
      name: Appliance Job Cycle
      description: 'A sensor that stores whether the appliance is still in a job cycle
        or not.<br> The Job Cycle variable will be able to tell if the machine has
        gone through the entire process (like washing the dishes) or if it''s still
        incomplete.

        This variable has to be a boolean (so: 0 or 1).<br> 0 -> The appliance is
        not performing any job, it has completed the previous one<br> 1 -> The appliance
        has a job ongoing that has not been completed yet. It might also mean that
        the appliance is in the pause state, which would still indicate that the job
        is not over yet.<br>

        <strong>Note that this entity does not provide any information about the status
        of the machine (ex. overload status). For that, you need the state machine.</strong>
        <br>      '
      default: []
      selector:
        entity:
          domain: input_boolean
          # multiple: false
    appliance_state_machine:
      name: Appliance States Sensor - State Machine
      description: 'An entity like: input_select.your_appliance_name_state_machine.

        <strong>Note that those options are mandatory! Do not change them.</strong>'
      default: []
      selector:
        entity:
          domain: input_select
          # multiple: false
    appliance_suspended_sensor:
      name: Appliance suspended sensor
      description: An input_number variable that turns into a value > 0.0. That would
        mean that the appliance was disconnected because of an overload situation.
      default: []
      selector:
        entity:
          domain: input_number
          # multiple: false
    appliance_starting_power_threshold:
      name: Starting power threshold
      description: Power threshold above which we assume the appliance has started
        a job (job_ongoing state).
      default: 5
      selector:
        number:
          min: 1.0
          max: 100.0
          unit_of_measurement: W
          mode: slider
          step: 1.0
    appliance_fiishing_power_threshold:
      name: Finishing power threshold
      description: Power threshold below which we assume the appliance has finished
        a job (job_completed state).
      default: 3
      selector:
        number:
          min: 1.0
          max: 100.0
          unit_of_measurement: W
          mode: slider
          step: 1.0
    actions_unplugged_overload:
      name: Action(s) on overload
      description: Executed when the appliance was unplugged because of an overload
        situation.
      default: []
      selector:
        action: {}
    actions_powered_again_after_overload:
      name: Action(s) on overload solved, now idle (but not resuming the job).
      description: Executed when the appliance was unplugged because of an overload
        and now it's idle but NOT resuming the job yet.
      default: []
      selector:
        action: {}
    actions_resuming_after_overload:
      name: Action(s) when the overload is solved, now resuming
      description: Executed when the appliance was unplugged because of an overload
        and it IS now resuming the previous job.
      default: []
      selector:
        action: {}
    actions_on:
      name: Action(s) when starting
      description: Executed when the appliance starts a new job/cycle (job_ongoing
        state).
      default: []
      selector:
        action: {}
    actions_off:
      name: Action(s) when finishing
      description: Executed when the appliance finishes a job/cycle (job_completed
        state).
      default: []
      selector:
        action: {}
  source_url: https://github.com/leofabri/hassio_appliance-status-monitor/blob/main/appliance-status-monitor.yaml
variables:
  appliance_socket: !input 'appliance_socket'
  appliance_suspended_sensor: !input 'appliance_suspended_sensor'
trigger:
- platform: state
  entity_id: !input 'appliance_power_sensor'
  id: power_event
- platform: state
  entity_id: !input 'appliance_socket'
  id: socket_state_change_event
- platform: state
  entity_id: !input 'appliance_state_machine'
  from: paused
  to: idle
  id: powered_again_after_overload_event
- platform: state
  entity_id: !input 'appliance_state_machine'
  from: paused
  to: job_ongoing
  id: resuming_after_overload_event
condition:
- condition: or
  conditions:
  - condition: trigger
    id: power_event
  - condition: trigger
    id: socket_state_change_event
  - condition: trigger
    id: powered_again_after_overload_event
  - condition: trigger
    id: resuming_after_overload_event
action:
- choose:
  - conditions:
    - condition: template
      value_template: '{{ states(appliance_suspended_sensor) | float > 0.0 }}'
    sequence:
    - condition: not
      conditions:
      - condition: state
        entity_id: !input 'appliance_state_machine'
        state: paused
    - service: input_select.select_option
      data:
        option: paused
      target:
        entity_id: !input 'appliance_state_machine'
    - choose: []
      default: !input 'actions_unplugged_overload'
  - conditions:
    - condition: template
      value_template: '{{ states(appliance_socket) == ''off'' }}'
    - condition: not
      conditions:
      - condition: state
        entity_id: !input 'appliance_state_machine'
        state: unplugged
      - condition: template
        value_template: '{{ states(appliance_suspended_sensor) | float > 0.0 }}'
      - condition: state
        entity_id: !input 'appliance_state_machine'
        state: paused
    sequence:
    - service: input_select.select_option
      data:
        option: unplugged
      target:
        entity_id: !input 'appliance_state_machine'
  - conditions:
    - condition: trigger
      id: powered_again_after_overload_event
    sequence:
    - choose: []
      default: !input 'actions_powered_again_after_overload'
  - conditions:
    - condition: trigger
      id: resuming_after_overload_event
    sequence:
    - choose: []
      default: !input 'actions_resuming_after_overload'
  default:
  - choose:
    - conditions:
      - condition: or
        conditions:
        - condition: state
          entity_id: !input 'appliance_job_cycle'
          state: 'off'
        - condition: state
          entity_id: !input 'appliance_state_machine'
          state: paused
      - condition: numeric_state
        entity_id: !input 'appliance_power_sensor'
        above: !input 'appliance_starting_power_threshold'
      sequence:
      - service: input_boolean.turn_on
        data: {}
        target:
          entity_id: !input 'appliance_job_cycle'
      - service: input_select.select_option
        data:
          option: job_ongoing
        target:
          entity_id: !input 'appliance_state_machine'
      - choose: []
        default: !input 'actions_on'
    - conditions:
      - condition: state
        entity_id: !input 'appliance_job_cycle'
        state: 'on'
      - condition: numeric_state
        entity_id: !input 'appliance_power_sensor'
        below: !input 'appliance_fiishing_power_threshold'
      - condition: not
        conditions:
        - condition: state
          entity_id: !input 'appliance_state_machine'
          state: paused
      sequence:
      - service: input_boolean.turn_off
        data: {}
        target:
          entity_id: !input 'appliance_job_cycle'
      - service: input_select.select_option
        data:
          option: job_completed
        target:
          entity_id: !input 'appliance_state_machine'
      - choose: []
        default: !input 'actions_off'
    default:
      choose:
      - conditions:
        - condition: state
          entity_id: !input 'appliance_job_cycle'
          state: 'off'
        - condition: not
          conditions:
          - condition: state
            entity_id: !input 'appliance_state_machine'
            state: idle
        sequence:
        - service: input_select.select_option
          data:
            option: idle
          target:
            entity_id: !input 'appliance_state_machine'
mode: single
max_exceeded: silent

The code of this blueprint is also available on my GitHub.

2 Likes

Hey, I pushed an update because I noticed a problem with the ‘idle’ state.
You’ll find more details above.

Version 1.0.1 of 05/16/2022 - [FIX!] Fixes the error of the ‘idle’ state which was not working correctly.

This is a minor change. Just delete the old blueprint and import it again, your existing automation will still work.