package main import ( "bytes" "encoding/json" "flag" "fmt" "iot-spray-equipment/mqttx" "net/http" "os" "time" mqtt "github.com/eclipse/paho.mqtt.golang" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" "github.com/spf13/viper" ) var ( configFilePath string ) func init() { flag.StringVar(&configFilePath, "config", "config.yml", "配置文件") buf, err := os.ReadFile(configFilePath) if err != nil { log.Fatal(err) } viper.SetConfigType("yaml") if err := viper.ReadConfig(bytes.NewBuffer(buf)); err != nil { log.Fatal(err) } c := mqttx.NewClient(&mqttx.ClientOptions{ Host: viper.GetString("mqtt.host"), Port: viper.GetInt("mqtt.port"), ClientOptions: mqtt.ClientOptions{ ClientID: viper.GetString("mqtt.client_id"), Username: viper.GetString("mqtt.username"), Password: viper.GetString("mqtt.password"), OnConnect: func(c mqtt.Client) { log.Info("mqtt: 服务器连接成功") }, OnConnectionLost: func(c mqtt.Client, err error) { log.Warningf("mqtt: 服务器连接断开: %v", err.Error()) }, OnReconnecting: func(c mqtt.Client, co *mqtt.ClientOptions) { log.Info("mqtt: 重连服务器...") }, }, }) mqttx.Push(c) } func main() { go func() { c, err := mqttx.Get(viper.GetString("mqtt.client_id")) if err != nil { log.WithFields(log.Fields{ "error": err, }).Error("mqtt: 客户端获取失败") return } RetryConnect: if err := c.Connect(); err != nil { log.WithFields(log.Fields{ "error": err, }).Error("mqtt: 服务器连接失败") time.Sleep(200 * time.Millisecond) goto RetryConnect } RetrySubscribe: subTopic := mqttx.SubscribeTopic{ Name: "testtopic/PLC325454756", Qos: 0, MessageHandler: func(c mqtt.Client, m mqtt.Message) {}, WaitTimeout: 5 * time.Second, } if err := c.Subscribe(subTopic); err != nil { log.WithFields(log.Fields{ "topic": subTopic.Name, "error": err, }).Error("mqtt: 话题订阅失败") time.Sleep(200 * time.Millisecond) goto RetrySubscribe } pubTopic := mqttx.PublishTopic{ Name: "testtopic/325454756", Qos: 0, Retained: false, Payload: `{"KEY1":0}`, WaitTimeout: 5 * time.Second, } for { if err := c.Publish(pubTopic); err != nil { log.WithFields(log.Fields{ "topic": pubTopic.Name, "error": err, }).Error("mqtt: 话题发送失败") } <-time.After(5 * time.Second) } }() r := gin.Default() r.GET("/status", StatusHandler) r.POST("/mqtt", MqttHandler) r.Run() } func StatusHandler(c *gin.Context) { // } func MqttHandler(c *gin.Context) { var input struct { Speed1 *uint8 `json:"speed1" binding:"required,gte=0,lte=100"` // 喷雾量(百分比): 0-100 Speed2 *uint8 `json:"speed2" binding:"required,gte=0,lte=100"` // 喷雾量(百分比): 0-100 YV1 *uint8 `json:"yv1" binding:"required"` // 电磁阀1: 0 关闭, 1 启动 YV2 *uint8 `json:"yv2" binding:"required"` // 电磁阀2: 0 关闭, 1 启动 } if err := c.ShouldBindJSON(&input); err != nil { c.JSON(http.StatusBadRequest, gin.H{"errcode": 400, "errmsg": err.Error()}) return } payload := make(map[string]interface{}) payload["KEY1"] = 2 payload["Speed1"] = input.Speed1 payload["Speed2"] = input.Speed2 payload["YV1"] = input.YV1 payload["YV2"] = input.YV2 buf, _ := json.Marshal(payload) topic := mqttx.PublishTopic{ Name: "testtopic/325454756", Qos: 0, Retained: false, Payload: buf, WaitTimeout: 5 * time.Second, } if mc, err := mqttx.Get(viper.GetString("mqtt.client_id")); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"errcode": 10001, "errmsg": fmt.Sprintf("mqtt: %v", err)}) return } else if err := mc.Publish(topic); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"errcode": 10002, "errmsg": fmt.Sprintf("mqtt: %v", err)}) return } c.JSON(http.StatusOK, gin.H{"msg": "ok"}) }