mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Migrate SNMP sensor to TemplateEntity (#73324)
This commit is contained in:
parent
8049170e5a
commit
e2327622c3
@ -17,12 +17,11 @@ from pysnmp.hlapi.asyncio import (
|
|||||||
)
|
)
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_NAME,
|
|
||||||
CONF_PORT,
|
CONF_PORT,
|
||||||
CONF_UNIT_OF_MEASUREMENT,
|
CONF_UNIQUE_ID,
|
||||||
CONF_USERNAME,
|
CONF_USERNAME,
|
||||||
CONF_VALUE_TEMPLATE,
|
CONF_VALUE_TEMPLATE,
|
||||||
STATE_UNKNOWN,
|
STATE_UNKNOWN,
|
||||||
@ -30,6 +29,10 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.helpers.template_entity import (
|
||||||
|
TEMPLATE_SENSOR_BASE_SCHEMA,
|
||||||
|
TemplateSensor,
|
||||||
|
)
|
||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -66,9 +69,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||||||
vol.Optional(CONF_COMMUNITY, default=DEFAULT_COMMUNITY): cv.string,
|
vol.Optional(CONF_COMMUNITY, default=DEFAULT_COMMUNITY): cv.string,
|
||||||
vol.Optional(CONF_DEFAULT_VALUE): cv.string,
|
vol.Optional(CONF_DEFAULT_VALUE): cv.string,
|
||||||
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
|
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
|
||||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
|
||||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
|
|
||||||
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
|
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
|
||||||
vol.Optional(CONF_VERSION, default=DEFAULT_VERSION): vol.In(SNMP_VERSIONS),
|
vol.Optional(CONF_VERSION, default=DEFAULT_VERSION): vol.In(SNMP_VERSIONS),
|
||||||
vol.Optional(CONF_USERNAME): cv.string,
|
vol.Optional(CONF_USERNAME): cv.string,
|
||||||
@ -81,7 +82,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||||||
MAP_PRIV_PROTOCOLS
|
MAP_PRIV_PROTOCOLS
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
)
|
).extend(TEMPLATE_SENSOR_BASE_SCHEMA.schema)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
async def async_setup_platform(
|
||||||
@ -91,12 +92,10 @@ async def async_setup_platform(
|
|||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the SNMP sensor."""
|
"""Set up the SNMP sensor."""
|
||||||
name = config.get(CONF_NAME)
|
|
||||||
host = config.get(CONF_HOST)
|
host = config.get(CONF_HOST)
|
||||||
port = config.get(CONF_PORT)
|
port = config.get(CONF_PORT)
|
||||||
community = config.get(CONF_COMMUNITY)
|
community = config.get(CONF_COMMUNITY)
|
||||||
baseoid = config.get(CONF_BASEOID)
|
baseoid = config.get(CONF_BASEOID)
|
||||||
unit = config.get(CONF_UNIT_OF_MEASUREMENT)
|
|
||||||
version = config[CONF_VERSION]
|
version = config[CONF_VERSION]
|
||||||
username = config.get(CONF_USERNAME)
|
username = config.get(CONF_USERNAME)
|
||||||
authkey = config.get(CONF_AUTH_KEY)
|
authkey = config.get(CONF_AUTH_KEY)
|
||||||
@ -105,10 +104,7 @@ async def async_setup_platform(
|
|||||||
privproto = config[CONF_PRIV_PROTOCOL]
|
privproto = config[CONF_PRIV_PROTOCOL]
|
||||||
accept_errors = config.get(CONF_ACCEPT_ERRORS)
|
accept_errors = config.get(CONF_ACCEPT_ERRORS)
|
||||||
default_value = config.get(CONF_DEFAULT_VALUE)
|
default_value = config.get(CONF_DEFAULT_VALUE)
|
||||||
value_template = config.get(CONF_VALUE_TEMPLATE)
|
unique_id = config.get(CONF_UNIQUE_ID)
|
||||||
|
|
||||||
if value_template is not None:
|
|
||||||
value_template.hass = hass
|
|
||||||
|
|
||||||
if version == "3":
|
if version == "3":
|
||||||
|
|
||||||
@ -146,35 +142,30 @@ async def async_setup_platform(
|
|||||||
return
|
return
|
||||||
|
|
||||||
data = SnmpData(request_args, baseoid, accept_errors, default_value)
|
data = SnmpData(request_args, baseoid, accept_errors, default_value)
|
||||||
async_add_entities([SnmpSensor(data, name, unit, value_template)], True)
|
async_add_entities([SnmpSensor(hass, data, config, unique_id)], True)
|
||||||
|
|
||||||
|
|
||||||
class SnmpSensor(SensorEntity):
|
class SnmpSensor(TemplateSensor):
|
||||||
"""Representation of a SNMP sensor."""
|
"""Representation of a SNMP sensor."""
|
||||||
|
|
||||||
def __init__(self, data, name, unit_of_measurement, value_template):
|
_attr_should_poll = True
|
||||||
"""Initialize the sensor."""
|
|
||||||
self.data = data
|
|
||||||
self._name = name
|
|
||||||
self._state = None
|
|
||||||
self._unit_of_measurement = unit_of_measurement
|
|
||||||
self._value_template = value_template
|
|
||||||
|
|
||||||
@property
|
def __init__(self, hass, data, config, unique_id):
|
||||||
def name(self):
|
"""Initialize the sensor."""
|
||||||
"""Return the name of the sensor."""
|
super().__init__(
|
||||||
return self._name
|
hass, config=config, unique_id=unique_id, fallback_name=DEFAULT_NAME
|
||||||
|
)
|
||||||
|
self.data = data
|
||||||
|
self._state = None
|
||||||
|
self._value_template = config.get(CONF_VALUE_TEMPLATE)
|
||||||
|
if (value_template := self._value_template) is not None:
|
||||||
|
value_template.hass = hass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self):
|
def native_value(self):
|
||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
return self._state
|
return self._state
|
||||||
|
|
||||||
@property
|
|
||||||
def native_unit_of_measurement(self):
|
|
||||||
"""Return the unit the value is expressed in."""
|
|
||||||
return self._unit_of_measurement
|
|
||||||
|
|
||||||
async def async_update(self):
|
async def async_update(self):
|
||||||
"""Get the latest data and updates the states."""
|
"""Get the latest data and updates the states."""
|
||||||
await self.data.async_update()
|
await self.data.async_update()
|
||||||
|
@ -1241,6 +1241,9 @@ pysmartapp==0.3.3
|
|||||||
# homeassistant.components.smartthings
|
# homeassistant.components.smartthings
|
||||||
pysmartthings==0.7.6
|
pysmartthings==0.7.6
|
||||||
|
|
||||||
|
# homeassistant.components.snmp
|
||||||
|
pysnmplib==5.0.15
|
||||||
|
|
||||||
# homeassistant.components.soma
|
# homeassistant.components.soma
|
||||||
pysoma==0.0.10
|
pysoma==0.0.10
|
||||||
|
|
||||||
|
1
tests/components/snmp/__init__.py
Normal file
1
tests/components/snmp/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
"""Tests for the SNMP integration."""
|
79
tests/components/snmp/test_sensor.py
Normal file
79
tests/components/snmp/test_sensor.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
"""SNMP sensor tests."""
|
||||||
|
|
||||||
|
from unittest.mock import MagicMock, Mock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def hlapi_mock():
|
||||||
|
"""Mock out 3rd party API."""
|
||||||
|
mock_data = MagicMock()
|
||||||
|
mock_data.prettyPrint = Mock(return_value="hello")
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.snmp.sensor.getCmd",
|
||||||
|
return_value=(None, None, None, [[mock_data]]),
|
||||||
|
):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
async def test_basic_config(hass: HomeAssistant) -> None:
|
||||||
|
"""Test basic entity configuration."""
|
||||||
|
|
||||||
|
config = {
|
||||||
|
SENSOR_DOMAIN: {
|
||||||
|
"platform": "snmp",
|
||||||
|
"host": "192.168.1.32",
|
||||||
|
"baseoid": "1.3.6.1.4.1.2021.10.1.3.1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert await async_setup_component(hass, SENSOR_DOMAIN, config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.snmp")
|
||||||
|
assert state.state == "hello"
|
||||||
|
assert state.attributes == {"friendly_name": "SNMP"}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_entity_config(hass: HomeAssistant) -> None:
|
||||||
|
"""Test entity configuration."""
|
||||||
|
|
||||||
|
config = {
|
||||||
|
SENSOR_DOMAIN: {
|
||||||
|
# SNMP configuration
|
||||||
|
"platform": "snmp",
|
||||||
|
"host": "192.168.1.32",
|
||||||
|
"baseoid": "1.3.6.1.4.1.2021.10.1.3.1",
|
||||||
|
# Entity configuration
|
||||||
|
"icon": "{{'mdi:one_two_three'}}",
|
||||||
|
"picture": "{{'blabla.png'}}",
|
||||||
|
"device_class": "temperature",
|
||||||
|
"name": "{{'SNMP' + ' ' + 'Sensor'}}",
|
||||||
|
"state_class": "measurement",
|
||||||
|
"unique_id": "very_unique",
|
||||||
|
"unit_of_measurement": "beardsecond",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert await async_setup_component(hass, SENSOR_DOMAIN, config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity_registry = er.async_get(hass)
|
||||||
|
assert entity_registry.async_get("sensor.snmp_sensor").unique_id == "very_unique"
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.snmp_sensor")
|
||||||
|
assert state.state == "hello"
|
||||||
|
assert state.attributes == {
|
||||||
|
"device_class": "temperature",
|
||||||
|
"entity_picture": "blabla.png",
|
||||||
|
"friendly_name": "SNMP Sensor",
|
||||||
|
"icon": "mdi:one_two_three",
|
||||||
|
"state_class": "measurement",
|
||||||
|
"unit_of_measurement": "beardsecond",
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user