diff --git a/internal/agent/mqtt.go b/internal/agent/mqtt.go index 2bcbc9a80..14c7c8204 100644 --- a/internal/agent/mqtt.go +++ b/internal/agent/mqtt.go @@ -7,6 +7,7 @@ package agent import ( "context" + "errors" "fmt" "log/slog" @@ -71,8 +72,10 @@ func setupMQTT(ctx context.Context) []MQTTWorker { // Set up custom MQTT commands worker. customCommandsWorker, err := commands.NewCommandsWorker(ctx, mqttDevice) if err != nil { - logging.FromContext(ctx).Warn("Could not setup custom MQTT commands.", - slog.Any("error", err)) + if !errors.Is(err, commands.ErrNoCommands) { + logging.FromContext(ctx).Warn("Could not setup custom MQTT commands.", + slog.Any("error", err)) + } } else { workers = append(workers, customCommandsWorker) } diff --git a/internal/hass/registration.go b/internal/hass/registration.go index 768cd561d..a59824701 100644 --- a/internal/hass/registration.go +++ b/internal/hass/registration.go @@ -53,6 +53,14 @@ func RegisterDevice(ctx context.Context, registration *preferences.Registration) registrationURL := registration.Server + RegistrationPath thisDevice := device.NewDevice() + // Set device details in preferences. + if err := preferences.SetDevicePreferences(&preferences.Device{ + Name: thisDevice.Name, + ID: thisDevice.ID, + }); err != nil { + return nil, fmt.Errorf("could not register device: %w", err) + } + // Register the device against the registration endpoint. registrationStatus, err := api.Send[preferences.Hass](ctx, registrationURL, newRegistrationRequest(thisDevice, registration.Token)) if err != nil { diff --git a/internal/preferences/mqtt.go b/internal/preferences/mqtt.go index 9baa90dec..203adfc6e 100644 --- a/internal/preferences/mqtt.go +++ b/internal/preferences/mqtt.go @@ -18,16 +18,16 @@ const ( prefMQTTServer = mqttPrefPrefix + ".server" prefMQTTUser = mqttPrefPrefix + ".user" prefMQTTPass = mqttPrefPrefix + ".password" - prefMQTTTopicPrefix = mqttPrefPrefix + ".topic_prefx" + prefMQTTTopicPrefix = mqttPrefPrefix + ".topic_prefix" prefMQTTEnabled = mqttPrefPrefix + ".enabled" ) // MQTT contains preferences related to MQTT functionality in Go Hass Agent. type MQTT struct { - MQTTServer string `toml:"server,omitempty" validate:"omitempty,uri" kong:"required,help='MQTT server URI. Required.',placeholder='scheme://some.host:port'"` //nolint:lll + MQTTServer string `toml:"server,omitempty" validate:"required,uri" kong:"required,help='MQTT server URI. Required.',placeholder='scheme://some.host:port'"` //nolint:lll MQTTUser string `toml:"user,omitempty" validate:"omitempty" kong:"optional,help='MQTT username.'"` MQTTPassword string `toml:"password,omitempty" validate:"omitempty" kong:"optional,help='MQTT password.'"` - MQTTTopicPrefix string `toml:"topic_prefix,omitempty" validate:"omitempty,ascii" kong:"optional,help='MQTT topic prefix.'"` + MQTTTopicPrefix string `toml:"topic_prefix,omitempty" validate:"required,ascii" kong:"optional,help='MQTT topic prefix.'"` MQTTEnabled bool `toml:"enabled" validate:"boolean" kong:"-"` } @@ -48,6 +48,10 @@ func SetMQTTPreferences(prefs *MQTT) error { return fmt.Errorf("%w: %w", ErrSetMQTTPreference, err) } + if prefs.MQTTTopicPrefix == "" { + prefs.MQTTTopicPrefix = MQTTTopicPrefix + } + if err := prefsSrc.Set(prefMQTTTopicPrefix, prefs.MQTTTopicPrefix); err != nil { return fmt.Errorf("%w: %w", ErrSetMQTTPreference, err) } diff --git a/internal/preferences/prefs.go b/internal/preferences/prefs.go index a344b1bc0..8a97fc802 100644 --- a/internal/preferences/prefs.go +++ b/internal/preferences/prefs.go @@ -13,7 +13,6 @@ import ( "sync" "github.com/adrg/xdg" - "github.com/davecgh/go-spew/spew" "github.com/knadh/koanf/parsers/toml" "github.com/knadh/koanf/providers/env" "github.com/knadh/koanf/providers/file" @@ -60,7 +59,8 @@ var defaultAgentPreferences = &preferences{ Version: AppVersion(), Registered: false, MQTT: &MQTT{ - MQTTEnabled: false, + MQTTEnabled: false, + MQTTTopicPrefix: MQTTTopicPrefix, }, Registration: &Registration{ Server: DefaultServer, @@ -147,13 +147,24 @@ func validate() error { return fmt.Errorf("%w: %w", ErrLoadPreferences, err) } - // Validate current preferences. - err := validation.Validate.Struct(currentPreferences) - if err != nil { - spew.Dump(err) + // Ensure device preferences are valid. + if err := validation.Validate.Struct(currentPreferences.Device); err != nil { + return fmt.Errorf("%w: %s", ErrValidatePreferences, validation.ParseValidationErrors(err)) + } + + // Ensure hass preferences are valid. + if err := validation.Validate.Struct(currentPreferences.Hass); err != nil { return fmt.Errorf("%w: %s", ErrValidatePreferences, validation.ParseValidationErrors(err)) } + if currentPreferences.IsMQTTEnabled() { + // Validate MQTT preferences are valid. + err := validation.Validate.Struct(currentPreferences.MQTT) + if err != nil { + return fmt.Errorf("%w: %s", ErrValidatePreferences, validation.ParseValidationErrors(err)) + } + } + slog.Debug("Preferences are valid.") return nil