Dynamic offset from input_number

I would like to make my automations more dynamic and useable by my wife.
Therefore I would like to use dynamic offsets.
e.g. the garden light turns on 15 minutes before sunset.

I would like to change that to be “state of an input_number” before sunset.
Will AppDaemon recognize changes on the input_number value and reschedule the callback?
If not, can I force it to do somehow when the state of the input_number changes?

self.run_at_sunset(self.sunset_lighting, offset=int(float(self.get_state('input_number.my_offset))))

Thanks.

You need to listen for a state change of the input number, cancel the previous timer(the return value of self.run_at_sunset) and schedule a new one.

Great. Thanks.

So this should work out then.

class HandleStateDarkness(hass.Hass):
    def __init__(self, *args, **kwargs):
        self.timer_sunset_lighting = None
        self.timer_sunset_cover = None
        self.timer_sunrise_lighting = None
        self.timer_sunrise_cover = None

        super().__init__(*args, **kwargs)

    def initialize(self):
        self.set_timers()

        # listen to state changes on the offset inputs and reset the timers
        self.listen_state(cb=self.set_timers, entity=AUTOMATION_DARKNESS_LIGHTING_OFFSET)
        self.listen_state(cb=self.set_timers, entity=AUTOMATION_DARKNESS_COVER_OFFSET)

    def set_timers(self, *args, **kwargs):
        # cancel existing timers
        if self.timer_sunset_lighting:
            self.cancel_timer(self.timer_sunset_lighting)
        if self.timer_sunset_cover:
            self.cancel_timer(self.timer_sunset_cover)
        if self.timer_sunrise_lighting:
            self.cancel_timer(self.timer_sunrise_lighting)
        if self.timer_sunrise_cover:
            self.cancel_timer(self.timer_sunrise_cover)

        offset_lighting = int(float(self.get_state(AUTOMATION_DARKNESS_LIGHTING_OFFSET)))
        offset_cover = int(float(self.get_state(AUTOMATION_DARKNESS_COVER_OFFSET)))

        self.timer_sunset_lighting = self.run_at_sunset(self.sunset_lighting, offset=offset_lighting)
        self.timer_sunset_cover = self.run_at_sunset(self.sunset_cover, offset=offset_cover)

        self.timer_sunrise_lighting = self.run_at_sunrise(self.sunrise_lighting, offset=offset_lighting * -1)
        self.timer_sunrise_cover = self.run_at_sunrise(self.sunrise_cover, offset=offset_cover * -1)

that should work.

i would go for another approach.
instead of rescheduling the offset you could just use a long offset(say -2 hours) and a run_in in the callback.

But then i’d have to reschedule the run_in if the offset is changed within this 2h window.

if you change things near the sunrise or sunset you would need to take into account that things go wrong anyway.

settings like that are normally not to change regularly
you change them once in a while and provide a manual override for if you have a specific occasion.

your wife probably has no clue what the exact times are for sunset and sunrise.
whit your approach she could change the offset from 15 mins to 30 mins while at that moment there is only 25 mins to go.
the result would be that it wont be triggered at all that day.
so you would have to tell her: “dont change anything when sunrise or sunset is near or it might fail that day”

and then you are at the same point as with my approach.

1 Like

That’s right. Unfortunately sun_down() doesn’t accept an offset :frowning:
Otherwise I could just call it with the new offset whenever the offset gets updated.

but why do you want to make a daily event that flexible?

give the option to override the running schedule for 1 day with another app.
use a constraint fort the running app and set that in the other app.
and when the day is over set the constraint back.