Files
platforms/backend/iot-server/internal/config/config.go

102 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package config 加载 IoT Server 的 MQTT、协议密钥和内部接口配置。
package config
import (
"encoding/hex"
"fmt"
"os"
"strings"
"gopkg.in/yaml.v3"
)
type MQTT struct {
Address string `yaml:"Address"`
ListenerID string `yaml:"ListenerID"`
Devices []MQTTDevice `yaml:"Devices"`
UpTopic string `yaml:"UpTopic"`
DownTopic string `yaml:"DownTopic"`
AckTopic string `yaml:"AckTopic"`
QoS byte `yaml:"QoS"`
TLS bool `yaml:"TLS"`
CAFile string `yaml:"CAFile"`
CertificateFile string `yaml:"CertificateFile"`
PrivateKeyFile string `yaml:"PrivateKeyFile"`
}
type MQTTDevice struct {
ClientID string `yaml:"ClientID"`
DeviceID string `yaml:"DeviceID"`
Username string `yaml:"Username"`
Password string `yaml:"Password"`
}
type HTTP struct {
Address string `yaml:"Address"`
InternalToken string `yaml:"InternalToken"`
CallbackURL string `yaml:"CallbackURL"`
}
type Protocol struct {
Key1 string `yaml:"Key1"`
Key2 string `yaml:"Key2"`
Key3 string `yaml:"Key3"`
}
type Config struct {
Service string `yaml:"Service"`
MQTT MQTT `yaml:"MQTT"`
HTTP HTTP `yaml:"HTTP"`
Protocol Protocol `yaml:"Protocol"`
}
func Load(path string) (Config, error) {
var cfg Config
data, err := os.ReadFile(path)
if err != nil {
return cfg, err
}
if err = yaml.Unmarshal(data, &cfg); err != nil {
return cfg, err
}
if len(cfg.MQTT.Devices) == 1 {
override(&cfg.MQTT.Devices[0].Password, "HEQI_IOT_MQTT_PASSWORD")
}
override(&cfg.HTTP.InternalToken, "HEQI_IOT_INTERNAL_TOKEN")
override(&cfg.Protocol.Key1, "HEQI_IOT_KEY_1")
override(&cfg.Protocol.Key2, "HEQI_IOT_KEY_2")
override(&cfg.Protocol.Key3, "HEQI_IOT_KEY_3")
if cfg.MQTT.Address == "" || cfg.HTTP.Address == "" || cfg.HTTP.InternalToken == "" {
return cfg, fmt.Errorf("MQTT.Address、HTTP.Address 和 HTTP.InternalToken 必填")
}
if cfg.MQTT.ListenerID == "" {
cfg.MQTT.ListenerID = "mqtt-tcp"
}
if len(cfg.MQTT.Devices) == 0 {
return cfg, fmt.Errorf("MQTT.Devices 必填Broker 禁止匿名连接")
}
for index, device := range cfg.MQTT.Devices {
if device.ClientID == "" || device.DeviceID == "" || device.Username == "" || device.Password == "" {
return cfg, fmt.Errorf("MQTT.Devices[%d] 的 ClientID、DeviceID、Username 和 Password 必填", index)
}
}
return cfg, nil
}
func (cfg Config) Keys() (map[byte][]byte, error) {
result := map[byte][]byte{}
for id, value := range map[byte]string{1: cfg.Protocol.Key1, 2: cfg.Protocol.Key2, 3: cfg.Protocol.Key3} {
if strings.TrimSpace(value) == "" {
continue
}
decoded, err := hex.DecodeString(value)
if err != nil || len(decoded) != 16 {
return nil, fmt.Errorf("Protocol.Key%d 必须是 32 位十六进制 AES-128 密钥", id)
}
result[id] = decoded
}
return result, nil
}
func override(target *string, name string) {
if value := os.Getenv(name); value != "" {
*target = value
}
}