I am new to Home Assistant and have been working to setup some functionality to improve some scheduling.
I have done hours worth of work trying to reverse engineer scripts and automations after reading through various threads with similar questions however, I am struggling to get to my goal. My intention is to create a script which iterates through a list of rooms which the Roborock stores as ‘Segments’. I have listed a few examples here. Ideally, I can have this script call on a weekday and within the script, I will specify the segment ID/rooms to be cleaned. It will then repeat the script for each one of the listed “for_each” segments. Ideally, I’d also like for it to wait to complete the first segment before going to the next itteration of the “for_each”. It appears to be just running all of these checks at once however.
I also have a helper setup to store the last time the clean was run for a set area. I am using this to store when it was last run so that if I have manually cleaned that room within the specified period, it will skip this room and go to the next in the list.
I have stripped this back to almost nothing to try and start from the bottom but now I am left wondering how to even achieve that. Hopefully someone who knows more about it can assist. I appreciate any guidance.
I will try and qualify some of what I was thinking, but with plain text as I am unsure of the syntax.
alias: Advanced Vacuum Loop
sequence:
- repeat:
for_each:
#here i need to create a list of variables which I can add or remove from. In this case, the numbers are 'segment IDs' which I can send to my vacuum using the command 'app_segment_clean'.
#e.g If i can go through the value 17, it will clean my 'Entryway', then value 23 cleans my kitchen etc.
#These weren't input_datetime values, but just an array of integers I suppose.
sequence:
- choose:
- conditions:
- condition: or
conditions:
- condition: template
value_template: >-
#The first value template here is checking a 'helper' which I have being set once this action completes succesfully further below.
#It will be set to the time this function is last trigerred in the script. I then compare the "NOW" time against this stored helper input_datetime so that I can check if the room was recently cleaned and not double up.
#My thoughts here with the nested 'repeat.item' inside the template, is that I can get the repeat.item values and insert them into my template to check this value is true for each of the values in the variable array.
{{ as_timestamp(now()) - (10) >
as_timestamp(states('input_datetime.{{ repeat.item }}'))
}}
- condition: template
value_template: >-
{{ is_state('vacuum.roborock_s6', 'returning') or is_state('vacuum.roborock_s6', 'docked') }}
#I expect that this first formula will look something like this below
#{{ as_timestamp(now()) - (I will put a value in seconds here to represent how long I want to make the time before it re-cleans the same room) >
#as_timestamp(states('input_datetime.last_clean_{{ repeat.item }}')) <---This section here will say "_.last_clean_17" and collect the value that has been stored in the helper being a date/time value.
#}}
sequence:
- action: vacuum.send_command
metadata: {}
data:
command: app_segment_clean
params: #This parameter section will need to grab the 'segment IDs' from above and for each time it send the command it will send app_segment_clean params: - 17, then it will send - 23 etc.
- "{{ repeat.item.value }}"
entity_id: vacuum.roborock_s6
- wait_template: >-
{{ is_state('vacuum.roborock_s6', 'returning') or is_state('vacuum.roborock_s6', 'docked') }}
continue_on_timeout: false
- action: input_datetime.set_datetime
#This action is now collecting the current datetime that this action is run and will then update the helper value with the current time so I can vallidate against it.
#The logic Id like here is that if I decide to manually select a room to clean at some time within my window, I will have it update this value. If the last clean now falls within my tolerance window, this room will be skipped in the Advanced Vacuum schedule script as the value will become false.
metadata: {}
data:
datetime: "{{ now() }}"
target:
entity_id: "{{ repeat.item.datetime }}"
Ideally, in the end, I’d like to be able to map each rooms ‘segment’ number to a friendly text that I can see without having to refer back to my notes on which number represents a room.
If you use that format, you have to duplicate the list as a dictionary… What you have there is a list of dictionaries with a dynamic key. If you use that over what I wrote, the code is significantly more complicated. I can post that code in a bit, on mobile at the moment
where it would need you to take notes. It’s the same data, just presented slightly differently.
In regards to that guys post, he has a script that executes the run vacuum command, so you can’t see what he’s doing inside it. He’s likely has and maintains a dictionary that maps room names to input datetimes and numerical values for the rooms.
Personally, I wouldn’t even have a loop. I’d just spool the data together and output the entire list at once with one command. Then the vacuum would just do all the rooms without needing to loop.
Thanks once again Petro! I guess I was more interested in learning the functionality of what is possible for future endeavours and not just going the datetime field route.
I will give this a try soon and continue learning I suppose!
Yes, the intention with the loop is to hopefully create the ability to pause between loops if something changes. i.e. If i only want the vacuum to run when I am not home, it will check this before it loops back again to continue to the next room.
Anyway, it’s just ongoing project and learning I suppose.
You may want to make it return to the base in the stop vacuum section. I’d probably add a counter helper to ensure you only vacuum once a day. And I’d probably add a condition to only do this on weekdays or something like that.
Agree. The loop is an issue. I very much prefer to build something that gathers state and responds in kind at runtime.
I do what you suggest. Twice a day I fire a script that collects information similar to Op… Last cleaned, days allowed between cleaning, is the room ready(some I require a manual check) the scheduler fires. And it goes. None of this loop nonsense. If it needs to charge or clean it’s mop halfway it does. The it goes back to the dock and waits for the next trigger. (usually on less than 4 hours)
I could also easily trigger on vacancy (just fire the scheduler script…)
But the trick is the scheduler is ALWAYS active - as templates - with state of if I fire the schedule now -who goes? (list of room names) The the trigger can just about be anything.
As for resolving the room names. I created a macro that resolves names from room numbers and vice versa. Then I use that macro when I need to refer to a room by name.