Created
December 27, 2022 18:20
-
-
Save WarriorRocker/dc26cc361f5826ba3f9aab3237eb269a to your computer and use it in GitHub Desktop.
Eufy 11S RoboVac with ESPHome and Home Assistant
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Eufy 11s v0.1.1 | |
substitutions: | |
# Eufy interface | |
gpio_ir_pin: GPIO5 | |
gpio_power_pin: GPIO4 | |
gpio_brushes_pin: GPIO0 | |
gpio_vacuum_pin: GPIO13 | |
gpio_charging_pin: GPIO12 | |
gpio_battery_pin: A0 | |
esphome: | |
name: eufy_r2 | |
platform: ESP8266 | |
board: d1_mini | |
wifi: | |
ssid: !secret wifi_ssid | |
password: !secret wifi_password | |
# Enable fallback hotspot (captive portal) in case wifi connection fails | |
ap: | |
ssid: "Eufy-R2 Fallback Hotspot" | |
password: !secret cap_password | |
# Enable Captive Portal for fallback hotspot | |
captive_portal: | |
# Enable logging | |
logger: | |
# Enable Home Assistant API | |
api: | |
encryption: | |
key: !secret eufy_enc_key | |
# Enable over-the-air updates | |
ota: | |
password: !secret ota_password | |
# Enable web server interface | |
web_server: | |
globals: | |
- id: internal_state | |
type: float | |
restore_value: no | |
initial_value: "0" | |
binary_sensor: | |
- platform: gpio | |
id: "power" | |
name: "Power" | |
pin: | |
number: $gpio_power_pin | |
mode: INPUT_PULLUP | |
inverted: True | |
- platform: gpio | |
id: "brushes" | |
name: "Brushes" | |
pin: | |
number: $gpio_brushes_pin | |
mode: INPUT_PULLUP | |
inverted: True | |
- platform: gpio | |
id: "vacuum" | |
name: "Vacuum" | |
pin: | |
number: $gpio_vacuum_pin | |
mode: INPUT_PULLUP | |
inverted: True | |
- platform: gpio | |
id: "charging" | |
name: "Charging" | |
pin: | |
number: $gpio_charging_pin | |
mode: INPUT_PULLUP | |
inverted: True | |
sensor: | |
- platform: adc | |
pin: VCC | |
id: "vcc_voltage" | |
name: "VCC Voltage" | |
update_interval: 60s | |
- platform: adc | |
pin: $gpio_battery_pin | |
id: "battery_voltage" | |
name: "Battery Voltage" | |
update_interval: 60s | |
filters: | |
- lambda: return x * 9 * 0.77; | |
- platform: template | |
id: "battery_level" | |
name: "Battery Level" | |
update_interval: 60s | |
accuracy_decimals: 0 | |
lambda: return min(max((id(battery_voltage).state - 20.5) / 1.7 * 100.0, 0.0), 100.0); | |
- platform: template | |
id: "state" | |
name: "State" | |
update_interval: 500ms | |
accuracy_decimals: 0 | |
lambda: |- | |
id(internal_state) = -1; // Set Unknown state | |
if (id(power).state == 1) { // Check if power on | |
id(internal_state) = 1; // Set Idle state | |
if (id(brushes).state == 1) { // Check if brushes on | |
id(internal_state) = 3; // Set Cleaning state | |
if (id(vacuum).state == 0) { // Check if vacuum off | |
id(internal_state) = 4; // Set Homing state | |
} | |
} | |
else { // Not brushes on | |
if (id(charging).state == 1) { // Check if charging on | |
id(internal_state) = 2; // Set Charging State | |
if (id(battery_level).state >= 100.0) { // Check if fully charged | |
id(internal_state) = 5; // Set Charged state | |
} | |
} | |
} | |
} | |
else { // Not powered on | |
id(internal_state) = 0; // Set Off state | |
if (id(charging).state == 1) { // Check if charging on | |
id(internal_state) = 2; // Set Charging state | |
if (id(battery_level).state >= 100.0) { // Check if fully charged | |
id(internal_state) = 5; // Set Charged state | |
} | |
} | |
} | |
if (id(state).state != id(internal_state)) { // Check if state has changed | |
return {id(internal_state)}; // Return updated state | |
} | |
return {}; // Return no state change | |
text_sensor: | |
- platform: template | |
id: "status" | |
name: "Status" | |
update_interval: 500ms | |
lambda: |- | |
if ((id(internal_state) == -1) && (id(status).state != "Unknown")) { | |
return {"Unknown"}; | |
} | |
if ((id(internal_state) == 0) && (id(status).state != "Off")) { | |
return {"Off"}; | |
} | |
if ((id(internal_state) == 1) && (id(status).state != "Idle")) { | |
return {"Idle"}; | |
} | |
if ((id(internal_state) == 2) && (id(status).state != "Charging")) { | |
return {"Charging"}; | |
} | |
if ((id(internal_state) == 3) && (id(status).state != "Cleaning")) { | |
return {"Cleaning"}; | |
} | |
if ((id(internal_state) == 4) && (id(status).state != "Homing")) { | |
return {"Homing"}; | |
} | |
if ((id(internal_state) == 5) && (id(status).state != "Charged")) { | |
return {"Charged"}; | |
} | |
return {}; | |
remote_transmitter: | |
pin: | |
number: $gpio_ir_pin | |
inverted: True | |
carrier_duty_percent: 100% | |
switch: | |
- platform: template | |
id: "action_start" | |
name: "Start" | |
icon: "mdi:play" | |
lambda: return (id(state).state == 3); | |
turn_on_action: | |
- remote_transmitter.transmit_raw: | |
carrier_frequency: 38kHz | |
repeat: | |
times: 3 | |
code: [ | |
3000, -3000, 500, -500, 500, -1500, 500, -1500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -500, 500, -500, | |
500, -1500, 500, -500, 500, -1500, 500, -1500, 500, -1500, | |
500, -500, 500, -500, 500, -500, 500, -500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -1500, 500, -500, | |
500, -500, 500, -500, 500, -1500, 500, -500, 500, -500, | |
500, -500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -500, 500, -500, 500, -500, 500 | |
] | |
- platform: template | |
id: "action_stop" | |
name: "Stop" | |
icon: "mdi:stop" | |
lambda: return ((id(state).state == 0) || (id(state).state == 1)); | |
turn_on_action: | |
- remote_transmitter.transmit_raw: | |
carrier_frequency: 38kHz | |
repeat: | |
times: 3 | |
code: [ | |
3000, -3000, 500, -500, 500, -1500, 500, -1500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -500, 500, -500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -1500, 500, -500, | |
500, -500, 500, -500, 500, -1500, 500, -500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -1500, 500, -1500, 500, -500, | |
500, -1500, 500, -1500, 500, -500, 500, -500, 500 | |
] | |
- platform: template | |
id: "action_forward" | |
name: "Forward" | |
icon: "mdi:chevron-up" | |
lambda: return false; | |
turn_on_action: | |
- remote_transmitter.transmit_raw: | |
carrier_frequency: 38kHz | |
code: [ | |
3000, -3000, 500, -500, 500, -1500, 500, -1500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -500, 500, -500, | |
500, -500, 500, -1500, 500, -500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -500, 500, -500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -500, 500, -1500, | |
500, -500, 500, -500, 500, -1500, 500, -500, 500, -1500, | |
500, -1500, 500, -500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -1500, 500, -500, 500, -1500, | |
500, -500, 500, -1500, 500, -500, 500, -500, 500 | |
] | |
- platform: template | |
id: "action_backward" | |
name: "Backward" | |
icon: "mdi:chevron-down" | |
lambda: return false; | |
turn_on_action: | |
- remote_transmitter.transmit_raw: | |
carrier_frequency: 38kHz | |
code: [ | |
3000, -3000, 500, -500, 500, -1500, 500, -1500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -500, 500, -500, | |
500, -1500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -500, 500, -500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -1500, 500, -500, | |
500, -500, 500, -500, 500, -500, 500, -500, 500, -1500, | |
500, -1500, 500, -500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -500, 500, -500, 500, -500, 500, -500, | |
500, -500, 500, -1500, 500, -500, 500, -1500, 500 | |
] | |
- platform: template | |
id: "action_left" | |
name: "Left" | |
icon: "mdi:chevron-left" | |
lambda: return false; | |
turn_on_action: | |
- remote_transmitter.transmit_raw: | |
carrier_frequency: 38kHz | |
code: [ | |
3000, -3000, 500, -500, 500, -1500, 500, -1500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -500, 500, -500, | |
500, -500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -500, 500, -500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -1500, 500, -500, | |
500, -500, 500, -500, 500, -500, 500, -1500, 500, -500, | |
500, -500, 500, -1500, 500, -500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -1500, 500, -500, 500, -500, | |
500, -1500, 500, -500, 500, -1500, 500, -500, 500 | |
] | |
- platform: template | |
id: "action_right" | |
name: "Right" | |
icon: "mdi:chevron-right" | |
lambda: return false; | |
turn_on_action: | |
- remote_transmitter.transmit_raw: | |
carrier_frequency: 38kHz | |
code: [ | |
3000, -3000, 500, -500, 500, -1500, 500, -1500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -500, 500, -500, | |
500, -1500, 500, -1500, 500, -500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -500, 500, -500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -1500, 500, -500, | |
500, -500, 500, -500, 500, -500, 500, -1500, 500, -1500, | |
500, -500, 500, -500, 500, -500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -500, 500, -500, 500, -500, 500, -500, | |
500, -500, 500, -500, 500, -500, 500, -500, 500 | |
] | |
- platform: template | |
id: "action_home" | |
name: "Home" | |
icon: "mdi:home" | |
lambda: return ((id(state).state == 2) || (id(state).state == 4) || (id(state).state == 5)); | |
turn_on_action: | |
- remote_transmitter.transmit_raw: | |
carrier_frequency: 38kHz | |
repeat: | |
times: 3 | |
code: [ | |
3000, -3000, 500, -500, 500, -1500, 500, -1500, 500, -500, | |
500, -1500, 500, -500, 500, -500, 500, -500, 500, -1500, | |
500, -1500, 500, -1500, 500, -500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -500, 500, -500, 500, -500, | |
500, -500, 500, -500, 500, -500, 500, -1500, 500, -1500, | |
500, -500, 500, -500, 500, -500, 500, -1500, 500, -1500, | |
500, -500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -1500, 500, -1500, 500, -1500, 500, -1500, | |
500, -1500, 500, -500, 500, -1500, 500, -1500, 500, -1500, | |
500, -500, 500, -1500, 500, -500, 500, -500, 500 | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment