// SPDX-License-Identifier: MIT // SPDX-FileCopyrightText: 2023 mysubarumq // SPDX-FileContributor: alex-savin package config import ( "log/slog" "os" "strings" ms "git.savin.nyc/alex/mysubaru/config" "github.com/spf13/viper" ) // Config . type Config struct { MQTT MQTT `json:"mqtt" yaml:"mqtt"` MySubaru ms.MySubaru `json:"mysubaru" yaml:"mysubaru"` Hassio Hassio `json:"hassio" yaml:"hassio"` Listeners map[string]*Listener `json:"listeners" yaml:"listeners"` Consul *Consul `json:"consul,omitempty" yaml:"consul,omitempty"` SubscriptionSize map[string]int `json:"subscription_size" yaml:"subscription_size"` Timezone string `json:"timezone" yaml:"timezone"` Logging *Logging `json:"logging" yaml:"logging"` ShareDeidentifiedData bool `json:"share_deidentified_data,omitempty" yaml:"share_deidentified_data,omitempty"` } // MQTT . type MQTT struct { Host string `json:"host" yaml:"host"` Port int `json:"port" yaml:"port"` Username string `json:"username" yaml:"username"` Password string `json:"password" yaml:"password"` ClientId string `json:"client_id,omitempty" yaml:"client_id,omitempty"` Retained bool `json:"retained" yaml:"retained"` Topic string `json:"topic" yaml:"topic"` } type Hassio struct { AutoDiscovery bool `json:"auto_discovery" yaml:"auto_discovery"` Topics struct { Discovery string `json:"discovery" yaml:"discovery"` Status string `json:"status" yaml:"status"` } `json:"topics" yaml:"topics"` } // Listeners . type Listener struct { ID string Port int `json:"port" yaml:"port"` Cert string `json:"cert,omitempty" yaml:"cert,omitempty"` PKey string `json:"pkey,omitempty" yaml:"pkey,omitempty"` } // Consul . type Consul struct { Host string `json:"host" yaml:"host"` Port int `json:"port,omitempty" yaml:"port,omitempty"` DataCenter string `json:"datacenter,omitempty" yaml:"datacenter,omitempty"` Token string `json:"token,omitempty" yaml:"token,omitempty"` Interfaces Interface `json:"interfaces,omitempty" yaml:"interfaces,omitempty"` } type Interface struct { WAN string `json:"wan,omitempty" yaml:"wan,omitempty"` LAN string `json:"lan,omitempty" yaml:"lan,omitempty"` } // Logging . type Logging struct { Level string `json:"level" yaml:"level"` Output string `json:"output" yaml:"output"` Source bool `json:"source,omitempty" yaml:"source,omitempty"` } // New . func New() (*Config, error) { viper.SetConfigName("config") // name of config file (without extension) viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name viper.AddConfigPath(".") // optionally look for config in the working directory viper.AddConfigPath("/etc/mysubarumq") // optionally look for config in the working directory viper.AutomaticEnv() viper.SetDefault("MQTT.ClientId", "mysubarumq") viper.SetDefault("MQTT.Retained", true) viper.SetDefault("MQTT.Topic", "mysubarumq") viper.SetDefault("Timezone", "America/New_York") viper.SetDefault("MySubaru.AutoReconnect", true) viper.SetDefault("MySubaru.Region", "USA") viper.SetDefault("Hassio.AutoDiscovery", true) viper.SetDefault("Logging.Level", "INFO") viper.SetDefault("Logging.Output", "TEXT") viper.SetDefault("Logging.Source", "false") err := viper.ReadInConfig() // Find and read the config file if err != nil { // Handle errors reading the config file slog.Error("cannot open config file", "error", err.Error()) os.Exit(1) } // viper.WatchConfig() // viper.OnConfigChange(func(e fsnotify.Event) { // log.Println("Config file changed:", e.Name) // }) var config Config if err := viper.Unmarshal(&config); err != nil { slog.Error("cannot unmarshal config file", "error", err.Error()) os.Exit(1) } config.MQTT.Topic = strings.TrimSuffix(config.MQTT.Topic, "/") slog.Debug("CONFIG", "config", config) return &config, err }