Add support for connecting to multiple zoneminder instances (#19955)
* Add support for connecting to multiple zoneminder instances * Lint * Lint * Clean up and better error handling * Fix config validation * Lint
This commit is contained in:
parent
fe93ea9bdf
commit
bc30491dc0
4 changed files with 78 additions and 54 deletions
|
@ -19,17 +19,18 @@ DEPENDENCIES = ['zoneminder']
|
||||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||||
"""Set up the ZoneMinder cameras."""
|
"""Set up the ZoneMinder cameras."""
|
||||||
filter_urllib3_logging()
|
filter_urllib3_logging()
|
||||||
zm_client = hass.data[ZONEMINDER_DOMAIN]
|
|
||||||
|
|
||||||
monitors = zm_client.get_monitors()
|
|
||||||
if not monitors:
|
|
||||||
_LOGGER.warning("Could not fetch monitors from ZoneMinder")
|
|
||||||
return
|
|
||||||
|
|
||||||
cameras = []
|
cameras = []
|
||||||
for monitor in monitors:
|
for zm_client in hass.data[ZONEMINDER_DOMAIN].values():
|
||||||
_LOGGER.info("Initializing camera %s", monitor.id)
|
monitors = zm_client.get_monitors()
|
||||||
cameras.append(ZoneMinderCamera(monitor, zm_client.verify_ssl))
|
if not monitors:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Could not fetch monitors from ZoneMinder host: %s"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
for monitor in monitors:
|
||||||
|
_LOGGER.info("Initializing camera %s", monitor.id)
|
||||||
|
cameras.append(ZoneMinderCamera(monitor, zm_client.verify_ssl))
|
||||||
add_entities(cameras)
|
add_entities(cameras)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,19 +42,21 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||||
"""Set up the ZoneMinder sensor platform."""
|
"""Set up the ZoneMinder sensor platform."""
|
||||||
include_archived = config.get(CONF_INCLUDE_ARCHIVED)
|
include_archived = config.get(CONF_INCLUDE_ARCHIVED)
|
||||||
|
|
||||||
zm_client = hass.data[ZONEMINDER_DOMAIN]
|
|
||||||
monitors = zm_client.get_monitors()
|
|
||||||
if not monitors:
|
|
||||||
_LOGGER.warning('Could not fetch any monitors from ZoneMinder')
|
|
||||||
|
|
||||||
sensors = []
|
sensors = []
|
||||||
for monitor in monitors:
|
for zm_client in hass.data[ZONEMINDER_DOMAIN].values():
|
||||||
sensors.append(ZMSensorMonitors(monitor))
|
monitors = zm_client.get_monitors()
|
||||||
|
if not monitors:
|
||||||
|
_LOGGER.warning('Could not fetch any monitors from ZoneMinder')
|
||||||
|
|
||||||
for sensor in config[CONF_MONITORED_CONDITIONS]:
|
for monitor in monitors:
|
||||||
sensors.append(ZMSensorEvents(monitor, include_archived, sensor))
|
sensors.append(ZMSensorMonitors(monitor))
|
||||||
|
|
||||||
sensors.append(ZMSensorRunState(zm_client))
|
for sensor in config[CONF_MONITORED_CONDITIONS]:
|
||||||
|
sensors.append(
|
||||||
|
ZMSensorEvents(monitor, include_archived, sensor)
|
||||||
|
)
|
||||||
|
|
||||||
|
sensors.append(ZMSensorRunState(zm_client))
|
||||||
add_entities(sensors)
|
add_entities(sensors)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,16 +29,15 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||||
on_state = MonitorState(config.get(CONF_COMMAND_ON))
|
on_state = MonitorState(config.get(CONF_COMMAND_ON))
|
||||||
off_state = MonitorState(config.get(CONF_COMMAND_OFF))
|
off_state = MonitorState(config.get(CONF_COMMAND_OFF))
|
||||||
|
|
||||||
zm_client = hass.data[ZONEMINDER_DOMAIN]
|
|
||||||
|
|
||||||
monitors = zm_client.get_monitors()
|
|
||||||
if not monitors:
|
|
||||||
_LOGGER.warning('Could not fetch monitors from ZoneMinder')
|
|
||||||
return
|
|
||||||
|
|
||||||
switches = []
|
switches = []
|
||||||
for monitor in monitors:
|
for zm_client in hass.data[ZONEMINDER_DOMAIN].values():
|
||||||
switches.append(ZMSwitchMonitors(monitor, on_state, off_state))
|
monitors = zm_client.get_monitors()
|
||||||
|
if not monitors:
|
||||||
|
_LOGGER.warning('Could not fetch monitors from ZoneMinder')
|
||||||
|
return
|
||||||
|
|
||||||
|
for monitor in monitors:
|
||||||
|
switches.append(ZMSwitchMonitors(monitor, on_state, off_state))
|
||||||
add_entities(switches)
|
add_entities(switches)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,10 @@ import logging
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_HOST, CONF_PASSWORD, CONF_PATH, CONF_SSL, CONF_USERNAME,
|
CONF_HOST, CONF_PASSWORD, CONF_PATH, CONF_SSL, CONF_USERNAME,
|
||||||
CONF_VERIFY_SSL, ATTR_NAME)
|
CONF_VERIFY_SSL, ATTR_NAME, ATTR_ID)
|
||||||
import homeassistant.helpers.config_validation as cv
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -26,20 +26,23 @@ DEFAULT_TIMEOUT = 10
|
||||||
DEFAULT_VERIFY_SSL = True
|
DEFAULT_VERIFY_SSL = True
|
||||||
DOMAIN = 'zoneminder'
|
DOMAIN = 'zoneminder'
|
||||||
|
|
||||||
|
HOST_CONFIG_SCHEMA = vol.Schema({
|
||||||
|
vol.Required(CONF_HOST): cv.string,
|
||||||
|
vol.Optional(CONF_PASSWORD): cv.string,
|
||||||
|
vol.Optional(CONF_PATH, default=DEFAULT_PATH): cv.string,
|
||||||
|
vol.Optional(CONF_PATH_ZMS, default=DEFAULT_PATH_ZMS): cv.string,
|
||||||
|
vol.Optional(CONF_SSL, default=DEFAULT_SSL): cv.boolean,
|
||||||
|
vol.Optional(CONF_USERNAME): cv.string,
|
||||||
|
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
|
||||||
|
})
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.Schema({
|
CONFIG_SCHEMA = vol.Schema({
|
||||||
DOMAIN: vol.Schema({
|
DOMAIN: vol.All(cv.ensure_list, [HOST_CONFIG_SCHEMA])
|
||||||
vol.Required(CONF_HOST): cv.string,
|
|
||||||
vol.Optional(CONF_PASSWORD): cv.string,
|
|
||||||
vol.Optional(CONF_PATH, default=DEFAULT_PATH): cv.string,
|
|
||||||
vol.Optional(CONF_PATH_ZMS, default=DEFAULT_PATH_ZMS): cv.string,
|
|
||||||
vol.Optional(CONF_SSL, default=DEFAULT_SSL): cv.boolean,
|
|
||||||
vol.Optional(CONF_USERNAME): cv.string,
|
|
||||||
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
|
|
||||||
})
|
|
||||||
}, extra=vol.ALLOW_EXTRA)
|
}, extra=vol.ALLOW_EXTRA)
|
||||||
|
|
||||||
SERVICE_SET_RUN_STATE = 'set_run_state'
|
SERVICE_SET_RUN_STATE = 'set_run_state'
|
||||||
SET_RUN_STATE_SCHEMA = vol.Schema({
|
SET_RUN_STATE_SCHEMA = vol.Schema({
|
||||||
|
vol.Required(ATTR_ID): cv.string,
|
||||||
vol.Required(ATTR_NAME): cv.string
|
vol.Required(ATTR_NAME): cv.string
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -48,27 +51,46 @@ def setup(hass, config):
|
||||||
"""Set up the ZoneMinder component."""
|
"""Set up the ZoneMinder component."""
|
||||||
from zoneminder.zm import ZoneMinder
|
from zoneminder.zm import ZoneMinder
|
||||||
|
|
||||||
conf = config[DOMAIN]
|
hass.data[DOMAIN] = {}
|
||||||
if conf[CONF_SSL]:
|
|
||||||
schema = 'https'
|
|
||||||
else:
|
|
||||||
schema = 'http'
|
|
||||||
|
|
||||||
server_origin = '{}://{}'.format(schema, conf[CONF_HOST])
|
success = True
|
||||||
hass.data[DOMAIN] = ZoneMinder(server_origin,
|
|
||||||
conf.get(CONF_USERNAME),
|
for conf in config[DOMAIN]:
|
||||||
conf.get(CONF_PASSWORD),
|
if conf[CONF_SSL]:
|
||||||
conf.get(CONF_PATH),
|
schema = 'https'
|
||||||
conf.get(CONF_PATH_ZMS),
|
else:
|
||||||
conf.get(CONF_VERIFY_SSL))
|
schema = 'http'
|
||||||
|
|
||||||
|
host_name = conf[CONF_HOST]
|
||||||
|
server_origin = '{}://{}'.format(schema, host_name)
|
||||||
|
zm_client = ZoneMinder(
|
||||||
|
server_origin,
|
||||||
|
conf.get(CONF_USERNAME),
|
||||||
|
conf.get(CONF_PASSWORD),
|
||||||
|
conf.get(CONF_PATH),
|
||||||
|
conf.get(CONF_PATH_ZMS),
|
||||||
|
conf.get(CONF_VERIFY_SSL)
|
||||||
|
)
|
||||||
|
hass.data[DOMAIN][host_name] = zm_client
|
||||||
|
|
||||||
|
success = zm_client.login() and success
|
||||||
|
|
||||||
def set_active_state(call):
|
def set_active_state(call):
|
||||||
"""Set the ZoneMinder run state to the given state name."""
|
"""Set the ZoneMinder run state to the given state name."""
|
||||||
return hass.data[DOMAIN].set_active_state(call.data[ATTR_NAME])
|
zm_id = call.data[ATTR_ID]
|
||||||
|
state_name = call.data[ATTR_NAME]
|
||||||
|
if zm_id not in hass.data[DOMAIN]:
|
||||||
|
_LOGGER.error('Invalid ZoneMinder host provided: %s', zm_id)
|
||||||
|
if not hass.data[DOMAIN][zm_id].set_active_state(state_name):
|
||||||
|
_LOGGER.error(
|
||||||
|
'Unable to change ZoneMinder state. Host: %s, state: %s',
|
||||||
|
zm_id,
|
||||||
|
state_name
|
||||||
|
)
|
||||||
|
|
||||||
hass.services.register(
|
hass.services.register(
|
||||||
DOMAIN, SERVICE_SET_RUN_STATE, set_active_state,
|
DOMAIN, SERVICE_SET_RUN_STATE, set_active_state,
|
||||||
schema=SET_RUN_STATE_SCHEMA
|
schema=SET_RUN_STATE_SCHEMA
|
||||||
)
|
)
|
||||||
|
|
||||||
return hass.data[DOMAIN].login()
|
return success
|
||||||
|
|
Loading…
Add table
Reference in a new issue