diff --git a/config.yml.example b/config.yml.example index 2350f49..7b29383 100644 --- a/config.yml.example +++ b/config.yml.example @@ -5,6 +5,14 @@ log: server: host: 127.0.0.1 port: 8080 +database: + driver: mysql + host: 127.0.0.1 + port: 3306 + database: aigc + username: root + password: 123456 + charset: utf8mb4 mqtt: client_id: mqttx_go host: broker.emqx.io diff --git a/database/database.go b/database/database.go new file mode 100644 index 0000000..0b7e5d6 --- /dev/null +++ b/database/database.go @@ -0,0 +1,81 @@ +package database + +import ( + "errors" + "fmt" + "time" + + "github.com/spf13/cast" + "gorm.io/driver/mysql" + "gorm.io/gorm" +) + +func New(config Config) (*gorm.DB, error) { + db, err := config.Build(&gorm.Config{}) + if err != nil { + return nil, err + } + + sqldb, err := db.DB() + if err != nil { + return nil, err + } + + if config.Has("max_open_conns") { + sqldb.SetMaxOpenConns(config.GetInt("max_open_conns")) + } + + if config.Has("max_idle_conns") { + sqldb.SetMaxIdleConns(config.GetInt("max_idle_conns")) + } + + if config.Has("conn_max_idle_time") { + sqldb.SetConnMaxIdleTime(config.GetDuration("conn_max_idle_time") * time.Second) + } + + if config.Has("conn_max_lifetime") { + sqldb.SetConnMaxLifetime(config.GetDuration("conn_max_lifetime") * time.Second) + } + + return db, nil +} + +type Config map[string]interface{} + +func (cfg Config) GetString(key string) string { + return cast.ToString(cfg[key]) +} + +func (cfg Config) GetInt(key string) int { + return cast.ToInt(cfg[key]) +} + +func (cfg Config) GetDuration(key string) time.Duration { + return cast.ToDuration(cfg[key]) +} + +func (cfg Config) Has(key string) bool { + _, ok := cfg[key] + return ok +} + +func (cfg Config) Build(opts ...gorm.Option) (*gorm.DB, error) { + switch cfg.GetString("driver") { + case "mysql": + dsn := cfg.GetString("dsn") + if dsn == "" { + dsn = fmt.Sprintf( + "%v:%v@tcp(%v:%v)/%v?charset=%v&parseTime=True&loc=Local", + cfg.GetString("username"), + cfg.GetString("password"), + cfg.GetString("host"), + cfg.GetInt("port"), + cfg.GetString("database"), + cfg.GetString("charset"), + ) + } + return gorm.Open(mysql.Open(dsn), opts...) + default: + return nil, errors.New("database driver not supported") + } +} diff --git a/go.mod b/go.mod index 7267374..82f4287 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,10 @@ require ( github.com/eclipse/paho.mqtt.golang v1.4.2 github.com/gin-gonic/gin v1.9.1 github.com/sirupsen/logrus v1.9.3 + github.com/spf13/cast v1.5.1 github.com/spf13/viper v1.16.0 + gorm.io/driver/mysql v1.5.1 + gorm.io/gorm v1.25.2 ) require ( @@ -18,9 +21,12 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.1 // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/leodido/go-urn v1.2.4 // indirect @@ -31,7 +37,6 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.2 // indirect diff --git a/go.sum b/go.sum index 0fac577..53c1fa1 100644 --- a/go.sum +++ b/go.sum @@ -82,6 +82,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -150,6 +152,10 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -537,6 +543,11 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw= +gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o= +gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho= +gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/main.go b/main.go index e73844d..c2b884b 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "encoding/json" "flag" "fmt" + "iot-spray-equipment/database" "iot-spray-equipment/equipment" "iot-spray-equipment/mqttx" "net/http" @@ -64,6 +65,11 @@ func init() { } func main() { + db, err := database.New(viper.GetStringMap("database")) + if err != nil { + log.Fatal("gorm 创建失败: ", err) + } + go func() { clientId := viper.GetString("mqtt.client_id") log.Debug("mqtt: 客户端获取中...") @@ -128,6 +134,13 @@ func main() { if connStatus == equipment.ConnStatusOffline { log.Info("mqtt: 喷雾设备已上线") } + + if connStatus != equipment.ConnStatusOnline { + result := db.Exec("UPDATE devices SET state = 1 WHERE sn = ?", sprayEquipment.GetId()) + if result.Error != nil { + log.Warning("mqtt: 喷雾设备状态更新失败: ", result.Error) + } + } }, WaitTimeout: 5 * time.Second, } @@ -180,6 +193,11 @@ func main() { if sprayEquipment.IncreaseConnLostTime(keepAliveInterval) >= keepAliveTimeout && sprayEquipment.GetConnStatus() != equipment.ConnStatusOffline { sprayEquipment.SetConnStatus(equipment.ConnStatusOffline) log.Warning("mqtt: 喷雾设备已离线") + + result := db.Exec("UPDATE devices SET state = 2 WHERE sn = ?", sprayEquipment.GetId()) + if result.Error != nil { + log.Warning("mqtt: 喷雾设备状态更新失败: ", result.Error) + } } } }()