-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsensor.py
132 lines (110 loc) · 4.39 KB
/
sensor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import logging
import sys
import async_timeout
from .const import (
DOMAIN,
CONF_CLIENT,
CONF_IP,
CONF_PLATFORM,
CONF_UPDATE_INTERVAL
)
from homeassistant.core import callback
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorStateClass,
SensorEntityDescription
)
from datetime import timedelta
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
UpdateFailed,
)
from homeassistant.const import (PERCENTAGE, UnitOfElectricPotential, UnitOfPower, UnitOfElectricCurrent)
_LOGGER = logging.getLogger(__name__)
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
steca = hass.data[DOMAIN][CONF_CLIENT]
update_interval = hass.data[DOMAIN][CONF_UPDATE_INTERVAL]
coordinator = StecaCoordinator(hass, steca, update_interval)
await coordinator.async_config_entry_first_refresh()
entities = [
StecaGridSensor(coordinator, steca, SensorEntityDescription(
key="acpower",
name="AC Power",
native_unit_of_measurement=UnitOfPower.WATT,
device_class=SensorDeviceClass.POWER,
state_class=SensorStateClass.MEASUREMENT,
)),
StecaGridSensor(coordinator, steca, SensorEntityDescription(
key="acvoltage",
name="AC Voltage",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
state_class=SensorStateClass.MEASUREMENT,
)),
StecaGridSensor(coordinator, steca, SensorEntityDescription(
key="accurrent",
name="AC Current",
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
device_class=SensorDeviceClass.CURRENT,
state_class=SensorStateClass.MEASUREMENT,
)),
StecaGridSensor(coordinator, steca, SensorEntityDescription(
key="dcvoltage",
name="DC Voltage",
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
device_class=SensorDeviceClass.VOLTAGE,
state_class=SensorStateClass.MEASUREMENT,
)),
StecaGridSensor(coordinator, steca, SensorEntityDescription(
key="dccurrent",
name="DC Current",
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
device_class=SensorDeviceClass.CURRENT,
state_class=SensorStateClass.MEASUREMENT,
)),
StecaGridSensor(coordinator, steca, SensorEntityDescription(
key="derating",
name="Derating",
native_unit_of_measurement=PERCENTAGE,
device_class=None,
state_class=SensorStateClass.MEASUREMENT,
))
]
async_add_entities(entities)
class StecaCoordinator(DataUpdateCoordinator):
def __init__(self, hass, steca, interval):
super().__init__(
hass,
_LOGGER,
# Name of the data. For logging purposes.
name="StecaGrid Inverter",
# Polling interval. Will only be polled if there are subscribers.
update_interval=timedelta(seconds=interval),
)
self.steca = steca
async def _async_update_data(self):
for x in range(5):
_LOGGER.info("Attempting to poll stecagrid %i / 5", (x+1))
try:
# Note: asyncio.TimeoutError and aiohttp.ClientError are already
# handled by the data update coordinator.
async with async_timeout.timeout(10):
return await self.hass.async_add_executor_job(self.steca.poll)
except:
_LOGGER.error("Error talking to StecaGrid inverter: %s", sys.exc_info())
class StecaGridSensor(CoordinatorEntity, SensorEntity):
def __init__(self, coordinator, steca, description):
super().__init__(coordinator)
self.entity_description = description
self._attr_name = f"Steca Inverter {steca.getIp()} {description.name}"
self._attr_unique_id = f"steca_inverter_{steca.getSerial()}_{description.key}"
@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._attr_native_value = self.coordinator.data[self.entity_description.key]
self.async_write_ha_state()
@property
def should_poll(self):
return False