1283 lines
40 KiB
Go
1283 lines
40 KiB
Go
|
package mqtt
|
|||
|
|
|||
|
import (
|
|||
|
"encoding/json"
|
|||
|
"errors"
|
|||
|
"fmt"
|
|||
|
mqtt "github.com/eclipse/paho.mqtt.golang"
|
|||
|
"github.com/gogf/gf/v2/crypto/gmd5"
|
|||
|
"github.com/gogf/gf/v2/database/gdb"
|
|||
|
"github.com/gogf/gf/v2/frame/g"
|
|||
|
"github.com/gogf/gf/v2/os/gctx"
|
|||
|
"github.com/gogf/gf/v2/os/gtime"
|
|||
|
_ "github.com/tiger1103/gfast-cache/cache"
|
|||
|
"github.com/tiger1103/gfast/v3/api/v1/common/coryCommon"
|
|||
|
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
|
|||
|
manageDeviceLogic "github.com/tiger1103/gfast/v3/internal/app/system/logic/manageDevice"
|
|||
|
manageOperationLog "github.com/tiger1103/gfast/v3/internal/app/system/logic/manageOperationLog"
|
|||
|
logic "github.com/tiger1103/gfast/v3/internal/app/system/logic/manageTaskRecord"
|
|||
|
logicManageTaskRecordResource "github.com/tiger1103/gfast/v3/internal/app/system/logic/manageTaskRecordResource"
|
|||
|
"github.com/tiger1103/gfast/v3/third/plane/dj"
|
|||
|
"github.com/tiger1103/gfast/v3/third/plane/event"
|
|||
|
"github.com/tiger1103/gfast/v3/third/plane/globe"
|
|||
|
tool "github.com/tiger1103/gfast/v3/utility/coryUtils"
|
|||
|
"golang.org/x/net/context"
|
|||
|
"log"
|
|||
|
"os"
|
|||
|
"path/filepath"
|
|||
|
"strconv"
|
|||
|
"strings"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
// var (
|
|||
|
//
|
|||
|
// DroneCoordinates = "sn:" //redisKey 无人机坐标
|
|||
|
// RainfallStr = "air:rainfall:" //redisKey 降雨量 {"0":"无雨","1":"小雨","2":"中雨","3":"大雨"}
|
|||
|
// YunTai = "air:yuntai:" //redisKey 云台重置
|
|||
|
//
|
|||
|
// )
|
|||
|
var (
|
|||
|
DroneCoordinates = "sn:" //redisKey 无人机坐标
|
|||
|
RainfallStr = "air:rainfall:" //redisKey 降雨量 {"0":"无雨","1":"小雨","2":"中雨","3":"大雨"}
|
|||
|
YunTai = "air:yuntai:" //redisKey 云台重置
|
|||
|
Host string
|
|||
|
Rtmp string
|
|||
|
Http string
|
|||
|
)
|
|||
|
|
|||
|
func init() {
|
|||
|
Host = g.Cfg().MustGet(context.Background(), "live.host").String()
|
|||
|
Rtmp = g.Cfg().MustGet(context.Background(), "live.rtmp").String()
|
|||
|
Http = g.Cfg().MustGet(context.Background(), "live.http").String()
|
|||
|
}
|
|||
|
|
|||
|
/*从topic中获取gatewaysn*/
|
|||
|
func GetGateWaySnFromTopic(topic string) string {
|
|||
|
split := strings.Split(topic, "/")
|
|||
|
return split[len(split)-2]
|
|||
|
}
|
|||
|
func dealOsd(client mqtt.Client, msg mqtt.Message) {
|
|||
|
//存储飞机与飞行器的数据
|
|||
|
cory := dj.CoryAirportOrAircraft{}
|
|||
|
//解析数据
|
|||
|
parsingOsd3(client, msg)
|
|||
|
//0、获取公共信息
|
|||
|
pc := dj.Public{}
|
|||
|
err := json.Unmarshal(msg.Payload(), &pc)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
sn := strings.Split(msg.Topic(), "/")[2]
|
|||
|
key := DroneCoordinates + pc.Gateway
|
|||
|
cory.HangarSn = pc.Gateway
|
|||
|
//fmt.Println("osd上报------ ", string(msg.Payload()))
|
|||
|
//1、Gateway与sn相同代表机场,否则代表无人机信息
|
|||
|
payload := string(msg.Payload())
|
|||
|
if pc.Gateway == sn {
|
|||
|
cory.Airport = string(msg.Payload())
|
|||
|
//if strings.Contains(payload, "drone_battery_maintenance_info") { //无人机电池维护信息
|
|||
|
// dealOsd1Cory(client, cory, msg)
|
|||
|
//} else if strings.Contains(payload, "wireless_link") { //无线电路
|
|||
|
// dealOsd2Cory(client, cory, msg)
|
|||
|
//} else if strings.Contains(payload, "network_state") { //网络状态
|
|||
|
// dealOsd3Cory(client, cory, msg)
|
|||
|
//} else if strings.Contains(payload, "live_status") { //直播状态
|
|||
|
// dealOsd4Cory(client, cory, msg)
|
|||
|
//}
|
|||
|
if strings.Contains(payload, "network_state") { //网络状态
|
|||
|
dealOsd3Cory(client, cory, msg)
|
|||
|
} else {
|
|||
|
dealOsd4Cory(client, cory, msg)
|
|||
|
}
|
|||
|
} else {
|
|||
|
var entity *dj.M30tEntity
|
|||
|
json.Unmarshal(msg.Payload(), &entity)
|
|||
|
//数据不能为null,为null就不需要在执行下一步
|
|||
|
if entity != nil {
|
|||
|
//1、获取当前飞机的坐标,然后存储到redis中
|
|||
|
ctx := gctx.New()
|
|||
|
result := fmt.Sprintf("%v,%v,%v", entity.Data.Longitude, entity.Data.Latitude, entity.Data.Elevation)
|
|||
|
_, err := g.Redis().Set(ctx, key, result)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("无人机坐标存储数据失败:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
cory.Aircraft = string(msg.Payload())
|
|||
|
cory.AircraftSn = sn
|
|||
|
//2、判断条件是否触发立即返航条件(电量)
|
|||
|
percent := entity.Data.Battery.CapacityPercent
|
|||
|
//power := entity.Data.Battery.ReturnHomePower
|
|||
|
if percent <= 70 {
|
|||
|
go Return_home(ctx, pc.Gateway)
|
|||
|
}
|
|||
|
//3、发送飞机飞行信息
|
|||
|
start_push_cory(globe.WS_Status_map, cory)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// parsingOsd3 解析osd3
|
|||
|
func parsingOsd3(client mqtt.Client, msg mqtt.Message) {
|
|||
|
payload := string(msg.Payload())
|
|||
|
if strings.Contains(payload, "rainfall") { //解析降雨量,后续下发任务的时候判断降雨量
|
|||
|
osd3 := dj.OSD3{}
|
|||
|
err := json.Unmarshal(msg.Payload(), &osd3)
|
|||
|
if err != nil {
|
|||
|
g.Log("uav").Error(gctx.New(), err)
|
|||
|
}
|
|||
|
g.Redis().Set(gctx.New(), RainfallStr+osd3.Gateway, osd3.Data.Rainfall)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// func dealOsd1Cory(client mqtt.Client, info dj.CoryAirportOrAircraft, msg mqtt.Message) {
|
|||
|
// start_push_cory(globe.WS_Status_map, info)
|
|||
|
// }
|
|||
|
//
|
|||
|
// func dealOsd2Cory(client mqtt.Client, info dj.CoryAirportOrAircraft, msg mqtt.Message) {
|
|||
|
// start_push_cory(globe.WS_Status_map, info)
|
|||
|
// }
|
|||
|
func dealOsd3Cory(client mqtt.Client, info dj.CoryAirportOrAircraft, msg mqtt.Message) {
|
|||
|
osd3 := dj.OSD3{}
|
|||
|
err := json.Unmarshal(msg.Payload(), &osd3)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
point := dj.Point{}
|
|||
|
point.Longitude = osd3.Data.Longitude
|
|||
|
point.Latitude = osd3.Data.Latitude
|
|||
|
point.Height = osd3.Data.Height
|
|||
|
sn := GetGateWaySnFromTopic(msg.Topic())
|
|||
|
savePosition(sn, point)
|
|||
|
//从redis中读取无人机最后一次的数据
|
|||
|
getValue, _ := g.Redis().Get(gctx.New(), DroneCoordinates+osd3.Gateway)
|
|||
|
info.Coordinates = getValue.String()
|
|||
|
start_push_cory(globe.WS_Status_map, info)
|
|||
|
}
|
|||
|
func dealOsd4Cory(client mqtt.Client, info dj.CoryAirportOrAircraft, msg mqtt.Message) {
|
|||
|
start_push_cory(globe.WS_Status_map, info)
|
|||
|
}
|
|||
|
|
|||
|
/*存储机场位置*/
|
|||
|
func savePosition(gateway_sn string, point dj.Point) {
|
|||
|
manageDeviceLogic.LongitudeAndLatitudeEdit(gateway_sn, point)
|
|||
|
}
|
|||
|
|
|||
|
// deal_events 事件
|
|||
|
func deal_events(client2 mqtt.Client, message mqtt.Message) {
|
|||
|
pub := dj.Public{}
|
|||
|
err := json.Unmarshal(message.Payload(), &pub)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
var _map globe.WS_MAP
|
|||
|
switch pub.Method {
|
|||
|
case dj.OtaProgress:
|
|||
|
fmt.Println("固件升级进度:", string(message.Payload()))
|
|||
|
break
|
|||
|
case dj.Drone_open:
|
|||
|
fmt.Println("飞机开机进度")
|
|||
|
fmt.Println(string(message.Payload()))
|
|||
|
StatusReply(message)
|
|||
|
_map = globe.WS_Progress_drone_open_map
|
|||
|
wspush(message, _map)
|
|||
|
break
|
|||
|
case dj.Drone_close:
|
|||
|
StatusReply(message)
|
|||
|
fmt.Println("飞机关机进度")
|
|||
|
fmt.Println(string(message.Payload()))
|
|||
|
_map = globe.WS_Progress_drone_close_map
|
|||
|
wspush(message, _map)
|
|||
|
break
|
|||
|
case dj.Cover_open:
|
|||
|
StatusReply(message)
|
|||
|
_map = globe.WS_Progress_cover_open_map
|
|||
|
wspush(message, _map)
|
|||
|
break
|
|||
|
case dj.Cover_close:
|
|||
|
StatusReply(message)
|
|||
|
_map = globe.WS_Progress_cover_close_map
|
|||
|
wspush(message, _map)
|
|||
|
break
|
|||
|
case dj.Device_reboot:
|
|||
|
fmt.Println("设备重启进度")
|
|||
|
fmt.Println(string(message.Payload()))
|
|||
|
_map = globe.WS_Progress_device_reboot_map
|
|||
|
StatusReply(message)
|
|||
|
wspush(message, _map)
|
|||
|
break
|
|||
|
case dj.Putter_open:
|
|||
|
StatusReply(message)
|
|||
|
_map = globe.WS_Progress_putter_open_map
|
|||
|
wspush(message, _map)
|
|||
|
break
|
|||
|
case dj.Putter_close:
|
|||
|
StatusReply(message)
|
|||
|
_map = globe.WS_Progress_putter_close_map
|
|||
|
wspush(message, _map)
|
|||
|
break
|
|||
|
case dj.Flighttask_ready: //任务就绪
|
|||
|
fmt.Println("任务就绪")
|
|||
|
fmt.Println(string(message.Payload()))
|
|||
|
break
|
|||
|
case dj.Return_home_info: //返航信息
|
|||
|
fmt.Println("返航信息")
|
|||
|
fmt.Println(string(message.Payload()))
|
|||
|
break
|
|||
|
case dj.Flighttask_progress: //上报航线任务进度
|
|||
|
fmt.Println("航线执行进度")
|
|||
|
go dealWaylineProgress(message)
|
|||
|
break
|
|||
|
case dj.File_upload_callback: //媒体文件上传结果上报
|
|||
|
fmt.Println("媒体文件上传结果上报")
|
|||
|
fmt.Println(string(message.Payload()))
|
|||
|
//解析回传结果
|
|||
|
fileUploadCallbackEntity := dj.FileUploadCallbackEntity{}
|
|||
|
if err := json.Unmarshal(message.Payload(), &fileUploadCallbackEntity); err != nil {
|
|||
|
log.Printf("媒体文件上传结果上报数据解析失败:%v", err)
|
|||
|
}
|
|||
|
//将解析的数据存储到mysql
|
|||
|
logicManageTaskRecordResource.StoresBackMediaFilesToTheDatabaseFunc(gctx.New(), &fileUploadCallbackEntity)
|
|||
|
break
|
|||
|
case dj.Fly_to_point_progress: //flyto 执行结果事件通知
|
|||
|
fmt.Println("flyto 执行结果事件通知")
|
|||
|
fmt.Println(string(message.Payload()))
|
|||
|
break
|
|||
|
case dj.Fileupload_progress: //文件上传进度通知(远程日志)
|
|||
|
fmt.Println("文件上传进度通知(远程日志)")
|
|||
|
fmt.Println(string(message.Payload()))
|
|||
|
break
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// deal_services 事件
|
|||
|
func deal_services(client2 mqtt.Client, message mqtt.Message) {
|
|||
|
pub := dj.Public{}
|
|||
|
err := json.Unmarshal(message.Payload(), &pub)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
//根据方法得到对应得数据信息
|
|||
|
switch pub.Method {
|
|||
|
case dj.FileuploadList: //获取设备可上传的文件列表
|
|||
|
break
|
|||
|
case dj.FileuploadStart: //发起日志文件上传
|
|||
|
break
|
|||
|
case dj.OtaCreate: //发起日志文件上传
|
|||
|
|
|||
|
break
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func StatusReply(message mqtt.Message) {
|
|||
|
public := dj.Public{}
|
|||
|
err := json.Unmarshal(message.Payload(), &public)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
reply := dj.StatusReply{}
|
|||
|
reply.Method = public.Method
|
|||
|
reply.Tid = public.Tid
|
|||
|
reply.Bid = public.Bid
|
|||
|
reply.Timestamp = gtime.TimestampMilli()
|
|||
|
reply.Data.Result = 0
|
|||
|
sn := GetGateWaySnFromTopic(message.Topic())
|
|||
|
marshal, _ := json.Marshal(reply)
|
|||
|
client.Publish(dj.GetEventsReplyTopic(sn), 1, true, string(marshal))
|
|||
|
}
|
|||
|
|
|||
|
func dealWaylineProgress(message mqtt.Message) (err error) {
|
|||
|
waylineProgress := dj.WaylineProgress{}
|
|||
|
err = json.Unmarshal(message.Payload(), &waylineProgress)
|
|||
|
if err != nil {
|
|||
|
fmt.Println(err)
|
|||
|
return
|
|||
|
}
|
|||
|
entity := waylineProgress.Data.Output
|
|||
|
|
|||
|
//if waylineProgress.Data.Result > 0 {
|
|||
|
// err = Geterror(waylineProgress.Data.Result)
|
|||
|
// fmt.Println(err)
|
|||
|
// return
|
|||
|
//}
|
|||
|
|
|||
|
ctx := gctx.New()
|
|||
|
//1、根据计划ID得到最近一次飞行的航线信息,然后给当前航线填入航线ID等信息
|
|||
|
//if strings.Contains(str, "wayline_id") {
|
|||
|
if entity.Status == "ok" || entity.Status == "paused" {
|
|||
|
gmp := g.Map{
|
|||
|
"route_id": entity.Ext.WaylineId,
|
|||
|
"interrupt_cause": entity.Ext.BreakPoint.BreakReason,
|
|||
|
"dd_index": entity.Ext.BreakPoint.Index,
|
|||
|
"dd_state": entity.Ext.BreakPoint.State,
|
|||
|
"course_reversal": tool.MillisecondTimestamp(),
|
|||
|
"accomplish": tool.MillisecondTimestamp(),
|
|||
|
}
|
|||
|
if entity.Ext.BreakPoint.Progress > 0 {
|
|||
|
gmp["dd_progress"] = entity.Ext.BreakPoint.Progress
|
|||
|
}
|
|||
|
if entity.Ext.TrackId != "" {
|
|||
|
gmp["track_id"] = entity.Ext.TrackId
|
|||
|
}
|
|||
|
dao.ManageTaskRecord.Ctx(ctx).
|
|||
|
Where("flight_id", entity.Ext.FlightId).
|
|||
|
OrderDesc("id").
|
|||
|
Update(gmp)
|
|||
|
}
|
|||
|
//}
|
|||
|
//2、航线为>0或者100的时候变更云台的方向
|
|||
|
gatewaySn := GetGateWaySnFromTopic(message.Topic())
|
|||
|
if entity.Progress.Percent >= 0 && entity.Progress.Percent < 95 {
|
|||
|
key := YunTai + gatewaySn + ":1"
|
|||
|
get, _ := g.Redis().Get(ctx, key)
|
|||
|
if !get.Bool() {
|
|||
|
sxt, _ := dealWaylineProgressSQL(ctx, gatewaySn)
|
|||
|
err, reply := Gimbal_reset(ctx, gatewaySn, sxt, 1)
|
|||
|
if err == nil && reply.Data.Result == 0 {
|
|||
|
//存放redis 每60过期秒
|
|||
|
g.Redis().SetEX(ctx, key, true, 60)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
g.Log("uav").Error(ctx, waylineProgress.Data.Output.Ext.FlightId+"返航进度---- "+strconv.Itoa(entity.Progress.Percent))
|
|||
|
if entity.Progress.Percent == 100 {
|
|||
|
key := YunTai + gatewaySn + ":0"
|
|||
|
get, _ := g.Redis().Get(ctx, key)
|
|||
|
if !get.Bool() {
|
|||
|
sxt, _ := dealWaylineProgressSQL(ctx, gatewaySn)
|
|||
|
err, reply := Gimbal_reset(ctx, gatewaySn, sxt, 0)
|
|||
|
if err == nil && reply.Data.Result == 0 {
|
|||
|
//存放redis 每60秒过期
|
|||
|
g.Redis().SetEX(ctx, key, true, 60)
|
|||
|
}
|
|||
|
if entity.Status == "ok" {
|
|||
|
//到达一百的时候变更当前航线任务的状态
|
|||
|
dao.ManageTaskRecord.Ctx(ctx).
|
|||
|
Where("flight_id", waylineProgress.Data.Output.Ext.FlightId).
|
|||
|
WhereNull("accomplish").
|
|||
|
Update(g.Map{"accomplish": tool.MillisecondTimestamp()})
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
func dealWaylineProgressSQL(ctx context.Context, gatewaySn string) (string, error) {
|
|||
|
sxt, err := g.DB().Model("manage_device_video").Ctx(ctx).
|
|||
|
Where("type = 1").Where("gateway_sn", gatewaySn).OrderDesc("id").Limit(1).Fields("son_sn").
|
|||
|
Cache(gdb.CacheOption{
|
|||
|
Duration: time.Hour,
|
|||
|
Force: false,
|
|||
|
}).Value()
|
|||
|
return sxt.String(), err
|
|||
|
}
|
|||
|
|
|||
|
func wspush(msg mqtt.Message, _map globe.WS_MAP) {
|
|||
|
if _map != nil {
|
|||
|
start_push(_map, msg)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func start_push(_map globe.WS_MAP, msg mqtt.Message) {
|
|||
|
globe.MutexRw.Lock()
|
|||
|
for _, socket := range _map {
|
|||
|
socket.WriteMessage(1, msg.Payload())
|
|||
|
}
|
|||
|
globe.MutexRw.Unlock()
|
|||
|
}
|
|||
|
|
|||
|
// cory 提供给osd使用的(用来区分机场和无人机的数据)
|
|||
|
func start_push_cory(_map globe.WS_MAP, info dj.CoryAirportOrAircraft) {
|
|||
|
globe.MutexRw.Lock()
|
|||
|
for _, socket := range _map {
|
|||
|
marshal, _ := json.Marshal(info)
|
|||
|
socket.WriteMessage(1, marshal)
|
|||
|
}
|
|||
|
globe.MutexRw.Unlock()
|
|||
|
}
|
|||
|
|
|||
|
// deal_requests 请求
|
|||
|
func deal_requests(client mqtt.Client, msg mqtt.Message) {
|
|||
|
pub := dj.Public{}
|
|||
|
err := json.Unmarshal(msg.Payload(), &pub)
|
|||
|
if err != nil {
|
|||
|
fmt.Println(err)
|
|||
|
return
|
|||
|
}
|
|||
|
switch pub.Method {
|
|||
|
case dj.Airport_organization_bind: //处理数据库
|
|||
|
fmt.Println("设备绑定到组织")
|
|||
|
fmt.Println(string(msg.Payload()))
|
|||
|
break
|
|||
|
case dj.Airport_organization_get:
|
|||
|
break
|
|||
|
case dj.Flighttask_resource_get:
|
|||
|
fmt.Println("获取任务资源了")
|
|||
|
fmt.Println(string(msg.Payload()))
|
|||
|
flighttask_resource_get(client, msg)
|
|||
|
break
|
|||
|
case dj.Airport_bind_status:
|
|||
|
break
|
|||
|
case dj.Config:
|
|||
|
pb := dj.Public{}
|
|||
|
if err = json.Unmarshal(msg.Payload(), &pb); err != nil {
|
|||
|
fmt.Println(err)
|
|||
|
}
|
|||
|
reply := dj.ConfigReply{}
|
|||
|
reply.SetDefaultValue()
|
|||
|
reply.Tid = pb.Tid
|
|||
|
reply.Bid = pb.Bid
|
|||
|
marshal, err := json.Marshal(reply)
|
|||
|
if err != nil {
|
|||
|
fmt.Println(err)
|
|||
|
}
|
|||
|
topic := msg.Topic() + "_reply"
|
|||
|
fmt.Println("配置更新开始推送", topic, string(marshal))
|
|||
|
client.Publish(topic, 1, true, string(marshal))
|
|||
|
break
|
|||
|
case dj.Storage_config_get:
|
|||
|
pb := dj.Public{}
|
|||
|
if err = json.Unmarshal(msg.Payload(), &pb); err != nil {
|
|||
|
fmt.Println(err)
|
|||
|
}
|
|||
|
get := dj.StorageConfigGetReply{}
|
|||
|
get.SetDefaultValue()
|
|||
|
get.Tid = pb.Tid
|
|||
|
get.Bid = pb.Bid
|
|||
|
marshal, err := json.Marshal(get)
|
|||
|
if err != nil {
|
|||
|
fmt.Println(err)
|
|||
|
}
|
|||
|
topic := msg.Topic() + "_reply"
|
|||
|
fmt.Println("临时凭证开始推送", topic, string(marshal))
|
|||
|
client.Publish(topic, 1, true, string(marshal))
|
|||
|
break
|
|||
|
}
|
|||
|
|
|||
|
//fmt.Println("获取数据了", string(msg.Payload()))
|
|||
|
}
|
|||
|
func deal_state(client mqtt.Client, msg mqtt.Message) {
|
|||
|
|
|||
|
// 获取当前可执行文件所在的目录
|
|||
|
dir, _ := os.Getwd()
|
|||
|
// 拼接文件路径
|
|||
|
filePath := filepath.Join(dir, "output.txt")
|
|||
|
// 以追加模式打开文件,如果文件不存在则创建
|
|||
|
file, _ := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|||
|
defer file.Close()
|
|||
|
// 写入内容并添加两个换行符
|
|||
|
file.WriteString(string(msg.Payload()) + "\n\n")
|
|||
|
|
|||
|
payload := string(msg.Payload())
|
|||
|
fmt.Println("设备端按需上报向云平台推送的设备属性", payload)
|
|||
|
|
|||
|
var ai *dj.AircraftInformation
|
|||
|
err := json.Unmarshal(msg.Payload(), &ai)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
if ai != nil {
|
|||
|
start_push(globe.WS_Status_map, msg)
|
|||
|
}
|
|||
|
|
|||
|
if strings.Contains(payload, "live_capacity") {
|
|||
|
var lscue *LiveStreamingCapabilityUpdateEntity
|
|||
|
err := json.Unmarshal(msg.Payload(), &lscue)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("《直播能力更新》数据转换失败!")
|
|||
|
}
|
|||
|
var gatewaySn = ""
|
|||
|
var mp []g.Map
|
|||
|
for i, data := range lscue.Data.LiveCapacity.DeviceList {
|
|||
|
if i == 0 { //机场 与 子设备(摄像头)
|
|||
|
for _, dataOne := range data.CameraList {
|
|||
|
count, _ := g.DB().Model("manage_device_video").
|
|||
|
Where("gateway_sn", data.Sn).
|
|||
|
Where("device_sn", data.Sn).
|
|||
|
Where("son_sn", dataOne.CameraIndex).Count()
|
|||
|
if count == 0 {
|
|||
|
mp = append(mp, g.Map{
|
|||
|
"type": i,
|
|||
|
"gateway_sn": data.Sn,
|
|||
|
"device_sn": data.Sn,
|
|||
|
"son_sn": dataOne.CameraIndex,
|
|||
|
})
|
|||
|
if data.Sn != "" {
|
|||
|
gatewaySn = data.Sn
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if i == 1 { //飞机 与 子设备(摄像头)
|
|||
|
for _, dataOne := range data.CameraList {
|
|||
|
count, _ := g.DB().Model("manage_device_video").
|
|||
|
Where("gateway_sn", gatewaySn).
|
|||
|
Where("device_sn", data.Sn).
|
|||
|
Where("son_sn", dataOne.CameraIndex).Count()
|
|||
|
if count == 0 && gatewaySn != "" {
|
|||
|
mp = append(mp, g.Map{
|
|||
|
"type": i,
|
|||
|
"gateway_sn": gatewaySn,
|
|||
|
"device_sn": data.Sn,
|
|||
|
"son_sn": dataOne.CameraIndex,
|
|||
|
})
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if len(mp) > 0 {
|
|||
|
g.DB().Model("manage_device_video").Insert(mp)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
func deal_status(client mqtt.Client, msg mqtt.Message) {
|
|||
|
pub := dj.Public{}
|
|||
|
err := json.Unmarshal(msg.Payload(), &pub)
|
|||
|
if err != nil {
|
|||
|
fmt.Println(err)
|
|||
|
return
|
|||
|
}
|
|||
|
switch pub.Method {
|
|||
|
case dj.Update_topo: //cory20250605
|
|||
|
fmt.Println("准备拓扑更新:", string(msg.Payload()))
|
|||
|
var reply dj.StatusReply
|
|||
|
reply.Timestamp = gtime.Now().TimestampMilli()
|
|||
|
reply.Bid = pub.Bid
|
|||
|
reply.Tid = pub.Tid
|
|||
|
reply.Method = "update_topo"
|
|||
|
reply.Data.Result = 0
|
|||
|
marshal, err := json.Marshal(reply)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
arr := strings.Split(msg.Topic(), "/")
|
|||
|
client.Publish("sys/product/"+arr[2]+"/status_reply", 1, true, marshal)
|
|||
|
break
|
|||
|
}
|
|||
|
st := dj.Status{}
|
|||
|
json.Unmarshal(msg.Payload(), &st)
|
|||
|
var reply dj.StatusReply
|
|||
|
reply.Timestamp = st.Timestamp
|
|||
|
reply.Bid = st.Bid
|
|||
|
reply.Tid = st.Tid
|
|||
|
reply.Method = "update_topo"
|
|||
|
marshal, err := json.Marshal(reply)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
arr := strings.Split(msg.Topic(), "/")
|
|||
|
client.Publish("sys/product/"+arr[2]+"/status_reply", 1, true, marshal)
|
|||
|
}
|
|||
|
|
|||
|
/*回复航线*/
|
|||
|
func flighttask_resource_get(client mqtt.Client, msg mqtt.Message) {
|
|||
|
get := dj.FlighttaskResourcGet{}
|
|||
|
err := json.Unmarshal(msg.Payload(), &get)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
//get.Data.FlightId
|
|||
|
rsp := dj.FlighttaskResourcGetReply{}
|
|||
|
rsp.Tid = get.Tid
|
|||
|
rsp.Bid = get.Bid
|
|||
|
rsp.Timestamp = gtime.Now().TimestampMilli()
|
|||
|
rsp.Method = get.Method
|
|||
|
arr := strings.Split(msg.Topic(), "/")
|
|||
|
topic := dj.GetRequestsReplyTopic(arr[len(arr)-2])
|
|||
|
f, err := logic.GetManageAirlineFile(get.Data.FlightId)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
rsp.Data.Result = 0
|
|||
|
rsp.Data.Output.File.Fingerprint = f.Fingerprint
|
|||
|
rsp.Data.Output.File.Url = f.Url
|
|||
|
ReplyMsg(topic, rsp)
|
|||
|
//rsp.Gateway = get.
|
|||
|
}
|
|||
|
|
|||
|
type File struct {
|
|||
|
Url string `json:"url"`
|
|||
|
Fingerprint string `json:"fingerprint"`
|
|||
|
}
|
|||
|
|
|||
|
func GetResource(flight_id string) File {
|
|||
|
return File{}
|
|||
|
}
|
|||
|
|
|||
|
//func Live_start_push(gateway_sn, devsn, camera_index string) (error, *dj.StartLiveReply) {
|
|||
|
// st := dj.StartLive{}
|
|||
|
// st.SetDefaultValue()
|
|||
|
// st.Data.UrlType = 1
|
|||
|
// //st.Data.Url = "serverIP=116.141.0.161&serverPort=7100&serverID=22010500002000000090&agentID=22010500002000000093&agentPassword=hik13579+&localPort=7060&channel=22010500002000000093"
|
|||
|
// //st.Data.Url = "serverIP=jl.yj-3d.com&serverPort=15060&serverID=34020000002000000001&agentID=34020000001320000010&agentPassword=0000000&localPort=7060&channel=34020000001320000010"
|
|||
|
// st.Data.VideoQuality = 4
|
|||
|
// st.Data.VideoId = devsn + "/" + camera_index + "/normal-0"
|
|||
|
// md5 := gmd5.MustEncryptString(st.Data.VideoId)
|
|||
|
// st.Data.Url = "rtmp://" + coryCommon.Global + ":9980/live/" + md5
|
|||
|
// topic := dj.GetServiceTopic(gateway_sn)
|
|||
|
//
|
|||
|
// //marshal, _ := json.Marshal(st)
|
|||
|
// //fmt.Println("数据为:", string(marshal))
|
|||
|
//
|
|||
|
// response := send(topic, st, st.Tid)
|
|||
|
//
|
|||
|
// sl := dj.StartLiveReply{}
|
|||
|
// err := json.Unmarshal([]byte(response), &sl)
|
|||
|
// if err != nil {
|
|||
|
// return err, nil
|
|||
|
// }
|
|||
|
// sl.Data.Url = "http://" + coryCommon.Global + ":9991/live/" + md5 + ".flv"
|
|||
|
//
|
|||
|
// return nil, &sl
|
|||
|
//}
|
|||
|
|
|||
|
func Live_start_push(gateway_sn, devsn, camera_index string) (error, *dj.StartLiveReply) {
|
|||
|
st := dj.StartLive{}
|
|||
|
st.SetDefaultValue()
|
|||
|
st.Data.UrlType = 1
|
|||
|
//st.Data.Url = "serverIP=116.141.0.161&serverPort=7100&serverID=22010500002000000090&agentID=22010500002000000093&agentPassword=hik13579+&localPort=7060&channel=22010500002000000093"
|
|||
|
//st.Data.Url = "serverIP=jl.yj-3d.com&serverPort=15060&serverID=34020000002000000001&agentID=34020000001320000010&agentPassword=0000000&localPort=7060&channel=34020000001320000010"
|
|||
|
st.Data.VideoQuality = 4
|
|||
|
st.Data.VideoId = devsn + "/" + camera_index + "/normal-0"
|
|||
|
md5 := gmd5.MustEncryptString(st.Data.VideoId)
|
|||
|
st.Data.Url = "rtmp://" + Host + ":" + Rtmp + "/live/" + md5
|
|||
|
topic := dj.GetServiceTopic(gateway_sn)
|
|||
|
|
|||
|
//marshal, _ := json.Marshal(st)
|
|||
|
//fmt.Println("数据为:", string(marshal))
|
|||
|
|
|||
|
response := send(topic, st, st.Tid)
|
|||
|
|
|||
|
sl := dj.StartLiveReply{}
|
|||
|
err := json.Unmarshal([]byte(response), &sl)
|
|||
|
if err != nil {
|
|||
|
return err, nil
|
|||
|
}
|
|||
|
sl.Data.Url = "http://" + Host + ":" + Http + "/live/" + md5 + ".live.flv"
|
|||
|
|
|||
|
return nil, &sl
|
|||
|
}
|
|||
|
|
|||
|
// GB28181 多路推流无效,废弃GB28181
|
|||
|
//func Live_start_push(gateway_sn, devsn, camera_index string) (error, *dj.StartLiveReply) {
|
|||
|
// gb := "34020000002000000001"
|
|||
|
// port := strings.ReplaceAll(camera_index, "-", "")
|
|||
|
// qvr := modifyString(gb, port)
|
|||
|
// st := dj.StartLive{}
|
|||
|
// st.SetDefaultValue()
|
|||
|
// st.Data.UrlType = 3
|
|||
|
// st.Data.VideoQuality = 4
|
|||
|
// st.Data.VideoId = devsn + "/" + camera_index + "/normal-0"
|
|||
|
// st.Data.Url = "serverIP=119.45.210.154&serverPort=15060&serverID=" + gb + "&agentID=" + qvr + "&agentPassword=12345678&localPort=" + port + "&channel=" + qvr
|
|||
|
// fmt.Println(st.Data.Url, gateway_sn)
|
|||
|
// topic := dj.GetServiceTopic(gateway_sn)
|
|||
|
// response := send(topic, st, st.Tid)
|
|||
|
// sl := dj.StartLiveReply{}
|
|||
|
// err := json.Unmarshal([]byte(response), &sl)
|
|||
|
// if err != nil {
|
|||
|
// return err, nil
|
|||
|
// }
|
|||
|
// sl.Data.Url = "http://119.45.210.154:10000/api/v1/stream/start?serial=" + qvr + "&code=" + qvr
|
|||
|
//
|
|||
|
// return nil, &sl
|
|||
|
//}
|
|||
|
|
|||
|
func modifyString(gb, qvr string) string {
|
|||
|
originalString := gb
|
|||
|
targetLength := len(qvr)
|
|||
|
resultString := ""
|
|||
|
// 如果原始字符串长度小于目标长度,则直接拼接
|
|||
|
if len(originalString) < targetLength {
|
|||
|
resultString = originalString + strings.Repeat("0", targetLength-len(originalString)) + qvr
|
|||
|
} else {
|
|||
|
// 将字符串转换为字节数组
|
|||
|
strBytes := []byte(originalString)
|
|||
|
// 修改最右边的字符
|
|||
|
copy(strBytes[len(strBytes)-targetLength:], qvr)
|
|||
|
// 将字节数组转换回字符串
|
|||
|
resultString = string(strBytes)
|
|||
|
}
|
|||
|
return resultString
|
|||
|
}
|
|||
|
|
|||
|
func Live_stop_push(gateway_sn, devsn, camera_index string) (error, *dj.StopLiveReply) {
|
|||
|
st := dj.StopLive{}
|
|||
|
st.SetDefaultValue()
|
|||
|
st.Data.VideoId = devsn + "/" + camera_index + "/normal-0"
|
|||
|
topic := dj.GetServiceTopic(gateway_sn)
|
|||
|
//md5 := gmd5.MustEncryptString(st.Data.VideoId)
|
|||
|
response := send(topic, st, st.Tid)
|
|||
|
sl := dj.StopLiveReply{}
|
|||
|
err := json.Unmarshal([]byte(response), &sl)
|
|||
|
if err != nil {
|
|||
|
return err, nil
|
|||
|
}
|
|||
|
return nil, &sl
|
|||
|
}
|
|||
|
|
|||
|
func deal_services_reply(client mqtt.Client, msg mqtt.Message) {
|
|||
|
fmt.Println("消息响应了", msg.Topic())
|
|||
|
pub1 := dj.PublicTwo{}
|
|||
|
err := json.Unmarshal(msg.Payload(), &pub1)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
//根据方法得到对应得数据信息
|
|||
|
switch pub1.Method {
|
|||
|
case dj.FileuploadList: //获取设备可上传的文件列表
|
|||
|
fmt.Println("services_reply获取设备可上传的\t\t//获取所有日志消息上传到minio中\n\t\tvar rdata *dj.FileUpLoadListDownUp\n\t\terr := json.Unmarshal(msg.Payload(), &rdata)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\treply := dj.LogFileUploadReply{}\n\t\treply.SetDefaultValue(rdata)\n\t\tmarshal, err := json.Marshal(reply)\n\t\tif err != nil {\n\t\t\tfmt.Println(err)\n\t\t}\n\t\treplace := strings.Replace(msg.Topic(), \"_reply\", \"\", 1)\n\t\tclient.Publish(replace, 1, true, string(marshal))\n\t\tbreak文件列表==================>", string(msg.Payload()))
|
|||
|
case dj.FileuploadStart:
|
|||
|
fmt.Println("services_reply发起日志文件上传==================>", string(msg.Payload()))
|
|||
|
break
|
|||
|
case dj.DeviceFormat:
|
|||
|
fmt.Println("机场数据格式化==================>", string(msg.Payload()))
|
|||
|
break
|
|||
|
case "drone_format":
|
|||
|
fmt.Println("飞行器数据格式化==================>", string(msg.Payload()))
|
|||
|
break
|
|||
|
case dj.ReturnHome1:
|
|||
|
fmt.Println("返航: ", string(msg.Payload()))
|
|||
|
case dj.OtaCreate:
|
|||
|
fmt.Println("固件升级: ", string(msg.Payload()))
|
|||
|
}
|
|||
|
publisher, ok := eventMap[pub1.Tid]
|
|||
|
if ok {
|
|||
|
publisher.Publish(msg.Payload())
|
|||
|
delete(eventMap, pub1.Tid)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func ReplyMsg(topic string, dt interface{}) {
|
|||
|
marshal, err := json.Marshal(dt)
|
|||
|
if err != nil {
|
|||
|
return
|
|||
|
}
|
|||
|
fmt.Println("回复任务资源消息", topic, string(marshal))
|
|||
|
client.Publish(topic, 1, true, string(marshal))
|
|||
|
}
|
|||
|
|
|||
|
func send(topic string, dt interface{}, tid string) string {
|
|||
|
marshal, err := json.Marshal(dt)
|
|||
|
if err != nil {
|
|||
|
return ""
|
|||
|
}
|
|||
|
fmt.Println("開始推送", topic, string(marshal))
|
|||
|
client.Publish(topic, 1, true, string(marshal))
|
|||
|
|
|||
|
mqttResponseChan := make(chan string)
|
|||
|
|
|||
|
timeout := time.After(15 * time.Second) // 创建一个3秒后超时的定时器
|
|||
|
|
|||
|
e := event.GetEvent(func(argc ...any) {
|
|||
|
/*这里的代码后执行*/
|
|||
|
fmt.Println("响应了")
|
|||
|
delete(eventMap, tid)
|
|||
|
b := argc[0].([]byte)
|
|||
|
response := string(b)
|
|||
|
fmt.Println(response)
|
|||
|
mqttResponseChan <- response
|
|||
|
})
|
|||
|
|
|||
|
eventMap[tid] = e
|
|||
|
|
|||
|
select {
|
|||
|
case response := <-mqttResponseChan:
|
|||
|
return response
|
|||
|
case <-timeout:
|
|||
|
return ""
|
|||
|
}
|
|||
|
|
|||
|
//// 这里的代码会比前面的事件内部回调先执行,所以需 阻塞等待 MQTT 响应消息
|
|||
|
//response := <-mqttResponseChan
|
|||
|
//return response
|
|||
|
}
|
|||
|
|
|||
|
func Device_reboot(gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
reboot := dj.Reboot{}
|
|||
|
reboot.SetDefaultValue()
|
|||
|
return send_msg(gateway_sn, reboot)
|
|||
|
}
|
|||
|
|
|||
|
func send_msg(gateway_sn string, in interface{}) (error, *dj.UsualReply) {
|
|||
|
marshal, err := json.Marshal(in)
|
|||
|
if err != nil {
|
|||
|
return err, nil
|
|||
|
}
|
|||
|
public := dj.Public{}
|
|||
|
err = json.Unmarshal(marshal, &public)
|
|||
|
if err != nil {
|
|||
|
return err, nil
|
|||
|
}
|
|||
|
topic := dj.GetServiceTopic(gateway_sn)
|
|||
|
response := send(topic, in, public.Tid)
|
|||
|
sl := dj.UsualReply{}
|
|||
|
err = json.Unmarshal([]byte(response), &sl)
|
|||
|
if err != nil {
|
|||
|
return err, nil
|
|||
|
}
|
|||
|
return nil, &sl
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func Debug_mode_open(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
debug := dj.DebugOpen{}
|
|||
|
debug.SetDefaultValue()
|
|||
|
|
|||
|
err, reply := send_msg(gateway_sn, debug)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, debug.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
func Debug_mode_close(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
debug := dj.DebugClose{}
|
|||
|
debug.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, debug)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, debug.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
func Putter_close(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
co := dj.PutterClose{}
|
|||
|
co.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
func Putter_open(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
co := dj.PutterOpen{}
|
|||
|
co.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
func Charge_close(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
co := dj.ChargeClose{}
|
|||
|
co.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
func Charge_open(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
co := dj.ChargeOpen{}
|
|||
|
co.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
func Cover_open(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
co := dj.CoverOpen{}
|
|||
|
co.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
func Cover_close(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
co := dj.CoverClose{}
|
|||
|
co.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
func Drone_open(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
fmt.Println("飞行器开机")
|
|||
|
co := dj.DroneOpen{}
|
|||
|
co.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
func Drone_close(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
co := dj.DroneClose{}
|
|||
|
co.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*执行任务*/
|
|||
|
func Flighttask_execute(ctx context.Context, gateway_sn, flight_id string) (error, *dj.UsualReply) {
|
|||
|
co := dj.FlighttaskExecute{}
|
|||
|
co.SetDefaultValue()
|
|||
|
co.Data.FlightId = flight_id
|
|||
|
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*取消任务*/
|
|||
|
func Flighttask_undo(ctx context.Context, gateway_sn string, flight_ids []string) (error, *dj.UsualReply) {
|
|||
|
co := dj.FlighttaskUndo{}
|
|||
|
co.SetDefaultValue()
|
|||
|
co.Data.Flight_ids = flight_ids
|
|||
|
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*航线暂停*/
|
|||
|
func Flighttask_pause(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
co := dj.FlighttaskPause{}
|
|||
|
co.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*航线恢复*/
|
|||
|
func Flighttask_recovery(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
co := dj.FlighttaskRecovery{}
|
|||
|
co.SetDefaultValue()
|
|||
|
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*一键返航*/
|
|||
|
func Return_home(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
co := dj.ReturnHome{}
|
|||
|
co.SetDefaultValue()
|
|||
|
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*取消返航*/
|
|||
|
func Return_home_cancel(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
co := dj.FlighttaskRecovery{}
|
|||
|
co.SetDefaultValue()
|
|||
|
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*摄像头单拍(拍照)*/
|
|||
|
func Camera_photo_take(ctx context.Context, gateway_sn, payload_index string) (error, *dj.UsualReply) {
|
|||
|
co := dj.CameraPhotoTake{}
|
|||
|
co.SetDefaultValue()
|
|||
|
co.Data.PayloadIndex = payload_index
|
|||
|
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*重置云台*/
|
|||
|
func Gimbal_reset(ctx context.Context, gateway_sn, payload_index string, reset_mode int) (error, *dj.UsualReply) {
|
|||
|
co := dj.GimbalReset{}
|
|||
|
co.SetDefaultValue()
|
|||
|
co.Data.PayloadIndex = payload_index
|
|||
|
co.Data.ResetMode = reset_mode
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*设置直播清晰度*/
|
|||
|
func Live_set_quality(ctx context.Context, gateway_sn, two_sn, payload_index string, enum int) (error, *dj.UsualReply) {
|
|||
|
co := dj.LiveSetQuality{}
|
|||
|
co.SetDefaultValue()
|
|||
|
co.Data.VideoId = two_sn + "/" + payload_index + "/normal-0"
|
|||
|
co.Data.VideoQuality = enum
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
///*设置直播镜头*/
|
|||
|
//func Camera_photo_take(gateway_sn, payload_index string) (error, *dj.UsualReply) {
|
|||
|
// co := dj.CameraPhotoTake{}
|
|||
|
// co.SetDefaultValue()
|
|||
|
// co.Data.PayloadIndex = payload_index
|
|||
|
// return send_msg(gateway_sn, co)
|
|||
|
//}
|
|||
|
|
|||
|
/*下发任务*/
|
|||
|
func Flighttask_prepare(ctx context.Context, gateway_sn string, prepareRes *dj.FlighttaskPrepareRes) (string, int64, error, *dj.UsualReply) {
|
|||
|
get, err := g.Redis().Get(ctx, RainfallStr+gateway_sn)
|
|||
|
if err == nil && get.String() == " " {
|
|||
|
err = errors.New("无法获取降雨量")
|
|||
|
return "", 0, err, nil
|
|||
|
} else if get.Int() > 0 {
|
|||
|
err = errors.New("机舱外正在下雨,无法下发任务!")
|
|||
|
return "", 0, err, nil
|
|||
|
}
|
|||
|
co := dj.FlighttaskPrepareRes{}
|
|||
|
co.SetDefaultValueCory()
|
|||
|
data := prepareRes.Data
|
|||
|
co.Data.FlightId = data.FlightId
|
|||
|
co.Data.TaskType = data.TaskType
|
|||
|
co.Data.ExecuteTime = data.ExecuteTime
|
|||
|
co.Data.WaylineType = data.WaylineType
|
|||
|
co.Data.File = data.File
|
|||
|
co.Data.RthAltitude = data.RthAltitude
|
|||
|
co.Data.RthMode = data.RthMode
|
|||
|
co.Data.OutOfControlAction = data.OutOfControlAction
|
|||
|
co.Data.ExitWaylineWhenRcLost = data.ExitWaylineWhenRcLost
|
|||
|
//断点信息
|
|||
|
if data.BreakPoint != nil { //断点续飞
|
|||
|
point := dj.BreakPoint{
|
|||
|
Index: data.BreakPoint.Index,
|
|||
|
State: data.BreakPoint.State,
|
|||
|
Progress: data.BreakPoint.Progress,
|
|||
|
WaylineId: data.BreakPoint.WaylineId,
|
|||
|
}
|
|||
|
co.Data.BreakPoint = &point
|
|||
|
}
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
tid := co.Tid
|
|||
|
bid := co.Timestamp
|
|||
|
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
|
|||
|
return tid, bid, err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*任务资源获取*/
|
|||
|
func Flighttask_resource_get(ctx context.Context, gateway_sn string, fileEneiey *dj.FileEntity) (error, *dj.UsualReply) {
|
|||
|
co := dj.FlighttaskResourcGetReply{}
|
|||
|
co.SetDefaultValue()
|
|||
|
co.Data.Output.File.Fingerprint = fileEneiey.Fingerprint
|
|||
|
co.Data.Output.File.Url = fileEneiey.Url
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*获取通用错误*/
|
|||
|
func Geterror(code int) error {
|
|||
|
if v, ok := dj.GetErrorMap()[code]; ok {
|
|||
|
return globe.GetErrors(v.Msg)
|
|||
|
} else {
|
|||
|
//manageOperationLog.AddLog(gctx.New(), sn, method, direction, code)
|
|||
|
return globe.GetErrors("未知错误:" + strconv.Itoa(code))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 结束飞向目标点
|
|||
|
func Fly_to_point(ctx context.Context, gateway_sn string, point dj.Point) (error, *dj.UsualReply) {
|
|||
|
toPoint := dj.FlyToPoint{}
|
|||
|
toPoint.SetDefaultValue()
|
|||
|
toPoint.Data.Points = append(toPoint.Data.Points, point)
|
|||
|
toPoint.Data.MaxSpeed = 3
|
|||
|
toPoint.Data.FlyToId = gtime.TimestampMicroStr()
|
|||
|
err, reply := send_msg(gateway_sn, toPoint)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, toPoint.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
// 结束飞向目标点
|
|||
|
func Fly_to_point_stop(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
toPoint := dj.FlyToPointStop{}
|
|||
|
toPoint.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, toPoint)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, toPoint.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
/*飞行夺权*/
|
|||
|
func Flight_authority_grab(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
grab := dj.FlightAuthorityGrab{}
|
|||
|
grab.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, grab)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, grab.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
// Fileupload_list 【远程日志】获取设备可上传的文件列表
|
|||
|
func Fileupload_list(ctx context.Context, gateway_sn string, module []string) (error, *dj.UsualReply) {
|
|||
|
co := dj.FileUpLoadListDown{}
|
|||
|
co.SetDefaultValue()
|
|||
|
co.Data.ModuleList = module
|
|||
|
err, reply := send_msg(gateway_sn, co)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
//// DeviceFormat 机场数据格式化
|
|||
|
//func DeviceFormat(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
// co := dj.Public{}
|
|||
|
// co.SetDefault()
|
|||
|
// co.Method = "device_format"
|
|||
|
// err, reply := send_msg(gateway_sn, co)
|
|||
|
// if err == nil { //记录操作日志
|
|||
|
// //manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
// }
|
|||
|
// return err, reply
|
|||
|
//}
|
|||
|
//
|
|||
|
//// DroneFormat 飞行器数据格式化
|
|||
|
//func DroneFormat(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
// co := dj.Public{}
|
|||
|
// co.SetDefault()
|
|||
|
// co.Method = "drone_format"
|
|||
|
// err, reply := send_msg(gateway_sn, co)
|
|||
|
// if err == nil { //记录操作日志
|
|||
|
// manageOperationLog.AddLog(ctx, gateway_sn, co.Method, "down", reply.Data.Result)
|
|||
|
// }
|
|||
|
// return err, reply
|
|||
|
//}
|
|||
|
|
|||
|
func Speaker_tts_play_start(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
sp := dj.SpeakerTtsPlayStart{}
|
|||
|
sp.SetDefaultValue()
|
|||
|
sp.Data.Tts.Name = "111"
|
|||
|
sp.Data.Tts.Text = "111"
|
|||
|
sp.Data.Tts.Md5 = "0bfb9bceee974f41a6ddfd81521bd795"
|
|||
|
sp.Data.PsdkIndex = 2
|
|||
|
err, reply := send_msg(gateway_sn, sp)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, sp.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
func speaker_audio_play_start(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
sp := dj.SpeakerAudioPlayStart{}
|
|||
|
sp.SetDefaultValue()
|
|||
|
sp.Data.PsdkIndex = 0
|
|||
|
sp.Data.File.Name = "output"
|
|||
|
sp.Data.File.Url = "http://" + coryCommon.Global + ":8899/file/masterMask/coryStorageTemplate/output.pcm"
|
|||
|
sp.Data.File.Md5 = "f69050c198f3a765a56020f5470d3bdf"
|
|||
|
sp.Data.File.Format = "pcm"
|
|||
|
err, reply := send_msg(gateway_sn, sp)
|
|||
|
if err == nil { //记录操作日志
|
|||
|
manageOperationLog.AddLog(ctx, gateway_sn, sp.Method, "down", reply.Data.Result)
|
|||
|
}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
func OtaCreateFunc(ctx context.Context, gateway_sn string) (error, *dj.UsualReply) {
|
|||
|
sp := dj.OtaCreateEntity{Data: struct {
|
|||
|
DeviceList []dj.OtaCreateDevice `json:"devices"`
|
|||
|
}{
|
|||
|
DeviceList: []dj.OtaCreateDevice{
|
|||
|
{
|
|||
|
FileName: "M4TD_13.01.00.07_pro.zip",
|
|||
|
FileSize: 712498,
|
|||
|
FileURL: "http://zmkg.cqet.top:8899/file/temporary/M4TD_13.01.00.07_pro.zip",
|
|||
|
FirmwareUpgradeType: 3,
|
|||
|
MD5: "acb28f172e62b38d2bfd797a522076a9",
|
|||
|
ProductVersion: "13.01.00.07",
|
|||
|
SN: "1581F8HGX253U00A0626",
|
|||
|
},
|
|||
|
//{
|
|||
|
// FileName: "DOCK3_13.01.00.07_pro.zip",
|
|||
|
// FileSize: 229252,
|
|||
|
// FileURL: "http://zmkg.cqet.top:8899/file/temporary/DOCK3_13.01.00.07_pro.zip",
|
|||
|
// FirmwareUpgradeType: 3,
|
|||
|
// MD5: "c217ee9a0bfc4cdfdda0a89407c504d7",
|
|||
|
// ProductVersion: "13.01.00.07",
|
|||
|
// SN: "8UUXN4P00A06NK",
|
|||
|
//},
|
|||
|
},
|
|||
|
}}
|
|||
|
sp.SetDefaultValue()
|
|||
|
err, reply := send_msg(gateway_sn, sp)
|
|||
|
fmt.Println("开始固件升级.......")
|
|||
|
//if err == nil { //记录操作日志dronedronedronedrddadadasdeddddd
|
|||
|
// manageOperationLog.AddLog(ctx, gateway_sn, sp.Method, "down", reply.Data.Result)
|
|||
|
//}
|
|||
|
return err, reply
|
|||
|
}
|
|||
|
|
|||
|
//// 获取文件的md5和大小
|
|||
|
//func aaaaa() {
|
|||
|
//
|
|||
|
// path := "C:\\Users\\MSI\\Downloads\\M4TD_13.01.00.07_pro.zip"
|
|||
|
// // 检查文件是否为ZIP格式
|
|||
|
// if !strings.HasSuffix(strings.ToLower(path), ".zip") {
|
|||
|
// fmt.Println("错误:请提供ZIP格式的文件")
|
|||
|
// return
|
|||
|
// }
|
|||
|
//
|
|||
|
// // 获取文件大小
|
|||
|
// fileInfo, err := os.Stat(path)
|
|||
|
// if err != nil {
|
|||
|
// fmt.Printf("无法获取文件信息: %v\n", err)
|
|||
|
// return
|
|||
|
// }
|
|||
|
// sizeKB := float64(fileInfo.Size()) / 1024.0
|
|||
|
// fmt.Printf("ZIP文件大小: %.2f KB\n", sizeKB)
|
|||
|
//
|
|||
|
// // 计算MD5
|
|||
|
// file, err := os.Open(path)
|
|||
|
// if err != nil {
|
|||
|
// fmt.Printf("无法打开文件: %v\n", err)
|
|||
|
// return
|
|||
|
// }
|
|||
|
// defer file.Close()
|
|||
|
//
|
|||
|
// md5Hash := md5.New()
|
|||
|
// if _, err := io.Copy(md5Hash, file); err != nil {
|
|||
|
// fmt.Printf("计算MD5失败: %v\n", err)
|
|||
|
// return
|
|||
|
// }
|
|||
|
// md5Sum := hex.EncodeToString(md5Hash.Sum(nil))
|
|||
|
// fmt.Printf("ZIP文件MD5: %s\n", md5Sum)
|
|||
|
//}
|