iot-spray-equipment/main.go

158 lines
3.9 KiB
Go

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"})
}