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.
| Function | Info |
| ------------------------------------ | ----------------------------------------------------------------------------------- |
| ExceptionDay(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. |
| Function | Info |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| ExceptionDates(t time.Time, ...time.Time) | Skip the schedule on the given date(s). Functions like a blocklist. Cannot be combined with OnlyOnDates. |
| 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
@@ -106,18 +106,18 @@ etl := ga.NewEntityListener().EntityIds("binary_sensor.front_door").Call(myFunc)
Entity listeners have other functions to change the behavior.
| Function | Info |
| ------------------------------------ | ------------------------------------------------------------------------------------------------- |
| ToState("on") | Function only called if new state matches argument. |
| FromState("on") | Function only called if old state matches argument. |
| 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. |
| 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. |
| 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. |
| ExceptionRange(time.Time, time.Time) | A one time exception between the two date/times. Both date and time are considered. |
| RunOnStartup() | Run your callback once during App.Start() |
| Function | Info |
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| ToState("on") | Function only called if new state matches argument. |
| FromState("on") | Function only called if old state matches argument. |
| Throttle("30s") | Minimum time between function calls. |
| 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. |
| 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. |
| 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. Functions like a "blocklist". |
| RunOnStartup() | Run your callback during `App.Start()`. |
#### 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.
| Function | Info |
| ------------------------------------ | ----------------------------------------------------------------------------------- |
| Throttle("30s") | Minimum time between function calls. |
| 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. |
| 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. |
| ExceptionRange(time.Time, time.Time) | A one time exception between the two date/times. Both date and time are considered. |
| Function | Info |
| --------------------------------------- | ----------------------------------------------------------------------------------- |
| Throttle("30s") | Minimum time between function calls. |
| 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. |
| OnlyBetween("03:00", "14:00") | Only run your function between two specified times of 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. |
#### 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.
| Function | Info |
| ------------------------------------ | ----------------------------------------------------------------------------------- |
| StartingAt(TimeString) | What time the interval begins to run 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. |
| ExceptionRange(time.Time, time.Time) | A one time exception between the two date/times. Both date and time are considered. |
| Function | Info |
| --------------------------------------- | ----------------------------------------------------------------------------------- |
| StartingAt(TimeString) | What time the interval begins to run each day. |
| EndingAt(TimeString) | What time the interval stops running each 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. |
#### Interval Callback function

View File

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

View File

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

View File

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

View File

@@ -62,7 +62,7 @@ func checkThrottle(throttle time.Duration, lastRan carbon.Carbon) conditionCheck
return cc
}
func checkExceptionDays(eList []time.Time) conditionCheck {
func checkExceptionDates(eList []time.Time) conditionCheck {
cc := conditionCheck{fail: false}
for _, e := range eList {
y1, m1, d1 := e.Date()
@@ -87,6 +87,23 @@ func checkExceptionRanges(eList []timeRange) conditionCheck {
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 {
cc := conditionCheck{fail: false}
// pass immediately if default

View File

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