- 在 SetPTZPos 函数中添加 Action 参数,用于控制 PTZ 操作类型- 更新 Core.go 中的 SetPTZPOS 函数,根据 Action 参数执行不同操作 - 修改 BallCamera.go 中的 SetPTZPos调用,传入 Action 参数
310 lines
7.7 KiB
Go
310 lines
7.7 KiB
Go
package HikSDK
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"sync"
|
|
)
|
|
|
|
const (
|
|
Base = 0
|
|
BuKongQiu = 1
|
|
)
|
|
|
|
type PTZEnumObj struct {
|
|
PTZ_LEFT int
|
|
PTZ_RIGHT int
|
|
PTZ_UP int
|
|
PTZ_DOWN int
|
|
PTZ_UP_LEFT int
|
|
PTZ_UP_RIGHT int
|
|
PTZ_DOWN_LEFT int
|
|
PTZ_DOWN_RIGHT int
|
|
PTZ_ZOOM_IN int
|
|
PTZ_ZOOM_OUT int
|
|
PTZ_Focus_Far int
|
|
PTZ_Focus_Near int
|
|
}
|
|
|
|
func (receiver *PTZEnumObj) toHikPTZEnum(v int) int {
|
|
switch v {
|
|
case PTZEnum.PTZ_LEFT:
|
|
return HikPTZEnum.PAN_LEFT
|
|
case PTZEnum.PTZ_RIGHT:
|
|
return HikPTZEnum.PAN_RIGHT
|
|
case PTZEnum.PTZ_UP:
|
|
return HikPTZEnum.TILT_UP
|
|
case PTZEnum.PTZ_DOWN:
|
|
return HikPTZEnum.TILT_DOWN
|
|
case PTZEnum.PTZ_ZOOM_IN:
|
|
return HikPTZEnum.ZOOM_IN
|
|
case PTZEnum.PTZ_ZOOM_OUT:
|
|
return HikPTZEnum.ZOOM_OUT
|
|
case PTZEnum.PTZ_Focus_Far:
|
|
return HikPTZEnum.FOCUS_FAR
|
|
case PTZEnum.PTZ_Focus_Near:
|
|
return HikPTZEnum.FOCUS_NEAR
|
|
case PTZEnum.PTZ_UP_LEFT:
|
|
return HikPTZEnum.UP_LEFT
|
|
case PTZEnum.PTZ_UP_RIGHT:
|
|
return HikPTZEnum.UP_RIGHT
|
|
case PTZEnum.PTZ_DOWN_LEFT:
|
|
return HikPTZEnum.DOWN_LEFT
|
|
case PTZEnum.PTZ_DOWN_RIGHT:
|
|
return HikPTZEnum.DOWN_RIGHT
|
|
|
|
default:
|
|
return -1
|
|
}
|
|
}
|
|
|
|
var PTZEnum = PTZEnumObj{
|
|
PTZ_LEFT: 1,
|
|
PTZ_RIGHT: 2,
|
|
PTZ_UP: 3,
|
|
PTZ_DOWN: 4,
|
|
PTZ_UP_LEFT: 5,
|
|
PTZ_UP_RIGHT: 6,
|
|
PTZ_DOWN_LEFT: 7,
|
|
PTZ_DOWN_RIGHT: 8,
|
|
PTZ_ZOOM_IN: 9,
|
|
PTZ_ZOOM_OUT: 10,
|
|
PTZ_Focus_Far: 11,
|
|
PTZ_Focus_Near: 12,
|
|
}
|
|
|
|
var HikPTZEnum = struct {
|
|
LIGHT_PWRON int //接通灯光电源
|
|
WIPER_PWRON int //接通雨刷开关
|
|
FAN_PWRON int //接通风扇开关
|
|
HEATER_PWRON int //接通加热器开关
|
|
AUX_PWRON1 int //接通辅助设备开关
|
|
AUX_PWRON2 int //接通辅助设备开关
|
|
ZOOM_IN int //焦距变大(倍率变大)
|
|
ZOOM_OUT int //焦距变小(倍率变小)
|
|
FOCUS_NEAR int //焦点前调
|
|
FOCUS_FAR int //焦点后调
|
|
IRIS_OPEN int //光圈扩大
|
|
IRIS_CLOSE int //光圈缩小
|
|
TILT_UP int //云台上仰
|
|
TILT_DOWN int //云台下俯
|
|
PAN_LEFT int //云台左转
|
|
PAN_RIGHT int //云台右转
|
|
UP_LEFT int //云台上仰和左转
|
|
UP_RIGHT int //云台上仰和右转
|
|
DOWN_LEFT int //云台下俯和左转
|
|
DOWN_RIGHT int //云台下俯和右转
|
|
PAN_AUTO int //云台左右自动扫描
|
|
TILT_DOWN_ZOOM_IN int //云台下俯和焦距变大(倍率变大)
|
|
TILT_DOWN_ZOOM_OUT int //云台下俯和焦距变小(倍率变小)
|
|
PAN_LEFT_ZOOM_IN int //云台左转和焦距变大(倍率变大)
|
|
PAN_LEFT_ZOOM_OUT int //云台左转和焦距变小(倍率变小)
|
|
PAN_RIGHT_ZOOM_IN int //云台右转和焦距变大(倍率变大)
|
|
PAN_RIGHT_ZOOM_OUT int //云台右转和焦距变小(倍率变小)
|
|
UP_LEFT_ZOOM_IN int //云台上仰和左转和焦距变大(倍率变大)
|
|
UP_LEFT_ZOOM_OUT int //云台上仰和左转和焦距变小(倍率变小)
|
|
UP_RIGHT_ZOOM_IN int //云台上仰和右转和焦距变大(倍率变大)
|
|
UP_RIGHT_ZOOM_OUT int //云台上仰和右转和焦距变小(倍率变小)
|
|
DOWN_LEFT_ZOOM_IN int //云台下俯和左转和焦距变大(倍率变大)
|
|
DOWN_LEFT_ZOOM_OUT int //云台下俯和左转和焦距变小(倍率变小)
|
|
DOWN_RIGHT_ZOOM_IN int //云台下俯和右转和焦距变大(倍率变大)
|
|
DOWN_RIGHT_ZOOM_OUT int //云台下俯和右转和焦距变小(倍率变小)
|
|
TILT_UP_ZOOM_IN int //云台上仰和焦距变大(倍率变大)
|
|
TILT_UP_ZOOM_OUT int //云台上仰和焦距变小(倍率变小)
|
|
}{LIGHT_PWRON: 2,
|
|
WIPER_PWRON: 3,
|
|
FAN_PWRON: 4,
|
|
HEATER_PWRON: 5,
|
|
AUX_PWRON1: 6,
|
|
AUX_PWRON2: 7,
|
|
ZOOM_IN: 11,
|
|
ZOOM_OUT: 12,
|
|
FOCUS_NEAR: 13,
|
|
FOCUS_FAR: 14,
|
|
IRIS_OPEN: 15,
|
|
IRIS_CLOSE: 16,
|
|
TILT_UP: 21,
|
|
TILT_DOWN: 22,
|
|
PAN_LEFT: 23,
|
|
PAN_RIGHT: 24,
|
|
UP_LEFT: 25,
|
|
UP_RIGHT: 26,
|
|
DOWN_LEFT: 27,
|
|
DOWN_RIGHT: 28,
|
|
PAN_AUTO: 29,
|
|
TILT_DOWN_ZOOM_IN: 58,
|
|
TILT_DOWN_ZOOM_OUT: 59,
|
|
PAN_LEFT_ZOOM_IN: 60,
|
|
PAN_LEFT_ZOOM_OUT: 61,
|
|
PAN_RIGHT_ZOOM_IN: 62,
|
|
PAN_RIGHT_ZOOM_OUT: 63,
|
|
UP_LEFT_ZOOM_IN: 64,
|
|
UP_LEFT_ZOOM_OUT: 65,
|
|
UP_RIGHT_ZOOM_IN: 66,
|
|
UP_RIGHT_ZOOM_OUT: 67,
|
|
DOWN_LEFT_ZOOM_IN: 68,
|
|
DOWN_LEFT_ZOOM_OUT: 69,
|
|
DOWN_RIGHT_ZOOM_IN: 70,
|
|
DOWN_RIGHT_ZOOM_OUT: 71,
|
|
TILT_UP_ZOOM_IN: 72,
|
|
TILT_UP_ZOOM_OUT: 73,
|
|
}
|
|
|
|
type BallCamera struct {
|
|
userId LONG
|
|
_type uint8
|
|
deviceInfo NET_DVR_DEVICEINFO
|
|
mu sync.Mutex
|
|
expectedType byte
|
|
}
|
|
|
|
func NewBallCamera(Ip string, Port int, Username, Password string, Type uint8) (*BallCamera, error) {
|
|
UserId, DeviceInfo, err := login(Ip, Port, Username, Password)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &BallCamera{
|
|
userId: UserId,
|
|
_type: Type,
|
|
deviceInfo: DeviceInfo,
|
|
}, nil
|
|
}
|
|
|
|
type PTZ struct {
|
|
Action int
|
|
P float64
|
|
T float64
|
|
Z float64
|
|
}
|
|
|
|
func (this *BallCamera) GetPTZ() (PTZ, error) {
|
|
if this == nil {
|
|
return PTZ{}, errors.New("BallCamera is nil")
|
|
}
|
|
if this._type == BuKongQiu {
|
|
ptzpos, err := GetPTZPOS(this.userId)
|
|
if err != nil {
|
|
return PTZ{}, err
|
|
}
|
|
return PTZ{
|
|
Action: ptzpos.Action,
|
|
P: float64(ptzpos.P),
|
|
T: float64(ptzpos.T),
|
|
Z: float64(ptzpos.Z),
|
|
}, nil
|
|
}
|
|
ptz, err := getPTZBase(this.userId)
|
|
if err != nil {
|
|
return PTZ{}, err
|
|
}
|
|
return PTZ{
|
|
P: ptz.P,
|
|
T: ptz.T,
|
|
Z: ptz.Z,
|
|
}, nil
|
|
}
|
|
|
|
func padding(n int) ([]byte, error) {
|
|
if n < 0 || n > 65535 {
|
|
return []byte{0x00, 0x00}, errors.New("n must be in the range 0-65535")
|
|
}
|
|
return []byte{byte(n >> 8), byte(n & 0xFF)}, nil
|
|
}
|
|
func (this *BallCamera) PtzGotoPut(Action int, P, T, Z float64) error {
|
|
if this == nil {
|
|
return errors.New("BallCamera is nil")
|
|
}
|
|
if this._type == BuKongQiu {
|
|
PByte, err := padding(int(P * 100))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
TByte, err := padding(int(T * 100))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
ZByte, err := padding(int(Z * 100))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
pBuf := append([]byte{0xff, 0x01, 0x00, 0x4b}, PByte...)
|
|
tBuf := append([]byte{0xff, 0x01, 0x00, 0x4d}, TByte...)
|
|
zBuf := append([]byte{0xff, 0x01, 0x00, 0x4f}, ZByte...)
|
|
|
|
pBufv, err := verify(pBuf)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tBufv, err := verify(tBuf)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
zBufv, err := verify(zBuf)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
pBuf = append(pBuf, pBufv)
|
|
tBuf = append(tBuf, tBufv)
|
|
zBuf = append(zBuf, zBufv)
|
|
err = SetPTZPos(this.userId, Action, pBuf, tBuf, zBuf)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
err := setPTZBase(this.userId, PTZ{Action, P, T, Z})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (receiver *BallCamera) StartBus(direction int, speed int) error {
|
|
if receiver == nil {
|
|
return errors.New("BallCamera is nil")
|
|
}
|
|
err := pTZControlWithSpeed_Other(receiver.userId, DWORD(PTZEnum.toHikPTZEnum(direction)), DWORD(0), DWORD(speed))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
func (receiver *BallCamera) StopBus(direction int, speed int) error {
|
|
if receiver == nil {
|
|
return errors.New("BallCamera is nil")
|
|
}
|
|
err := pTZControlWithSpeed_Other(receiver.userId, DWORD(PTZEnum.toHikPTZEnum(direction)), DWORD(1), DWORD(speed))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func verify(data []byte) (byte, error) {
|
|
if len(data) < 6 {
|
|
return 0, fmt.Errorf("data too short")
|
|
}
|
|
sum := 0
|
|
for i := 1; i < 6; i++ {
|
|
sum += int(data[i])
|
|
}
|
|
// 取模并转换为16进制
|
|
checksum := sum % 0x100
|
|
return byte(checksum), nil
|
|
}
|
|
|
|
func (this *BallCamera) Logout() error {
|
|
if this == nil {
|
|
return errors.New("BallCamera is nil")
|
|
}
|
|
return logout(this.userId)
|
|
}
|
|
|
|
func (this *BallCamera) Status() bool {
|
|
if this == nil {
|
|
return false
|
|
}
|
|
return deviceOnline(this.userId)
|
|
}
|