bruxy70 / Garbage-Collection

đź—‘ Custom Home Assistant sensor for scheduling garbage collection (or other regularly re-occurring events - weekly on given days, semi-weekly or monthly)
MIT License
383 stars 90 forks source link

Changing dates for holidays #432

Closed pdobrien3 closed 1 year ago

pdobrien3 commented 1 year ago

Before you submit a new bug report, please check that

Write your question here

I have a garbage integration sensor that is scheduled for bi-weekly on a monday. I also have a workday sensor setup (2 day offset) for holidays and an input boolean that turns on when the holiday falls on a monday. The input boolean allows me to change several things. I have been successfully able to change the pickup date from Monday to Tuesday when Monday is a Holiday. My automation basically checks sunday morning with a trigger of event_type: garbage_collection_loaded and if certain conditions exist, does a garbage_collection.offset_date. On Sunday, everything looks to be working as expected. When Monday morning rolls around and event_type: garbage_collection_loaded triggers again, the sensor rolls the date back to Monday. What am I doing wrong? Here is the automation:

- id: 'u8'
  alias: Update Garbage Entity On Holiday Garbage Integration
  trigger:
    platform: event
    event_type: garbage_collection_loaded
    event_data:
      entity_id: sensor.garbage
  action:
    - choose:
        - conditions: # CHANGE THE DATE WHEN IT FALLS ON A HOLIDAY ##
            - condition: state
              entity_id: input_boolean.holiday
              state: 'on'
            - condition: time
              weekday:
                - sun
            - condition: template
              value_template: "{% if states('sensor.garbage').split(', ')[1] == 'in 2 days' %}True {% else %}False {% endif %}"
          sequence:
            - service: garbage_collection.offset_date
              data:
                entity_id: sensor.garbage
                date: "{{(as_timestamp(now()) + (24*3600))| timestamp_custom('%Y-%m-%d') }}"
                offset: 1 
            - service: garbage_collection.update_state
              data:
                entity_id: sensor.garbage
      default:
        - service: garbage_collection.update_state
          data:
            entity_id: sensor.garbage
  mode: single

The only thing I can guess is the default operation is somehow reverting the state but it would make sense that once the date is changed and set, a update_state would only help to show the actual state (2 days, tomorrow, today). Help me understand please. Thank you !!!

bruxy70 commented 1 year ago

The way this was meant to do is to iterate through the calculated dates in for_each: "{{ trigger.event.data.collection_dates }}", evaluate the condition there, and eventually call the offset for date: "{{ repeat.item }}". This is done BEFORE the state gets updated (reason being, if you have an automation triggered by the date, you should trigger it by the modified date, not by the invalid date that will get moved). So using the state in an automation that runs before the state is calculated will not work. Also, I have the feeling that you trigger it for the date in 2 days, but then you offset the date today + 1 day. So such date will not exist, so it won't offset it.

pdobrien3 commented 1 year ago

unfortunately that explanation is a little above my knowledge level. I am trying to understand though. If I look at my calendar. The dates are properly set well in advance throughout the year. The only thing I want to do is change a single date on a holiday. The automation I posted runs before the date gets updated so it would be in two days (for the condition). It still has the date from Saturday. It checks if there is a holiday (input boolean) and then adds one more day to the current date that is already set.

I have been able to successfully move the date. My only issue is figuring out why it changes it back to Monday on monday morning. Sorry I dont fully understand your explanation.

pdobrien3 commented 1 year ago

the only thing I do is use an entity_filter card to show icons in the UI with a filter of tomorrow so the tomorrow state is really only valid for a short period in the middle of the night until it is updates. I also do notifications but those are dependant on another input boolean that is used as a condition to tell if the notifications should happen on Sunday (not a holiday) or Monday (holiday)

bruxy70 commented 1 year ago

What I say is, the automation runs before the state gets updated (and then you do the update by calling garbage_collection.update_state). So if you refer to states('sensor.garbage'), it is unpredictable what it does, sometimes it will not work at all, sometimes it will work wrong, and sometimes it might do something,

pdobrien3 commented 1 year ago

that is just it. I only refer to the state of the sensor to update it if it falls on a holiday, and I can predict its state for conditions, cause I know it hasn't been updated. The only other times I refer to the state of the sensor, I know it has been updated. I guess my question is, does the garbage_collection.update_state refer back to the pre-defined setup in helpers? If so, I just need to have another choose for monday when it is a holiday, like so:

        - conditions: # MAINTAIN THE DATE WHEN IT FALLS ON A HOLIDAY ##
            - condition: state
              entity_id: input_boolean.holiday
              state: 'on'
            - condition: time
              weekday:
                - mon
            - condition: state
              entity_id: sensor.garbage
              state: 'tomorrow'
          sequence:
            - service: garbage_collection.add_date
              data:
                entity_id: sensor.garbage
                date: "{{(as_timestamp(now()) + (24*3600))| timestamp_custom('%Y-%m-%d') }}"
            - service: garbage_collection.update_state
              data:
                entity_id: sensor.garbage
bruxy70 commented 1 year ago

The whole automation is called before the state is updated. In fact, the state is not updated at all automatically, you update it by calling garbage_collection.update_state. So before that, you can modify the dates by calling the services. Then you call update state, and it will calculate the state. So referring to the state in the automation makes no sense. If it gets any state, it is a random value from some previous update. It does not work that way. So if you keep doing it this way, I can't help you I am afraid.

pdobrien3 commented 1 year ago

Auh, no. The default is to update the state with garbage_collection.update_state nightly. The only time that is different is on Sunday morning if Monday is a holiday. Am I still missing something?

And the reality is, that condition that checks the state is probably not even needed.

bruxy70 commented 1 year ago

The whole point is, it should be able to calculate the calendar not only at the actual day, but at any time. Otherwise it will show a wrong date all the way until the collection day. So you should not really care when this is updated.

If you want to do the logic on the day it is triggered, you perhaps do not need to modify the helper at all. Just leave it as it is, then trigger an automation every day and set-up a helper based on whatever logic you want.

pdobrien3 commented 1 year ago

The whole point is, it should be able to calculate the calendar not only at the actual day, but at any time. Otherwise it will show a wrong date all the way until the collection day. So you should not really care when this is updated.

That is not the case but you closed the issue so I guess I will figure it out on my own. I really don’t understand the need for some of the services exposed by this integration.

If you want to do the logic on the day it is triggered, you perhaps do not need to modify the helper at all. Just leave it as it is, then trigger an automation every day and set-up a helper based on whatever logic you want.

that is really what I am doing but having the ability to pre-determine 99% of the dates is just a great benefit. Anyway, peace.