Skip to content

Commit

Permalink
Merge pull request #16 from jaroschek/release/1.1.x
Browse files Browse the repository at this point in the history
Release 1.1.1
  • Loading branch information
jaroschek authored Sep 22, 2024
2 parents dcfb9ee + 82932b7 commit edc4472
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 34 deletions.
68 changes: 43 additions & 25 deletions custom_components/eaton_epdu/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@

import logging

from pysnmp.error import PySnmpError
import pysnmp.hlapi.asyncio as hlapi
from pysnmp.hlapi.asyncio import SnmpEngine

from homeassistant.components.snmp import async_get_snmp_engine
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant

from .const import (
ATTR_AUTH_KEY,
Expand Down Expand Up @@ -58,13 +57,26 @@ def __init__(self, entry: ConfigEntry, snmpEngine: SnmpEngine) -> None:
"""Init the SnmpApi."""
self._snmpEngine = snmpEngine

self._target = hlapi.UdpTransportTarget(
(
entry.data.get(ATTR_HOST),
entry.data.get(ATTR_PORT, SNMP_PORT_DEFAULT),
),
10,
)
try:
self._target = hlapi.UdpTransportTarget(
(
entry.data.get(ATTR_HOST),
entry.data.get(ATTR_PORT, SNMP_PORT_DEFAULT),
),
10,
)
except PySnmpError:
try:
self._target = hlapi.Udp6TransportTarget(
(
entry.data.get(ATTR_HOST),
entry.data.get(ATTR_PORT, SNMP_PORT_DEFAULT),
),
10,
)
except PySnmpError as err:
_LOGGER.error("Invalid SNMP host: %s", err)
return

self._version = entry.data.get(ATTR_VERSION)
if self._version == SnmpVersion.V1:
Expand All @@ -90,27 +102,33 @@ def construct_object_types(list_of_oids):

async def get(self, oids) -> dict:
"""Get data for given OIDs in a single call."""
_LOGGER.debug("Get OID(s) %s", oids)
result = []
error_indication, error_status, error_index, var_binds = await hlapi.getCmd(
self._snmpEngine,
self._credentials,
self._target,
hlapi.ContextData(),
*__class__.construct_object_types(oids),
)
while len(oids):
_LOGGER.debug("Get OID(s) %s", oids)

error_indication, error_status, error_index, var_binds = await hlapi.getCmd(
self._snmpEngine,
self._credentials,
self._target,
hlapi.ContextData(),
*__class__.construct_object_types(oids),
)

if error_index:
_LOGGER.debug("Remove error index %d", error_index - 1)
oids.pop(error_index - 1)
continue

if error_indication or error_status:
raise RuntimeError(
f"Got SNMP error: {error_indication} {error_status} {error_index}"
)

if not error_indication and not error_status:
items = {}
for var_bind in var_binds:
items[str(var_bind[0])] = __class__.cast(var_bind[1])
result.append(items)
else:
raise RuntimeError(
"Got SNMP error: {error_indication} {error_status} {error_index}"
)
return items

return result[0]
return []

async def get_bulk(
self,
Expand Down
23 changes: 17 additions & 6 deletions custom_components/eaton_epdu/entity.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Definition of base Eaton ePDU Entity."""

from __future__ import annotations

from homeassistant.helpers.entity import DeviceInfo
Expand Down Expand Up @@ -28,6 +29,20 @@ def get_unit_data(self, oid: str, default=None):
"""Fetch data from coordinator for current unit."""
return self.coordinator.data.get(oid.replace("unit", self._unit), default)

@property
def identifier(self):
"""Return the device identifier."""
return self.get_unit_data(
SNMP_OID_UNITS_SERIAL_NUMBER,
self.get_unit_data(
SNMP_OID_UNITS_DEVICE_NAME,
self.get_unit_data(
SNMP_OID_UNITS_PART_NUMBER,
self.get_unit_data(SNMP_OID_UNITS_PRODUCT_NAME),
),
),
)

@property
def device_info(self):
"""Return the device_info of the device."""
Expand All @@ -39,14 +54,10 @@ def device_info(self):
name = self.get_unit_data(SNMP_OID_UNITS_PART_NUMBER)

return DeviceInfo(
identifiers={
(
DOMAIN,
self.get_unit_data(SNMP_OID_UNITS_SERIAL_NUMBER),
)
},
identifiers={(DOMAIN, self.identifier)},
manufacturer=MANUFACTURER,
model=model,
name=name,
serial_number=self.get_unit_data(SNMP_OID_UNITS_SERIAL_NUMBER),
sw_version=self.get_unit_data(SNMP_OID_UNITS_FIRMWARE_VERSION),
)
3 changes: 2 additions & 1 deletion custom_components/eaton_epdu/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"domain": "eaton_epdu",
"name": "Eaton ePDU",
"after_dependencies": ["snmp"],
"codeowners": ["@jaroschek"],
"config_flow": true,
"dependencies": [],
Expand All @@ -10,6 +11,6 @@
"issue_tracker": "https://github.com/jaroschek/home-assistant-eaton-epdu/issues",
"requirements": ["pysnmp==6.2.5"],
"ssdp": [],
"version": "1.1.0",
"version": "1.1.1",
"zeroconf": []
}
4 changes: 2 additions & 2 deletions custom_components/eaton_epdu/sensor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Support for Eaton ePDU sensors."""

from __future__ import annotations

from datetime import timedelta
Expand Down Expand Up @@ -31,7 +32,6 @@
SNMP_OID_OUTLETS_WATTS,
SNMP_OID_UNITS_INPUT_COUNT,
SNMP_OID_UNITS_OUTLET_COUNT,
SNMP_OID_UNITS_SERIAL_NUMBER,
)
from .coordinator import SnmpCoordinator
from .entity import SnmpEntity
Expand Down Expand Up @@ -100,7 +100,7 @@ def __init__(self, coordinator: SnmpCoordinator, unit: str, index: str) -> None:
self._attr_name = (
f"{device_name} {self._name_prefix} {sensor_name} {self._name_suffix}"
)
self._attr_unique_id = f"{DOMAIN}_{self.get_unit_data(SNMP_OID_UNITS_SERIAL_NUMBER)}_{self._value_oid}"
self._attr_unique_id = f"{DOMAIN}_{self.identifier}_{self._value_oid}"
self._attr_native_value = self.coordinator.data.get(
self._value_oid, self._default_value
)
Expand Down

0 comments on commit edc4472

Please sign in to comment.