|
|
@@ -218,6 +218,10 @@ class DahuaSDK:
|
|
|
self.sdk.CLIENT_SnapPicture.argtypes = [c_long, POINTER(self.SNAP_PARAMS)]
|
|
|
self.sdk.CLIENT_SnapPicture.restype = ctypes.c_bool
|
|
|
|
|
|
+ # CLIENT_GetLastError() -> DWORD
|
|
|
+ self.sdk.CLIENT_GetLastError.argtypes = []
|
|
|
+ self.sdk.CLIENT_GetLastError.restype = c_uint32
|
|
|
+
|
|
|
# === 可选函数(某些SDK版本/平台可能缺失)===
|
|
|
self._optional_funcs = {}
|
|
|
|
|
|
@@ -387,10 +391,31 @@ class DahuaSDK:
|
|
|
是否成功
|
|
|
"""
|
|
|
if not self.sdk or login_handle <= 0:
|
|
|
+ print(f"[PTZ] 失败: sdk={self.sdk is not None}, handle={login_handle}")
|
|
|
return False
|
|
|
- return self.sdk.CLIENT_DHPTZControlEx(
|
|
|
+
|
|
|
+ # 命令名称映射 (用于调试日志)
|
|
|
+ cmd_names = {
|
|
|
+ 0: 'UP', 1: 'DOWN', 2: 'LEFT', 3: 'RIGHT',
|
|
|
+ 4: 'ZOOM_ADD', 5: 'ZOOM_DEC',
|
|
|
+ 0x20: 'LEFTTOP', 0x21: 'RIGHTTOP', 0x22: 'LEFTDOWN', 0x23: 'RIGHTDOWN',
|
|
|
+ 0x33: 'FASTGOTO', 0x43: 'EXACTGOTO', 0x44: 'RESETZERO',
|
|
|
+ 0x45: 'MOVE_ABSOLUTELY', 0x46: 'MOVE_CONTINUOUSLY', 0x47: 'GOTOPRESET',
|
|
|
+ }
|
|
|
+ cmd_name = cmd_names.get(command, f'CMD_{command:#x}')
|
|
|
+
|
|
|
+ result = self.sdk.CLIENT_DHPTZControlEx(
|
|
|
login_handle, channel, command, param1, param2, param3, stop
|
|
|
)
|
|
|
+
|
|
|
+ print(f"[PTZ] {cmd_name}(ch={channel}, p1={param1}, p2={param2}, p3={param3}, stop={stop}) → {'✓' if result else '✗'}")
|
|
|
+
|
|
|
+ if not result:
|
|
|
+ # 获取SDK错误码
|
|
|
+ error = self.sdk.CLIENT_GetLastError() if hasattr(self.sdk, 'CLIENT_GetLastError') else -1
|
|
|
+ print(f"[PTZ] 错误码: {error}")
|
|
|
+
|
|
|
+ return result
|
|
|
|
|
|
def snap_picture(self, login_handle: int, channel: int = 0,
|
|
|
cmd_serial: int = 0) -> bool:
|