This commit is contained in:
2025-07-07 20:11:59 +08:00
parent ab0fdbc447
commit 06e3aa2eb3
2009 changed files with 193082 additions and 0 deletions

51
third/ys7/struct.go Normal file
View File

@ -0,0 +1,51 @@
package ys7
const OK = "200"
//type Public struct {
// Code string `json:"code"`
// Msg string `json:"msg"`
//}
type TP struct {
Public
Data struct {
AccessToken string `json:"accessToken"`
ExpireTime int64 `json:"expireTime"`
} `json:"data"`
}
type HelMet struct {
Public
RequestId string `json:"requestId"`
Data []struct {
Id string `json:"id"`
Height string `json:"height"`
TargetList []struct {
BodyRect struct {
VmodelHF string `json:"vmodel_h_f"`
VmodelWF string `json:"vmodel_w_f"`
VmodelXF string `json:"vmodel_x_f"`
VmodelYF string `json:"vmodel_y_f"`
} `json:"body_rect"`
AlarmFlg int `json:"alarm_flg"`
UniformType int `json:"uniform_type"`
ID int `json:"ID"`
HelmetType int `json:"helmet_type"`
HeadRect struct {
VmodelHF string `json:"vmodel_h_f"`
VmodelWF string `json:"vmodel_w_f"`
VmodelXF string `json:"vmodel_x_f"`
VmodelYF string `json:"vmodel_y_f"`
} `json:"head_rect"`
ColorType int `json:"color_type"`
} `json:"target_list"`
Width string `json:"width"`
RuleInfo []interface{} `json:"rule_info"`
RuleList [][]struct {
Y string `json:"y"`
X string `json:"x"`
} `json:"rule_list"`
ErrorCode int `json:"errorCode"`
} `json:"data"`
}

558
third/ys7/ys7.go Normal file
View File

@ -0,0 +1,558 @@
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
//}

338
third/ys7/ys72.go Normal file
View File

@ -0,0 +1,338 @@
package ys7
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/frame/g"
"github.com/tidwall/gjson"
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
"github.com/tiger1103/gfast/v3/internal/app/system/model/do"
"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
)
type Ys72 struct {
FnLogin func() (string, error) // 登录回调
Devices map[string]Ys7Device // 设备列表
Total int // 总页数 和 当前页数
}
var Ys72Instance = NewYs72()
// NewYs72 初始化
func NewYs72() *Ys72 {
ys7 := &Ys72{
FnLogin: DefaultLogin,
Devices: make(map[string]Ys7Device),
Total: 999, // 第一次获取设备列表时,会刷新其实际值
}
// 刷新 ys7.go 中的 AccessToken
_ = ys7.GetAccessToken()
// 初始化设备列表
//if err := ys7.Init(); err != nil {
// panic(err)
//}
// 定时任务更新设备列表
go func() {
for range time.Tick(3 * time.Minute) {
if err := ys7.Init(); err != nil {
panic(err)
}
if err := ys7.GetAllDeviceList(); err != nil {
log.Println("更新设备列表失败:", err)
}
// 获取设备截图并存入 Redis
ys7.CaptureAllDevice()
}
}()
return ys7
}
// Init 第一次初始化时从数据库获取设备列表存入 Devices
func (ys *Ys72) Init() error {
device := []entity.Ys7Devices{}
// 获取设备列表
err := dao.Ys7Devices.Ctx(context.Background()).Scan(&device)
if err != nil {
return err
}
// 将设备列表存入 Devices
for _, v := range device {
ys.Devices[v.DeviceSerial] = Ys7Device{
DeviceSerial: v.DeviceSerial,
DeviceName: v.DeviceName,
DeviceType: v.DeviceType,
Status: v.Status,
Defence: int(v.Defence),
DeviceVersion: v.DeviceVersion,
}
}
return nil
}
// 遍历 ys.Devices 调用 Capture 获取设备截图并存入Redis
func (ys *Ys72) CaptureAllDevice() {
for _, device := range ys.Devices {
// 获取设备截图
resp, err := device.Capture()
if err != nil {
log.Println("获取设备截图失败:", err)
return
}
// 存入 Redis
ctx := context.Background()
g.Redis().Set(ctx, "ys7:capture:"+device.DeviceSerial, resp.Data.PicUrl)
// 两小时后过期
g.Redis().Expire(ctx, "ys7:capture:"+device.DeviceSerial, 2*60*60)
}
}
// 由 Redis 管理 AccessToken 的生命周期,如果获取失败则重新刷新
func (ys *Ys72) GetAccessToken() string {
ctx := context.Background()
// 从 Redis 获取 AccessToken
accessToken, err := g.Redis().Get(ctx, "ys7:accessToken")
// 兼容原本获取 AccessToken 的逻辑
SetAccessToken(accessToken.String())
if err == nil && accessToken.String() != "" {
return accessToken.String()
}
// 未获取到 AccessToken 则重新登录
if accessToken.String() == "" {
// 如果登录失败则递归重试
if err := ys.login(); err != nil {
return ys.GetAccessToken()
}
accessToken, err = g.Redis().Get(ctx, "ys7:accessToken")
if err != nil {
return accessToken.String()
}
}
return accessToken.String()
}
// 传入 deviceSerial 获取设备信息
func (ys *Ys72) GetDevice(deviceSerial string) (Ys7Device, error) {
if device, ok := ys.Devices[deviceSerial]; ok {
return device, nil
}
return Ys7Device{}, fmt.Errorf("设备不存在: %s", deviceSerial)
}
// 获取单页设备列表并存入 Devices
func (ys *Ys72) getDeviceList(page int, deviceMapping map[string]Ys7Device) error {
accessToken := ys.GetAccessToken()
req := struct {
AccessToken string `json:"accessToken"`
PageStart int `json:"pageStart"`
PageSize int `json:"pageSize"`
}{AccessToken: accessToken, PageSize: 50, PageStart: page}
resp, err := Post("https://open.ys7.com/api/lapp/device/list", req)
if err != nil {
return err
}
body := string(resp)
// 解析返回数据
if gjson.Get(body, "code").Int() != 200 {
return fmt.Errorf("获取设备列表失败: %s", gjson.Get(body, "msg").String())
}
// 解析设备列表
gjson.Get(body, "data").ForEach(func(_, value gjson.Result) bool {
deviceSerial := value.Get("deviceSerial").String() // 设备序列号
deviceName := value.Get("deviceName").String() // 设备名称
deviceType := value.Get("deviceType").String() // 设备类型
deviceStatus := int(value.Get("status").Int()) // 设备状态 1:在线 2:离线
defence := int(value.Get("defence").Int()) // 是否布撤防 0:未布防 1:布防 不用管
deviceVersion := value.Get("deviceVersion").String() // 设备版本
deviceMapping[deviceSerial] = Ys7Device{
DeviceSerial: deviceSerial,
DeviceName: deviceName,
DeviceType: deviceType,
Status: deviceStatus,
Defence: defence,
DeviceVersion: deviceVersion,
}
return true
})
ys.Total = int(gjson.Get(body, "page.total").Int())
return nil
}
// 依次调用 getDeviceList 获取所有设备列表
func (ys *Ys72) GetAllDeviceList() error {
// 创建一个设备map
deviceMapping := make(map[string]Ys7Device)
// 遍历页码获取所有设备列表
for page := 0; page <= ys.Total; page++ {
if err := ys.getDeviceList(page, deviceMapping); err != nil {
return err
}
}
newDevices := []do.Ys7Devices{} // 新设备列表
updateDevices := []do.Ys7Devices{} // 更新设备列表
// 遍历 deviceMapping 对比 ys.Devices 筛选出增量或更新设备列表
for deviceSerial, device := range deviceMapping {
// 如果设备不存在则为新增设备
if _, ok := ys.Devices[deviceSerial]; !ok {
newDevices = append(newDevices, do.Ys7Devices{
DeviceSerial: device.DeviceSerial,
DeviceName: device.DeviceName,
DeviceType: device.DeviceType,
Status: device.Status,
Defence: device.Defence,
DeviceVersion: device.DeviceVersion,
})
} else {
// 如果设备存在则对比设备状态
if ok, newDevice := ys.CompareDevice(ys.Devices[deviceSerial], device); !ok {
// 如果设备状态不同则更新设备
updateDevices = append(updateDevices, do.Ys7Devices{
DeviceSerial: newDevice.DeviceSerial,
DeviceName: newDevice.DeviceName,
DeviceType: newDevice.DeviceType,
Status: newDevice.Status,
Defence: newDevice.Defence,
DeviceVersion: newDevice.DeviceVersion,
})
}
}
}
// 新旧状态替换
ys.Devices = deviceMapping
// 新设备列表入库
if len(newDevices) > 0 {
_, err := dao.Ys7Devices.Ctx(context.Background()).Data(newDevices).Batch(20).Insert()
if err != nil {
return err
}
}
// 更新设备列表
if len(updateDevices) > 0 {
for _, device := range updateDevices {
_, err := dao.Ys7Devices.Ctx(context.Background()).Data(device).
Where(dao.Ys7Devices.Columns().DeviceSerial, device.DeviceSerial).Update()
if err != nil {
return err
}
}
// _, err := dao.Ys7Devices.Ctx(context.Background()).Data(updateDevices).Batch(20).Update()
// if err != nil {
// log.Println("更新错误:", err)
// return err
// }
}
return nil
}
// 登录并将 AccessToken 存入 Redis 由 Redis 管理其有效期
// 当获取失败则重新登录后刷新周期
func (ys *Ys72) login() error {
accessToken, err := ys.FnLogin()
if err != nil {
return err
}
ctx := context.Background()
g.Redis().Set(ctx, "ys7:accessToken", accessToken)
// 设置 key 将在 5 天后过期
g.Redis().Expire(ctx, "ys7:accessToken", 5*24*60*60)
return nil
}
// CompareDevice 对比传递的两个设备结构体是否相同
// 如果不同则返回 false 并构造出新的设备结构体
func (ys *Ys72) CompareDevice(old, new Ys7Device) (bool, Ys7Device) {
// 对比old 和 new 结构体的所有字段,是否相同
if old == new {
return true, Ys7Device{}
}
// 构造出新的ys7Device
return false, Ys7Device{
DeviceSerial: new.DeviceSerial,
DeviceName: new.DeviceName,
DeviceType: new.DeviceType,
Status: new.Status,
Defence: new.Defence,
DeviceVersion: new.DeviceVersion,
}
}
type defalutFn func() (string, error)
var DefaultLogin = defalutFn(func() (string, error) {
appKey := "3acf9f1a43dc4209841e0893003db0a2"
appSecret := "4bbf3e9394f55d3af6e3af27b2d3db36"
req := struct {
AppKey string `json:"appKey"`
AppSecret string `json:"appSecret"`
}{AppKey: appKey, AppSecret: appSecret}
// 登录
resp, err := Post("https://open.ys7.com/api/lapp/token/get", req)
if err != nil {
return "", err
}
body := string(resp)
// 解析返回数据
if gjson.Get(body, "code").Int() != 200 {
return "", fmt.Errorf("登录失败: %s", gjson.Get(body, "msg").String())
}
// 返回 AccessToken
return gjson.Get(body, "data.accessToken").String(), nil
})
func StartAI(device Ys7Device) {
capture, err := device.Capture()
if err != nil {
fmt.Println("定时快照错误!", err)
} else {
get, err := g.Client().Get(gctx.New(), capture.Data.PicUrl)
if err != nil {
} else {
os.WriteFile("", get.ReadAll(), 0o666)
}
}
}