Skip to content

Commit

Permalink
Reworks sensor to include state and device classes.
Browse files Browse the repository at this point in the history
Sensor names are now human readable and defines entity_id to have qw_ in front for easy grouping.
  • Loading branch information
tanelvakker committed Dec 21, 2024
1 parent cca167c commit 2b02957
Showing 1 changed file with 87 additions and 24 deletions.
111 changes: 87 additions & 24 deletions custom_components/qilowatt/sensor.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,64 @@
# custom_components/qilowatt/sensor.py

import logging

from homeassistant.components.sensor import Entity
from homeassistant.components.sensor import SensorEntity, SensorEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity import DeviceInfo, Entity
from homeassistant.helpers.entity import DeviceInfo, async_generate_entity_id
from qilowatt import WorkModeCommand

from .const import CONF_INVERTER_ID, DATA_CLIENT, DOMAIN

_LOGGER = logging.getLogger(__name__)

ENTITY_ID_FORMAT = "sensor.{}"

# Define the metadata for each field
WORKMODE_FIELDS = {
"Mode": {
"name": "Mode",
"unit_of_measurement": None,
"device_class": None,
"state_class": None,
},
"_source": {
"name": "Source",
"unit_of_measurement": None,
"device_class": None,
"state_class": None,
},
"BatterySoc": {
"name": "Battery State of Charge",
"unit_of_measurement": "%",
"device_class": "battery",
"state_class": "measurement",
},
"PowerLimit": {
"name": "Power Limit",
"unit_of_measurement": "W",
"device_class": "power",
"state_class": "measurement",
},
"PeakShaving": {
"name": "Peak Shaving",
"unit_of_measurement": "W",
"device_class": "power",
"state_class": "measurement",
},
"ChargeCurrent": {
"name": "Charge Current",
"unit_of_measurement": "A",
"device_class": "current",
"state_class": "measurement",
},
"DischargeCurrent": {
"name": "Discharge Current",
"unit_of_measurement": "A",
"device_class": "current",
"state_class": "measurement",
},
}

async def async_setup_entry(
hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities
Expand All @@ -22,36 +68,38 @@ async def async_setup_entry(

# Add sensors for WORKMODE commands
workmode_sensors = []
workmode_fields = [
"Mode",
"_source",
"BatterySoc",
"PowerLimit",
"PeakShaving",
"ChargeCurrent",
"DischargeCurrent",
]
for field in workmode_fields:
for field, metadata in WORKMODE_FIELDS.items():
entity_description = SensorEntityDescription(
key=field,
name=metadata["name"],
unit_of_measurement=metadata["unit_of_measurement"],
device_class=metadata["device_class"],
state_class=metadata["state_class"],
)
sensor = WorkModeSensor(
hass,
inverter_id,
field,
entity_description,
config_entry,
)
workmode_sensors.append(sensor)

async_add_entities(workmode_sensors, update_before_add=True)


class WorkModeSensor(Entity):
class WorkModeSensor(SensorEntity):
"""Sensor for WORKMODE command fields."""

def __init__(self, inverter_id, field_name, entry) -> None:
def __init__(self, hass: HomeAssistant, inverter_id, entity_description: SensorEntityDescription, entry) -> None:
self.hass = hass
self._inverter_id = inverter_id
self._field_name = field_name
self.entity_description = entity_description
self.entry = entry
self._name = field_name
self._unique_id = f"{inverter_id}_{field_name}"
self._name = entity_description.name
self._unique_id = f"{inverter_id}_{entity_description.key}"
self._state = None
self.entity_id = async_generate_entity_id(
ENTITY_ID_FORMAT, f"qw_{entity_description.key}", hass.states.async_entity_ids()
)

@property
def name(self):
Expand All @@ -60,8 +108,8 @@ def name(self):

@property
def unique_id(self):
"""Return the name of the sensor."""
return self._name
"""Return the unique ID of the sensor."""
return self._unique_id

@property
def device_info(self) -> DeviceInfo:
Expand All @@ -79,6 +127,21 @@ def state(self):
"""Return the state of the sensor."""
return self._state

@property
def unit_of_measurement(self):
"""Return the unit of measurement of the sensor."""
return self.entity_description.unit_of_measurement

@property
def device_class(self):
"""Return the device class of the sensor."""
return self.entity_description.device_class

@property
def state_class(self):
"""Return the state class of the sensor."""
return self.entity_description.state_class

async def async_added_to_hass(self):
"""Register dispatcher to listen for WORKMODE updates."""
self.async_on_remove(
Expand All @@ -92,6 +155,6 @@ async def async_added_to_hass(self):
async def _handle_workmode_update(self, command: WorkModeCommand):
"""Handle WORKMODE command updates."""
_LOGGER.debug(f"WorkModeSensor '{self._name}' handling update.")
value = getattr(command, self._field_name, None)
value = getattr(command, self.entity_description.key, None)
self._state = value
self.async_schedule_update_ha_state()
self.async_schedule_update_ha_state()

0 comments on commit 2b02957

Please sign in to comment.