1 """Support for the sensors in a GreenEye Monitor."""
3 from __future__
import annotations
13 CONF_TEMPERATURE_UNIT,
14 UnitOfElectricPotential,
24 CONF_COUNTED_QUANTITY,
25 CONF_COUNTED_QUANTITY_PER_PULSE,
31 CONF_TEMPERATURE_SENSORS,
34 DATA_GREENEYE_MONITOR,
37 DATA_PULSES =
"pulses"
38 DATA_WATT_SECONDS =
"watt_seconds"
40 COUNTER_ICON =
"mdi:counter"
46 async_add_entities: AddEntitiesCallback,
47 discovery_info: DiscoveryInfoType |
None =
None,
49 """Set up a single GEM temperature sensor."""
50 if not discovery_info:
53 monitor_configs = discovery_info[CONF_MONITORS]
55 def on_new_monitor(monitor: greeneye.monitor.Monitor) ->
None:
56 monitor_config = next(
58 lambda monitor_config: monitor_config[CONF_SERIAL_NUMBER]
59 == monitor.serial_number,
65 channel_configs = monitor_config[CONF_CHANNELS]
66 entities: list[GEMSensor] = [
71 sensor[CONF_NET_METERING],
73 for sensor
in channel_configs
76 pulse_counter_configs = monitor_config[CONF_PULSE_COUNTERS]
82 sensor[CONF_COUNTED_QUANTITY],
83 sensor[CONF_TIME_UNIT],
84 sensor[CONF_COUNTED_QUANTITY_PER_PULSE],
86 for sensor
in pulse_counter_configs
89 temperature_sensor_configs = monitor_config[CONF_TEMPERATURE_SENSORS]
95 temperature_sensor_configs[CONF_TEMPERATURE_UNIT],
97 for sensor
in temperature_sensor_configs[CONF_SENSORS]
100 voltage_sensor_configs = monitor_config[CONF_VOLTAGE_SENSORS]
102 VoltageSensor(monitor, sensor[CONF_NUMBER], sensor[CONF_NAME])
103 for sensor
in voltage_sensor_configs
107 monitor_configs.remove(monitor_config)
109 if len(monitor_configs) == 0:
110 monitors.remove_listener(on_new_monitor)
112 monitors: greeneye.Monitors = hass.data[DATA_GREENEYE_MONITOR]
113 monitors.add_listener(on_new_monitor)
114 for monitor
in monitors.monitors.values():
115 on_new_monitor(monitor)
118 type UnderlyingSensorType = (
119 greeneye.monitor.Channel
120 | greeneye.monitor.PulseCounter
121 | greeneye.monitor.TemperatureSensor
122 | greeneye.monitor.VoltageSensor
127 """Base class for GreenEye Monitor sensors."""
129 _attr_should_poll =
False
133 monitor: greeneye.monitor.Monitor,
136 sensor: UnderlyingSensorType,
139 """Construct the entity."""
144 self._sensor: UnderlyingSensorType = sensor
147 f
"{self._monitor_serial_number}-{self._sensor_type}-{self._number}"
151 """Wait for and connect to the sensor."""
155 """Remove listener from the sensor."""
161 """Entity showing power usage on one channel of the monitor."""
163 _attr_native_unit_of_measurement = UnitOfPower.WATT
164 _attr_device_class = SensorDeviceClass.POWER
168 monitor: greeneye.monitor.Monitor,
173 """Construct the entity."""
174 super().
__init__(monitor, name,
"current", monitor.channels[number - 1], number)
175 self._sensor: greeneye.monitor.Channel = self._sensor
180 """Return the current number of watts being used by the channel."""
181 return self._sensor.watts
185 """Return total wattseconds in the state dictionary."""
187 watt_seconds = self._sensor.polarized_watt_seconds
189 watt_seconds = self._sensor.absolute_watt_seconds
191 return {DATA_WATT_SECONDS: watt_seconds}
195 """Entity showing rate of change in one pulse counter of the monitor."""
197 _attr_icon = COUNTER_ICON
201 monitor: greeneye.monitor.Monitor,
204 counted_quantity: str,
206 counted_quantity_per_pulse: float,
208 """Construct the entity."""
210 monitor, name,
"pulse", monitor.pulse_counters[number - 1], number
212 self._sensor: greeneye.monitor.PulseCounter = self._sensor
219 """Return the current rate of change for the given pulse counter."""
220 if self._sensor.pulses_per_second
is None:
224 self._sensor.pulses_per_second
231 """Return the number of seconds in the given display time unit."""
232 if self.
_time_unit_time_unit == UnitOfTime.SECONDS:
234 if self.
_time_unit_time_unit == UnitOfTime.MINUTES:
236 if self.
_time_unit_time_unit == UnitOfTime.HOURS:
241 f
"Invalid value for time unit: {self._time_unit}. Expected one of"
242 f
" {UnitOfTime.SECONDS}, {UnitOfTime.MINUTES}, or {UnitOfTime.HOURS}"
247 """Return total pulses in the data dictionary."""
248 return {DATA_PULSES: self._sensor.pulses}
252 """Entity showing temperature from one temperature sensor."""
254 _attr_device_class = SensorDeviceClass.TEMPERATURE
257 self, monitor: greeneye.monitor.Monitor, number: int, name: str, unit: str
259 """Construct the entity."""
261 monitor, name,
"temp", monitor.temperature_sensors[number - 1], number
263 self._sensor: greeneye.monitor.TemperatureSensor = self._sensor
268 """Return the current temperature being reported by this sensor."""
269 return self._sensor.temperature
273 """Entity showing voltage."""
275 _attr_native_unit_of_measurement = UnitOfElectricPotential.VOLT
276 _attr_device_class = SensorDeviceClass.VOLTAGE
279 self, monitor: greeneye.monitor.Monitor, number: int, name: str
281 """Construct the entity."""
282 super().
__init__(monitor, name,
"volts", monitor.voltage_sensor, number)
283 self._sensor: greeneye.monitor.VoltageSensor = self._sensor
287 """Return the current voltage being reported by this sensor."""
288 return self._sensor.voltage
None __init__(self, greeneye.monitor.Monitor monitor, int number, str name, bool net_metering)
float|None native_value(self)
dict[str, Any]|None extra_state_attributes(self)
None async_added_to_hass(self)
None async_will_remove_from_hass(self)
None __init__(self, greeneye.monitor.Monitor monitor, str name, str sensor_type, UnderlyingSensorType sensor, int number)
None __init__(self, greeneye.monitor.Monitor monitor, int number, str name, str counted_quantity, str time_unit, float counted_quantity_per_pulse)
dict[str, Any] extra_state_attributes(self)
int _seconds_per_time_unit(self)
_counted_quantity_per_pulse
float|None native_value(self)
_attr_native_unit_of_measurement
None __init__(self, greeneye.monitor.Monitor monitor, int number, str name, str unit)
float|None native_value(self)
_attr_native_unit_of_measurement
None __init__(self, greeneye.monitor.Monitor monitor, int number, str name)
float|None native_value(self)
None async_write_ha_state(self)
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback async_add_entities, DiscoveryInfoType|None discovery_info=None)