Skip to content

Commit

Permalink
joined alarm host ip and host name entities (#258)
Browse files Browse the repository at this point in the history
  • Loading branch information
maciej-or authored Nov 26, 2024
1 parent 300ecc3 commit 9a7bdf6
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 41 deletions.
23 changes: 18 additions & 5 deletions custom_components/hikvision_next/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from contextlib import suppress
import logging
import traceback

from homeassistant.util import slugify
from homeassistant.components.binary_sensor import (
ENTITY_ID_FORMAT as BINARY_SENSOR_ENTITY_ID_FORMAT,
)
Expand Down Expand Up @@ -130,12 +130,25 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry):

config_entry.version = 2

_LOGGER.debug(
"Migration to version %s.%s successful",
config_entry.version,
config_entry.minor_version,
# 2 -> 3: Delete previous alaram server sensor entities
if config_entry.version == 2:
old_keys = ["protocoltype", "ipaddress", "portno", "url"]
entity_registry = er.async_get(hass)
for key in old_keys:
entity_id = f"sensor.{slugify(config_entry.unique_id)}_alarm_server_{key}"
entity_registry.async_remove(entity_id)

hass.config_entries.async_update_entry(
config_entry,
version=3,
)

_LOGGER.debug(
"Migration to version %s.%s successful",
config_entry.version,
config_entry.minor_version,
)

return True


Expand Down
2 changes: 1 addition & 1 deletion custom_components/hikvision_next/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
class HikvisionConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for hikvision device."""

VERSION = 2
VERSION = 3
_entry: HikvisionConfigEntry

async def get_schema(self, user_input: dict[str, Any]):
Expand Down
8 changes: 7 additions & 1 deletion custom_components/hikvision_next/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,13 @@ async def _async_update_data(self):
try:
if self.device.capabilities.support_alarm_server:
alarm_server = await self.device.get_alarm_server()
data[CONF_ALARM_SERVER_HOST] = alarm_server
data[CONF_ALARM_SERVER_HOST] = {
"protocol_type": alarm_server.protocol_type,
"address": alarm_server.ip_address or alarm_server.host_name,
"port_no": alarm_server.port_no,
"path": alarm_server.url,

}
except Exception as ex: # pylint: disable=broad-except
self.device.handle_exception(ex, f"Cannot fetch state for {CONF_ALARM_SERVER_HOST}")
return data
8 changes: 4 additions & 4 deletions custom_components/hikvision_next/isapi/isapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,11 +564,11 @@ async def get_alarm_server(self) -> AlarmServer | None:
host = self._get_event_notification_host(data)

return AlarmServer(
ipAddress=host.get("ipAddress"),
portNo=int(host.get("portNo")),
ip_address=host.get("ipAddress"),
port_no=int(host.get("portNo")),
url=host.get("url"),
protocolType=host.get("protocolType"),
hostName=host.get("hostName"),
protocol_type=host.get("protocolType"),
host_name=host.get("hostName"),
)

async def set_alarm_server(self, base_url: str, path: str) -> None:
Expand Down
11 changes: 5 additions & 6 deletions custom_components/hikvision_next/isapi/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
class AlarmServer:
"""Holds alarm server info."""

# Uses pylint invalid names to not break previous versions
ipAddress: str # pylint: disable=invalid-name
hostName: str # pylint: disable=invalid-name
portNo: int # pylint: disable=invalid-name
url: str # pylint: disable=invalid-name
protocolType: str # pylint: disable=invalid-name
ip_address: str
host_name: str
port_no: int
url: str
protocol_type: str


@dataclass
Expand Down
17 changes: 8 additions & 9 deletions custom_components/hikvision_next/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@
from .const import CONF_ALARM_SERVER_HOST, SECONDARY_COORDINATOR
from .isapi import StorageInfo

NOTIFICATION_HOST_KEYS = {
"protocolType": "protocol_type",
"ipAddress": "ip_address",
"hostName": "hostname",
"portNo": "port_no",
"url": "url",
}
NOTIFICATION_HOST_KEYS = [
"protocol_type",
"address", # ip_address or host_name
"port_no",
"path",
]


async def async_setup_entry(
Expand Down Expand Up @@ -56,14 +55,14 @@ def __init__(self, coordinator, key: str) -> None:
self._attr_unique_id = f"{device.device_info.serial_no}_{CONF_ALARM_SERVER_HOST}_{key}"
self.entity_id = ENTITY_ID_FORMAT.format(self.unique_id)
self._attr_device_info = device.hass_device_info()
self._attr_translation_key = f"notifications_host_{NOTIFICATION_HOST_KEYS[key]}"
self._attr_translation_key = f"notifications_host_{key}"
self.key = key

@property
def native_value(self) -> str | None:
"""Return the state of the sensor."""
host = self.coordinator.data.get(CONF_ALARM_SERVER_HOST)
return getattr(host, self.key) if host else None
return host.get(self.key)


class StorageSensor(CoordinatorEntity, SensorEntity):
Expand Down
6 changes: 3 additions & 3 deletions custom_components/hikvision_next/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,13 @@
"notifications_host_protocol_type": {
"name": "Notifications Host Protocol"
},
"notifications_host_ip_address": {
"name": "Notifications Host IP"
"notifications_host_address": {
"name": "Notifications Host"
},
"notifications_host_port_no": {
"name": "Notifications Host Port"
},
"notifications_host_url": {
"notifications_host_path": {
"name": "Notifications Host Path"
}
},
Expand Down
4 changes: 2 additions & 2 deletions custom_components/hikvision_next/translations/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@
"name": "Host powiadomień protokół"
},
"notifications_host_ip_address": {
"name": "Host powiadomień IP"
"name": "Host powiadomień"
},
"notifications_host_port_no": {
"name": "Host powiadomień port"
},
"notifications_host_url": {
"notifications_host_path": {
"name": "Host powiadomień ścieżka"
}
},
Expand Down
4 changes: 2 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def mock_config_entry(request) -> MockConfigEntry:
return MockConfigEntry(
domain=DOMAIN,
data=config,
version=2
version=3
)


Expand Down Expand Up @@ -150,7 +150,7 @@ async def init_multi_device_integration(respx_mock, request, mock_isapi, hass: H
config_entry = MockConfigEntry(
domain=DOMAIN,
data=device['config'],
version=2
version=3
)
model = device['model']
mock_device_endpoints(model, device['config'][CONF_HOST])
Expand Down
16 changes: 8 additions & 8 deletions tests/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ async def test_sensor_value(
"""Test sensors value."""

for entity_id, state in [
("sensor.ds_7608nxi_i0_0p_s0000000000ccrrj00000000wcvu_alarm_server_ipaddress", "1.0.0.159"),
("sensor.ds_7608nxi_i0_0p_s0000000000ccrrj00000000wcvu_alarm_server_portno", "8123"),
("sensor.ds_7608nxi_i0_0p_s0000000000ccrrj00000000wcvu_alarm_server_url", "/api/hikvision"),
("sensor.ds_7608nxi_i0_0p_s0000000000ccrrj00000000wcvu_alarm_server_protocoltype", "HTTP"),
("sensor.ds_7608nxi_i0_0p_s0000000000ccrrj00000000wcvu_alarm_server_address", "1.0.0.159"),
("sensor.ds_7608nxi_i0_0p_s0000000000ccrrj00000000wcvu_alarm_server_port_no", "8123"),
("sensor.ds_7608nxi_i0_0p_s0000000000ccrrj00000000wcvu_alarm_server_path", "/api/hikvision"),
("sensor.ds_7608nxi_i0_0p_s0000000000ccrrj00000000wcvu_alarm_server_protocol_type", "HTTP"),
("sensor.ds_7608nxi_i0_0p_s0000000000ccrrj00000000wcvu_1_hdd1", "OK"),
]:
assert (sensor := hass.states.get(entity_id))
Expand All @@ -31,10 +31,10 @@ async def test_sensor_value_outside_network(
"""Test sensors value."""

for entity_id, state in [
("sensor.ds_2cd2t86g2_isu_sl00000000aawrae0000000_alarm_server_hostname", "ha.hostname.domain"),
("sensor.ds_2cd2t86g2_isu_sl00000000aawrae0000000_alarm_server_portno", "443"),
("sensor.ds_2cd2t86g2_isu_sl00000000aawrae0000000_alarm_server_url", "/api/hikvision"),
("sensor.ds_2cd2t86g2_isu_sl00000000aawrae0000000_alarm_server_protocoltype", "HTTPS"),
("sensor.ds_2cd2t86g2_isu_sl00000000aawrae0000000_alarm_server_address", "ha.hostname.domain"),
("sensor.ds_2cd2t86g2_isu_sl00000000aawrae0000000_alarm_server_port_no", "443"),
("sensor.ds_2cd2t86g2_isu_sl00000000aawrae0000000_alarm_server_path", "/api/hikvision"),
("sensor.ds_2cd2t86g2_isu_sl00000000aawrae0000000_alarm_server_protocol_type", "HTTPS"),
("sensor.ds_2cd2t86g2_isu_sl00000000aawrae0000000_1_hdde", "OK"),
]:
assert (sensor := hass.states.get(entity_id))
Expand Down

0 comments on commit 9a7bdf6

Please sign in to comment.