Files
zmkgC/third/ys7/ys7.go

559 lines
14 KiB
Go
Raw Normal View History

2025-07-07 20:11:59 +08:00
package ys7
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
)
var accessToken = "at.ddhhz6ea49jorccubhg3elqs19nvmxta-1754nu5ce8-017egq8-fmymwvvhv"
const (
Ok = "200"
Online = 1
)
// 改变 accessToken
func SetAccessToken(token string) {
accessToken = token
}
// 传入 serial 返回 Devicemap 中的设备信息
func GetDevice(serial string) (Ys7Device, error) {
device, ok := deviceMap[serial]
if ok {
return device, nil
}
return Ys7Device{}, fmt.Errorf("设备不存在")
}
var deviceMap = make(map[string]Ys7Device)
/*当前包的入口方法*/
func InitYs7() {
/*获取一次token*/
getAccessToken()
/*获取一次设备列表*/
getDeviceList(0, 50) // 可以提前获取数据库中的记录进行缓存,比对当前设备是否在数据库中已经存在,不存在则自动入库
}
func GetAccessToken() string {
return accessToken
}
/*获取设备表*/
func GetDeviceMap() map[string]Ys7Device {
return deviceMap
}
type TokenRes struct {
Public
Data struct {
AccessToken string `json:"accessToken"`
ExpireTime int64 `json:"expireTime"`
} `json:"data"`
}
func getAccessToken() {
// ctx := gctx.New()
// appKey := g.Cfg().MustGet(ctx, "ys7.appKey").String()
// appSecret := g.Cfg().MustGet(ctx, "ys7.appSecret").String()
appKey := "3acf9f1a43dc4209841e0893003db0a2"
appSecret := "4bbf3e9394f55d3af6e3af27b2d3db36"
url := "https://open.ys7.com/api/lapp/token/get"
dt := struct {
AppKey string `json:"appKey"`
AppSecret string `json:"appSecret"`
}{AppKey: appKey, AppSecret: appSecret}
post, err := Post(url, dt)
if err != nil {
} else {
res := TokenRes{}
err = json.Unmarshal(post, &res)
if err != nil {
} else {
accessToken = res.Data.AccessToken
}
}
}
type DeviceListRes struct {
Public
Page struct {
Total int `json:"total"`
Page int `json:"page"`
Size int `json:"size"`
} `json:"page"`
Data []Ys7Device `json:"data"`
}
func delayRequest(page, pageSize int) {
time.Sleep(time.Second * 5)
getDeviceList(page, pageSize)
}
func getDeviceList(page, pageSize int) {
url := "https://open.ys7.com/api/lapp/device/list"
dt := struct {
AccessToken string `json:"accessToken"`
PageStart int `json:"pageStart"`
PageSize int `json:"pageSize"`
}{AccessToken: accessToken, PageSize: pageSize, PageStart: page}
post, err := Post(url, dt)
if err != nil {
delayRequest(page, pageSize)
} else {
res := DeviceListRes{}
err = json.Unmarshal(post, &res)
if err != nil {
delayRequest(page, pageSize)
} else {
if res.Code == Ok {
for _, datum := range res.Data {
deviceMap[datum.DeviceSerial] = datum
//marshal, err := json.Marshal(datum)
//if err != nil {
// return
//}
//fmt.Println(string(marshal))
//if datum.Online() {
// capRes, err := datum.Capture()
// if err != nil {
// fmt.Println("抓图识别")
// } else {
// SavePicture(capRes.Data.PicUrl, "static/"+gmd5.MustEncryptString(capRes.Data.PicUrl)+".jpg")
// }
//}
}
if (page+1)*pageSize < res.Page.Total {
getDeviceList(page+1, pageSize)
}
} else {
delayRequest(page, pageSize)
}
}
}
}
type Ys7Device struct {
DeviceSerial string `json:"deviceSerial"`
DeviceName string `json:"deviceName"`
DeviceType string `json:"deviceType"`
Status int `json:"status"`
Defence int `json:"defence"`
DeviceVersion string `json:"deviceVersion"`
}
type Public struct {
Code string `json:"code"`
Msg string `json:"msg"`
}
func (receiver *Ys7Device) Online() bool {
if receiver.Status == Online {
return true
} else {
return false
}
}
func Post(url string, data interface{}) (res []byte, err error) {
response, err := g.Client().Header(map[string]string{"Content-Type": "application/x-www-form-urlencoded"}).Post(gctx.New(), url, data)
if err != nil {
return nil, err
}
return response.ReadAll(), nil
}
/*开始云台控制*/
func (receiver *Ys7Device) PTZStart(direction int) (res *Public, err error) {
url := "https://open.ys7.com/api/lapp/device/ptz/start"
dt := struct {
ChannelNo int `json:"channelNo"`
Direction int `json:"direction"`
Speed int `json:"speed"`
DeviceSerial string `json:"deviceSerial"`
AccessToken string `json:"accessToken"`
}{
AccessToken: accessToken, DeviceSerial: receiver.DeviceSerial, ChannelNo: 1, Speed: 1, Direction: direction,
}
post, err := Post(url, dt)
if err != nil {
return nil, err
} else {
res = &Public{}
err = json.Unmarshal(post, &res)
if err != nil {
return nil, err
}
return
}
}
/*停止云台控制*/
func (receiver *Ys7Device) PTZEnd(direction int) (res *Public, err error) {
url := "https://open.ys7.com/api/lapp/device/ptz/stop"
dt := struct {
ChannelNo int `json:"channelNo"`
Direction int `json:"direction"`
DeviceSerial string `json:"deviceSerial"`
AccessToken string `json:"accessToken"`
}{
AccessToken: accessToken, DeviceSerial: receiver.DeviceSerial, ChannelNo: 1, Direction: direction,
}
post, err := Post(url, dt)
if err != nil {
return nil, err
} else {
res = &Public{}
err = json.Unmarshal(post, &res)
if err != nil {
return nil, err
}
return
}
}
type PresetAddRes struct {
Public
Data struct {
Index int `json:"index"` // 预置点序号C6设备是1-12该参数需要开发者自行保存
} `json:"data"`
}
/*添加预制点*/
func (receiver *Ys7Device) AddPreset() (res *PresetAddRes, err error) {
url := "https://open.ys7.com/api/lapp/device/preset/add"
dt := struct {
ChannelNo int `json:"channelNo"`
DeviceSerial string `json:"deviceSerial"`
AccessToken string `json:"accessToken"`
}{
AccessToken: accessToken, DeviceSerial: receiver.DeviceSerial, ChannelNo: 1,
}
post, err := Post(url, dt)
if err != nil {
return nil, err
} else {
res = &PresetAddRes{}
err = json.Unmarshal(post, &res)
if err != nil {
return nil, err
}
return
}
}
/*调用预制点*/
func (receiver *Ys7Device) MovePreset(index int) (res *Public, err error) {
url := "https://open.ys7.com/api/lapp/device/preset/move"
dt := struct {
ChannelNo int `json:"channelNo"`
DeviceSerial string `json:"deviceSerial"`
AccessToken string `json:"accessToken"`
Index int `json:"index"`
}{ChannelNo: 1, DeviceSerial: receiver.DeviceSerial, AccessToken: accessToken, Index: index}
post, err := Post(url, dt)
if err != nil {
return nil, err
} else {
res = &Public{}
err = json.Unmarshal(post, &res)
if err != nil {
return nil, err
}
return
}
}
/*清除预制点*/
func (receiver *Ys7Device) ClearPreset(index int) (res *Public, err error) {
url := "https://open.ys7.com/api/lapp/device/preset/clear"
dt := struct {
ChannelNo int `json:"channelNo"`
DeviceSerial string `json:"deviceSerial"`
AccessToken string `json:"accessToken"`
Index int `json:"index"`
}{ChannelNo: 1, DeviceSerial: receiver.DeviceSerial, AccessToken: accessToken, Index: index}
post, err := Post(url, dt)
if err != nil {
return nil, err
} else {
res = &Public{}
err = json.Unmarshal(post, &res)
if err != nil {
return nil, err
}
return
}
}
// 开启设备视频加密
func (r *Ys7Device) OpenEncrypt() error {
url := "https://open.ys7.com/api/lapp/device/encrypt/on"
dt := struct {
AccessToken string `json:"accessToken"`
DeviceSerial string `json:"deviceSerial"`
}{
AccessToken: accessToken,
DeviceSerial: r.DeviceSerial,
}
post, err := Post(url, dt)
if err != nil {
return err
}
if gjson.New(string(post)).Get("code").Int() != 200 {
return fmt.Errorf("%s", gjson.New(string(post)).Get("msg").String())
}
// 更新数据库
_, err = dao.Ys7Devices.Ctx(context.Background()).
Where(dao.Ys7Devices.Columns().DeviceSerial, r.DeviceSerial).
Update(g.Map{
"VideoEncrypted": 1,
})
if err != nil {
return err
}
return nil
}
// 关闭设备视频加密
func (r *Ys7Device) CloseEncrypt() error {
url := "https://open.ys7.com/api/lapp/device/encrypt/off"
dt := struct {
AccessToken string `json:"accessToken"`
DeviceSerial string `json:"deviceSerial"`
}{
AccessToken: accessToken,
DeviceSerial: r.DeviceSerial,
}
post, err := Post(url, dt)
if err != nil {
return err
}
if gjson.New(string(post)).Get("code").Int() != 200 {
return fmt.Errorf("%s", gjson.New(string(post)).Get("msg").String())
}
_, err = dao.Ys7Devices.Ctx(context.Background()).
Where(dao.Ys7Devices.Columns().DeviceSerial, r.DeviceSerial).
Update(g.Map{
"VideoEncrypted": 0,
})
if err != nil {
return err
}
return nil
}
// GetLiveAddress 获取播放地址
func (r *Ys7Device) GetLiveAddress() (string, error) {
url := "https://open.ys7.com/api/lapp/v2/live/address/get"
dt := struct {
AccessToken string `json:"accessToken"`
DeviceSerial string `json:"deviceSerial"`
ChannelNo int `json:"channelNo"`
}{
AccessToken: accessToken,
DeviceSerial: r.DeviceSerial,
ChannelNo: 1,
}
post, err := Post(url, dt)
if err != nil {
return "", err
}
Body := string(post)
println(Body)
if gjson.New(Body).Get("code").Int() != 200 {
return "", fmt.Errorf("获取播放地址失败: %s", gjson.New(Body).Get("msg").String())
}
return gjson.New(Body).Get("data.url").String(), nil
}
/*抓图结果返回*/
type CapRes struct {
Public
Data struct {
PicUrl string `json:"picUrl"`
} `json:"data"`
}
/*抓拍图片*/
func (receiver *Ys7Device) Capture() (cap *CapRes, err error) {
url := "https://open.ys7.com/api/lapp/device/capture"
dt := struct {
DeviceSerial string `json:"deviceSerial"`
ChannelNo int `json:"channelNo"`
AccessToken string `json:"accessToken"`
}{DeviceSerial: receiver.DeviceSerial, ChannelNo: 1, AccessToken: accessToken}
res, err := Post(url, dt)
if err != nil {
return nil, err
}
cap = &CapRes{}
err = json.Unmarshal(res, &cap)
if err != nil {
return nil, err
}
// cap.Data.PicUrl = string(TransHtmlJson([]byte(cap.Data.PicUrl)))
return cap, nil
}
// download file会将url下载到本地文件它会在下载时写入而不是将整个文件加载到内存中。
func SavePicture(url, dst string) (err error) {
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Create the file
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
// Write the body to file
_, err = io.Copy(out, resp.Body)
return err
}
//var appKey = ""
//var secret = ""
//var token = ""
//
//// InitYs7 安全帽 absolutePath绝对路径
//func InitYs7(absolutePath string) (flag bool, num int, err error) {
// getConfig()
// GetAccesstoken()
// imageData, err := os.ReadFile(absolutePath)
// if err != nil {
// err = errors.New("读取图片文件失败")
// return
// }
//
// // 将图片数据转换为Base64字符串
// base64String := base64.StdEncoding.EncodeToString(imageData)
// flag, num, err = HelmetCheck(base64String, absolutePath)
// return
//}
//
//func getConfig() {
// appKey = g.Cfg().MustGet(gctx.New(), "ys7.key").String()
// secret = g.Cfg().MustGet(gctx.New(), "ys7.secret").String()
//}
//
//func GetAccesstoken() {
// key := "ys7"
// //从缓存捞取key
// ctx := gctx.New()
// get := commonService.Cache().Get(ctx, key)
// if get != nil && get.String() != "" {
// token = get.String()
// } else {
// getConfig()
// url := "https://open.ys7.com/api/lapp/token/get"
// dt := struct {
// AppKey string `json:"appKey"`
// AppSecret string `json:"appSecret"`
// }{appKey, secret}
// err, s := post(url, dt)
// if err != nil {
// return
// }
// tp := TP{}
// err = json.Unmarshal(s, &tp)
// if err != nil {
// return
// }
// if tp.Code == OK {
// token = tp.Data.AccessToken
// //将token存储到redis中tiken默认时间为秒实际计算为7天,(这里少100秒,防止token过期还存在redis中)
// commonService.Cache().Set(ctx, key, tp.Data.AccessToken, time.Duration(tp.Data.ExpireTime-100)*time.Second)
// token = tp.Data.AccessToken
// }
// }
//
//}
//
//func post(uri string, data interface{}) (error, []byte) {
// response, err := g.Client().ContentType("application/x-www-form-urlencoded").Post(gctx.New(), uri, data)
// if err != nil {
// return err, nil
// }
// return nil, response.ReadAll()
//}
//
//// HelmetCheck 图片中标记安全帽
//func HelmetCheck(image string, absolutePath string) (flag bool, num int, err error) {
// flag = false
// num = 0
// url := "https://open.ys7.com/api/lapp/intelligence/target/analysis"
// dt := struct {
// AccessToken string `json:"accessToken"`
// DataType int `json:"dataType"`
// Image string `json:"image"`
// ServiceType string `json:"serviceType"`
// }{token, 1, image, "helmet"}
// err, s := post(url, dt)
// if err != nil {
// return
// }
// tp := HelMet{}
// err = json.Unmarshal(s, &tp)
// if err != nil {
// return
// }
// if tp.Code == OK && len(tp.Data) > 0 {
// for _, data := range tp.Data {
// height, _ := strconv.ParseFloat(data.Height, 64)
// width, _ := strconv.ParseFloat(data.Width, 64)
// if len(tp.Data) <= 0 {
// continue
// }
// for _, dataTwo := range data.TargetList {
// HeadRect := dataTwo.HeadRect
// helmetType := dataTwo.HelmetType
// if helmetType == 2 || helmetType == 0 {
// flag = true
// num = num + 1
// vmodel_h_f, _ := strconv.ParseFloat(HeadRect.VmodelHF, 64)
// vmodel_w_f, _ := strconv.ParseFloat(HeadRect.VmodelWF, 64)
// vmodel_x_f, _ := strconv.ParseFloat(HeadRect.VmodelXF, 64)
// vmodel_y_f, _ := strconv.ParseFloat(HeadRect.VmodelYF, 64)
//
// vmodel_h_f = vmodel_h_f * height
// vmodel_w_f = vmodel_w_f * width
// vmodel_x_f = vmodel_x_f * width
// vmodel_y_f = vmodel_y_f * height
// coryCommon.Test_draw_rect_text(absolutePath,
// vmodel_x_f, vmodel_y_f, vmodel_w_f, vmodel_h_f)
// }
// }
// }
// }
// return
//}