Air refreshener ESPHome/Wi-Fi controlled

Very interesting… How do you monitor flushing the toilet? What kind of sensor do you use…?

Currently it is not installed but I think an aqara door and window sensor should to the job.
The sensor will be opened, two reeds installed in parallel instead of one. The magnets will be attached at the toilet button plate.
I do not know how it works at your home, ours look like that:

O.K. You have build-in wall system… In my case all is ceramic and outside (old fashioned type)…

Very interesting. My region only have this version of the Glade and I have search the net to find one post that said it is not possible to quite challenging to to be smart. I used a relay to intercept the power. Where it turns on for a 10 seconds, spray and shut off. Works great, but it still uses the battery.

I would imagine my unit version would still work with your setup since it does have a motor? The little issue I would run into is that the unit is quite small and I will need to mount everything outside.

I think it should be possible.
Not sure which motor is used (could also be 1.5V).
First you should measure the voltage on the motor when spraying.
DRV8833 can operate with 3-10V.

I’ve found the post. The shell is different but the internal looks the same down the the pc board. The post said the motor to be 2.5v.

Hey there,
alternative approach: I’ve hacked an Air Wick Freshmatic. The 3D printed cover houses the ESP, which switches the device on and off by acting as a AA battery. The device releases one spray 15 seconds after the power was connected. Assuming this delay is acceptable to you the electrical solution and further HA automation is rather simple. Works perfectly in two bathrooms for the last two years. :slight_smile:

Happy to share details and code.

2 Likes

Very clean setup. For this particular Air Wick model without converting it to smart, how does it activate?

For my model, it spray once motion is detected AND every 30 minutes( something like that) throughout the day whether it detects motion or not. Marketing scheme to make you constantly buy the refills.

This particular model sprays 15 seconds after activated, then every 30min or so. This initial spray is what made this clean setup possible. From Home Assistant I simply turn the device on when no one is in the room and turn it off some time after. If you ignore the 15 seconds you could say I have direct control of it spraying.

Here’s a simplified copy of my rules.

On:

  - trigger:
      - platform: state
        entity_id: binary_sensor.bathroom_door
        to: "off"
        for:
          seconds: 5
    condition:
      - condition: state
        entity_id: light.bathroom
        state: "off"
    action:
      - service: switch.turn_on
        entity_id: switch.airwick

Off:

  - trigger:
      - platform: state
        entity_id: light.bathroom
        to: "on"
      - platform: state
        entity_id: switch.airwick
        to: "on"
        for:
          minutes: 30
    condition:
      - condition: state
        entity_id: switch.airwick
        state: "on"
    action:
      - service: switch.turn_off
        entity_id: switch.airwick

No magic on the ESP either. It’s running standard Tasmota with one “Switch” GPIO.

Hey Daxi,

This is great, thank you so much for sharing. I’d love to see more pictures of the inside as well as the reassembled Air freshener. For example, where does the USB cable enter the air freshener?

Thank you in advance!

@rodri2566: Project is updated and pictures of the final air freshener added:

  • Added spray counter as readonly data
  • Added reset button to set spraycounter back to 0
  • Changed timings for glade cans (previously worked fine for airwick cans but not glade cans)
  • Spraying logic moved to a script
  • Avoiding multiple script executions by the button which avoids motor stress.
  • Moved ESPHome YAML to its own file

Thank you so much for sharing @Daxi . It’s a very elegant solution, both in terms of hardware as well as software.

Hey Daxi.
Added a lock to your code at the end of 2400 sprays and the presence of a spray in the can.

script:

  - id: do_spray
    then:
      - if:
          condition: 
            lambda: 'return id(spray_counter).state < 2400 ;'
          then:
            - number.increment: spray_counter
            - component.update: spray_counter
            - fan.hbridge.brake: spray_motor
            - fan.turn_on:
                id: spray_motor
                speed: 80
                direction: forward
            - delay: 350ms
            - fan.hbridge.brake: spray_motor
            - fan.turn_on:
                id: spray_motor
                speed: 80
                direction: reverse
            - delay: 200ms
            - fan.hbridge.brake: spray_motor
            - fan.turn_off:
                id: spray_motor
            - delay: 500ms

sensor:

  - platform: template
    name: ${friendly_name} ${friendly_suffix_counter}
    icon: mdi:counter
    id: spray_counter_template
    state_class: measurement
    unit_of_measurement: ""
    accuracy_decimals: 0
    lambda: |-
      return id(spray_counter).state;
    update_interval: 1s
    on_value:
      - if:
          condition:
            - lambda: |-
                return id(spray_counter).state <= 2399 ;
          then:
            - text_sensor.template.publish:
                id: ballon
                state: "The balloon is ok"
      - if:
          condition:
            - lambda: |-
                return id(spray_counter).state >= 2400 ;
          then:
            - text_sensor.template.publish:
                id: ballon
                state: "empty balloon"


text_sensor:

  - platform: template
    name: ${friendly_suffix_button_spray} Ballon
    icon: mdi:spray
    id: ballon
    update_interval: 60s

If it is not, change the GPIO pins at forward and reverse pin.

I’ve received all my parts and have done soldering. When I test the motor, it is turning the opposite direction. I am confused of what to change as I have tried a couple of ways, but the motor does not change direction.

I have tried swapping the gpio pins on the d1 mini. Change the pin id labels in the config file.

You can change the direction by changing the pins in the yaml and reinstall the firmware.

Original part:

output:
  - platform: esp8266_pwm
    id: motor_forward_pin
    pin: GPIO4
  - platform: esp8266_pwm
    id: motor_reverse_pin
    pin: GPIO5

Swapped pins:

output:
  - platform: esp8266_pwm
    id: motor_forward_pin
    pin: GPIO5
  - platform: esp8266_pwm
    id: motor_reverse_pin
    pin: GPIO4

so strange. Swapped the pins as you suggest above, but not change in direction.

this is my config:


substitutions:
  devicename: lr-airfreshener
  friendly_name: LR Airfreshener
  friendly_suffix_counter: Spray counter
  friendly_suffix_button_spray: Spray
  friendly_suffix_button_reset: Reset spray counter

esphome:
  name: $devicename

esp8266:
  board: esp01_1m

logger:

api:
  password: !secret ota_pass
ota:
  password: !secret ota_pass

wifi:
  ssid: !secret ssid3
  password: !secret ssid_pass
  fast_connect : true
  manual_ip:
    static_ip: 192.168.1.119
    subnet: 255.255.255.0
    gateway: 192.168.1.1

output:
  - platform: esp8266_pwm
    id: motor_forward_pin
    pin: GPIO5
  - platform: esp8266_pwm
    id: motor_reverse_pin
    pin: GPIO4

fan:
  - platform: hbridge
    id: spray_motor
    name: ${friendly_name} Motor
    pin_a: motor_forward_pin
    pin_b: motor_reverse_pin
    # enable_pin: motor_enable
    decay_mode: slow
    internal: true

number:
  - platform: template
    #name: ${friendly_name} ${friendly_suffix_counter}
    icon: mdi:counter
    id: spray_counter
    restore_value: true
    update_interval: 30s
    min_value: 0
    max_value: 3000
    mode: box
    step: 1
    optimistic: true
    internal: true

sensor:
  - platform: template
    name: ${friendly_name} ${friendly_suffix_counter}
    icon: mdi:counter
    id: spray_counter_template
    state_class: measurement
    unit_of_measurement: ""
    accuracy_decimals: 0
    lambda: |-
      return id(spray_counter).state;
    update_interval: 60s

  - platform: wifi_signal
    name: ${friendly_name} wifi signal
    update_interval: 15s

#  - platform: adc
#    pin: A0
#    name: '${friendly_name} illuminance'
#    unit_of_measurement: lux
#    update_interval: 60s
#    filters:
#      - lambda: |-
#          return (x / 10000.0) * 2000000.0;

binary_sensor:
  - platform: status
    name: ${friendly_name} status

button:
  - platform: template
    name: ${friendly_name} ${friendly_suffix_button_spray}
    id: btn_spray
    icon: mdi:spray
    on_press:
      then:
        if:
          condition:
            not:
              script.is_running: do_spray
          then:
            script.execute: do_spray
  - platform: template
    name: ${friendly_name} ${friendly_suffix_button_reset}
    icon: mdi:restart
    on_press:
      then:
        - number.set:
            id: spray_counter
            value: 0

script:
  - id: do_spray
    then:
      - number.increment: spray_counter
      - component.update: spray_counter
      - component.update: spray_counter_template
      - fan.hbridge.brake: spray_motor
      - fan.turn_on:
          id: spray_motor
          speed: 80
          direction: forward
      - delay: 350ms
      - fan.hbridge.brake: spray_motor
      - fan.turn_on:
          id: spray_motor
          speed: 80
          direction: reverse
      - delay: 200ms
      - fan.hbridge.brake: spray_motor
      - fan.turn_off:
          id: spray_motor
      - delay: 500ms

Strange.
The motor moves in both directions but the opposite direction, right?
Could you make a picture of your wiring?

Overall of how this Glade air freshener looks like.

brown/purple wire → IN1/IN2

The red/white single set wires go to drv8266 vcc/ground.

Brown/gray → motor

Hey guys,
just out of curiosity and because someone might have missed it. I did show my solution to this problem a couple of responses earlier in this thread. It is a fully satisfying technical solution with minimal effort.

Why do you guys bother to go through massive rebuilds of the devices internals? Is it only because you already have your other air freshener model at home and it wouldn’t work that way? The Air Wick Freshmatic model I own costs 5-10€ and the modifications are straight forward :face_with_raised_eyebrow:

The wiring should be ok.
At the picture with the dc motor, I see a red an black wire. Not sure if they are connected to the motor or not.
The motor should be only connected to the DRV board.

@ThomDietrich yes, there are multiple solutions.
The reason why I was using my approach was because of full control. For the Airwick, I would prefer your solution.

Not everybody has the same tools like a 3D printer.

Isn‘t it the nice wonderful part on open source and communities? You get different ideas and solutions and you can pick that one you want. :wink:

My solution is only one, not intended to be the best but one way you can do it. For me it is and was fun to get a little bit of deep dive into dc motors and how to control it with ESPHome. Learning by doing.