Created
February 3, 2022 06:59
-
-
Save vidvisionify/d0daf4549223909795fa09de1b1b432e to your computer and use it in GitHub Desktop.
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
# ======================================================================================= # | |
# | |
# V A L E T U D O & H O M E A S S I S T A N T | |
# | |
# Phil Cooper, @ 2022 Jan 26 | |
# Latest Major Revision: Let's begin. | |
# | |
# vidvisionify@gmail.com | |
# @vidvisionify | |
# | |
# ======================================================================================= # | |
# I was going through the Valetudo docs again after install, and I was confused by the Home Assistant integration. | |
# Sure, most of the functionality is there via MQTT and services, but the reccomendations in the tutorial | |
# suggest you edit several files. | |
# https://valetudo.cloud/pages/integrations/home-assistant-integration.html | |
# | |
## Why not use a package instead?? | |
## I took several bits from the above tutorial for this, and threw in some other things I use. | |
## I'm no programmer, I just bodge things together in YAML. This is my personal package, YMMV | |
## For this package, my robot is a Dreame D9 called 'Dreame' with the entity id of 'vacuum.valetudo_d9' | |
## No autoempty dock here, since my robot doesn't have that. | |
# ======================================================================================= # | |
## Automation Ideas | |
## - Error Notifications via Phone | |
## - Vacuum when everyone is Away | |
## - Vacuum Daily | |
## - Return to base when people return home | |
## - When filters/brush low | |
## - Notification on phone | |
## - Add todoist task | |
## I've had issues in the past when customize-related stuff isn't at the top of a package, so we'll get that out of the way now. | |
## Valetudo's script wants us to add room-ids attributes to our selections, so doing that here. Check your 'map segments' sensor. | |
homeassistant: | |
customize_glob: | |
"sensor.dreame*": | |
icon: mdi:robot-vacuum | |
input_boolean.vacuum_livingroom: | |
room_id: "5" | |
input_boolean.vacuum_kitchen: | |
room_id: "6" | |
input_boolean.vacuum_hallway: | |
room_id: "4" | |
input_boolean.vacuum_lobby: | |
room_id: "1" | |
input_boolean.vacuum_bathroom: | |
room_id: "2" | |
input_boolean.vacuum_alex: | |
room_id: "3" | |
# Sure, Valetudo creates a sensor for the current job, but let's create sensors to track today's cleaning time, and the time for the week. | |
# Using these, you could make an automation to make a to-do task after X hours of cleaning. | |
# I honestly forgot where I got these templates from, I've used them since I had an ECOVACS Deebot. | |
sensor: | |
- platform: history_stats | |
name: Dreame Today | |
entity_id: vacuum.valetudo_d9 | |
state: 'cleaning' | |
type: time | |
# icon: identified above in customize_glob | |
start: '{{ now().replace(hour=0).replace(minute=0).replace(second=0) }}' | |
end: '{{ now() }}' | |
- platform: history_stats | |
name: Dreame This Week | |
entity_id: vacuum.valetudo_d9 | |
state: 'cleaning' | |
type: time | |
# icon: identified above in customize_glob | |
start: '{{ as_timestamp( now().replace(hour=0).replace(minute=0).replace(second=0) ) - now().weekday() * 86400 }}' | |
end: '{{ now() }}' | |
# I also like to breakout the battery into it's own sensor. | |
# Probably could just use templates for that, but I use attributes-extractor instead. | |
# https://github.com/pilotak/homeassistant-attributes | |
- platform: attributes | |
attribute: battery_level | |
friendly_name: "Dreame Battery" | |
entities: | |
- vacuum.valetudo_d9 | |
## You know, having the consumable sensors as minutes isn't great. | |
## Let's make new sensors with hours instead. I don't think I can set entity_ids AND names via config, | |
## we'll focus on IDs and customize the names later. | |
template: | |
- sensor: | |
- name: "valetudo_d9_main_brush_hours" | |
unique_id: "valetudo_d9_main_brush_hours" | |
unit_of_measurement: "hours" | |
state_class: total | |
icon: mdi:progress-wrench | |
state: > | |
{% set time = states.sensor.valetudo_d9_main_brush.state %} | |
{% set hours = ((time | int / 60) | string).split('.')[0] %} | |
{{hours}} | |
attributes: | |
minutes: > | |
{{states.sensor.valetudo_d9_main_brush.state}} | |
hours: > | |
{% set time = states.sensor.valetudo_d9_main_brush.state %} | |
{% set hours = ((time | int / 60) | string).split('.')[0] %} | |
{{hours}} | |
days: > | |
{% set time = states.sensor.valetudo_d9_main_brush.state %} | |
{% set hours = ((time | int / 60) | string).split('.')[0] %} | |
{% set days = ((hours | int / 24) | string).split('.')[0] %} | |
{{days}} | |
- name: "valetudo_d9_main_filter_hours" | |
unique_id: "valetudo_d9_main_filter_hours" | |
unit_of_measurement: "hours" | |
state_class: total | |
icon: mdi:progress-wrench | |
state: > | |
{% set time = states.sensor.valetudo_d9_main_filter.state %} | |
{% set hours = ((time | int / 60) | string).split('.')[0] %} | |
{{hours}} | |
attributes: | |
minutes: > | |
{{states.sensor.valetudo_d9_main_filter.state}} | |
hours: > | |
{% set time = states.sensor.valetudo_d9_main_filter.state %} | |
{% set hours = ((time | int / 60) | string).split('.')[0] %} | |
{{hours}} | |
days: > | |
{% set time = states.sensor.valetudo_d9_main_filter.state %} | |
{% set hours = ((time | int / 60) | string).split('.')[0] %} | |
{% set days = ((hours | int / 24) | string).split('.')[0] %} | |
{{days}} | |
- name: "valetudo_d9_right_brush_hours" | |
unique_id: "valetudo_d9_right_brush_hours" | |
unit_of_measurement: "hours" | |
state_class: total | |
icon: mdi:progress-wrench | |
state: > | |
{% set time = states.sensor.valetudo_d9_right_brush.state %} | |
{% set hours = ((time | int / 60) | string).split('.')[0] %} | |
{{hours}} | |
attributes: | |
minutes: > | |
{{states.sensor.valetudo_d9_right_brush.state}} | |
hours: > | |
{% set time = states.sensor.valetudo_d9_right_brush.state %} | |
{% set hours = ((time | int / 60) | string).split('.')[0] %} | |
{{hours}} | |
days: > | |
{% set time = states.sensor.valetudo_d9_right_brush.state %} | |
{% set hours = ((time | int / 60) | string).split('.')[0] %} | |
{% set days = ((hours | int / 24) | string).split('.')[0] %} | |
{{days}} | |
# A sensor to convert the 'Current Run' time from seconds to minutes. | |
# This could built upon to show hours too, but I'm bad at templates. | |
- name: "valetudo_d9_current_statistics_time_minutes" | |
unique_id: "valetudo_d9_current_statistics_time_minutes" | |
unit_of_measurement: "minutes" | |
state_class: total | |
icon: mdi:timer-outline | |
state: > | |
{% set uptime = (states.sensor.valetudo_d9_current_statistics_time.state | int) | int %} | |
{% set minutes = ((uptime / 60) % 60)| int %} | |
{{minutes}} | |
# Converting 'Current Area' to square meters | |
- name: "valetudo_d9_current_statistics_area_meters" | |
unique_id: "valetudo_d9_current_statistics_area_meters" | |
unit_of_measurement: "m²" | |
state_class: total | |
icon: mdi:texture-box | |
state: > | |
{% set area = (states.sensor.valetudo_d9_current_statistics_area.state | int) | int %} | |
{% set meters = ((area)/ 100)/100| int %} | |
{{meters}} | |
# Time to create the segment selections. | |
# I added 'Clean' to the friendly names, to make them easier to find later. | |
input_boolean: | |
vacuum_livingroom: | |
name: Clean Living Room | |
icon: mdi:sofa | |
vacuum_kitchen: | |
name: Clean Kitchen | |
icon: mdi:silverware-fork-knife | |
vacuum_hallway: | |
name: Clean Hallway | |
icon: mdi:foot-print | |
vacuum_lobby: | |
name: Clean Lobby | |
icon: mdi:popcorn | |
vacuum_bathroom: | |
name: Clean Bathroom | |
icon: mdi:toilet | |
vacuum_alex: | |
name: Clean Alex's Bedroom | |
icon: mdi:bed-empty | |
# One pass of my first floor only takes 30min, let's add the ability for it to run multiple times. | |
input_number: | |
vacuum_iterations: | |
name: Vacuum Iterations | |
icon: mdi:repeat | |
initial: 1 | |
min: 1 | |
max: 4 | |
step: 1 | |
# Grouping the segments together makes the script do things. | |
group: | |
vacuum_rooms: | |
name: Vacuum Rooms | |
entities: | |
- input_boolean.vacuum_livingroom | |
- input_boolean.vacuum_kitchen | |
- input_boolean.vacuum_hallway | |
- input_boolean.vacuum_lobby | |
- input_boolean.vacuum_bathroom | |
- input_boolean.vacuum_alex | |
# Time for the script that actually makes things go. | |
# I'm not sure why the tutorial splits this into two scripts? We can just use one template. | |
script: | |
vacuum_clean_segments: | |
alias: Start Cleaning | |
icon: mdi:robot-vacuum | |
mode: single | |
sequence: | |
- service: mqtt.publish | |
data: | |
# The line below you may need to edit for your robot. My identifier is D9. | |
topic: valetudo/D9/MapSegmentationCapability/clean/set | |
payload_template: >- | |
{"segment_ids": {{expand("group.vacuum_rooms") | | |
selectattr("state","eq","on")| map(attribute="attributes.room_id") | list | | |
to_json}}, "iterations": {{states.input_number.vacuum_iterations.state|int | |
}} } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment