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 //}