[HIDDEN INSTAL] Robot Vacuum Automatic Door System

My install post is here.

To hardware interlock 4 relays use the below wiring. This way no 2 relays can output at the same time.

2 Likes

Great job!

1 Like

Thak you! Really appreciate it

I have a spare shelly 2.5 and was looking at doing something similar, noticed your comment on going 12v for actuator is there a lot of difference noise wise between 24/12 ?
wondering if i should get 12v actuator and use a stepdown converter to 12v on outputs.

1 Like

Using a shelly is a great idea. I would probably use it in the future for such projects.

You can get a 24v actuator, just make sure it has a force of around 100N. Somenthing more powerfull is extremly noisy and slow.

If you can’t find a 24V actuator with a force of 100N, buy a 12V and use a step-down.

Ah that makes sense the gearbox in the lower speed models would be noisier.

The same seller you linked for actuator does a 24v model now in 100N, ill give them a try

Thanks again for the inspiration.

1 Like

Can you share the wire diagram when connecting the shelly 2.5 with a step-down into the actuator ? I guess your using the “roller shutter” options right ?

Finished mine today, finally.


2 Likes

Congratz! This is some clean work!

It’s amazing to me that after 2 years this is still getting attention :))

Great job!

Let me start with a big ‘Thank you!’ to @smowk: Great guide! I have made this vacuum door as well based on your description, with some changes:

  1. Made a wooden frame to which the kitchen cover, hinge and motor are mounted to. This eases the assembly of everything. This wooden frame, with everything connected to it, just slides underneath the kitchen cabinet

  2. Added a light sensor to the relay board, just a simple light sensor for an arduino. As relay board I used this, which has some additional GPIO pins for the light sensor.This light sensor is taped on top of the dock of the robot vacuum. The light on the dock is on when the vacuum is driving around and off when it is docked. I use this sensor to open the vacuum door in case it is not controlled by a script in home assistant.

  3. I use a 3D printed hinge with magnets to assemble the motor to the door. I found that simple velcro did not do the trick for me as it was not strong enough; the weight of the door when opened actually caused the motor bracket to act as a hinge and tear of the velcro, up to the point that the door was not opened enough for the vacuum to pass through. Therefore I designed my own hinge which would open when there is something stuck under the door. See video, where I actually had my hand holding the phone under the door. In case somebody would like to have the STL files to print this yourself, I could post it on thingiverse. Let me know if there is interest?

  4. I used ESPhome as basis for programming the relay board. For code see below

---
esphome:
  name: vacuum_gate
  platform: ESP8266
  board: esp12e

# WiFi connection, correct these
# with values for your WiFi.
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# Enable logging.
logger:

# Enable Home Assistant API.
api:

# Enable over-the-air updates.
ota:

# Enable Web server.
web_server:
  port: 80

# Sync time with Home Assistant.
time:
  - platform: homeassistant
    id: homeassistant_time

# Text sensors with general information.
text_sensor:
  # Expose ESPHome version as sensor.
  - platform: version
    name: Vacuum Gate ESPHome Version
  # Expose WiFi information as sensors.
  - platform: wifi_info
    ip_address:
      name: Vacuum Gate IP
    ssid:
      name: Vacuum Gate SSID
    bssid:
      name: Vacuum Gate BSSID

# Sensors with general information.
sensor:
  # Uptime sensor.
  - platform: uptime
    name: Vacuum Gate Uptime

  # WiFi Signal sensor.
  - platform: wifi_signal
    name: Vacuum Gate WiFi Signal
    update_interval: 60s

# Exposed switches.
switch:
  # Switch to restart the Vacuum Gate.
  - platform: restart
    name: Vacuum Gate Restart

  # Relays
  - platform: gpio
    id: open_cover #relay 1
    inverted: false
    name: Vacuum Gate relay 1
    internal: true
    pin: GPIO5
    interlock: &interlock [open_cover, close_cover]
    restore_mode: always off

  - platform: gpio
    id: close_cover #relay 2
    inverted: false
    name: Vacuum Gate relay 2
    internal: true
    pin: GPIO4
    interlock: *interlock
    restore_mode: always off
    
cover:
- platform: time_based
  name: "Vacuum Cover"
  id: my_cover
  device_class: shutter
  open_action:
    - switch.turn_on: open_cover
  open_duration: 3s
  close_action:
    - switch.turn_on: close_cover
  close_duration: 3s
  stop_action:
    - switch.turn_off: open_cover
    - switch.turn_off: close_cover
    
binary_sensor:
  - platform: gpio
    id: charger_led
    name: Charger LED state
    device_class: light
    pin:
      # Connected to GPIO16
      number: GPIO16
      inverted: true
      mode: 
        input: true
        pullup: false
        pulldown: false
    filters:
      # Small filter, to debounce.
      - delayed_on: 25ms
      - delayed_off: 25ms
    on_press:
      then:
        - cover.open: my_cover

I actually also have some questions for @smowk;

  1. Where do you actually call the ‘vacuum_send_command’ script? I think you do that in automations, but also in the Lovelace Xiaomi Vacuum Map card? Can you share this with some example code?
  2. Could you also share some yaml example of how you configured your dashboard (and the Lovelace Xiaomi Vacuum Map card)? I think it looks really clean!
1 Like

I know this has been a little bit since this post, however, you seem to be the latest crack at this, would you mind sending your parts list? Or even better a full step by step!

1 Like

So funny I posted on this a few hours after you and didnt see your post. I am looking to start this build and it will be my first go at something like this. Any step by step, parts list or instructions would be greatly appreciated!!

1 Like

Hello @BdeBresser, congratz on your build! It’s amazing to me that this post is still getting attention :)\

Great modification with the 3D printed hinges, your ‘vacuum door’ is definitely too big/heavy for my velcro solution.

To answer your questions:

  1. The script is called directly by the custom card, by pressing “start”.

‘vacuum_send_command’ is an independent Python script documented under " python_scripts/vacuum_send_command.py" used to send the cleaning command to the vacuum (including the parameters set via the interface: rooms, area, speed, etc.). Basically, I create a set of instructions for the vacuum in the interface and send those to the vacuum with this script.

To actually call this Python script named “python_script.vacuum_send_command” I have created a HomeAssistant script named “vacuum_send_command” documented under " scripts.yaml" as “# ---------- VACDOOR PYTHON CONTROLLER” and as you can see, in this HomeAssistant script there are 2 sequences:

# ---------- VACDOOR PYTHON CONTROLLER
vacuum_send_command:
  sequence:
    - service: script.vacdoor_open
    - service: python_script.vacuum_send_command

The first service (“script.vacdoor_open”) is in charge of opening the door by sending a MQTT command to the relay in charge of controlling the actuator and the second script is the cleaning command discussed above, sent to the vacuum itself (with the cleaning parameters).

Therefore, the Homeassistant script “vacuum_send_command” is calling 2 services/scripts in series, one to the door opening mechanism and the second to the vacuum itself so I can send all the necessary commands with a single press of a button.

This script is what is called by pressing the “START” button from the Custom card Lovelace Xiaomi Vacuum Map card

YAML Config for the Vacuum Controller:

###################################################################################################################################################################################################################
#####                                                                                                       ROBOROCK                                                                                          #####
###################################################################################################################################################################################################################
# Lovelace / scripts / sensor

- name: RoboRock
  path: vacuum
  icon: mdi:robot-vacuum
  cards:
  - type: vertical-stack                     
    cards: 
    - type: glance                                        # VACUUM QUICK CONTROLLER    
      show_name: false
      show_state: false
      columns: 6
      entities:
      - entity: script.vacuum_start                       # START :: Clean everywhere
        tap_action:
            action: toggle 
      - entity: script.vacuum_stop                        # STOP  :: Stops current task and the vacuum at current position
        tap_action:
          action: toggle  
      - entity: script.vacuum_pause                       # PAUSE :: Pauses current task and the vacuum at current position
        tap_action:
          action: toggle  
      - entity: script.vacuum_dock                        # DOCK  ::  ET go home
        tap_action:
          action: toggle  
      # - script.vacuum_spot
      - entity: script.vacuum_locate                      # HELLO ::  Hello Vacuum!
        tap_action:
          action: toggle 
        double_tap_action:                                                
          action: call-service
          service: input_boolean.toggle
          service_data:
            entity_id: input_boolean.vacuum_info   
      - entity: input_boolean.vacuum_advanced             # MAP   :: Activates the manual control - MAP CUSTOM CARD
        tap_action:
          action: toggle  

    - type: conditional                                   # ADVANCED CONTROLLER  :: MAP :: CUSTOM CARD            
      conditions:
      - entity: input_boolean.vacuum_advanced                                                     
        state: "on"  
      card:
        type: custom:xiaomi-vacuum-map-card
        entity: vacuum.roborock
        map_image: '/local/custom-lovelace/xiaomi_vacuum_map_card/ARK_MAP.png?v=3'
        default_mode: zoned_cleanup
        service: script.vacuum_send_command

        calibration_points:                               # VACUUM CALIBRATION COORDONATES
        - vacuum:                                             
            x: 23550
            y: 24900
          map:
            x: 253
            y: 148
        - vacuum:
            x: 21800
            y: 22600
          map:
            x: 113
            y: 332
        - vacuum:
            x: 26350
            y: 22600
          map:
            x: 481
            y: 332

        zones:                                            # AREA COORDONATES: Also mentioned in script:roborock.yaml
        - [[25224,25100,28300,25430,1]]   #Cooking
        - [[25224,22599,28300,25430,1]]   #Kitchen
        - [[22270,22599,25242,25430,1]]   #Couch
        - [[20764,22599,22270,24500,1]]   #Entrance
        - [[25860,18626,28270,22450,1]]   #Office
        - [[22570,18626,25820,22450,1]]   #Bedroom
        - [[20764,20910,22527,22450,1]]   #Shower
        - [[20750,18626,22510,20825,1]]   #Bathroom


    - type: conditional                                  # ZONE CONTROLLER                
      conditions:
      - entity: input_boolean.vacuum_advanced            # Condotional Entity Display: MAP
        state: "off"  
      card:
        type: vertical-stack                     
        cards: 
        - type: glance                      
          show_name: true
          show_state: false
          columns: 4
          entities:
          - entity: script.vacuum_living                  # Living
            tap_action:
              action: toggle 
          - entity: script.vacuum_kitchen                 # Kitchen
            tap_action:
              action: toggle 
          - entity: script.vacuum_couch                   # Couch
            tap_action:
              action: toggle 
          - entity: script.vacuum_entrance                # Entrance
            tap_action:
              action: toggle 
          - entity: script.vacuum_bedroom                 # Bedroom
            tap_action:
              action: toggle 
          - entity: script.vacuum_office                  # Office
            tap_action:
              action: toggle 
          - entity: script.vacuum_bathroom                # Bathroom
            tap_action:
              action: toggle 
          - entity: script.vacuum_shower                  # Shower
            tap_action:
              action: toggle 
 
    - type: conditional                                   # INFO Pannel :: SENSORS / POWER SETTINGS               
      conditions:
      - entity: input_boolean.vacuum_info                
        state: "on"  
      card:
        type: vertical-stack                              # VACUUM SENSORS          
        cards: 
        - type: glance                   
          show_name: true
          show_state: true
          entities:
          - sensor.vacuum_battery_level
          - entity: sensor.vacuum_fan_speed               # Noise level 
            tap_action:
              action: call-service
              service: input_boolean.toggle
              service_data:
                entity_id: input_boolean.vacuum_power_selector   
          - sensor.vacuum_status                          # Status
          - sensor.vacuum_state                           # State
          - entity: sensor.vacuum_operation               # MAINTENANCE
            tap_action:
              action: call-service
              service: input_boolean.toggle
              service_data:
                entity_id: input_boolean.vacuum_maintenance      

        - type: conditional                               # POWER SELECTOR MENU                
          conditions:
          - entity: input_boolean.vacuum_power_selector   # [ Hidden behind POWER Button / Behind INFO Pannel ]
            state: "on"  
          card:
            type: glance                    
            show_name: false
            show_state: false
            columns: 5
            entities:
            - entity: script.vacuum_power_gentle          # Moping
              tap_action:
                action: call-service
                service: script.toggle
                service_data:
                  entity_id: script.vacuum_power_gentle        
            - entity: script.vacuum_power_quiet           # Quiet
              tap_action:
                  action: call-service
                  service: script.toggle
                  service_data:
                    entity_id: script.vacuum_power_quiet
            - entity: script.vacuum_power_balanced        # Balanced
              tap_action:
                action: call-service
                service: script.toggle
                service_data:
                  entity_id: script.vacuum_power_balanced 
            - entity: script.vacuum_power_turbo           # Turbo
              tap_action:
                action: call-service
                service: script.toggle
                service_data:
                  entity_id: script.vacuum_power_turbo
            - entity: script.vacuum_power_max            # Maximum
              tap_action:
                action: call-service
                service: script.toggle
                service_data:
                  entity_id: script.vacuum_power_max

        - type: conditional                              # MAINTENANCE SENSORS               
          conditions:
          - entity: input_boolean.vacuum_maintenance
            state: "on"  
          card:
            type: entities      
            entities:
            - sensor.vacuum_main_brush                              
            - sensor.vacuum_side_brush
            - sensor.vacuum_filter
            - sensor.vacuum_sensors

To keep the interface clean, and have things out of sight, but without having to compromise on utility/relevant information or options regarding the vacuum, most settings are hidden behind input_boolean used as buttons to reveal selected sections; those are my “buttons”

boolean.yaml

# ________________________________________________________________________________ BOOLEAN
# ROBOROCK VACUUM
vacuum_advanced:
  name: MAP
  initial: off
vacuum_power_selector:
  name: POWER
  initial: off
vacuum_maintenance:
  name: OPERATION
  initial: off
vacuum_info:
  name: VacuumHi
  initial: off

some quick actions for the vacuum are defined as scrips uder

scripts.yaml

# ________________________________________________________________________________ VACUUM _____________________________________________________________________________

# ----------  VACUUM DOOR
vacdoor_open:
  alias: OPEN
  sequence:
  - service: mqtt.publish
    data:
      topic: cmnd/VACDOOR_RF/POWER1
      payload: ON

vacdoor_close:
  alias: CLOSE
  sequence:
  - service: mqtt.publish
    data:
      topic: cmnd/VACDOOR_RF/POWER2
      payload: ON

# ---------- VACDOOR PYTHON CONTROLLER
vacuum_send_command:
  sequence:
    - service: script.vacdoor_open
    - service: python_script.vacuum_send_command
      data_template:
        entity_id: "{{ entity_id }}"
        command: "{{ command }}"
        params: "{{ params }}"

# ----------  QUICK MENU   
# Say HELLO, find the vacuum
vacuum_locate:
  alias: Hello
  sequence:
  - service: vacuum.locate
    entity_id: vacuum.roborock

# Start the cleaning of the house
vacuum_start:
  alias: START
  sequence:
  - service: script.vacdoor_open
  - service: vacuum.start
    entity_id: vacuum.roborock    

# Stop the vacuum task; doesn't return to dock
vacuum_stop:
  alias: STOP
  sequence:
  - service: vacuum.stop
    entity_id: vacuum.roborock    

# Pause the current task
vacuum_pause:
  alias: Pause
  sequence:
  - service: vacuum.pause
    entity_id: vacuum.roborock        

# Return to dock
vacuum_dock:
  alias: Dock
  sequence:
  - service: vacuum.return_to_base
    entity_id: vacuum.roborock    

# # Clean around current position
# vacuum_spot:
#   alias: Spot
#   sequence:
#   - service: vacuum.clean_spot
#     entity_id: vacuum.roborock   

# ----------  AERAS      
# Clean up AREA: LIVING
vacuum_living:
  alias: Living
  sequence:
  - service: script.vacdoor_open
  - service: vacuum.send_command
    data:
      entity_id: vacuum.roborock  
      command: app_zoned_clean
      params: [[20764,22599,28300,25430,1]] 

# Clean up AREA: COOKING 
vacuum_kitchen:
  alias: Kitchen
  sequence:
  - service: script.vacdoor_open
  - service: vacuum.send_command
    data:
      entity_id: vacuum.roborock  
      command: app_zoned_clean
      params: [[25224,25100,28300,25430,1]]

# Clean up AREA: KITCHEN 
vacuum_kitchen:
  alias: Kitchen
  sequence:
  - service: script.vacdoor_open
  - service: vacuum.send_command
    data:
      entity_id: vacuum.roborock  
      command: app_zoned_clean
      params: [[25224,22599,28300,25430,1]] 

# Clean up AREA: COUCH
vacuum_couch:
  alias: Couch
  sequence:
  - service: script.vacdoor_open
  - service: vacuum.send_command
    data:
      entity_id: vacuum.roborock  
      command: app_zoned_clean
      params: [[22270,22599,25242,25430,1]] 

# Clean up AREA: ENTRANCE
vacuum_entrance:
  alias: Entrance
  sequence:
  - service: script.vacdoor_open
  - service: vacuum.send_command
    data:
      entity_id: vacuum.roborock  
      command: app_zoned_clean
      params: [[20764,22599,22270,24500,1]] 

# Clean up AREA: BEDROOM
vacuum_bedroom:
  alias: Bedroom
  sequence:
  - service: script.vacdoor_open
  - service: vacuum.send_command
    data:
      entity_id: vacuum.roborock  
      command: app_zoned_clean
      params: [[22570,18626,25820,22450,1]]

# Clean up AREA: OFFICE
vacuum_office:
  alias: Office
  sequence:
  - service: script.vacdoor_open
  - service: vacuum.send_command
    data:
      entity_id: vacuum.roborock  
      command: app_zoned_clean
      params: [[25860,18626,28270,22450,1]] 

# Clean up AREA: BATHROOM
vacuum_bathroom:
  alias: Bathroom
  sequence:
  - service: script.vacdoor_open
  - service: vacuum.send_command
    data:
      entity_id: vacuum.roborock  
      command: app_zoned_clean
      params: [[20750,18626,22510,20825,1]]

# Clean up AREA: SHOWER
vacuum_shower:
  alias: Shower
  sequence:
  - service: script.vacdoor_open
  - service: vacuum.send_command
    data:
      entity_id: vacuum.roborock  
      command: app_zoned_clean
      params: [[20764,20910,22527,22450,1]] 

# ----------  POWER         

# Set vacuum POWER: Quiet
vacuum_power_quiet:
  alias: Quiet
  sequence:
  - service: vacuum.set_fan_speed
    data:
      entity_id: vacuum.roborock  
      fan_speed: Quiet

# Set vacuum POWER: Balanced
vacuum_power_balanced:
  alias: Balanced
  sequence:
  - service: vacuum.set_fan_speed
    data:
      entity_id: vacuum.roborock  
      fan_speed: Balanced

# Set vacuum POWER: Turbo
vacuum_power_turbo:
  alias: Turbo
  sequence:
  - service: vacuum.set_fan_speed
    data:
      entity_id: vacuum.roborock  
      fan_speed: Turbo

# Set vacuum POWER: Max
vacuum_power_max:
  alias: Max
  sequence:
  - service: vacuum.set_fan_speed
    data:
      entity_id: vacuum.roborock  
      fan_speed: Max

# Set vacuum POWER: Gentle
vacuum_power_gentle:
  alias: Gentle
  sequence:
  - service: vacuum.set_fan_speed
    data:
      entity_id: vacuum.roborock  
      fan_speed: Gentle

other potentially relevant information comes from sensors under

sensor.yaml

###################################################################################################################################################################################################################
#####                                                                                                APPLIANCES                                                                                               #####
###################################################################################################################################################################################################################

# ________________________________________________________________________________ VACUUM 

# ---------- ROBOROCK 
  - platform: template                                      
    sensors:
# VACUUM STATE
      vacuum_state:                                                                 
        friendly_name: "STATE"
        value_template: >-
          {{ states.vacuum.roborock.state }}  
# VACUUM STATUS
      vacuum_status:                                                                
        friendly_name: "STATUS"
        value_template: >-   
          {{ states.vacuum.roborock.attributes.status }}    
# VACUUM BATTERY LEVEL
      vacuum_battery_level:                                                         
        friendly_name: "BATTERY"
        value_template: >-
          {{ states.vacuum.roborock.attributes.battery_level }}
        icon_template: >-
          {{ states.vacuum.roborock.attributes.battery_icon }}  
# VACUUM POWER
      vacuum_fan_speed:                                                             
        friendly_name: "POWER"
        value_template: >-
          {{ states.vacuum.roborock.attributes.fan_speed }}
# VACUUM MAIN BRUSH
      vacuum_main_brush:                                                            
        friendly_name: "Main Brush"
        value_template: >-
          {{ states.vacuum.roborock.attributes.main_brush_left }}
# VACUUM SIDE BRUSH
      vacuum_side_brush:                                                            
        friendly_name: "Side Brush"
        value_template: >-
          {{ states.vacuum.roborock.attributes.side_brush_left }}
# VACUUM FILTER
      vacuum_filter:                                                                
        friendly_name: "Filter"
        value_template: >-
          {{ states.vacuum.roborock.attributes.filter_left }}
# VACUUM GUIDANCE SENSORS
      vacuum_sensors:                                                               
        friendly_name: "Sensors"
        value_template: >-
          {{ states.vacuum.roborock.attributes.sensor_dirty_left }}
# VACUUM MAINTENANCE SENSORS
      vacuum_operation:                                                             
        friendly_name: "OPERATION"
        value_template: >-
          {% if (states.vacuum.roborock.attributes.main_brush_left|int > 24) and (states.vacuum.roborock.attributes.side_brush_left|int > 24) and (states.vacuum.roborock.attributes.filter_left|int > 24) and (states.vacuum.roborock.attributes.sensor_dirty_left|int > 24) %}  
            OK
          {% else %}
            Dirty
          {% endif %}             

and the map itself that is located in \www\custom-lovelace\xiaomi_vacuum_map_card was made in Photoshop by overlapping my floorplan design over the map extracted from the Xiaomi app, just to make sure all the proportions will fit perfectly and i have millimeter-level accuracy when i want to send the vacuum to a certain locaton via the interface.

Hope this helps. Have fun!

Hello Nico, this implementation works perfectly, with nothing changed or modified in 2 years, since I originally made it.

The parts from Aliexpress might not be still available fom those particular links, but you can search by using the technical specs mentioned.

From my experiments (some documented in the post) i have decided the optimal solution for an actuator is 100N force, at 100mm stroke, mainly regarding speed and noise aspects.
For example, Linear Actuator ( 100N | 100mm stroke | 60mm/s )

As a power supply, you can use any 12V DC Output with AC Input, but the one in the link is still available.

And for the controller, the one used by @BdeBresser in his implementation should work perfectly.

You can create an better implementation by using a Shelly as a controller, with any power supply you like.

Hello. Here is my roborock vacuum door automation in node red. It opens door only when previous roborock state is docked and it close door after 35 sec. I will paste flow here but don’t know if its proper way to show it.

[{"id":"778a24ba49caeda8","type":"miio-roborock-event","z":"3f0bd0edbddd9955","name":"","server":"14389417df3a3acf","outputAtStartup":true,"x":120,"y":260,"wires":[["4d511f79d6032b27","c8a3f39b750d9ce3","bdbd9bfbbf448238","ceb6a2e35c97dd29"]]},{"id":"4d511f79d6032b27","type":"function","z":"3f0bd0edbddd9955","name":"is_returning?","func":"var payload=msg.payload.key;\nif (payload == \"in_returning\") {\n msg.payload=msg.payload.value\n return msg;\n}\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":380,"wires":[["af6aca477f571a97"]]},{"id":"c8a3f39b750d9ce3","type":"function","z":"3f0bd0edbddd9955","name":"charging","func":"var payload=msg.payload.key;\nif (payload == \"state_text\" && msg.payload.value == \"charging\") {\n msg.payload=msg.payload.value\n return msg;\n}\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":360,"y":300,"wires":[["392ab6d9e87a1777"]]},{"id":"af6aca477f571a97","type":"api-call-service","z":"3f0bd0edbddd9955","name":"VacuumDoor Open","server":"79e2662a.5e8a78","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.tasmota"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":590,"y":380,"wires":[[]]},{"id":"392ab6d9e87a1777","type":"api-call-service","z":"3f0bd0edbddd9955","name":"VacuumDoor Close","server":"79e2662a.5e8a78","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.tasmota2"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":590,"y":300,"wires":[[]]},{"id":"ceb6a2e35c97dd29","type":"function","z":"3f0bd0edbddd9955","name":"going_target","func":"const globalHomeAssistant = global.get('homeassistant');\n\nvar state1 = globalHomeAssistant.homeAssistant.states[\"vacuum.roborock_vacuum_a15\"].state;\nvar payload=msg.payload.key;\nif ((payload == \"state_text\" && msg.payload.value == \"coordinates\")  && (state1 === \"docked\")) {\n    msg.payload = { \"service\": \"turn_on\" }\n return msg;\n}\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":220,"wires":[["29779f4339074b0d"]]},{"id":"a68d836993c85379","type":"trigger","z":"3f0bd0edbddd9955","name":"","op1":"","op2":"{\"service\":\"turn_on\"}","op1type":"nul","op2type":"json","duration":"35","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":790,"y":180,"wires":[["2c0af1be309305e3"]]},{"id":"2c0af1be309305e3","type":"api-call-service","z":"3f0bd0edbddd9955","name":"VacuumDoor Close","server":"79e2662a.5e8a78","version":5,"debugenabled":false,"domain":"switch","service":"","areaId":[],"deviceId":[],"entityId":["switch.tasmota2"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":990,"y":180,"wires":[[]]},{"id":"29779f4339074b0d","type":"api-call-service","z":"3f0bd0edbddd9955","name":"VacuumDoor Open","server":"79e2662a.5e8a78","version":5,"debugenabled":false,"domain":"switch","service":"","areaId":[],"deviceId":[],"entityId":["switch.tasmota"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":590,"y":180,"wires":[["a68d836993c85379"]]},{"id":"bdbd9bfbbf448238","type":"function","z":"3f0bd0edbddd9955","name":"is_cleaning?","func":"const globalHomeAssistant = global.get('homeassistant');\n\nvar state1 = globalHomeAssistant.homeAssistant.states[\"vacuum.roborock_vacuum_a15\"].state;\nvar payload=msg.payload.key;\nif ((payload == \"in_cleaning\") && (state1 === \"docked\")) {\n    msg.payload = { \"service\": \"turn_on\" }\n return msg;\n}\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":140,"wires":[["29779f4339074b0d"]]},{"id":"14389417df3a3acf","type":"miio-roborock-server","name":"Rumburak","ip":"192.168.1.202","token":"3174664d326f63623138514d68477955","polling":"10"},{"id":"79e2662a.5e8a78","type":"server","name":"Home Assistant","version":4,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m"}]

Great project and write-up! I am looking into this as well, but some images/videos in the first post are not online anymore. I would like to leverage an existing ESP32 with a simple 4 channel relais module.

What would be the best way to power the 100N (12V?) actuator and my ESP32? I have quite some experience with ESP32+ESPHome, but until now they were always powered by USB/5V. So any advice here is welcome.

If you use a 12v power supply you can then step that down to 5v for the ESP using something like this.

Hi there, @smowk ! Awesome project (and I hear you are from Norway, as well) :slight_smile: I’m thinking of doing something like this, but in Homey.
All I would need to buy, is the Shelly Plus 2PM (will Roller Shutter 3 from Fibaro also work for this?), the accurator and a 240V to 12 or 24V converter, am I right?