initial commit
This commit is contained in:
commit
97699c6c2d
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"python.formatting.provider": "black",
|
||||
"python.linting.flake8Enabled": false,
|
||||
"python.linting.pylintEnabled": true,
|
||||
"python.linting.enabled": true
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
"""Support for ZoneMinder."""
|
||||
import logging
|
||||
from time import sleep
|
||||
|
||||
import voluptuous as vol
|
||||
from zoneminder.zm import ZoneMinder
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_ID,
|
||||
ATTR_NAME,
|
||||
CONF_HOST,
|
||||
CONF_NAME,
|
||||
CONF_PASSWORD,
|
||||
CONF_PATH,
|
||||
CONF_SSL,
|
||||
CONF_TTL,
|
||||
CONF_USERNAME,
|
||||
CONF_VERIFY_SSL,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.discovery import async_load_platform
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.components.zoneminder import DOMAIN as ZONEMINDER_DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
DOMAIN = "zoneminder_alarm"
|
||||
|
||||
DELAY = 10
|
||||
|
||||
SERVICE_TRIGGER_ALARM_STATE = "trigger_alarm_state"
|
||||
TRIGGER_ALARM_SCHEMA = vol.Schema(
|
||||
{vol.Required(ATTR_ID): cv.string, vol.Required(ATTR_NAME): cv.string}
|
||||
)
|
||||
|
||||
ALARM_COMMAND_ON = "on"
|
||||
ALARM_COMMAND_OFF = "off"
|
||||
ALARM_COMMAND_STATUS = "status"
|
||||
ALARM_STATUS_URL = "api/monitors/alarm/id:{monitor_id}/command:{command}.json"
|
||||
|
||||
|
||||
def setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Set up the ZoneMinder component."""
|
||||
hass.data.setdefault(DOMAIN, {})
|
||||
|
||||
for conf in config[DOMAIN]:
|
||||
zm_id = conf.get(CONF_HOST)
|
||||
hass.data[DOMAIN].setdefault(zm_id, {})
|
||||
|
||||
def trigger_alarm_state(call: ServiceCall) -> None:
|
||||
zm_id = call.data[ATTR_NAME]
|
||||
monitor_id = call.data[ATTR_ID]
|
||||
client = hass.data[ZONEMINDER_DOMAIN][zm_id]
|
||||
|
||||
def get_alarm_status():
|
||||
result = client.get_state(
|
||||
ALARM_STATUS_URL.format(
|
||||
monitor_id=monitor_id, command=ALARM_COMMAND_STATUS
|
||||
)
|
||||
)
|
||||
return int(result["status"])
|
||||
|
||||
def set_alarm_on():
|
||||
result = client.get_state(
|
||||
ALARM_STATUS_URL.format(monitor_id=monitor_id, command=ALARM_COMMAND_ON)
|
||||
)
|
||||
return result["status"]
|
||||
|
||||
def set_alarm_off():
|
||||
result = client.get_state(
|
||||
ALARM_STATUS_URL.format(
|
||||
monitor_id=monitor_id, command=ALARM_COMMAND_OFF
|
||||
)
|
||||
)
|
||||
return result["status"]
|
||||
|
||||
if get_alarm_status() == 0:
|
||||
set_alarm_on()
|
||||
hass.data[DOMAIN][zm_id][monitor_id] = DELAY
|
||||
|
||||
while hass.data[DOMAIN][zm_id][monitor_id] > 0:
|
||||
sleep(1)
|
||||
hass.data[DOMAIN][zm_id][monitor_id] -= 1
|
||||
|
||||
set_alarm_off()
|
||||
else:
|
||||
hass.data[DOMAIN][zm_id][monitor_id] += DELAY
|
||||
|
||||
hass.services.register(
|
||||
DOMAIN,
|
||||
SERVICE_TRIGGER_ALARM_STATE,
|
||||
trigger_alarm_state,
|
||||
schema=TRIGGER_ALARM_SCHEMA,
|
||||
)
|
||||
|
||||
platforms = (Platform.SWITCH, Platform.SENSOR)
|
||||
for platform in platforms:
|
||||
hass.async_create_task(async_load_platform(hass, platform, DOMAIN, {}, config))
|
||||
|
||||
return True
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"domain": "zoneminder_alarm",
|
||||
"name": "Zoneminder Alarm",
|
||||
"documentation": "",
|
||||
"dependencies": [],
|
||||
"codeowners": [],
|
||||
"requirements": [
|
||||
"zm-py"
|
||||
],
|
||||
"iot_class": "local_polling",
|
||||
"version": "0.1.0"
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
"""Support for ZoneMinder switches."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from zoneminder.monitor import Monitor
|
||||
from zoneminder.zm import ZoneMinder
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorEntity,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
from homeassistant.components.zoneminder import DOMAIN as ZONEMINDER_DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def setup_platform(
|
||||
hass: HomeAssistant,
|
||||
config: ConfigType, # pylint: disable=unused-argument
|
||||
add_entities: AddEntitiesCallback,
|
||||
discovery_info: DiscoveryInfoType | None = None, # pylint: disable=unused-argument
|
||||
) -> None:
|
||||
"""Set up the ZoneMinder switch platform."""
|
||||
sensors = []
|
||||
for zm_client in hass.data[ZONEMINDER_DOMAIN].values():
|
||||
if not (monitors := zm_client.get_monitors()):
|
||||
_LOGGER.warning("Could not fetch monitors from ZoneMinder")
|
||||
return
|
||||
|
||||
for monitor in monitors:
|
||||
sensors.append(ZMSensorAlarm(zm_client, monitor))
|
||||
add_entities(sensors)
|
||||
|
||||
|
||||
class ZMSensorAlarm(SensorEntity):
|
||||
"""Representation of a Sensor."""
|
||||
|
||||
def __init__(self, client: ZoneMinder, monitor: Monitor):
|
||||
"""Initialize the switch."""
|
||||
self._client = client
|
||||
self._monitor = monitor
|
||||
self._state = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the switch."""
|
||||
return f"{self._monitor.name} Alarm Status"
|
||||
|
||||
def update(self):
|
||||
"""Update the switch value."""
|
||||
data = self._get_data("status")
|
||||
state = int(data["status"])
|
||||
if state == 0:
|
||||
self._state = "Normal"
|
||||
if state == 1:
|
||||
self._state = "Warnung"
|
||||
if state == 2:
|
||||
self._state = "Alarm"
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
return self._state
|
||||
|
||||
def _get_data(self, command: str):
|
||||
return self._client.get_state(
|
||||
f"api/monitors/alarm/id:{self._monitor.id}/command:{command}.json"
|
||||
)
|
|
@ -0,0 +1,15 @@
|
|||
trigger_alarm_state:
|
||||
description: Trigger alarm in Zoneminder for monitor id.
|
||||
fields:
|
||||
name:
|
||||
description: Zoneminder hostname
|
||||
required: true
|
||||
example: default
|
||||
selector:
|
||||
text:
|
||||
id:
|
||||
description: Monitor ID
|
||||
required: true
|
||||
example: 1
|
||||
selector:
|
||||
text:
|
|
@ -0,0 +1,79 @@
|
|||
"""Support for ZoneMinder switches."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from zoneminder.monitor import Monitor
|
||||
from zoneminder.zm import ZoneMinder
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
from homeassistant.components.zoneminder import DOMAIN as ZONEMINDER_DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def setup_platform(
|
||||
hass: HomeAssistant,
|
||||
config: ConfigType, # pylint: disable=unused-argument
|
||||
add_entities: AddEntitiesCallback,
|
||||
discovery_info: DiscoveryInfoType | None = None, # pylint: disable=unused-argument
|
||||
) -> None:
|
||||
"""Set up the ZoneMinder switch platform."""
|
||||
switches = []
|
||||
for zm_client in hass.data[ZONEMINDER_DOMAIN].values():
|
||||
if not (monitors := zm_client.get_monitors()):
|
||||
_LOGGER.warning("Could not fetch monitors from ZoneMinder")
|
||||
return
|
||||
|
||||
for monitor in monitors:
|
||||
switches.append(ZMSwitchMonitors(zm_client, monitor))
|
||||
add_entities(switches)
|
||||
|
||||
|
||||
class ZMSwitchMonitors(SwitchEntity):
|
||||
"""Representation of a ZoneMinder switch."""
|
||||
|
||||
icon = "mdi:alarm-bell"
|
||||
|
||||
def __init__(self, client: ZoneMinder, monitor: Monitor):
|
||||
"""Initialize the switch."""
|
||||
self._client = client
|
||||
self._monitor = monitor
|
||||
self._state = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the switch."""
|
||||
return f"{self._monitor.name} Alarm Status"
|
||||
|
||||
def update(self):
|
||||
"""Update the switch value."""
|
||||
data = self._get_data("status")
|
||||
self._state = int(data["status"]) > 0
|
||||
|
||||
def _get_data(self, command: str):
|
||||
return self._client.get_state(
|
||||
f"api/monitors/alarm/id:{self._monitor.id}/command:{command}.json"
|
||||
)
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return True if entity is on."""
|
||||
return self._state
|
||||
|
||||
def turn_on(self, **kwargs):
|
||||
"""Turn the entity on."""
|
||||
result = self._get_data("on")
|
||||
data = self._get_data("status")
|
||||
self._state = int(data["status"]) > 0
|
||||
return result
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
"""Turn the entity off."""
|
||||
result = self._get_data("off")
|
||||
data = self._get_data("status")
|
||||
self._state = int(data["status"]) > 0
|
||||
return result
|
Loading…
Reference in New Issue