Files
PandaX/iothub/netbase/hook_base.go
PandaX 37fb57a3f5 [fix] 日期时间-8小时
Signed-off-by: PandaX <18610165312@163.com>
2025-01-03 02:42:50 +00:00

226 lines
5.9 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 netbase
import (
"encoding/json"
"github.com/PandaXGO/PandaKit/utils"
"pandax/apps/device/entity"
"pandax/apps/device/services"
exhook "pandax/iothub/server/emqxserver/protobuf"
"pandax/pkg/cache"
"pandax/pkg/global"
"pandax/pkg/global/model"
"pandax/pkg/tdengine"
"pandax/pkg/tool"
"regexp"
"strings"
"time"
)
func Auth(authToken string) bool {
// 根据token去查设备Id以及设备类型
if authToken == global.Conf.Mqtt.Username {
return true
}
etoken := &model.DeviceAuth{}
// redis 中有就查询,没有就添加
exists := cache.ExistsDeviceEtoken(authToken)
if exists {
err := cache.GetDeviceEtoken(authToken, etoken)
if err != nil {
global.Log.Infof("认证失败,缓存读取设备错误: %s", err)
return false
}
} else {
device, err := services.DeviceModelDao.FindOneByToken(authToken)
if err != nil {
global.Log.Infof("认证失败设备token %s 不存在", authToken)
return false
}
etoken = services.GetDeviceToken(&device.Device)
etoken.Protocol = device.Product.ProtocolName
err = cache.SetDeviceEtoken(authToken, etoken.GetMarshal(), time.Hour*24*365)
if err != nil {
global.Log.Infof("认证失败设备TOKEN %s添加缓存失败", authToken)
return false
}
}
return true
}
// SubAuth 获取子设备的认证信息
func SubAuth(authToken string, productAuth *model.DeviceAuth) (*model.DeviceAuth, bool) {
defer func() {
if Rerr := recover(); Rerr != nil {
global.Log.Error(Rerr)
return
}
}()
// 解析认证
tokens := strings.Split(authToken, "_")
producId := ""
name := ""
if len(tokens) >= 2 {
producId = tokens[0]
name = tokens[1]
} else if len(tokens) == 1 {
name = tokens[0]
} else {
return nil, false
}
etoken := &model.DeviceAuth{}
// redis 中有就查询,没有就添加
err := cache.GetDeviceEtoken(name, etoken)
if err == nil {
return etoken, true
}
// 判断子设备 已经创建的子设备
deviceRes, err := services.DeviceModelDao.FindOneByName(name)
// 没有设备就要创建子设备
if err != nil {
product, err := services.ProductModelDao.FindOne(producId)
if err != nil {
return nil, false
}
//自动创建设备,
// 1. 创建设备
device := entity.Device{
Name: name,
Pid: producId,
Alias: productAuth.Name + "子设备",
ParentId: productAuth.DeviceId,
Gid: productAuth.DeviceGroup,
Status: "0",
LinkStatus: global.ONLINE,
LastAt: time.Now(),
DeviceType: entity.GATEWAYS_DEVICE,
}
device.Id = utils.GenerateID("d")
device.OrgId = product.OrgId
device.Owner = product.Owner
device.Protocol = product.ProtocolName
deviceD, err := services.DeviceModelDao.Insert(device)
if err != nil {
return nil, false
}
etoken = services.GetDeviceToken(deviceD)
etoken.Protocol = product.ProtocolName
} else {
etoken = services.GetDeviceToken(&deviceRes.Device)
etoken.Protocol = deviceRes.Product.ProtocolName
}
err = cache.SetDeviceEtoken(name, etoken.GetMarshal(), time.Hour*24*365)
if err != nil {
global.Log.Infof("设备 %s添加缓存失败", name)
return nil, false
}
return etoken, true
}
// UpdateDeviceTelemetryData 解析遥测数据类型 返回标准带时间戳格式
func UpdateDeviceTelemetryData(data string) map[string]interface{} {
tel := make(map[string]interface{})
err := json.Unmarshal([]byte(data), &tel)
if err != nil {
global.Log.Error("上传遥测数据结构错误")
return nil
}
if _, ok := tel["ts"]; ok {
if _, ok := tel["values"]; ok {
marshal, err := json.Marshal(tel["values"])
if err != nil {
global.Log.Error("上传遥测数据values数据结构错误")
return nil
}
resTel := make(map[string]interface{})
json.Unmarshal(marshal, &resTel)
format := tool.TimeToFormat(tel["ts"])
if format == "" {
return nil
}
resTel["ts"] = format
return resTel
}
}
tel["ts"] = time.Now().Local().Format("2006-01-02 15:04:05.000")
return tel
}
// UpdateDeviceAttributesData 解析属性数据类型 返回标准带时间戳格式
func UpdateDeviceAttributesData(data string) map[string]interface{} {
tel := make(map[string]interface{})
err := json.Unmarshal([]byte(data), &tel)
if err != nil {
global.Log.Error("上传属性数据结构错误")
return nil
}
tel["ts"] = time.Now().Local().Format("2006-01-02 15:04:05.000")
return tel
}
// GetUserName 根据emqx连接信息获取用户名
func GetUserName(Clientinfo *exhook.ClientInfo) string {
// coap 协议 用户名最大支持5个字符
protocol := Clientinfo.GetProtocol()
var username string
if protocol == "coap" {
username = Clientinfo.GetClientid()
} else if protocol == "lwm2m" {
username = SplitLwm2mClientID(Clientinfo.GetClientid(), 0)
} else {
username = Clientinfo.GetUsername()
}
return username
}
func SplitLwm2mClientID(lwm2mClientID string, index int) string {
// LwM2M client id should be username@password
idArray := strings.Split(lwm2mClientID, "@")
if len(idArray) < 2 || index > (len(idArray)+1) {
return ""
}
return idArray[index]
}
func GetRequestIdFromTopic(reg, topic string) (requestId string) {
re := regexp.MustCompile(reg)
res := re.FindStringSubmatch(topic)
if len(res) > 2 {
return res[2]
}
return ""
}
func GetEventFromTopic(reg, topic string) (identifier string) {
re := regexp.MustCompile(reg)
res := re.FindStringSubmatch(topic)
if len(res) > 1 {
return res[1]
}
return ""
}
// eventType 事件类型 info alarm
func CreateEventInfo(msgType, eventType, content string, deviceAuth *model.DeviceAuth) *DeviceEventInfo {
ts := time.Now().Local().Format("2006-01-02 15:04:05.000")
ci := &tdengine.Events{
DeviceId: deviceAuth.DeviceId,
Name: msgType,
Type: eventType,
Content: content,
Ts: ts,
}
v, err := json.Marshal(*ci)
if nil != err {
return nil
}
// 添加设备上线记录
return &DeviceEventInfo{
DeviceId: deviceAuth.DeviceId,
DeviceAuth: deviceAuth,
Datas: string(v),
Type: msgType,
}
}