Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
584ea43d8e |
1 changed files with 32 additions and 14 deletions
|
@ -39,6 +39,7 @@ CONF_PROFILE = "profile"
|
||||||
ATTR_PAN = "pan"
|
ATTR_PAN = "pan"
|
||||||
ATTR_TILT = "tilt"
|
ATTR_TILT = "tilt"
|
||||||
ATTR_ZOOM = "zoom"
|
ATTR_ZOOM = "zoom"
|
||||||
|
ATTR_TYPE = "type"
|
||||||
|
|
||||||
DIR_UP = "UP"
|
DIR_UP = "UP"
|
||||||
DIR_DOWN = "DOWN"
|
DIR_DOWN = "DOWN"
|
||||||
|
@ -46,6 +47,9 @@ DIR_LEFT = "LEFT"
|
||||||
DIR_RIGHT = "RIGHT"
|
DIR_RIGHT = "RIGHT"
|
||||||
ZOOM_OUT = "ZOOM_OUT"
|
ZOOM_OUT = "ZOOM_OUT"
|
||||||
ZOOM_IN = "ZOOM_IN"
|
ZOOM_IN = "ZOOM_IN"
|
||||||
|
TYPE_CONTINOUS = "CONTINOUS"
|
||||||
|
TYPE_ABSOLUTE = "ABSOLUTE"
|
||||||
|
TYPE_RELATIVE = "RELATIVE"
|
||||||
|
|
||||||
SERVICE_PTZ = "onvif_ptz"
|
SERVICE_PTZ = "onvif_ptz"
|
||||||
|
|
||||||
|
@ -65,9 +69,11 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
|
|
||||||
SERVICE_PTZ_SCHEMA = vol.Schema({
|
SERVICE_PTZ_SCHEMA = vol.Schema({
|
||||||
ATTR_ENTITY_ID: cv.entity_ids,
|
ATTR_ENTITY_ID: cv.entity_ids,
|
||||||
ATTR_PAN: vol.In([DIR_LEFT, DIR_RIGHT]),
|
ATTR_PAN: vol.Or(vol.In([DIR_LEFT, DIR_RIGHT]), vol.Range(min=-1, max=1)),
|
||||||
ATTR_TILT: vol.In([DIR_UP, DIR_DOWN]),
|
ATTR_TILT: vol.Or(vol.In([DIR_UP, DIR_DOWN]), vol.Range(min=-1, max=1)),
|
||||||
ATTR_ZOOM: vol.In([ZOOM_OUT, ZOOM_IN])
|
ATTR_ZOOM: vol.Or(vol.In([ZOOM_OUT, ZOOM_IN]), vol.Range(min=-1, max=1)),
|
||||||
|
vol.Required(ATTR_TYPE, default=TYPE_CONTINOUS):
|
||||||
|
vol.In([TYPE_CONTINOUS, TYPE_ABSOLUTE, TYPE_RELATIVE])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,6 +87,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||||
pan = service.data.get(ATTR_PAN, None)
|
pan = service.data.get(ATTR_PAN, None)
|
||||||
tilt = service.data.get(ATTR_TILT, None)
|
tilt = service.data.get(ATTR_TILT, None)
|
||||||
zoom = service.data.get(ATTR_ZOOM, None)
|
zoom = service.data.get(ATTR_ZOOM, None)
|
||||||
|
type_ = service.data.get(ATTR_TYPE, None)
|
||||||
all_cameras = hass.data[ONVIF_DATA][ENTITIES]
|
all_cameras = hass.data[ONVIF_DATA][ENTITIES]
|
||||||
entity_ids = extract_entity_ids(hass, service)
|
entity_ids = extract_entity_ids(hass, service)
|
||||||
target_cameras = []
|
target_cameras = []
|
||||||
|
@ -90,7 +97,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||||
target_cameras = [camera for camera in all_cameras
|
target_cameras = [camera for camera in all_cameras
|
||||||
if camera.entity_id in entity_ids]
|
if camera.entity_id in entity_ids]
|
||||||
for camera in target_cameras:
|
for camera in target_cameras:
|
||||||
camera.perform_ptz(pan, tilt, zoom)
|
camera.perform_ptz(type_, pan, tilt, zoom)
|
||||||
|
|
||||||
hass.services.async_register(DOMAIN, SERVICE_PTZ, handle_ptz,
|
hass.services.async_register(DOMAIN, SERVICE_PTZ, handle_ptz,
|
||||||
schema=SERVICE_PTZ_SCHEMA)
|
schema=SERVICE_PTZ_SCHEMA)
|
||||||
|
@ -162,23 +169,34 @@ class ONVIFHassCamera(Camera):
|
||||||
self._name, err)
|
self._name, err)
|
||||||
return
|
return
|
||||||
|
|
||||||
def perform_ptz(self, pan, tilt, zoom):
|
def perform_ptz(self, type_, pan, tilt, zoom):
|
||||||
"""Perform a PTZ action on the camera."""
|
"""Perform a PTZ action on the camera."""
|
||||||
from onvif import exceptions
|
from onvif import exceptions
|
||||||
|
|
||||||
if self._ptz_service:
|
if self._ptz_service:
|
||||||
pan_val = 1 if pan == DIR_RIGHT else -1 if pan == DIR_LEFT else 0
|
type_val = "continous" if type_ == "" else type_
|
||||||
tilt_val = 1 if tilt == DIR_UP else -1 if tilt == DIR_DOWN else 0
|
pan_val = 1 if pan == DIR_RIGHT else -1 if pan == DIR_LEFT else (pan or 0)
|
||||||
zoom_val = 1 if zoom == ZOOM_IN else -1 if zoom == ZOOM_OUT else 0
|
tilt_val = 1 if tilt == DIR_UP else -1 if tilt == DIR_DOWN else (tilt or 0)
|
||||||
req = {"Velocity": {
|
zoom_val = 1 if zoom == ZOOM_IN else -1 if zoom == ZOOM_OUT else (zoom or 0)
|
||||||
"PanTilt": {"_x": pan_val, "_y": tilt_val},
|
|
||||||
"Zoom": {"_x": zoom_val}}}
|
xy = {"_x": pan_val, "_y": tilt_val}
|
||||||
|
z = {"_x": zoom_val}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._ptz_service.ContinuousMove(req)
|
if type_val == TYPE_ABSOLUTE:
|
||||||
|
req = {"Position": {"PanTilt": xy, "Zoom": z}}
|
||||||
|
self._ptz_service.AbsoluteMove(req)
|
||||||
|
elif type_val == TYPE_RELATIVE:
|
||||||
|
req = {"Position": {"Translation": xy, "Zoom": z}}
|
||||||
|
self._ptz_service.RelativeMove(req)
|
||||||
|
else:
|
||||||
|
req = {"Velocity": {"PanTilt": xy, "Zoom": z}}
|
||||||
|
self._ptz_service.ContinuousMove(req)
|
||||||
except exceptions.ONVIFError as err:
|
except exceptions.ONVIFError as err:
|
||||||
if "Bad Request" in err.reason:
|
if "Bad Request" in err.reason:
|
||||||
self._ptz_service = None
|
self._ptz_service = None
|
||||||
_LOGGER.debug("Camera '%s' doesn't support PTZ.",
|
_LOGGER.debug("Camera '%s' doesn't support PTZ of type '%s.",
|
||||||
self._name)
|
self._name, type_)
|
||||||
else:
|
else:
|
||||||
_LOGGER.debug("Camera '%s' doesn't support PTZ.", self._name)
|
_LOGGER.debug("Camera '%s' doesn't support PTZ.", self._name)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue