2023-10-13 20:31:23 +00:00
|
|
|
package nats
|
|
|
|
|
|
|
|
import (
|
2023-10-18 18:35:46 +00:00
|
|
|
"fmt"
|
2023-10-18 18:49:54 +00:00
|
|
|
"strings"
|
2023-10-13 20:31:23 +00:00
|
|
|
"time"
|
|
|
|
|
2023-10-18 18:35:46 +00:00
|
|
|
"code.jhot.me/jhot/hats/pkg/config"
|
|
|
|
"code.jhot.me/jhot/hats/pkg/homeassistant"
|
2023-10-13 20:31:23 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2023-10-18 18:35:46 +00:00
|
|
|
haClient *homeassistant.RestClient
|
2023-10-13 20:31:23 +00:00
|
|
|
)
|
|
|
|
|
2023-10-18 18:35:46 +00:00
|
|
|
func initHomeAssistantClient() {
|
|
|
|
if haClient == nil {
|
|
|
|
cfg = config.FromEnvironment()
|
|
|
|
haClient = homeassistant.NewRestClient(cfg.GetHomeAssistantBaseUrl(), cfg.HomeAssistantToken)
|
2023-10-13 20:31:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type HatsTimer struct {
|
2023-10-18 18:35:46 +00:00
|
|
|
Name string
|
|
|
|
State string
|
|
|
|
Duration time.Duration
|
|
|
|
FinishTime time.Time
|
2023-10-13 20:31:23 +00:00
|
|
|
}
|
|
|
|
|
2023-10-18 18:35:46 +00:00
|
|
|
func GetTimer(name string) (*HatsTimer, error) {
|
|
|
|
initHomeAssistantClient()
|
2023-10-18 18:49:54 +00:00
|
|
|
if !strings.HasPrefix(name, "timer.") {
|
|
|
|
name = fmt.Sprintf("timer.%s", name)
|
|
|
|
}
|
|
|
|
state, err := haClient.GetState(name)
|
2023-10-13 20:31:23 +00:00
|
|
|
if err != nil {
|
2023-10-18 18:35:46 +00:00
|
|
|
return nil, err
|
2023-10-13 20:31:23 +00:00
|
|
|
}
|
|
|
|
|
2023-10-18 18:35:46 +00:00
|
|
|
d, err := homeassistant.ParseDuration(state.Attributes["duration"].(string))
|
2023-10-13 20:31:23 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-10-18 18:35:46 +00:00
|
|
|
var finishTime time.Time
|
|
|
|
if finishesAt, ok := state.Attributes["finishes_at"]; ok {
|
|
|
|
finishTime, _ = time.Parse(time.RFC3339, finishesAt.(string))
|
|
|
|
}
|
2023-10-13 20:31:23 +00:00
|
|
|
|
2023-10-18 18:35:46 +00:00
|
|
|
return &HatsTimer{
|
|
|
|
Name: name,
|
|
|
|
State: state.State,
|
|
|
|
Duration: d,
|
|
|
|
FinishTime: finishTime,
|
|
|
|
}, nil
|
2023-10-13 20:31:23 +00:00
|
|
|
}
|
|
|
|
|
2023-10-18 18:35:46 +00:00
|
|
|
func (t *HatsTimer) Activate(durationOverride string) {
|
|
|
|
d := t.Duration
|
|
|
|
if durationOverride != "" {
|
|
|
|
var err error
|
|
|
|
d, err = time.ParseDuration(durationOverride)
|
|
|
|
if err != nil {
|
|
|
|
logger.Error("Error parsing duration", "error", err)
|
|
|
|
d = t.Duration
|
|
|
|
}
|
|
|
|
}
|
|
|
|
logger.Error("Starting timer", "duration", int(d.Seconds()))
|
2023-10-18 18:49:54 +00:00
|
|
|
err := haClient.CallService(t.Name, homeassistant.Services.Start, map[string]any{
|
2023-10-18 18:35:46 +00:00
|
|
|
homeassistant.ExtraProps.Duration: int(d.Seconds()),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
logger.Error("Error starting timer", "error", err)
|
|
|
|
}
|
2023-10-13 20:31:23 +00:00
|
|
|
}
|
|
|
|
|
2023-10-18 18:35:46 +00:00
|
|
|
func (t *HatsTimer) ActivateIfNotAlready(durationOverride string) {
|
2023-10-18 18:49:54 +00:00
|
|
|
if state, err := haClient.GetState(t.Name); err == nil && !homeassistant.StateToBool(state.State) {
|
2023-10-18 18:35:46 +00:00
|
|
|
t.Activate(durationOverride)
|
|
|
|
}
|
2023-10-13 20:31:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t *HatsTimer) Cancel() {
|
2023-10-18 18:49:54 +00:00
|
|
|
haClient.CallService(t.Name, homeassistant.Services.Cancel)
|
2023-10-13 20:31:23 +00:00
|
|
|
}
|
|
|
|
|
2023-10-18 18:35:46 +00:00
|
|
|
func (t *HatsTimer) ToString() string {
|
2023-10-18 18:49:54 +00:00
|
|
|
if homeassistant.StateToBool(t.State) {
|
2023-10-18 18:35:46 +00:00
|
|
|
time, _ := t.FinishTime.MarshalText()
|
|
|
|
return string(time)
|
2023-10-13 20:31:23 +00:00
|
|
|
}
|
2023-10-18 18:35:46 +00:00
|
|
|
return t.State
|
2023-10-13 20:31:23 +00:00
|
|
|
}
|