Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IO events v2 #91

Merged
merged 4 commits into from
Jul 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 8 additions & 22 deletions custom_components/hikvision_next/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import DATA_ISAPI, DOMAIN, EVENTS
from .isapi import ISAPI, AnalogCamera, EventInfo, IPCamera
from .isapi import EventInfo


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback) -> None:
Expand All @@ -22,39 +22,25 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
# Camera Events
for camera in isapi.cameras:
for event in camera.supported_events:
entities.append(CameraEventBinarySensor(isapi, camera, event))
entities.append(EventBinarySensor(isapi, camera.id, event))

# NVR Events
if isapi.device_info.is_nvr:
for io_event in isapi.device_info.supported_events:
entities.append(NVREventBinarySensor(isapi, io_event))
for event in isapi.device_info.supported_events:
entities.append(EventBinarySensor(isapi, 0, event))

async_add_entities(entities)


class CameraEventBinarySensor(BinarySensorEntity):
class EventBinarySensor(BinarySensorEntity):
"""Event detection sensor."""

_attr_has_entity_name = True
_attr_is_on = False

def __init__(self, isapi, camera: AnalogCamera | IPCamera, event: EventInfo) -> None:
def __init__(self, isapi, device_id: int, event: EventInfo) -> None:
self.entity_id = ENTITY_ID_FORMAT.format(event.unique_id)
self._attr_unique_id = self.entity_id
self._attr_name = EVENTS[event.id]["label"]
self._attr_name = f"{EVENTS[event.id]['label']}{' ' + str(event.io_port_id) if event.io_port_id != 0 else ''}"
self._attr_device_class = EVENTS[event.id]["device_class"]
self._attr_device_info = isapi.get_device_info(camera.id)


class NVREventBinarySensor(BinarySensorEntity):
"""IO Event detection sensor."""

_attr_has_entity_name = True
_attr_is_on = False

def __init__(self, isapi: ISAPI, event: EventInfo) -> None:
self.entity_id = ENTITY_ID_FORMAT.format(event.unique_id)
self._attr_unique_id = self.entity_id
self._attr_name = f"{EVENTS[event.id]['label']} {event.channel_id}"
self._attr_device_class = EVENTS[event.id]["device_class"]
self._attr_device_info = isapi.get_device_info(0)
self._attr_device_info = isapi.get_device_info(device_id)
15 changes: 7 additions & 8 deletions custom_components/hikvision_next/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@
HOLIDAY_MODE_SWITCH_LABEL = "Holiday mode"
ALARM_SERVER_SENSOR_LABEL_FORMAT = "Alarm Server {}"

DEVICE_TYPE_IP_CAMERA = "IPCamera"
DEVICE_TYPE_ANALOG_CAMERA = "AnalogCamera"
DEVICE_TYPE_NVR = "NVR"
CONNECTION_TYPE_DIRECT = "Direct"
CONNECTION_TYPE_PROXIED = "Proxied"

HIKVISION_EVENT = f"{DOMAIN}_event"
EVENT_BASIC: Final = "basic"
EVENT_NVR_BASIC: Final = "nvr_basic"
EVENT_IO: Final = "io"
EVENT_SMART: Final = "smart"
EVENTS = {
"motiondetection": {
Expand Down Expand Up @@ -81,11 +80,11 @@
"device_class": BinarySensorDeviceClass.MOTION,
},
"io": {
"type": EVENT_NVR_BASIC,
"type": EVENT_IO,
"label": "Alarm Input",
"channel_attr": "inputIOPortID",
"url_path": "IO/inputs",
"slug": "IOInputPort",
"slug": "inputs",
"direct_node": "IOInputPort",
"proxied_node": "IOProxyInputPort",
"device_class": BinarySensorDeviceClass.MOTION
}
}
Expand Down
19 changes: 9 additions & 10 deletions custom_components/hikvision_next/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,15 @@ async def _async_update_data(self):
except Exception as ex: # pylint: disable=broad-except
self.isapi.handle_exception(ex, f"Cannot fetch state for {event.id}")

# Get NVR outputs status
if self.isapi.device_info.is_nvr:
for i in range(1, self.isapi.device_info.output_ports + 1):
try:
entity_id = ENTITY_ID_FORMAT.format(
f"{slugify(self.isapi.device_info.serial_no.lower())}_{i}_alarm_output"
)
data[entity_id] = await self.isapi.get_port_status("output", i)
except Exception as ex: # pylint: disable=broad-except
self.isapi.handle_exception(ex, f"Cannot fetch state for {event.id}")
# Get output port(s) status
for i in range(1, self.isapi.device_info.output_ports + 1):
try:
entity_id = ENTITY_ID_FORMAT.format(
f"{slugify(self.isapi.device_info.serial_no.lower())}_{i}_alarm_output"
)
data[entity_id] = await self.isapi.get_port_status("output", i)
except Exception as ex: # pylint: disable=broad-except
self.isapi.handle_exception(ex, f"Cannot fetch state for {event.id}")

# Refresh HDD data
try:
Expand Down
48 changes: 20 additions & 28 deletions custom_components/hikvision_next/diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,44 +63,36 @@ async def _async_get_diagnostics(
info.update({"Entity Data": to_json(coordinator.data)})

# Add raw device info
info.update(await get_isapi_data("RAW Device Info", isapi.isapi.System.deviceInfo, "DeviceInfo"))

# Add raw camera info
info.update(
await get_isapi_data(
"RAW Analog Camera Info",
isapi.isapi.System.Video.inputs.channels,
"VideoInputChannelList",
)
)
info.update(
await get_isapi_data(
"RAW IP Camera Info",
isapi.isapi.ContentMgmt.InputProxy.channels,
"InputProxyChannelList",
)
)
info.update(await get_isapi_data("RAW Device Info", isapi.isapi.System.deviceInfo))

# Add raw camera info - Direct connected
info.update(await get_isapi_data("RAW Analog Camera Info", isapi.isapi.System.Video.inputs.channels))

# Add raw camera info - Proxy connected
info.update(await get_isapi_data("RAW IP Camera Info", isapi.isapi.ContentMgmt.InputProxy.channels))

# Add raw capabilities
info.update(await get_isapi_data("RAW Capabilities Info", isapi.isapi.System.capabilities, "DeviceCap"))
info.update(await get_isapi_data("RAW Capabilities Info", isapi.isapi.System.capabilities))

# Add raw supported events
info.update(await get_isapi_data("RAW Events Info", isapi.isapi.Event.triggers, ""))
info.update(await get_isapi_data("RAW Events Info", isapi.isapi.Event.triggers))

# Add IO info - direct connected
info.update(await get_isapi_data("Direct IO Inputs", isapi.isapi.System.IO.inputs))
info.update(await get_isapi_data("Direct IO Outputs", isapi.isapi.System.IO.outputs))

# Add IO info - proxy connected
info.update(await get_isapi_data("Proxied IO Inputs", isapi.isapi.ContentMgmt.IOProxy.inputs))
info.update(await get_isapi_data("Proxied IO Outputs", isapi.isapi.ContentMgmt.IOProxy.outputs))

# Add raw streams info
info.update(await get_isapi_data("RAW Streams Info", isapi.isapi.Streaming.channels, "StreamingChannelList"))
info.update(await get_isapi_data("RAW Streams Info", isapi.isapi.Streaming.channels))

# Add raw holiday info
info.update(await get_isapi_data("RAW Holiday Info", isapi.isapi.System.Holidays, "HolidayList"))
info.update(await get_isapi_data("RAW Holiday Info", isapi.isapi.System.Holidays))

# Add alarms server info
info.update(
await get_isapi_data(
"RAW Alarm Server Info",
isapi.isapi.Event.notification.httpHosts,
"HttpHostNotificationList",
)
)
info.update(await get_isapi_data("RAW Alarm Server Info", isapi.isapi.Event.notification.httpHosts))

return info

Expand Down
Loading