Vibration sensor sw-420 detection

Well, I’m having some complex situation with the SW-420 sensor. I’m trying to use 2 of these to detect my washing machine as well as dryer machine. The trouble I’m having is that when the sensor vibrates it can change from off to on or the opposite and then it will stay on that situation until the next vibration. This brings me to the situation that at the end of the laundry the sensor could end at the on position and will stay on the on position forever (or until the next cycle).

I’m unsure how should I implement this sensor. I was thinking about setting a global var and then use the on_value: of the sensor to set the global var to 1 (vibration detected) then maybe use a timer to reset the global if no other vibration has been detected in the last x minutes ?? It seems to me a very complex way of implementing the vibration sensor.

How should I properly implement the sensor so that I get ‘on’ state if it has detected vibration in the last x min and state ‘off’ if no vibration has been detected ?? Keep in mind that the sensor could be on position ‘on’ and become ‘off’ after a vibration, or that it was ‘off’ and then become ‘on’ and will stay ‘on’ because there are no other vibrations.

I feel I’m doing something wrong. Please advice. I have a good programming background (C#) but low/medium YAML knowledge.

Thanks a lot.

I think you are on the right track. With this sensor it would be best to say the sensor is on if you detect a vibration (off to on or on to off) in X minutes, and the sensor if off if it doesn’t detect a toggle after X minutes. I use NodeRed for my dyer cycle and a xiaomi vibration sensor. I just use a power monitoring plug for the washer. NodeRed will listen for an event, which would be the dryer vibration, and the dryer is on if there are vibration in X minutes, but after x minutes with no vibrations the dryer if off, and time to send a notification. Hoe this helps.

1 Like

So this is the current code I have, currently testing

#Timer
script:
  id: my_timer
  then:
  - delay: 5min
  - globals.set:
      id: washer_working
      value: '0'

#Global var
globals:
   - id: washer_working
     type: int
     restore_value: no
     initial_value: '0'

#Main sensor used in HA
text_sensor:
  - platform: template
    name: "Washing machine"
    lambda: |-
         if (id(washer_working) > 0){
           return {"running"};
         }else{
           return {"idle"};
         }

# Vibration sensors
binary_sensor:
  - platform: gpio
    pin: D5
    name: "Washing machine Vibration"
    id: washer_vibration
    device_class: vibration
    on_state:
      then:
      - globals.set:
          id: washer_working
          value: '1'
      - script.stop: my_timer
      - script.execute: my_timer

Don’t know if this helps, I just spotted it https://github.com/rmooreID/Home-Assistant-Appliance-Monitor/

1 Like

@nickrout
That’s the guide I used when I setuped my system originally. The creator even uses delay_on and off to limit the false positives, yet it doesn’t solve the main problem. If you vibrate the sensor it could happen that at the end of that vibration it stays ‘on’. The solution you posted would work most of the time, yet ‘most’ it’s not good enought. So I’m seeking a better solution and posting it here for other people with the same trouble who would search these forums.

Alright I have been thinking about this a lot, because without out using something like NodeRed or AppDeamon, this isn’t easy to do. This hasn’t been tested but is a working theory. If you were to use delayed_on_off this will send an ON or OFF value if the binary sensor has stayed in the same state for a specified period time. Now we do not care if it send ON or OFF, just the fact that is sends something, because if we give a big enough delay, this would most likely state that the dryer is done. So, for the Homeassistant side you would need an automation that would fire from both conditions, so something like this:

automation:
  trigger:
    - platform: state
      entity_id: binary_sensor.xxxxxxx
      from: "ON"
      to: "OFF"
    - platform: state
      entity_id: binary_sensor.xxxxxxx
      from: "OFF"
      to: "ON"
action:

We do not care about “ON” or “OFF” we just care about it no longer toggling, because that means the job is done. You can then add in your action to do whatever, most likely a notification. The theory of this seems to work, but it will need to be tested.

TinyDot the use of delayed_on_off is very interesting, I should test it, but I think (upon reading documentation) that it will work to signal the end of the cycle, at least for the dryer that has a more constant vibration than the washer. The downside is I would not be able to check when the dryer begun as well as the duration, but at least the alert will work well I think.

I have another problem, my washer is silent and doesn’t vibrate hard enough, the vibration sensor doesn’t detect most of the movements, even if I settled it on very sensitive. Also the washer does long pauses while doing the laundry.

In the end I’m thinking about abandoning it altogether. I understand better the people who use photosensitive sensors to check their washers, it will be more effective, but I wanted to mount the Wemos on the back of the washer/dryer to make it invisible, a photo resistor on the front will defeat this purpose :frowning:

I will rethink how to properly check the system. I’m thinking about opening the washer/dryer and internally wiring signal relays to check if the leds have power (not sure how to wire it)

@DrakeColdwinter, you can determine the start cycle with delayed_on and/or delayed_off. Moving on from that you have several options, here. On the washer you could plug the washer into a plug that has energy monitoring, and when the amps go above x the washer is on and when the washer goes below x the washer is done. This would be the easiest option. Next you could you could use a Hall Effect senor or a CT clamp. Have a look at these:

There are more out there, but I think these will get the ideas flowing for you.

1 Like

I know this is an old thread, but I want to share my solution, in case anyone finds this by searching.

I used the config posted by @DrakeColdwinter as a starting point, and added a way to measure the intensity of the vibration. This lets you look for a certain signature in your automation. In my config, I look for high intensity vibration for >1 minute so I know the spin cycle of the washing machine is running.

The intensity measurement works by adding 1 to a counter any time a vibration is measured, and a background script will periodically divide the counter by 2. The purpose of the division (rather than simply resetting the counter) is to make the measurement more smooth.

binary_sensor:
  - platform: gpio
    pin: GPIOXX
    name: "Washer Vibration"
    id: washer_vibration
    device_class: vibration
    internal: true
    on_state:
      then:
      - lambda: |-
          (id(washer_working)) += 1;
      - script.execute: washer_working_timer

sensor:
  - platform: template
    name: "Washer Vibration Intensity"
    id : washer_vibration_intensity
    lambda: |-
         return id(washer_working);

script:
  id: washer_working_timer
  then:
  - while:
      condition:
        lambda: |-
          return id(washer_working) > 0;
      then:
      - delay: 1sec
      - lambda: |-
          (id(washer_working))/=2;
      - component.update: washer_vibration_intensity

I abandoned the vibration sensors and pivoted to using CT clamps and measuring the electricity usage of both machines (washing and dryer) it works very well. I never managed to make the vibration work well :frowning:

My ESP01 / SW-420 vibration sensor for my clothes dryer has been in place just over 2 years and hasn’t missed a beat.

For my washing maching I went down the energy-monitoring path with an existing library blueprint, as with soak and fill cycles this proved much easier. Has also been in place over 2 years, trouble-free.