diff --git a/internal/api/api.go b/internal/api/api.go index ad9a9c3..be04e1f 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -29,7 +29,7 @@ const ( func Listen(parentLogger *slog.Logger) { logger = parentLogger cfg = config.FromEnvironment() - haClient = homeassistant.NewRestClient(cfg.HomeAssistantBaseUrl, cfg.HomeAssistantToken) + haClient = homeassistant.NewRestClient(cfg.GetHomeAssistantBaseUrl(), cfg.HomeAssistantToken) router := chi.NewRouter() router.Use(middleware.RequestID) diff --git a/internal/homeassistant/subscriber.go b/internal/homeassistant/subscriber.go index a9d3af9..98c0a6e 100644 --- a/internal/homeassistant/subscriber.go +++ b/internal/homeassistant/subscriber.go @@ -42,7 +42,7 @@ func Subscribe(parentLogger *slog.Logger) error { cfg = config.FromEnvironment() var err error - url := fmt.Sprintf(cfg.HomeAssistantWebsocketUrl) + url := cfg.GetHomeAssistantWebsocketUrl() logger.Debug("Dialing Home Assistant websocket API", "url", url) diff --git a/main.go b/main.go index 6755877..a4ba581 100644 --- a/main.go +++ b/main.go @@ -9,19 +9,22 @@ import ( "code.jhot.me/jhot/hats/internal/api" "code.jhot.me/jhot/hats/internal/homeassistant" "code.jhot.me/jhot/hats/internal/nats" + "code.jhot.me/jhot/hats/pkg/config" ) var ( interrupt chan os.Signal + cfg *config.HatsConfig logger *slog.Logger ctx context.Context cancel context.CancelFunc ) func main() { + cfg = config.FromEnvironment() ctx, cancel = context.WithCancel(context.Background()) logger = slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ - Level: slog.LevelDebug, + Level: cfg.GetLogLevel(), })) interrupt = make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt) diff --git a/pkg/client/client.go b/pkg/client/client.go index 1582900..de79257 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -64,7 +64,7 @@ func (c *HatsClient) GetStateBool(entityId string) (bool, error) { return ha.StateToBool(stateString), nil } -func (c *HatsClient) CallService(entityId string, service string, extras ...map[string]string) error { +func (c *HatsClient) CallService(entityId string, service string, extras ...map[string]any) error { req := c.client.R() if len(extras) > 0 { data := map[string]interface{}{} @@ -101,6 +101,11 @@ func (c *HatsClient) GetTimer(name string) (string, error) { return resp.String(), nil } +// Set a timer +// +// name: the name of the timer (should be unique) +// duration: time.Duration string for how long the timer should last +// force: if true, will start the timer over even if it is already running func (c *HatsClient) SetTimer(name string, duration string, force bool) (string, error) { data := api.CreateTimerData{ Duration: duration, diff --git a/pkg/config/config.go b/pkg/config/config.go index 7297dc7..165b057 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -2,33 +2,34 @@ package config import ( "fmt" + "log/slog" "strconv" + "strings" "code.jhot.me/jhot/hats/internal/util" ) type HatsConfig struct { - HomeAssistantHost string - HomeAssistantPort string - HomeAssistantSecure bool - HomeAssistantBaseUrl string - HomeAssistantWebsocketUrl string - HomeAssistantToken string + LogLevl string + + HomeAssistantHost string + HomeAssistantPort string + HomeAssistantSecure bool + HomeAssistantToken string NatsHost string NatsPort string - NatsBaseUrl string NatsToken string NatsClientName string - HatsHost string - HatsPort string - HatsSecure bool - HatsBaseUrl string + HatsHost string + HatsPort string + HatsSecure bool } func FromEnvironment() *HatsConfig { config := &HatsConfig{ + LogLevl: util.GetEnvWithDefault("LOG_LEVEL", "INFO"), HomeAssistantHost: util.GetEnvWithDefault("HASS_HOST", "127.0.0.1"), HomeAssistantPort: util.GetEnvWithDefault("HASS_PORT", "8123"), HomeAssistantToken: util.GetEnvWithDefault("HASS_TOKEN", ""), @@ -41,23 +42,48 @@ func FromEnvironment() *HatsConfig { } config.HomeAssistantSecure, _ = strconv.ParseBool(util.GetEnvWithDefault("HASS_SECURE", "false")) - hassProtocol := "http" - HassWsProtocol := "ws" - if config.HomeAssistantSecure { - hassProtocol += "s" - HassWsProtocol += "s" - } - config.HomeAssistantBaseUrl = fmt.Sprintf("%s://%s:%s", hassProtocol, config.HomeAssistantHost, config.HomeAssistantPort) - config.HomeAssistantWebsocketUrl = fmt.Sprintf("%s://%s:%s/api/websocket", HassWsProtocol, config.HomeAssistantHost, config.HomeAssistantPort) - - config.NatsBaseUrl = fmt.Sprintf("nats://%s:%s", config.NatsHost, config.NatsPort) - config.HatsSecure, _ = strconv.ParseBool(util.GetEnvWithDefault("HATS_SECURE", "false")) - hatsProtocol := "http" - if config.HatsSecure { - hatsProtocol += "s" - } - config.HatsBaseUrl = fmt.Sprintf("%s://%s:%s", hatsProtocol, config.HatsHost, config.HatsPort) return config } + +func (c *HatsConfig) GetHomeAssistantBaseUrl() string { + hassProtocol := "http" + if c.HomeAssistantSecure { + hassProtocol += "s" + } + return fmt.Sprintf("%s://%s:%s", hassProtocol, c.HomeAssistantHost, c.HomeAssistantPort) +} + +func (c *HatsConfig) GetHomeAssistantWebsocketUrl() string { + protocol := "ws" + if c.HomeAssistantSecure { + protocol += "s" + } + return fmt.Sprintf("%s://%s:%s/api/websocket", protocol, c.HomeAssistantHost, c.HomeAssistantPort) +} + +func (c *HatsConfig) GetNatsBaseUrl() string { + return fmt.Sprintf("nats://%s:%s", c.NatsHost, c.NatsPort) +} + +func (c *HatsConfig) GetHatsBaseUrl() string { + protocol := "http" + if c.HomeAssistantSecure { + protocol += "s" + } + return fmt.Sprintf("%s://%s:%s", protocol, c.HatsHost, c.HatsPort) +} + +func (c *HatsConfig) GetLogLevel() slog.Level { + switch strings.ToLower(c.LogLevl) { + case "error": + return slog.LevelError + case "warn": + return slog.LevelWarn + case "debug": + return slog.LevelDebug + default: + return slog.LevelInfo + } +}