Fix UTF-8 handling for Onvif

This commit is contained in:
Nicolas Mowen 2025-12-08 07:36:33 -07:00
parent 63ea076aa2
commit 17ac273b90
2 changed files with 35 additions and 10 deletions

View File

@ -610,14 +610,19 @@ class Dispatcher:
def _on_ptz_command(self, camera_name: str, payload: str) -> None: def _on_ptz_command(self, camera_name: str, payload: str) -> None:
"""Callback for ptz topic.""" """Callback for ptz topic."""
try: try:
if "preset" in payload.lower(): if isinstance(payload, bytes):
payload = payload.decode("utf-8")
preset = payload.lower()
if "preset" in preset:
command = OnvifCommandEnum.preset command = OnvifCommandEnum.preset
param = payload.lower()[payload.index("_") + 1 :] param = preset[preset.index("_") + 1 :]
elif "move_relative" in payload.lower(): elif "move_relative" in preset:
command = OnvifCommandEnum.move_relative command = OnvifCommandEnum.move_relative
param = payload.lower()[payload.index("_") + 1 :] param = preset[preset.index("_") + 1 :]
else: else:
command = OnvifCommandEnum[payload.lower()] command = OnvifCommandEnum[preset]
param = "" param = ""
self.onvif.handle_command(camera_name, command, param) self.onvif.handle_command(camera_name, command, param)

View File

@ -95,12 +95,21 @@ class OnvifController:
cam = self.camera_configs[cam_name] cam = self.camera_configs[cam_name]
try: try:
user = cam.onvif.user
password = cam.onvif.password
if user is not None and isinstance(user, bytes):
user = user.decode("utf-8")
if password is not None and isinstance(password, bytes):
password = password.decode("utf-8")
self.cams[cam_name] = { self.cams[cam_name] = {
"onvif": ONVIFCamera( "onvif": ONVIFCamera(
cam.onvif.host, cam.onvif.host,
cam.onvif.port, cam.onvif.port,
cam.onvif.user, user,
cam.onvif.password, password,
wsdl_dir=str(Path(find_spec("onvif").origin).parent / "wsdl"), wsdl_dir=str(Path(find_spec("onvif").origin).parent / "wsdl"),
adjust_time=cam.onvif.ignore_time_mismatch, adjust_time=cam.onvif.ignore_time_mismatch,
encrypt=not cam.onvif.tls_insecure, encrypt=not cam.onvif.tls_insecure,
@ -325,9 +334,15 @@ class OnvifController:
presets = [] presets = []
for preset in presets: for preset in presets:
self.cams[camera_name]["presets"][ # Ensure preset name is a Unicode string and handle UTF-8 characters correctly
(getattr(preset, "Name") or f"preset {preset['token']}").lower() preset_name = getattr(preset, "Name") or f"preset {preset['token']}"
] = preset["token"]
if isinstance(preset_name, bytes):
preset_name = preset_name.decode("utf-8")
# Convert to lowercase while preserving UTF-8 characters
preset_name_lower = preset_name.lower()
self.cams[camera_name]["presets"][preset_name_lower] = preset["token"]
# get list of supported features # get list of supported features
supported_features = [] supported_features = []
@ -563,6 +578,11 @@ class OnvifController:
self.cams[camera_name]["active"] = False self.cams[camera_name]["active"] = False
async def _move_to_preset(self, camera_name: str, preset: str) -> None: async def _move_to_preset(self, camera_name: str, preset: str) -> None:
if isinstance(preset, bytes):
preset = preset.decode("utf-8")
preset = preset.lower()
if preset not in self.cams[camera_name]["presets"]: if preset not in self.cams[camera_name]["presets"]:
logger.error(f"{preset} is not a valid preset for {camera_name}") logger.error(f"{preset} is not a valid preset for {camera_name}")
return return