mirror of
https://github.com/Xevion/go-ha.git
synced 2025-12-06 11:15:13 -06:00
add Duration for entityListener and rename TimeString to DurationString
This commit is contained in:
13
app.go
13
app.go
@@ -2,7 +2,6 @@ package gomeassistant
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
@@ -30,7 +29,11 @@ type app struct {
|
|||||||
eventListeners map[string][]*EventListener
|
eventListeners map[string][]*EventListener
|
||||||
}
|
}
|
||||||
|
|
||||||
type TimeString string
|
/*
|
||||||
|
DurationString represents a duration, such as "2s" or "24h".
|
||||||
|
See https://pkg.go.dev/time#ParseDuration for all valid time units.
|
||||||
|
*/
|
||||||
|
type DurationString string
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NewApp establishes the websocket connection and returns an object
|
NewApp establishes the websocket connection and returns an object
|
||||||
@@ -112,7 +115,7 @@ func (a *app) RegisterEventListener(evl EventListener) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSunriseSunset(a *app, sunrise bool, offset []TimeString) carbon.Carbon {
|
func getSunriseSunset(a *app, sunrise bool, offset []DurationString) carbon.Carbon {
|
||||||
printString := "Sunset"
|
printString := "Sunset"
|
||||||
attrKey := "next_setting"
|
attrKey := "next_setting"
|
||||||
if sunrise {
|
if sunrise {
|
||||||
@@ -145,10 +148,6 @@ func getSunriseSunset(a *app, sunrise bool, offset []TimeString) carbon.Carbon {
|
|||||||
return nextSetOrRise
|
return nextSetOrRise
|
||||||
}
|
}
|
||||||
|
|
||||||
func carbon2TimeString(c carbon.Carbon) string {
|
|
||||||
return fmt.Sprintf("%02d:%02d", c.Hour(), c.Minute())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *app) Start() {
|
func (a *app) Start() {
|
||||||
// schedules
|
// schedules
|
||||||
go runSchedules(a)
|
go runSchedules(a)
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ type EntityListener struct {
|
|||||||
betweenEnd string
|
betweenEnd string
|
||||||
throttle time.Duration
|
throttle time.Duration
|
||||||
lastRan carbon.Carbon
|
lastRan carbon.Carbon
|
||||||
|
delay time.Duration
|
||||||
|
delayTimer *time.Timer
|
||||||
}
|
}
|
||||||
|
|
||||||
type EntityListenerCallback func(*Service, EntityData)
|
type EntityListenerCallback func(*Service, EntityData)
|
||||||
@@ -111,7 +113,20 @@ func (b elBuilder3) ToState(s string) elBuilder3 {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b elBuilder3) Throttle(s TimeString) elBuilder3 {
|
func (b elBuilder3) Duration(s DurationString) elBuilder3 {
|
||||||
|
// TODO: test this, should rename duration? not sure if Delay implies that state change cancels the callback
|
||||||
|
// if change name to Duration then enforce being used with ToState, should FromState be allowed?
|
||||||
|
// if FromState set to 3, then state changes to 2 and changes again to 1 halfway through delay, should the
|
||||||
|
// delay reset?
|
||||||
|
d, err := time.ParseDuration(string(s))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Couldn't parse string duration passed to For(): \"%s\" see https://pkg.go.dev/time#ParseDuration for valid time units", s)
|
||||||
|
}
|
||||||
|
b.entityListener.delay = d
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b elBuilder3) Throttle(s DurationString) elBuilder3 {
|
||||||
d, err := time.ParseDuration(string(s))
|
d, err := time.ParseDuration(string(s))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Couldn't parse string duration passed to Throttle(): \"%s\" see https://pkg.go.dev/time#ParseDuration for valid time units", s)
|
log.Fatalf("Couldn't parse string duration passed to Throttle(): \"%s\" see https://pkg.go.dev/time#ParseDuration for valid time units", s)
|
||||||
@@ -145,6 +160,9 @@ func callEntityListeners(app *app, msgBytes []byte) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if c := checkStatesMatch(l.toState, data.NewState.State); c.fail {
|
if c := checkStatesMatch(l.toState, data.NewState.State); c.fail {
|
||||||
|
if l.delayTimer != nil {
|
||||||
|
l.delayTimer.Stop()
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if c := checkThrottle(l.throttle, l.lastRan); c.fail {
|
if c := checkThrottle(l.throttle, l.lastRan); c.fail {
|
||||||
@@ -159,6 +177,16 @@ func callEntityListeners(app *app, msgBytes []byte) {
|
|||||||
ToAttributes: data.NewState.Attributes,
|
ToAttributes: data.NewState.Attributes,
|
||||||
LastChanged: data.OldState.LastChanged,
|
LastChanged: data.OldState.LastChanged,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if l.delay != 0 {
|
||||||
|
l.delayTimer = time.AfterFunc(l.delay, func() {
|
||||||
|
go l.callback(app.service, entityData)
|
||||||
|
l.lastRan = carbon.Now()
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// run now if no delay set
|
||||||
go l.callback(app.service, entityData)
|
go l.callback(app.service, entityData)
|
||||||
l.lastRan = carbon.Now()
|
l.lastRan = carbon.Now()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ func (b eventListenerBuilder3) OnlyBefore(end string) eventListenerBuilder3 {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b eventListenerBuilder3) Throttle(s TimeString) eventListenerBuilder3 {
|
func (b eventListenerBuilder3) Throttle(s DurationString) eventListenerBuilder3 {
|
||||||
d, err := time.ParseDuration(string(s))
|
d, err := time.ParseDuration(string(s))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Couldn't parse string duration passed to Throttle(): \"%s\" see https://pkg.go.dev/time#ParseDuration for valid time units", s)
|
log.Fatalf("Couldn't parse string duration passed to Throttle(): \"%s\" see https://pkg.go.dev/time#ParseDuration for valid time units", s)
|
||||||
|
|||||||
12
schedule.go
12
schedule.go
@@ -20,7 +20,7 @@ type Schedule struct {
|
|||||||
|
|
||||||
isSunrise bool
|
isSunrise bool
|
||||||
isSunset bool
|
isSunset bool
|
||||||
sunOffset TimeString
|
sunOffset DurationString
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Schedule) Hash() string {
|
func (s Schedule) Hash() string {
|
||||||
@@ -98,7 +98,7 @@ func (sb scheduleBuilderDaily) At(s string) scheduleBuilderEnd {
|
|||||||
// Sunrise takes an app pointer and an optional duration string that is passed to time.ParseDuration.
|
// Sunrise takes an app pointer and an optional duration string that is passed to time.ParseDuration.
|
||||||
// Examples include "-1.5h", "30m", etc. See https://pkg.go.dev/time#ParseDuration
|
// Examples include "-1.5h", "30m", etc. See https://pkg.go.dev/time#ParseDuration
|
||||||
// for full list.
|
// for full list.
|
||||||
func (sb scheduleBuilderDaily) Sunrise(a *app, offset ...TimeString) scheduleBuilderEnd {
|
func (sb scheduleBuilderDaily) Sunrise(a *app, offset ...DurationString) scheduleBuilderEnd {
|
||||||
sb.schedule.realStartTime = getSunriseSunset(a, true, offset).Carbon2Time()
|
sb.schedule.realStartTime = getSunriseSunset(a, true, offset).Carbon2Time()
|
||||||
sb.schedule.isSunrise = true
|
sb.schedule.isSunrise = true
|
||||||
return scheduleBuilderEnd(sb)
|
return scheduleBuilderEnd(sb)
|
||||||
@@ -107,13 +107,13 @@ func (sb scheduleBuilderDaily) Sunrise(a *app, offset ...TimeString) scheduleBui
|
|||||||
// Sunset takes an app pointer and an optional duration string that is passed to time.ParseDuration.
|
// Sunset takes an app pointer and an optional duration string that is passed to time.ParseDuration.
|
||||||
// Examples include "-1.5h", "30m", etc. See https://pkg.go.dev/time#ParseDuration
|
// Examples include "-1.5h", "30m", etc. See https://pkg.go.dev/time#ParseDuration
|
||||||
// for full list.
|
// for full list.
|
||||||
func (sb scheduleBuilderDaily) Sunset(a *app, offset ...TimeString) scheduleBuilderEnd {
|
func (sb scheduleBuilderDaily) Sunset(a *app, offset ...DurationString) scheduleBuilderEnd {
|
||||||
sb.schedule.realStartTime = getSunriseSunset(a, false, offset).Carbon2Time()
|
sb.schedule.realStartTime = getSunriseSunset(a, false, offset).Carbon2Time()
|
||||||
sb.schedule.isSunset = true
|
sb.schedule.isSunset = true
|
||||||
return scheduleBuilderEnd(sb)
|
return scheduleBuilderEnd(sb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb scheduleBuilderCall) Every(s TimeString) scheduleBuilderCustom {
|
func (sb scheduleBuilderCall) Every(s DurationString) scheduleBuilderCustom {
|
||||||
d, err := time.ParseDuration(string(s))
|
d, err := time.ParseDuration(string(s))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("couldn't parse string duration passed to Every(): \"%s\" see https://pkg.go.dev/time#ParseDuration for valid time units", s)
|
log.Fatalf("couldn't parse string duration passed to Every(): \"%s\" see https://pkg.go.dev/time#ParseDuration for valid time units", s)
|
||||||
@@ -122,7 +122,7 @@ func (sb scheduleBuilderCall) Every(s TimeString) scheduleBuilderCustom {
|
|||||||
return scheduleBuilderCustom(sb)
|
return scheduleBuilderCustom(sb)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb scheduleBuilderCustom) Offset(s TimeString) scheduleBuilderEnd {
|
func (sb scheduleBuilderCustom) Offset(s DurationString) scheduleBuilderEnd {
|
||||||
t, err := time.ParseDuration(string(s))
|
t, err := time.ParseDuration(string(s))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Couldn't parse string duration passed to Offset(): \"%s\" see https://pkg.go.dev/time#ParseDuration for valid time units", s)
|
log.Fatalf("Couldn't parse string duration passed to Offset(): \"%s\" see https://pkg.go.dev/time#ParseDuration for valid time units", s)
|
||||||
@@ -174,7 +174,7 @@ func popSchedule(a *app) Schedule {
|
|||||||
|
|
||||||
func requeueSchedule(a *app, s Schedule) {
|
func requeueSchedule(a *app, s Schedule) {
|
||||||
if s.isSunrise || s.isSunset {
|
if s.isSunrise || s.isSunset {
|
||||||
nextSunTime := getSunriseSunset(a, s.isSunrise, []TimeString{s.sunOffset})
|
nextSunTime := getSunriseSunset(a, s.isSunrise, []DurationString{s.sunOffset})
|
||||||
|
|
||||||
// this is true when there is a negative offset, so schedule runs before sunset/sunrise and
|
// this is true when there is a negative offset, so schedule runs before sunset/sunrise and
|
||||||
// HA still shows today's sunset as next sunset. Just add 24h as a default handler
|
// HA still shows today's sunset as next sunset. Just add 24h as a default handler
|
||||||
|
|||||||
Reference in New Issue
Block a user