add OnlyOnDates to schedule, change exceptionday to exceptiondates everywhere

This commit is contained in:
Sam Lewis
2022-11-26 23:36:19 -05:00
parent 555bafa2e5
commit 60349852e6
6 changed files with 70 additions and 53 deletions

View File

@@ -78,10 +78,10 @@ sunset := ga.NewDailySchedule().Call(myFunc).Sunset().Build()
Daily schedules have other functions to change the behavior. Daily schedules have other functions to change the behavior.
| Function | Info | | Function | Info |
| ------------------------------------ | ----------------------------------------------------------------------------------- | | ----------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| ExceptionDay(time.Time) | A one time exception on the given date. Time is ignored, applies to whole day. | | ExceptionDates(t time.Time, ...time.Time) | Skip the schedule on the given date(s). Functions like a blocklist. Cannot be combined with OnlyOnDates. |
| ExceptionRange(time.Time, time.Time) | A one time exception between the two date/times. Both date and time are considered. | | OnlyOnDates(t time.Time, ...time.Time) | Run only on the given date(s). Functions like an allowlist. Cannot be combined with ExceptionDates. |
#### Schedule Callback function #### Schedule Callback function
@@ -106,18 +106,18 @@ etl := ga.NewEntityListener().EntityIds("binary_sensor.front_door").Call(myFunc)
Entity listeners have other functions to change the behavior. Entity listeners have other functions to change the behavior.
| Function | Info | | Function | Info |
| ------------------------------------ | ------------------------------------------------------------------------------------------------- | | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| ToState("on") | Function only called if new state matches argument. | | ToState("on") | Function only called if new state matches argument. |
| FromState("on") | Function only called if old state matches argument. | | FromState("on") | Function only called if old state matches argument. |
| Throttle("30s") | Minimum time between function calls. | | Throttle("30s") | Minimum time between function calls. |
| Duration("30s") | Requires ToState(). Sets how long the entity should be in the state before running your function. | | Duration("30s") | Requires ToState(). Sets how long the entity must be in the state before running your function. |
| OnlyAfter("03:00") | Only run your function after a specified time of day. | | OnlyAfter("03:00") | Only run your function after a specified time of day. |
| OnlyBefore("03:00") | Only run your function before a specified time of day. | | OnlyBefore("03:00") | Only run your function before a specified time of day. |
| OnlyBetween("03:00", "14:00") | Only run your function between two specified times of day. | | OnlyBetween("03:00", "14:00") | Only run your function between two specified times of day. |
| ExceptionDay(time.Time) | A one time exception on the given date. Time is ignored, applies to whole day. | | ExceptionDates(time.Time, ...time.Time) | A one time exception on the given date. Time is ignored, applies to whole day. Functions like a "blocklist". |
| ExceptionRange(time.Time, time.Time) | A one time exception between the two date/times. Both date and time are considered. | | ExceptionRange(time.Time, time.Time) | A one time exception between the two date/times. Both date and time are considered. Functions like a "blocklist". |
| RunOnStartup() | Run your callback once during App.Start() | | RunOnStartup() | Run your callback during `App.Start()`. |
#### Entity Listener Callback function #### Entity Listener Callback function
@@ -143,14 +143,14 @@ evl := ga.NewEntityListener().EntityIds("binary_sensor.front_door").Call(myFunc)
Event listeners have other functions to change the behavior. Event listeners have other functions to change the behavior.
| Function | Info | | Function | Info |
| ------------------------------------ | ----------------------------------------------------------------------------------- | | --------------------------------------- | ----------------------------------------------------------------------------------- |
| Throttle("30s") | Minimum time between function calls. | | Throttle("30s") | Minimum time between function calls. |
| OnlyAfter("03:00") | Only run your function after a specified time of day. | | OnlyAfter("03:00") | Only run your function after a specified time of day. |
| OnlyBefore("03:00") | Only run your function before a specified time of day. | | OnlyBefore("03:00") | Only run your function before a specified time of day. |
| OnlyBetween("03:00", "14:00") | Only run your function between two specified times of day. | | OnlyBetween("03:00", "14:00") | Only run your function between two specified times of day. |
| ExceptionDay(time.Time) | A one time exception on the given date. Time is ignored, applies to whole day. | | ExceptionDates(time.Time, ...time.Time) | A one time exception on the given date. Time is ignored, applies to whole day. |
| ExceptionRange(time.Time, time.Time) | A one time exception between the two date/times. Both date and time are considered. | | ExceptionRange(time.Time, time.Time) | A one time exception between the two date/times. Both date and time are considered. |
#### Event Listener Callback function #### Event Listener Callback function
@@ -179,12 +179,12 @@ interval = ga.NewInterval().Call(myFunc).Every("5m").StartingAt("10:00").EndingA
Intervals have other functions to change the behavior. Intervals have other functions to change the behavior.
| Function | Info | | Function | Info |
| ------------------------------------ | ----------------------------------------------------------------------------------- | | --------------------------------------- | ----------------------------------------------------------------------------------- |
| StartingAt(TimeString) | What time the interval begins to run each day. | | StartingAt(TimeString) | What time the interval begins to run each day. |
| EndingAt(TimeString) | What time the interval stops running each day. | | EndingAt(TimeString) | What time the interval stops running each day. |
| ExceptionDay(time.Time) | A one time exception on the given date. Time is ignored, applies to whole day. | | ExceptionDates(time.Time, ...time.Time) | A one time exception on the given date. Time is ignored, applies to whole day. |
| ExceptionRange(time.Time, time.Time) | A one time exception between the two date/times. Both date and time are considered. | | ExceptionRange(time.Time, time.Time) | A one time exception between the two date/times. Both date and time are considered. |
#### Interval Callback function #### Interval Callback function

View File

@@ -22,7 +22,7 @@ type EntityListener struct {
delay time.Duration delay time.Duration
delayTimer *time.Timer delayTimer *time.Timer
exceptionDays []time.Time exceptionDates []time.Time
exceptionRanges []timeRange exceptionRanges []timeRange
runOnStartup bool runOnStartup bool
@@ -133,8 +133,8 @@ func (b elBuilder3) Throttle(s DurationString) elBuilder3 {
return b return b
} }
func (b elBuilder3) ExceptionDay(t time.Time) elBuilder3 { func (b elBuilder3) ExceptionDates(t time.Time, tl ...time.Time) elBuilder3 {
b.entityListener.exceptionDays = append(b.entityListener.exceptionDays, t) b.entityListener.exceptionDates = append(tl, t)
return b return b
} }
@@ -189,7 +189,7 @@ func callEntityListeners(app *App, msgBytes []byte) {
if c := checkThrottle(l.throttle, l.lastRan); c.fail { if c := checkThrottle(l.throttle, l.lastRan); c.fail {
continue continue
} }
if c := checkExceptionDays(l.exceptionDays); c.fail { if c := checkExceptionDates(l.exceptionDates); c.fail {
continue continue
} }
if c := checkExceptionRanges(l.exceptionRanges); c.fail { if c := checkExceptionRanges(l.exceptionRanges); c.fail {

View File

@@ -17,7 +17,7 @@ type EventListener struct {
throttle time.Duration throttle time.Duration
lastRan carbon.Carbon lastRan carbon.Carbon
exceptionDays []time.Time exceptionDates []time.Time
exceptionRanges []timeRange exceptionRanges []timeRange
} }
@@ -80,8 +80,8 @@ func (b eventListenerBuilder3) Throttle(s DurationString) eventListenerBuilder3
return b return b
} }
func (b eventListenerBuilder3) ExceptionDay(t time.Time) eventListenerBuilder3 { func (b eventListenerBuilder3) ExceptionDates(t time.Time, tl ...time.Time) eventListenerBuilder3 {
b.eventListener.exceptionDays = append(b.eventListener.exceptionDays, t) b.eventListener.exceptionDates = append(tl, t)
return b return b
} }
@@ -118,7 +118,7 @@ func callEventListeners(app *App, msg ws.ChanMsg) {
if c := checkThrottle(l.throttle, l.lastRan); c.fail { if c := checkThrottle(l.throttle, l.lastRan); c.fail {
continue continue
} }
if c := checkExceptionDays(l.exceptionDays); c.fail { if c := checkExceptionDates(l.exceptionDates); c.fail {
continue continue
} }
if c := checkExceptionRanges(l.exceptionRanges); c.fail { if c := checkExceptionRanges(l.exceptionRanges); c.fail {

View File

@@ -16,12 +16,12 @@ type Interval struct {
endTime TimeString endTime TimeString
nextRunTime time.Time nextRunTime time.Time
exceptionDays []time.Time exceptionDates []time.Time
exceptionRanges []timeRange exceptionRanges []timeRange
} }
func (i Interval) Hash() string { func (i Interval) Hash() string {
return fmt.Sprint(i.startTime, i.endTime, i.frequency, i.callback, i.exceptionDays, i.exceptionRanges) return fmt.Sprint(i.startTime, i.endTime, i.frequency, i.callback, i.exceptionDates, i.exceptionRanges)
} }
// Call // Call
@@ -34,7 +34,7 @@ type intervalBuilderCall struct {
interval Interval interval Interval
} }
// Offset, ExceptionDay, ExceptionRange // Offset, ExceptionDates, ExceptionRange
type intervalBuilderEnd struct { type intervalBuilderEnd struct {
interval Interval interval Interval
} }
@@ -93,8 +93,8 @@ func (sb intervalBuilderEnd) EndingAt(s TimeString) intervalBuilderEnd {
return sb return sb
} }
func (sb intervalBuilderEnd) ExceptionDay(t time.Time) intervalBuilderEnd { func (sb intervalBuilderEnd) ExceptionDates(t time.Time, tl ...time.Time) intervalBuilderEnd {
sb.interval.exceptionDays = append(sb.interval.exceptionDays, t) sb.interval.exceptionDates = append(tl, t)
return sb return sb
} }
@@ -137,7 +137,7 @@ func (i Interval) maybeRunCallback(a *App) {
if c := checkStartEndTime(i.endTime /* isStart = */, false); c.fail { if c := checkStartEndTime(i.endTime /* isStart = */, false); c.fail {
return return
} }
if c := checkExceptionDays(i.exceptionDays); c.fail { if c := checkExceptionDates(i.exceptionDates); c.fail {
return return
} }
if c := checkExceptionRanges(i.exceptionRanges); c.fail { if c := checkExceptionRanges(i.exceptionRanges); c.fail {

View File

@@ -62,7 +62,7 @@ func checkThrottle(throttle time.Duration, lastRan carbon.Carbon) conditionCheck
return cc return cc
} }
func checkExceptionDays(eList []time.Time) conditionCheck { func checkExceptionDates(eList []time.Time) conditionCheck {
cc := conditionCheck{fail: false} cc := conditionCheck{fail: false}
for _, e := range eList { for _, e := range eList {
y1, m1, d1 := e.Date() y1, m1, d1 := e.Date()
@@ -87,6 +87,23 @@ func checkExceptionRanges(eList []timeRange) conditionCheck {
return cc return cc
} }
func checkAllowlistDates(eList []time.Time) conditionCheck {
if len(eList) == 0 {
return conditionCheck{fail: false}
}
cc := conditionCheck{fail: true}
for _, e := range eList {
y1, m1, d1 := e.Date()
y2, m2, d2 := time.Now().Date()
if y1 == y2 && m1 == m2 && d1 == d2 {
cc.fail = false
break
}
}
return cc
}
func checkStartEndTime(s TimeString, isStart bool) conditionCheck { func checkStartEndTime(s TimeString, isStart bool) conditionCheck {
cc := conditionCheck{fail: false} cc := conditionCheck{fail: false}
// pass immediately if default // pass immediately if default

View File

@@ -23,8 +23,8 @@ type DailySchedule struct {
isSunset bool isSunset bool
sunOffset DurationString sunOffset DurationString
exceptionDays []time.Time exceptionDates []time.Time
exceptionRanges []timeRange allowlistDates []time.Time
} }
func (s DailySchedule) Hash() string { func (s DailySchedule) Hash() string {
@@ -93,13 +93,13 @@ func (sb scheduleBuilderCall) Sunset(offset ...DurationString) scheduleBuilderEn
return scheduleBuilderEnd(sb) return scheduleBuilderEnd(sb)
} }
func (sb scheduleBuilderEnd) ExceptionDay(t time.Time) scheduleBuilderEnd { func (sb scheduleBuilderEnd) ExceptionDates(t time.Time, tl ...time.Time) scheduleBuilderEnd {
sb.schedule.exceptionDays = append(sb.schedule.exceptionDays, t) sb.schedule.exceptionDates = append(tl, t)
return sb return sb
} }
func (sb scheduleBuilderEnd) ExceptionRange(start, end time.Time) scheduleBuilderEnd { func (sb scheduleBuilderEnd) OnlyOnDates(t time.Time, tl ...time.Time) scheduleBuilderEnd {
sb.schedule.exceptionRanges = append(sb.schedule.exceptionRanges, timeRange{start, end}) sb.schedule.allowlistDates = append(tl, t)
return sb return sb
} }
@@ -132,10 +132,10 @@ func runSchedules(a *App) {
} }
func (s DailySchedule) maybeRunCallback(a *App) { func (s DailySchedule) maybeRunCallback(a *App) {
if c := checkExceptionDays(s.exceptionDays); c.fail { if c := checkExceptionDates(s.exceptionDates); c.fail {
return return
} }
if c := checkExceptionRanges(s.exceptionRanges); c.fail { if c := checkAllowlistDates(s.allowlistDates); c.fail {
return return
} }
go s.callback(a.service, a.state) go s.callback(a.service, a.state)