Home Assistant integrated WiFi Power Strip for your HomeLAB

One of the things the lazy side of me hates, is physically having to go to my HomeLAB to hard reset any device. While this has been happening less and less, it’s still something I dread. My solution to the problem is to make a poor man’s rack PDU that’s integrated into Home Assistant. This how-to will outline how you can do the same for less than $7 per controlled socket using ESPHome firmware.

Hardware

I have used a Teckin and Tunbox (white or black), but there are many manufacturers that seem to brand label the same physical product. The key is that the description needs to mention the “Smart Life” app as that means it’s using the Tuya WiFi module.

Firmware

The overall process is to flash this unit with custom firmware that tightly integrated to Home Assistant. To get the unit converted from the original firmware, I used Tuya Convert combined with ESPHome to get this accomplished. If you are not familiar with these, digiblurDIY and DrZzs both have extensive videos on how to get started with these. I will cover the detailed configuration for these power strips.

The configuration I’ve set up for this device is focused on keeping the power on, as typically you do not want to shut it off accidentally. So, the physical button on the unit only toggles the USB power and all power sockets default to being ON when it’s plugged in or power is restored. The only way to control the power sockets is through the device’s webpage or Home Assistant.

Follow the guides linked above to flash your power strip via the tuya convert method. Then create a new device in ESPHome and load the YAML below to this device.

substitutions: board: esp01_1m device_name: esphome_homelab_powerstrip friendly_name: Homelab Powerstrip 1 esphome: name: ${device_name} platform: ESP8266 board: ${board} wifi: ssid: !secret wifi_iot_ssid password: !secret wifi_iot_pwd fast_connect: on ap: ssid: !secret wifi_backup_ssid password: !secret wifi_backup_pwd reboot_timeout: 0s api: ota: web_server: port: 80 logger: switch: - platform: gpio name: "${friendly_name} Socket 1" icon: mdi:power-socket-us id: relay1 pin: number: GPIO4 inverted: True restore_mode: RESTORE_DEFAULT_ON on_turn_on: - switch.turn_on: red_led on_turn_off: - if: condition: and: - switch.is_off: relay2 - switch.is_off: relay3 - switch.is_off: relay4 then: - switch.turn_off: red_led - platform: gpio name: "${friendly_name} Socket 2" icon: mdi:power-socket-us id: relay2 pin: number: GPIO13 inverted: True restore_mode: RESTORE_DEFAULT_ON on_turn_on: - switch.turn_on: red_led on_turn_off: - if: condition: and: - switch.is_off: relay1 - switch.is_off: relay3 - switch.is_off: relay4 then: - switch.turn_off: red_led - platform: gpio name: "${friendly_name} Socket 3" icon: mdi:power-socket-us id: relay3 pin: number: GPIO12 inverted: True restore_mode: RESTORE_DEFAULT_ON on_turn_on: - switch.turn_on: red_led on_turn_off: - if: condition: and: - switch.is_off: relay1 - switch.is_off: relay2 - switch.is_off: relay4 then: - switch.turn_off: red_led - platform: gpio name: "${friendly_name} Socket 4" icon: mdi:power-socket-us id: relay4 pin: number: GPIO14 inverted: True restore_mode: RESTORE_DEFAULT_ON on_turn_on: - switch.turn_on: red_led on_turn_off: - if: condition: and: - switch.is_off: relay1 - switch.is_off: relay2 - switch.is_off: relay3 then: - switch.turn_off: red_led - platform: gpio name: "${friendly_name} USB Ports" icon: mdi:usb id: relay5 pin: number: GPIO16 inverted: False restore_mode: RESTORE_DEFAULT_ON - platform: gpio internal: true id: red_led pin: number: GPIO3 inverted: True - platform: restart name: '${friendly_name} REBOOT' binary_sensor: - platform: gpio pin: number: GPIO5 mode: INPUT_PULLUP inverted: False internal: true on_press: - switch.toggle: relay5 status_led: id: blue_led pin: number: GPIO0 inverted: True text_sensor: - platform: version name: ${friendly_name} ESPhome Version 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 substitutions : board : esp01_1m device_name : esphome_homelab_powerstrip friendly_name : Homelab Powerstrip 1 esphome : name : $ { device _ name } platform : ESP8266 board : $ { board } wifi : ssid : !secret wifi_iot_ssid password : !secret wifi_iot_pwd fast_connect : on ap : ssid : !secret wifi_backup_ssid password : !secret wifi_backup_pwd reboot_timeout : 0s api : ota : web_server : port : 80 logger : switch : - platform : gpio name : "$ { friendly _ name } Socket 1 " icon: mdi:power-socket-us id: relay1 pin: number: GPIO4 inverted: True restore_mode: RESTORE_DEFAULT_ON on_turn_on: - switch.turn_on: red_led on_turn_off: - if: condition: and: - switch.is_off: relay2 - switch.is_off: relay3 - switch.is_off: relay4 then: - switch.turn_off: red_led - platform: gpio name: " $ { friendly _ name } Socket 2 " icon: mdi:power-socket-us id: relay2 pin: number: GPIO13 inverted: True restore_mode: RESTORE_DEFAULT_ON on_turn_on: - switch.turn_on: red_led on_turn_off: - if: condition: and: - switch.is_off: relay1 - switch.is_off: relay3 - switch.is_off: relay4 then: - switch.turn_off: red_led - platform: gpio name: " $ { friendly _ name } Socket 3 " icon: mdi:power-socket-us id: relay3 pin: number: GPIO12 inverted: True restore_mode: RESTORE_DEFAULT_ON on_turn_on: - switch.turn_on: red_led on_turn_off: - if: condition: and: - switch.is_off: relay1 - switch.is_off: relay2 - switch.is_off: relay4 then: - switch.turn_off: red_led - platform: gpio name: " $ { friendly _ name } Socket 4 " icon: mdi:power-socket-us id: relay4 pin: number: GPIO14 inverted: True restore_mode: RESTORE_DEFAULT_ON on_turn_on: - switch.turn_on: red_led on_turn_off: - if: condition: and: - switch.is_off: relay1 - switch.is_off: relay2 - switch.is_off: relay3 then: - switch.turn_off: red_led - platform: gpio name: " $ { friendly _ name } USB Ports" icon : mdi :usb id : relay5 pin : number : GPIO16 inverted : False restore_mode : RESTORE_DEFAULT_ON - platform : gpio internal : true id : red_led pin : number : GPIO3 inverted : True - platform : restart name : '$ { friendly _ name } REBOOT' binary_sensor : - platform : gpio pin : number : GPIO5 mode : INPUT_PULLUP inverted : False internal : true on_press : - switch . toggle : relay5 status_led : id : blue_led pin : number : GPIO0 inverted : True text_sensor : - platform : version name : $ { friendly _ name } ESPhome Version

Home Assistant UI (Lovelace)

At first, I did not want to display these in my lovelace UI because I was worried about fat fingering something by accident. Then, I discovered the Toggle Lock Entity Row plugin developed by Thomas Loven. The easiest method for installing this is to utilize HACS (Home Assistant Community Store) – if you don’t have it, get it…now. This plugin prevents accidental switching by requiring a secondary click within 5 seconds in order to turn off the device.

In my instance, I have chosen to name the entities generically via the firmware and add the label in lovelace.

Lovelace YAML - type: entities show_header_toggle: false title: HomeLAB Powerstrip 1 entities: - entity: switch.homelab_powerstrip_1_socket_1 name: Modem type: custom:toggle-lock-entity-row - entity: switch.homelab_powerstrip_1_socket_2 name: UniFi USG type: custom:toggle-lock-entity-row - entity: switch.homelab_powerstrip_1_socket_3 name: UniFi Switch type: custom:toggle-lock-entity-row - entity: switch.homelab_powerstrip_1_socket_4 name: Dell R210 type: custom:toggle-lock-entity-row - entity: switch.homelab_powerstrip_1_usb_ports name: UniFi Console Pi type: custom:toggle-lock-entity-row 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 - type : entities show_header_toggle : false title : HomeLAB Powerstrip 1 entities : - entity : switch.homelab_powerstrip_1_socket_1 name : Modem type : custom :toggle-lock-entity-row - entity : switch.homelab_powerstrip_1_socket_2 name : UniFi USG type : custom :toggle-lock-entity-row - entity : switch.homelab_powerstrip_1_socket_3 name : UniFi Switch type : custom :toggle-lock-entity-row - entity : switch.homelab_powerstrip_1_socket_4 name : Dell R210 type : custom :toggle-lock-entity-row - entity : switch.homelab_powerstrip_1_usb_ports name : UniFi Console Pi type : custom :toggle-lock-entity-row

Concerns

One of the concerns I initially had with this setup was the relays. Since these are going to be on 99.9% of their life, the coil will be energized all of that time. I couldn’t find a coil life listed anywhere from the manufacturer of the Y3F-SS-105DM. After some googling, it appears for DC coils, this is a somewhat negligible concern as they will run very cool. My power strip has been on since April 2018 without issues.

If you’ve got any questions, feel free to ping me below.