mirror of
https://github.com/Xevion/go-ha.git
synced 2025-12-05 23:15:07 -06:00
refactor: move types out of app.go into types/, renamed module files
This commit is contained in:
57
app.go
57
app.go
@@ -17,6 +17,7 @@ import (
|
||||
internal "github.com/Xevion/go-ha/internal"
|
||||
"github.com/Xevion/go-ha/internal/parse"
|
||||
ws "github.com/Xevion/go-ha/internal/websocket"
|
||||
"github.com/Xevion/go-ha/types"
|
||||
)
|
||||
|
||||
var ErrInvalidArgs = errors.New("invalid arguments provided")
|
||||
@@ -41,10 +42,7 @@ type App struct {
|
||||
eventListeners map[string][]*EventListener
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
Value interface{}
|
||||
Priority float64
|
||||
}
|
||||
type Item types.Item
|
||||
|
||||
func (mi Item) Compare(other queue.Item) int {
|
||||
if mi.Priority > other.(Item).Priority {
|
||||
@@ -55,51 +53,6 @@ func (mi Item) Compare(other queue.Item) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// DurationString represents a duration, such as "2s" or "24h".
|
||||
// See https://pkg.go.dev/time#ParseDuration for all valid time units.
|
||||
type DurationString string
|
||||
|
||||
// TimeString is a 24-hr format time "HH:MM" such as "07:30".
|
||||
type TimeString string
|
||||
|
||||
type timeRange struct {
|
||||
start time.Time
|
||||
end time.Time
|
||||
}
|
||||
|
||||
type NewAppRequest struct {
|
||||
// Required
|
||||
URL string
|
||||
|
||||
// Optional
|
||||
// Deprecated: use URL instead
|
||||
// IpAddress of your Home Assistant instance i.e. "localhost"
|
||||
// or "192.168.86.59" etc.
|
||||
IpAddress string
|
||||
|
||||
// Optional
|
||||
// Deprecated: use URL instead
|
||||
// Port number Home Assistant is running on. Defaults to 8123.
|
||||
Port string
|
||||
|
||||
// Required
|
||||
// Auth token generated in Home Assistant. Used
|
||||
// to connect to the Websocket API.
|
||||
HAAuthToken string
|
||||
|
||||
// Required
|
||||
// EntityId of the zone representing your home e.g. "zone.home".
|
||||
// Used to pull latitude/longitude from Home Assistant
|
||||
// to calculate sunset/sunrise times.
|
||||
HomeZoneEntityId string
|
||||
|
||||
// Optional
|
||||
// Whether to use secure connections for http and websockets.
|
||||
// Setting this to `true` will use `https://` instead of `https://`
|
||||
// and `wss://` instead of `ws://`.
|
||||
Secure bool
|
||||
}
|
||||
|
||||
// validateHomeZone verifies that the home zone entity exists and has latitude/longitude
|
||||
func validateHomeZone(state State, entityID string) error {
|
||||
entity, err := state.Get(entityID)
|
||||
@@ -130,7 +83,7 @@ func validateHomeZone(state State, entityID string) error {
|
||||
NewApp establishes the websocket connection and returns an object
|
||||
you can use to register schedules and listeners.
|
||||
*/
|
||||
func NewApp(request NewAppRequest) (*App, error) {
|
||||
func NewApp(request types.NewAppRequest) (*App, error) {
|
||||
if (request.URL == "" && request.IpAddress == "") || request.HAAuthToken == "" {
|
||||
slog.Error("URL and HAAuthToken are required arguments in NewAppRequest")
|
||||
return nil, ErrInvalidArgs
|
||||
@@ -306,7 +259,7 @@ func (a *App) RegisterEventListeners(evls ...EventListener) {
|
||||
}
|
||||
}
|
||||
|
||||
func getSunriseSunset(s *StateImpl, sunrise bool, dateToUse carbon.Carbon, offset ...DurationString) carbon.Carbon {
|
||||
func getSunriseSunset(s *StateImpl, sunrise bool, dateToUse carbon.Carbon, offset ...types.DurationString) carbon.Carbon {
|
||||
date := dateToUse.Carbon2Time()
|
||||
rise, set := sunriseLib.SunriseSunset(s.latitude, s.longitude, date.Year(), date.Month(), date.Day())
|
||||
rise, set = rise.Local(), set.Local()
|
||||
@@ -339,7 +292,7 @@ func getSunriseSunset(s *StateImpl, sunrise bool, dateToUse carbon.Carbon, offse
|
||||
return setOrRiseToday
|
||||
}
|
||||
|
||||
func getNextSunRiseOrSet(a *App, sunrise bool, offset ...DurationString) carbon.Carbon {
|
||||
func getNextSunRiseOrSet(a *App, sunrise bool, offset ...types.DurationString) carbon.Carbon {
|
||||
sunriseOrSunset := getSunriseSunset(a.state, sunrise, carbon.Now(), offset...)
|
||||
if sunriseOrSunset.Lt(carbon.Now()) {
|
||||
// if we're past today's sunset or sunrise (accounting for offset) then get tomorrows
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/Xevion/go-ha/internal"
|
||||
"github.com/Xevion/go-ha/internal/parse"
|
||||
"github.com/Xevion/go-ha/types"
|
||||
"github.com/golang-module/carbon"
|
||||
)
|
||||
|
||||
@@ -75,11 +76,11 @@ func checkExceptionDates(eList []time.Time) conditionCheck {
|
||||
return cc
|
||||
}
|
||||
|
||||
func checkExceptionRanges(eList []timeRange) conditionCheck {
|
||||
func checkExceptionRanges(eList []types.TimeRange) conditionCheck {
|
||||
cc := conditionCheck{fail: false}
|
||||
now := time.Now()
|
||||
for _, eRange := range eList {
|
||||
if now.After(eRange.start) && now.Before(eRange.end) {
|
||||
if now.After(eRange.Start) && now.Before(eRange.End) {
|
||||
cc.fail = true
|
||||
break
|
||||
}
|
||||
@@ -161,7 +162,7 @@ func checkAllowlistDates(eList []time.Time) conditionCheck {
|
||||
return cc
|
||||
}
|
||||
|
||||
func checkStartEndTime(s TimeString, isStart bool) conditionCheck {
|
||||
func checkStartEndTime(s types.TimeString, isStart bool) conditionCheck {
|
||||
cc := conditionCheck{fail: false}
|
||||
// pass immediately if default
|
||||
if s == "00:00" {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/Xevion/go-ha/internal"
|
||||
"github.com/Xevion/go-ha/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -15,16 +16,16 @@ type MockState struct {
|
||||
GetError bool
|
||||
}
|
||||
|
||||
func (s MockState) AfterSunrise(_ ...DurationString) bool {
|
||||
func (s MockState) AfterSunrise(_ ...types.DurationString) bool {
|
||||
return true
|
||||
}
|
||||
func (s MockState) BeforeSunrise(_ ...DurationString) bool {
|
||||
func (s MockState) BeforeSunrise(_ ...types.DurationString) bool {
|
||||
return true
|
||||
}
|
||||
func (s MockState) AfterSunset(_ ...DurationString) bool {
|
||||
func (s MockState) AfterSunset(_ ...types.DurationString) bool {
|
||||
return true
|
||||
}
|
||||
func (s MockState) BeforeSunset(_ ...DurationString) bool {
|
||||
func (s MockState) BeforeSunset(_ ...types.DurationString) bool {
|
||||
return true
|
||||
}
|
||||
func (s MockState) Get(eid string) (EntityState, error) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"text/template"
|
||||
|
||||
ga "github.com/Xevion/go-ha"
|
||||
"github.com/Xevion/go-ha/types"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@@ -98,7 +99,7 @@ func generate(config Config) error {
|
||||
config.HomeZoneEntityId = "zone.home"
|
||||
}
|
||||
|
||||
app, err := ga.NewApp(ga.NewAppRequest{
|
||||
app, err := ga.NewApp(types.NewAppRequest{
|
||||
URL: config.URL,
|
||||
HAAuthToken: config.HAAuthToken,
|
||||
HomeZoneEntityId: config.HomeZoneEntityId,
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/Xevion/go-ha/internal"
|
||||
"github.com/Xevion/go-ha/internal/parse"
|
||||
"github.com/Xevion/go-ha/types"
|
||||
)
|
||||
|
||||
type EntityListener struct {
|
||||
@@ -26,7 +27,7 @@ type EntityListener struct {
|
||||
delayTimer *time.Timer
|
||||
|
||||
exceptionDates []time.Time
|
||||
exceptionRanges []timeRange
|
||||
exceptionRanges []types.TimeRange
|
||||
|
||||
runOnStartup bool
|
||||
runOnStartupCompleted bool
|
||||
@@ -127,13 +128,13 @@ func (b elBuilder3) ToState(s string) elBuilder3 {
|
||||
return b
|
||||
}
|
||||
|
||||
func (b elBuilder3) Duration(s DurationString) elBuilder3 {
|
||||
func (b elBuilder3) Duration(s types.DurationString) elBuilder3 {
|
||||
d := parse.ParseDuration(string(s))
|
||||
b.entityListener.delay = d
|
||||
return b
|
||||
}
|
||||
|
||||
func (b elBuilder3) Throttle(s DurationString) elBuilder3 {
|
||||
func (b elBuilder3) Throttle(s types.DurationString) elBuilder3 {
|
||||
d := parse.ParseDuration(string(s))
|
||||
b.entityListener.throttle = d
|
||||
return b
|
||||
@@ -145,7 +146,7 @@ func (b elBuilder3) ExceptionDates(t time.Time, tl ...time.Time) elBuilder3 {
|
||||
}
|
||||
|
||||
func (b elBuilder3) ExceptionRange(start, end time.Time) elBuilder3 {
|
||||
b.entityListener.exceptionRanges = append(b.entityListener.exceptionRanges, timeRange{start, end})
|
||||
b.entityListener.exceptionRanges = append(b.entityListener.exceptionRanges, types.TimeRange{start, end})
|
||||
return b
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/Xevion/go-ha/internal"
|
||||
"github.com/Xevion/go-ha/internal/parse"
|
||||
ws "github.com/Xevion/go-ha/internal/websocket"
|
||||
"github.com/Xevion/go-ha/types"
|
||||
)
|
||||
|
||||
type EventListener struct {
|
||||
@@ -21,7 +22,7 @@ type EventListener struct {
|
||||
lastRan carbon.Carbon
|
||||
|
||||
exceptionDates []time.Time
|
||||
exceptionRanges []timeRange
|
||||
exceptionRanges []types.TimeRange
|
||||
|
||||
enabledEntities []internal.EnabledDisabledInfo
|
||||
disabledEntities []internal.EnabledDisabledInfo
|
||||
@@ -80,7 +81,7 @@ func (b eventListenerBuilder3) OnlyBefore(end string) eventListenerBuilder3 {
|
||||
return b
|
||||
}
|
||||
|
||||
func (b eventListenerBuilder3) Throttle(s DurationString) eventListenerBuilder3 {
|
||||
func (b eventListenerBuilder3) Throttle(s types.DurationString) eventListenerBuilder3 {
|
||||
d := parse.ParseDuration(string(s))
|
||||
b.eventListener.throttle = d
|
||||
return b
|
||||
@@ -92,7 +93,7 @@ func (b eventListenerBuilder3) ExceptionDates(t time.Time, tl ...time.Time) even
|
||||
}
|
||||
|
||||
func (b eventListenerBuilder3) ExceptionRange(start, end time.Time) eventListenerBuilder3 {
|
||||
b.eventListener.exceptionRanges = append(b.eventListener.exceptionRanges, timeRange{start, end})
|
||||
b.eventListener.exceptionRanges = append(b.eventListener.exceptionRanges, types.TimeRange{start, end})
|
||||
return b
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
|
||||
"github.com/Xevion/go-ha/internal"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
var ErrInvalidToken = errors.New("invalid authentication token")
|
||||
|
||||
17
interval.go
17
interval.go
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/Xevion/go-ha/internal"
|
||||
"github.com/Xevion/go-ha/internal/parse"
|
||||
"github.com/Xevion/go-ha/types"
|
||||
)
|
||||
|
||||
type IntervalCallback func(*Service, State)
|
||||
@@ -14,12 +15,12 @@ type IntervalCallback func(*Service, State)
|
||||
type Interval struct {
|
||||
frequency time.Duration
|
||||
callback IntervalCallback
|
||||
startTime TimeString
|
||||
endTime TimeString
|
||||
startTime types.TimeString
|
||||
endTime types.TimeString
|
||||
nextRunTime time.Time
|
||||
|
||||
exceptionDates []time.Time
|
||||
exceptionRanges []timeRange
|
||||
exceptionRanges []types.TimeRange
|
||||
|
||||
enabledEntities []internal.EnabledDisabledInfo
|
||||
disabledEntities []internal.EnabledDisabledInfo
|
||||
@@ -63,7 +64,7 @@ func (i Interval) String() string {
|
||||
)
|
||||
}
|
||||
|
||||
func formatStartOrEndString(s TimeString, isStart bool) string {
|
||||
func formatStartOrEndString(s types.TimeString, isStart bool) string {
|
||||
if s == "00:00" {
|
||||
return ""
|
||||
}
|
||||
@@ -80,20 +81,20 @@ func (ib intervalBuilder) Call(callback IntervalCallback) intervalBuilderCall {
|
||||
}
|
||||
|
||||
// Takes a DurationString ("2h", "5m", etc) to set the frequency of the interval.
|
||||
func (ib intervalBuilderCall) Every(s DurationString) intervalBuilderEnd {
|
||||
func (ib intervalBuilderCall) Every(s types.DurationString) intervalBuilderEnd {
|
||||
d := parse.ParseDuration(string(s))
|
||||
ib.interval.frequency = d
|
||||
return intervalBuilderEnd(ib)
|
||||
}
|
||||
|
||||
// Takes a TimeString ("HH:MM") when this interval will start running for the day.
|
||||
func (ib intervalBuilderEnd) StartingAt(s TimeString) intervalBuilderEnd {
|
||||
func (ib intervalBuilderEnd) StartingAt(s types.TimeString) intervalBuilderEnd {
|
||||
ib.interval.startTime = s
|
||||
return ib
|
||||
}
|
||||
|
||||
// Takes a TimeString ("HH:MM") when this interval will stop running for the day.
|
||||
func (ib intervalBuilderEnd) EndingAt(s TimeString) intervalBuilderEnd {
|
||||
func (ib intervalBuilderEnd) EndingAt(s types.TimeString) intervalBuilderEnd {
|
||||
ib.interval.endTime = s
|
||||
return ib
|
||||
}
|
||||
@@ -104,7 +105,7 @@ func (ib intervalBuilderEnd) ExceptionDates(t time.Time, tl ...time.Time) interv
|
||||
}
|
||||
|
||||
func (ib intervalBuilderEnd) ExceptionRange(start, end time.Time) intervalBuilderEnd {
|
||||
ib.interval.exceptionRanges = append(ib.interval.exceptionRanges, timeRange{start, end})
|
||||
ib.interval.exceptionRanges = append(ib.interval.exceptionRanges, types.TimeRange{start, end})
|
||||
return ib
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/Xevion/go-ha/internal"
|
||||
"github.com/Xevion/go-ha/internal/parse"
|
||||
"github.com/Xevion/go-ha/types"
|
||||
"github.com/golang-module/carbon"
|
||||
)
|
||||
|
||||
@@ -23,7 +24,7 @@ type DailySchedule struct {
|
||||
|
||||
isSunrise bool
|
||||
isSunset bool
|
||||
sunOffset DurationString
|
||||
sunOffset types.DurationString
|
||||
|
||||
exceptionDates []time.Time
|
||||
allowlistDates []time.Time
|
||||
@@ -85,7 +86,7 @@ func (sb scheduleBuilderCall) At(s string) scheduleBuilderEnd {
|
||||
// Sunrise takes an optional duration string that is passed to time.ParseDuration.
|
||||
// Examples include "-1.5h", "30m", etc. See https://pkg.go.dev/time#ParseDuration
|
||||
// for full list.
|
||||
func (sb scheduleBuilderCall) Sunrise(offset ...DurationString) scheduleBuilderEnd {
|
||||
func (sb scheduleBuilderCall) Sunrise(offset ...types.DurationString) scheduleBuilderEnd {
|
||||
sb.schedule.isSunrise = true
|
||||
if len(offset) > 0 {
|
||||
sb.schedule.sunOffset = offset[0]
|
||||
@@ -96,7 +97,7 @@ func (sb scheduleBuilderCall) Sunrise(offset ...DurationString) scheduleBuilderE
|
||||
// Sunset takes an optional duration string that is passed to time.ParseDuration.
|
||||
// Examples include "-1.5h", "30m", etc. See https://pkg.go.dev/time#ParseDuration
|
||||
// for full list.
|
||||
func (sb scheduleBuilderCall) Sunset(offset ...DurationString) scheduleBuilderEnd {
|
||||
func (sb scheduleBuilderCall) Sunset(offset ...types.DurationString) scheduleBuilderEnd {
|
||||
sb.schedule.isSunset = true
|
||||
if len(offset) > 0 {
|
||||
sb.schedule.sunOffset = offset[0]
|
||||
|
||||
17
state.go
17
state.go
@@ -9,13 +9,14 @@ import (
|
||||
"github.com/golang-module/carbon"
|
||||
|
||||
internal "github.com/Xevion/go-ha/internal"
|
||||
"github.com/Xevion/go-ha/types"
|
||||
)
|
||||
|
||||
type State interface {
|
||||
AfterSunrise(...DurationString) bool
|
||||
BeforeSunrise(...DurationString) bool
|
||||
AfterSunset(...DurationString) bool
|
||||
BeforeSunset(...DurationString) bool
|
||||
AfterSunrise(...types.DurationString) bool
|
||||
BeforeSunrise(...types.DurationString) bool
|
||||
AfterSunset(...types.DurationString) bool
|
||||
BeforeSunset(...types.DurationString) bool
|
||||
ListEntities() ([]EntityState, error)
|
||||
Get(entityId string) (EntityState, error)
|
||||
Equals(entityId, state string) (bool, error)
|
||||
@@ -99,20 +100,20 @@ func (s *StateImpl) Equals(entityId string, expectedState string) (bool, error)
|
||||
return currentState.State == expectedState, nil
|
||||
}
|
||||
|
||||
func (s *StateImpl) BeforeSunrise(offset ...DurationString) bool {
|
||||
func (s *StateImpl) BeforeSunrise(offset ...types.DurationString) bool {
|
||||
sunrise := getSunriseSunset(s /* sunrise = */, true, carbon.Now(), offset...)
|
||||
return carbon.Now().Lt(sunrise)
|
||||
}
|
||||
|
||||
func (s *StateImpl) AfterSunrise(offset ...DurationString) bool {
|
||||
func (s *StateImpl) AfterSunrise(offset ...types.DurationString) bool {
|
||||
return !s.BeforeSunrise(offset...)
|
||||
}
|
||||
|
||||
func (s *StateImpl) BeforeSunset(offset ...DurationString) bool {
|
||||
func (s *StateImpl) BeforeSunset(offset ...types.DurationString) bool {
|
||||
sunset := getSunriseSunset(s /* sunrise = */, false, carbon.Now(), offset...)
|
||||
return carbon.Now().Lt(sunset)
|
||||
}
|
||||
|
||||
func (s *StateImpl) AfterSunset(offset ...DurationString) bool {
|
||||
func (s *StateImpl) AfterSunset(offset ...types.DurationString) bool {
|
||||
return !s.BeforeSunset(offset...)
|
||||
}
|
||||
|
||||
35
types/app.go
Normal file
35
types/app.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package types
|
||||
|
||||
// NewAppRequest contains the configuration for creating a new App instance.
|
||||
type NewAppRequest struct {
|
||||
// Required
|
||||
URL string
|
||||
|
||||
// Optional
|
||||
// Deprecated: use URL instead
|
||||
// IpAddress of your Home Assistant instance i.e. "localhost"
|
||||
// or "192.168.86.59" etc.
|
||||
IpAddress string
|
||||
|
||||
// Optional
|
||||
// Deprecated: use URL instead
|
||||
// Port number Home Assistant is running on. Defaults to 8123.
|
||||
Port string
|
||||
|
||||
// Required
|
||||
// Auth token generated in Home Assistant. Used
|
||||
// to connect to the Websocket API.
|
||||
HAAuthToken string
|
||||
|
||||
// Required
|
||||
// EntityId of the zone representing your home e.g. "zone.home".
|
||||
// Used to pull latitude/longitude from Home Assistant
|
||||
// to calculate sunset/sunrise times.
|
||||
HomeZoneEntityId string
|
||||
|
||||
// Optional
|
||||
// Whether to use secure connections for http and websockets.
|
||||
// Setting this to `true` will use `https://` instead of `https://`
|
||||
// and `wss://` instead of `ws://`.
|
||||
Secure bool
|
||||
}
|
||||
22
types/common.go
Normal file
22
types/common.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package types
|
||||
|
||||
import "time"
|
||||
|
||||
// DurationString represents a duration, such as "2s" or "24h".
|
||||
// See https://pkg.go.dev/time#ParseDuration for all valid time units.
|
||||
type DurationString string
|
||||
|
||||
// TimeString is a 24-hr format time "HH:MM" such as "07:30".
|
||||
type TimeString string
|
||||
|
||||
// TimeRange represents a time range with start and end times.
|
||||
type TimeRange struct {
|
||||
Start time.Time
|
||||
End time.Time
|
||||
}
|
||||
|
||||
// Item represents a priority queue item with a value and priority.
|
||||
type Item struct {
|
||||
Value interface{}
|
||||
Priority float64
|
||||
}
|
||||
Reference in New Issue
Block a user