- 在 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)
 | |
| }
 |