Files
zmkgC/third/ys7/ys7.go
2025-07-07 20:11:59 +08:00

559 lines
14 KiB
Go
Raw Permalink 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 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
//}