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