You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
3.8 KiB
148 lines
3.8 KiB
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
mqtt "github.com/eclipse/paho.mqtt.golang"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/jinzhu/gorm"
|
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
|
"io/ioutil"
|
|
"log"
|
|
"math/rand"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
var client mqtt.Client
|
|
var db *gorm.DB
|
|
var conf Config
|
|
|
|
type DeviceInfo struct {
|
|
ID int64 `json:"id"`
|
|
DevEui string `json:"devEUI"`
|
|
DevAddr string `json:"devAddr"`
|
|
Username string `json:"username"`
|
|
CreateAt time.Time `json:"createAt"`
|
|
}
|
|
|
|
type Config struct {
|
|
Server struct {
|
|
Port string
|
|
}
|
|
DB struct {
|
|
Host string
|
|
Port int
|
|
User string
|
|
Password string
|
|
Name string
|
|
LogMode bool
|
|
}
|
|
MQTT struct {
|
|
Server string
|
|
Topic string
|
|
}
|
|
}
|
|
|
|
func loadConfig(filename string, c *Config) error {
|
|
data, err := ioutil.ReadFile(filename)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
err = json.Unmarshal(data, c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
func Krand(size int, kind int) []byte {
|
|
ikind, kinds, result := kind, [][]int{[]int{10, 48}, []int{26, 97}, []int{26, 65}}, make([]byte, size)
|
|
is_all := kind > 2 || kind < 0
|
|
for i :=0; i < size; i++ {
|
|
if is_all { // random ikind
|
|
ikind = rand.Intn(3)
|
|
}
|
|
scope, base := kinds[ikind][0], kinds[ikind][1]
|
|
result[i] = uint8(base+rand.Intn(scope))
|
|
}
|
|
return result
|
|
}
|
|
|
|
func Setup(c *Config) {
|
|
var err error
|
|
dsn := fmt.Sprintf("%s:%s@(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", c.DB.User, c.DB.Password, c.DB.Host, c.DB.Port,c.DB.Name)
|
|
db, err = gorm.Open("mysql", dsn)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
db.LogMode(c.DB.LogMode)
|
|
db.AutoMigrate(&DeviceInfo{})
|
|
db.Model(&DeviceInfo{}).AddUniqueIndex("idx_dev_eui","dev_eui")
|
|
db.Model(&DeviceInfo{}).AddUniqueIndex("idx_dev_addr", "dev_addr")
|
|
db.Model(&DeviceInfo{}).AddIndex("idx_create_at", "create_at")
|
|
opts := mqtt.NewClientOptions().AddBroker(c.MQTT.Server).SetClientID("deviceIDServer_"+string(Krand(16,3)))
|
|
client = mqtt.NewClient(opts)
|
|
if token := client.Connect(); token.Wait() && token.Error() != nil {
|
|
panic(token.Error())
|
|
}
|
|
}
|
|
|
|
func PostDevice(c *gin.Context) {
|
|
var device DeviceInfo
|
|
device.CreateAt = time.Now()
|
|
if err := c.BindJSON(&device); err != nil {
|
|
log.Println("bind json error: ",err)
|
|
c.JSON(http.StatusOK,gin.H{"code":-1,"msg": err.Error()})
|
|
return
|
|
}
|
|
if err := db.Create(&device).Error; err != nil {
|
|
log.Println("db insert error: ",err)
|
|
c.JSON(http.StatusOK,gin.H{"code":-1,"msg": err.Error()})
|
|
return
|
|
}
|
|
data,_ := json.Marshal(device)
|
|
token := client.Publish(conf.MQTT.Topic,0,false,data)
|
|
if token.Wait() && token.Error() != nil {
|
|
log.Println("mqtt publish error: ",token.Error())
|
|
c.JSON(http.StatusOK,gin.H{"code":-1,"msg": token.Error().Error()})
|
|
return
|
|
}
|
|
log.Println("devEUI: "+ device.DevEui + " post success")
|
|
c.JSON(http.StatusOK,gin.H{"code":0,"msg": "OK"})
|
|
return
|
|
}
|
|
|
|
func GetDevice(c *gin.Context) {
|
|
devEui := c.Query("dev_eui")
|
|
limit,_ := strconv.Atoi(c.DefaultQuery("limit","10"))
|
|
offset,_ := strconv.Atoi(c.DefaultQuery("offset","0"))
|
|
total := 0
|
|
var deviceInfos []DeviceInfo
|
|
devEui = "%" + devEui + "%"
|
|
db.Model(&DeviceInfo{}).Where("dev_eui like ?", devEui).Count(&total)
|
|
err := db.Where("dev_eui like ?",devEui).Limit(limit).Offset(offset).Order("create_at desc").Find(&deviceInfos).Error
|
|
if err != nil {
|
|
log.Println("query db error",err)
|
|
c.JSON(http.StatusOK,gin.H{"code":-1,"msg": err.Error()})
|
|
} else {
|
|
c.JSON(http.StatusOK,gin.H{"code":0,"msg": "OK","data":gin.H{"total": total, "result": deviceInfos}})
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
err := loadConfig("./config.json",&conf)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
Setup(&conf)
|
|
gin.SetMode(gin.ReleaseMode)
|
|
engine := gin.Default()
|
|
engine.GET("/device/info", GetDevice)
|
|
engine.POST("/device/info", PostDevice)
|
|
log.Println("start deviceIDServer port " + conf.Server.Port)
|
|
err = engine.Run(":" + conf.Server.Port)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
_ = db.Close()
|
|
}
|
|
|