| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- package main
- import (
- "errors"
- "strconv"
- "time"
- "lc/common/mqtt"
- "lc/common/onvif/profiles/ptz"
- "lc/common/onvif/soap"
- "lc/common/protocol"
- )
- var (
- NotSupportPtz = errors.New("不支持云台PTZ")
- )
- // ContinuousMove direction 0:停止移动;1:向左边;2:向右边;3:向上;4:向下;5:缩小;6:放大
- // speed/255.0,speed的范围[0,255]
- func (o *LcDevice) ContinuousMove(profileToken string, direction, speed uint8) error {
- XAddr, ok := o.endpoints["ptz"]
- if !ok {
- return NotSupportPtz
- }
- p := ptz.NewPTZ(o.client, XAddr)
- var x float32 = 0.0
- var y float32 = 0.0
- var z float32 = 0.0
- s := float32(speed) / 255
- switch direction {
- case 0: //停止移动,用初始值,全零
- case 1: //向左边移动
- x = -s
- case 2: //向右边移动
- x = s
- case 3: //向上移动
- y = s
- case 4: //向下移动
- y = -s
- case 5: //缩小
- z = -s
- case 6: //放大
- z = s
- }
- _, err := p.ContinuousMove(&ptz.ContinuousMove{
- ProfileToken: ptz.ReferenceToken(profileToken),
- Velocity: ptz.PTZSpeed{
- PanTilt: ptz.Vector2D{
- X: x,
- Y: y,
- //Space: "http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace",
- },
- Zoom: ptz.Vector1D{
- X: z,
- //Space: "http://www.onvif.org/ver10/tptz/ZoomSpaces/ZoomGenericSpeedSpace",
- },
- },
- })
- return err
- }
- // GetPresets 获取所有预置点并上报到平台
- func (o *LcDevice) GetPresets(profileToken string, filter bool) ([]protocol.PresetInfo, error) {
- XAddr, ok := o.endpoints["ptz"]
- if !ok {
- return nil, NotSupportPtz
- }
- //新球机需要重新生成签名dsz 20230704
- client := soap.NewClient(soap.WithTimeout(time.Second * 0))
- client.AddHeader(soap.NewWSSSecurityHeader(o.onvifDev.User, o.onvifDev.Password))
- o.client = client
- p := ptz.NewPTZ(o.client, XAddr)
- resp, err := p.GetPresets(&ptz.GetPresets{ProfileToken: ptz.ReferenceToken(profileToken)})
- if err != nil {
- return nil, err
- }
- var Data []protocol.PresetInfo
- for _, v := range resp.Preset {
- //海康某球机默认包含300个预置点,需要过滤默认的预置点
- if filter {
- if v.PTZPosition.PanTilt.X == 0 && v.PTZPosition.PanTilt.Y == 1 && v.PTZPosition.Zoom.X == 0 {
- continue
- }
- }
- pi := protocol.PresetInfo{Token: string(v.Token), Name: string(v.Name),
- X: v.PTZPosition.PanTilt.Y, Y: v.PTZPosition.PanTilt.Y, Z: v.PTZPosition.Zoom.X}
- Data = append(Data, pi)
- }
- return Data, nil
- }
- // SetPreset 设置预置点
- func (o *LcDevice) SetPreset(profileToken, presetToken, presetName string) (string, error) {
- XAddr, ok := o.endpoints["ptz"]
- if !ok {
- return "", NotSupportPtz
- }
- //新球机需要重新生成签名dsz 20230704
- client := soap.NewClient(soap.WithTimeout(time.Second * 0))
- client.AddHeader(soap.NewWSSSecurityHeader(o.onvifDev.User, o.onvifDev.Password))
- o.client = client
- p := ptz.NewPTZ(o.client, XAddr)
- resp, err := p.SetPreset(&ptz.SetPreset{
- ProfileToken: ptz.ReferenceToken(profileToken),
- PresetName: presetName,
- PresetToken: ptz.ReferenceToken(presetToken),
- })
- if err != nil {
- if _, ok := err.(*soap.SOAPFault); ok { //可能是token错误
- resp, err = p.SetPreset(&ptz.SetPreset{
- ProfileToken: ptz.ReferenceToken(profileToken),
- PresetName: presetName,
- })
- }
- }
- if err == nil {
- return string(resp.PresetToken), nil
- }
- return "", err
- }
- // DeletePreset 删除预置点
- func (o *LcDevice) DeletePreset(profileToken, presetToken string) error {
- XAddr, ok := o.endpoints["ptz"]
- if !ok {
- return NotSupportPtz
- }
- //新球机需要重新生成签名dsz 20230704
- client := soap.NewClient(soap.WithTimeout(time.Second * 0))
- client.AddHeader(soap.NewWSSSecurityHeader(o.onvifDev.User, o.onvifDev.Password))
- o.client = client
- p := ptz.NewPTZ(o.client, XAddr)
- _, err := p.RemovePreset(&ptz.RemovePreset{
- ProfileToken: ptz.ReferenceToken(profileToken),
- PresetToken: ptz.ReferenceToken(presetToken),
- })
- return err
- }
- // GotoPreset 跳转到指定的预置点
- func (o *LcDevice) GotoPreset(profileToken, presetToken string) error {
- XAddr, ok := o.endpoints["ptz"]
- if !ok {
- return NotSupportPtz
- }
- //新球机需要重新生成签名dsz 20230704
- client := soap.NewClient(soap.WithTimeout(time.Second * 0))
- client.AddHeader(soap.NewWSSSecurityHeader(o.onvifDev.User, o.onvifDev.Password))
- o.client = client
- p := ptz.NewPTZ(o.client, XAddr)
- _, err := p.GotoPreset(&ptz.GotoPreset{
- ProfileToken: ptz.ReferenceToken(profileToken),
- PresetToken: ptz.ReferenceToken(presetToken),
- })
- return err
- }
- // SetHomePosition 跳转到指定的预置点
- func (o *LcDevice) SetHomePosition(profileToken string) error {
- XAddr, ok := o.endpoints["ptz"]
- if !ok {
- return NotSupportPtz
- }
- //新球机需要重新生成签名dsz 20230704
- client := soap.NewClient(soap.WithTimeout(time.Second * 0))
- client.AddHeader(soap.NewWSSSecurityHeader(o.onvifDev.User, o.onvifDev.Password))
- o.client = client
- p := ptz.NewPTZ(o.client, XAddr)
- _, err := p.SetHomePosition(&ptz.SetHomePosition{ProfileToken: ptz.ReferenceToken(profileToken)})
- return err
- }
- // GotoHomePosition 跳转到指定的预置点
- func (o *LcDevice) GotoHomePosition(profileToken string) error {
- XAddr, ok := o.endpoints["ptz"]
- if !ok {
- return NotSupportPtz
- }
- //新球机需要重新生成签名dsz 20230704
- client := soap.NewClient(soap.WithTimeout(time.Second * 0))
- client.AddHeader(soap.NewWSSSecurityHeader(o.onvifDev.User, o.onvifDev.Password))
- o.client = client
- p := ptz.NewPTZ(o.client, XAddr)
- _, err := p.GotoHomePosition(&ptz.GotoHomePosition{ProfileToken: ptz.ReferenceToken(profileToken)})
- return err
- }
- func (o *LcDevice) HandleTpSPtzComm(m mqtt.Message) {
- //新球机需要重新生成签名dsz 20230704
- client := soap.NewClient(soap.WithTimeout(time.Second * 0))
- client.AddHeader(soap.NewWSSSecurityHeader(o.onvifDev.User, o.onvifDev.Password))
- o.client = client
- var obj protocol.Pack_PTZCommonInfo
- if err := obj.DeCode(m.PayloadString()); err != nil {
- return
- }
- if o.onvifDev.Code != obj.Id {
- return
- }
- profileToken := o.GetProfileToken(obj.Data.ProfileToken)
- //0:获取所有预置点,1:设置预置点,2:删除预置点,3:跳转到预置点,4:设置home点,5:跳转到home点
- switch obj.Data.Flag {
- case 0:
- presets, err := o.GetPresets(profileToken, true)
- var ret protocol.Pack_PresetInfo
- strRet, err := ret.EnCode(o.onvifDev.Code, appConfig.GID, obj.Seq, err, obj.Data.Flag, presets)
- GetMQTTMgr().Publish(GetTopic(o.GetDevType(), o.onvifDev.Code, protocol.TP_ONVIF_PRESETS_ACK), strRet, mqtt.AtMostOnce, ToCloud)
- case 1:
- token, err := o.SetPreset(profileToken, obj.Data.PresetToken, obj.Data.PresetName)
- var (
- ret protocol.Pack_IPCSetPresetACK
- file string
- x, y, z float32 = 0, 0, 0
- )
- if err == nil {
- //预置位设置成功,则抓拍一张图片
- tmpFile := o.onvifDev.Code + "_" + strconv.FormatUint(obj.Seq, 10) + ".jpg"
- err = o.Snapshot2(tmpFile)
- if err == nil {
- file = tmpFile
- }
- //获取x,y,z
- if preset, err2 := o.GetPresets(profileToken, true); err2 == nil {
- for _, pis := range preset {
- if pis.Name == obj.Data.PresetName && pis.Token == token {
- x = pis.X
- y = pis.Y
- z = pis.Z
- break
- }
- }
- }
- }
- strRet, err := ret.EnCode(o.onvifDev.Code, appConfig.GID, token, obj.Data.PresetName, file, x, y, z, obj.Seq, err)
- GetMQTTMgr().Publish(GetTopic(o.GetDevType(), o.onvifDev.Code, protocol.TP_ONVIF_PRESET_ACK), strRet, mqtt.AtMostOnce, ToAll)
- case 2:
- err := o.DeletePreset(profileToken, obj.Data.PresetToken)
- var ret protocol.Pack_IPCCommonACK
- strRet, err := ret.EnCode(o.onvifDev.Code, appConfig.GID, "", obj.Seq, err)
- GetMQTTMgr().Publish(GetTopic(o.GetDevType(), o.onvifDev.Code, protocol.TP_ONVIF_PTZ_COMM_ACK), strRet, mqtt.AtMostOnce, ToAll)
- case 3:
- err := o.GotoPreset(profileToken, obj.Data.PresetToken)
- var ret protocol.Pack_IPCCommonACK
- strRet, err := ret.EnCode(o.onvifDev.Code, appConfig.GID, "", obj.Seq, err)
- GetMQTTMgr().Publish(GetTopic(o.GetDevType(), o.onvifDev.Code, protocol.TP_ONVIF_PTZ_COMM_ACK), strRet, mqtt.AtMostOnce, ToAll)
- case 4:
- err := o.SetHomePosition(profileToken)
- var ret protocol.Pack_IPCCommonACK
- strRet, err := ret.EnCode(o.onvifDev.Code, appConfig.GID, "", obj.Seq, err)
- GetMQTTMgr().Publish(GetTopic(o.GetDevType(), o.onvifDev.Code, protocol.TP_ONVIF_PTZ_COMM_ACK), strRet, mqtt.AtMostOnce, ToAll)
- case 5:
- err := o.GotoHomePosition(profileToken)
- var ret protocol.Pack_IPCCommonACK
- strRet, err := ret.EnCode(o.onvifDev.Code, appConfig.GID, "", obj.Seq, err)
- GetMQTTMgr().Publish(GetTopic(o.GetDevType(), o.onvifDev.Code, protocol.TP_ONVIF_PTZ_COMM_ACK), strRet, mqtt.AtMostOnce, ToAll)
- case 6:
- Preset, err := o.GetPresets(profileToken, false)
- var ret protocol.Pack_PresetInfo
- strRet, err := ret.EnCode(o.onvifDev.Code, appConfig.GID, obj.Seq, err, obj.Data.Flag, Preset)
- GetMQTTMgr().Publish(GetTopic(o.GetDevType(), o.onvifDev.Code, protocol.TP_ONVIF_PRESETS_ACK), strRet, mqtt.AtMostOnce, ToCloud)
- }
- }
- func (o *LcDevice) HandleTpOnvifPtz(m mqtt.Message) {
- var obj protocol.Pack_PTZMoveInfo
- if err := obj.DeCode(m.PayloadString()); err != nil {
- return
- }
- if o.onvifDev.Code != obj.Id {
- return
- }
- //新球机需要重新生成签名dsz 20230704
- client := soap.NewClient(soap.WithTimeout(time.Second * 0))
- client.AddHeader(soap.NewWSSSecurityHeader(o.onvifDev.User, o.onvifDev.Password))
- o.client = client
- token := o.GetProfileToken(obj.Data.ProfileToken)
- err := o.ContinuousMove(token, obj.Data.Direction, obj.Data.Speed)
- var ret protocol.Pack_IPCCommonACK
- strRet, err := ret.EnCode(o.onvifDev.Code, appConfig.GID, "", obj.Seq, err)
- GetMQTTMgr().Publish(GetTopic(o.GetDevType(), o.onvifDev.Code, protocol.TP_ONVIF_PTZ_COMM_ACK), strRet, mqtt.AtMostOnce, ToAll)
- }
|