Skip to content

Commit ebd1619

Browse files
committed
Fixed data update issue caused by api errors #28
1 parent 74a81b4 commit ebd1619

File tree

5 files changed

+128
-214
lines changed

5 files changed

+128
-214
lines changed

custom_components/wemportal/number.py

+23-56
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from homeassistant.components.number import NumberEntity
66
from homeassistant.config_entries import ConfigEntry
7-
from homeassistant.core import HomeAssistant
7+
from homeassistant.core import HomeAssistant, callback
88
from homeassistant.helpers.entity_platform import AddEntitiesCallback
99
from homeassistant.helpers.update_coordinator import CoordinatorEntity
1010
from . import get_wemportal_unique_id
@@ -66,18 +66,19 @@ def __init__(
6666
super().__init__(coordinator)
6767
self._config_entry = config_entry
6868
self._device_id = device_id
69-
self._name = _unique_id
70-
self._unique_id = get_wemportal_unique_id(
71-
self._config_entry.entry_id, str(self._device_id), str(self._name)
69+
self._attr_name = _unique_id
70+
self._attr_unique_id = get_wemportal_unique_id(
71+
self._config_entry.entry_id, str(self._device_id), str(self._attr_name)
7272
)
7373
self._last_updated = None
7474
self._parameter_id = entity_data["ParameterID"]
75-
self._icon = entity_data["icon"]
76-
self._unit = entity_data["unit"]
77-
self._state = self.state
75+
self._attr_icon = entity_data["icon"]
76+
self._attr_native_unit_of_measurement = entity_data["unit"]
77+
self._attr_native_value = entity_data["value"]
7878
self._attr_native_min_value = entity_data["min_value"]
7979
self._attr_native_max_value = entity_data["max_value"]
8080
self._attr_native_step = entity_data["step"]
81+
self._attr_should_poll = False
8182
self._module_index = entity_data["ModuleIndex"]
8283
self._module_type = entity_data["ModuleType"]
8384

@@ -91,8 +92,7 @@ async def async_set_native_value(self, value: float) -> None:
9192
self._module_type,
9293
value,
9394
)
94-
self._state = value
95-
self.coordinator.data[self._device_id][self._name]["value"] = value
95+
self._attr_native_value = value # type: ignore
9696
self.async_write_ha_state()
9797

9898
@property
@@ -107,64 +107,31 @@ def device_info(self) -> DeviceInfo:
107107
"manufacturer": "Weishaupt",
108108
}
109109

110-
@property
111-
def should_poll(self):
112-
"""No need to poll. Coordinator notifies entity of updates."""
113-
return False
114-
115110
@property
116111
def available(self):
117112
"""Return if entity is available."""
118113
return self.coordinator.last_update_success
119114

120-
async def async_added_to_hass(self):
121-
"""When entity is added to hass."""
122-
self.async_on_remove(
123-
self.coordinator.async_add_listener(self.async_write_ha_state)
124-
)
125-
126-
@property
127-
def name(self):
128-
"""Return the name of the sensor."""
129-
return self._name
115+
# async def async_added_to_hass(self):
116+
# """When entity is added to hass."""
117+
# self.async_on_remove(
118+
# self.coordinator.async_add_listener(self._handle_coordinator_update)
119+
# )
130120

131-
@property
132-
def unique_id(self):
133-
"""Return the unique ID of the binary sensor."""
134-
return self._unique_id
121+
@callback
122+
def _handle_coordinator_update(self) -> None:
123+
"""Handle updated data from the coordinator."""
135124

136-
@property
137-
def icon(self):
138-
"""Icon to use in the frontend, if any."""
139-
return self._icon
140-
141-
@property
142-
def state(self):
143-
"""Return the state of the sensor."""
144125
try:
145-
state = self.coordinator.data[self._device_id][self._name]["value"]
146-
if state:
147-
return state
148-
return 0
126+
self._attr_native_value = self.coordinator.data[self._device_id][
127+
self._attr_name
128+
]["value"]
149129
except KeyError:
150-
_LOGGER.warning("Can't find %s", self._unique_id)
130+
self._attr_native_value = None
131+
_LOGGER.warning("Can't find %s", self._attr_unique_id)
151132
_LOGGER.debug("Sensor data %s", self.coordinator.data)
152-
return None
153133

154-
@property
155-
def native_unit_of_measurement(self):
156-
"""Return the unit of measurement of this entity, if any."""
157-
return self._unit
158-
159-
# @property
160-
# def state_class(self):
161-
# """Return the state class of this entity, if any."""
162-
# if self._unit in ("°C", "kW", "W", "%"):
163-
# return STATE_CLASS_MEASUREMENT
164-
# elif self._unit in ("kWh", "Wh"):
165-
# return STATE_CLASS_TOTAL_INCREASING
166-
# else:
167-
# return None
134+
self.async_write_ha_state()
168135

169136
@property
170137
def extra_state_attributes(self):

custom_components/wemportal/select.py

+32-45
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from homeassistant.components.select import SelectEntity
66
from homeassistant.config_entries import ConfigEntry
7-
from homeassistant.core import HomeAssistant
7+
from homeassistant.core import HomeAssistant, callback
88
from homeassistant.helpers.entity import DeviceInfo
99
from homeassistant.helpers.entity_platform import AddEntitiesCallback
1010
from homeassistant.helpers.update_coordinator import CoordinatorEntity
@@ -68,16 +68,17 @@ def __init__(
6868
self._last_updated = None
6969
self._config_entry = config_entry
7070
self._device_id = device_id
71-
self._name = _unique_id
72-
self._unique_id = get_wemportal_unique_id(
73-
self._config_entry.entry_id, str(self._device_id), str(self._name)
71+
self._attr_name = _unique_id
72+
self._attr_unique_id = get_wemportal_unique_id(
73+
self._config_entry.entry_id, str(self._device_id), str(self._attr_name)
7474
)
7575
self._parameter_id = entity_data["ParameterID"]
76-
self._icon = entity_data["icon"]
76+
self._attr_icon = entity_data["icon"]
7777
self._options = entity_data["options"]
7878
self._options_names = entity_data["optionsNames"]
7979
self._module_index = entity_data["ModuleIndex"]
8080
self._module_type = entity_data["ModuleType"]
81+
self._attr_current_option = entity_data["value"]
8182

8283
async def async_select_option(self, option: str) -> None:
8384
"""Call the API to change the parameter value"""
@@ -90,9 +91,7 @@ async def async_select_option(self, option: str) -> None:
9091
self._options[self._options_names.index(option)],
9192
)
9293

93-
self.coordinator.data[self._device_id][self._name]["value"] = self._options[
94-
self._options_names.index(option)
95-
]
94+
self._attr_current_option = option
9695

9796
self.async_write_ha_state()
9897

@@ -108,48 +107,21 @@ def device_info(self) -> DeviceInfo:
108107
"manufacturer": "Weishaupt",
109108
}
110109

110+
@property
111+
def available(self):
112+
"""Return if entity is available."""
113+
return self.coordinator.last_update_success
114+
111115
@property
112116
def options(self) -> list[str]:
113117
"""Return list of available options."""
114118
return self._options_names
115119

116-
@property
117-
def current_option(self) -> str:
118-
"""Return the current option."""
119-
try:
120-
options = self._options_names[
121-
self._options.index(
122-
self.coordinator.data[self._device_id][self._name]["value"]
123-
)
124-
]
125-
if options:
126-
return options
127-
except KeyError:
128-
_LOGGER.warning("Can't find %s", self._unique_id)
129-
_LOGGER.debug("Sensor data %s", self.coordinator.data)
130-
131-
return None
132-
133-
async def async_added_to_hass(self):
134-
"""When entity is added to hass."""
135-
self.async_on_remove(
136-
self.coordinator.async_add_listener(self.async_write_ha_state)
137-
)
138-
139-
@property
140-
def name(self):
141-
"""Return the name of the sensor."""
142-
return self._name
143-
144-
@property
145-
def unique_id(self):
146-
"""Return the unique ID of the binary sensor."""
147-
return self._unique_id
148-
149-
@property
150-
def icon(self):
151-
"""Icon to use in the frontend, if any."""
152-
return self._icon
120+
# async def async_added_to_hass(self):
121+
# """When entity is added to hass."""
122+
# self.async_on_remove(
123+
# self.coordinator.async_add_listener(self._handle_coordinator_update)
124+
# )
153125

154126
@property
155127
def extra_state_attributes(self):
@@ -159,6 +131,21 @@ def extra_state_attributes(self):
159131
attr["Last Updated"] = self._last_updated
160132
return attr
161133

134+
@callback
135+
def _handle_coordinator_update(self) -> None:
136+
"""Handle updated data from the coordinator."""
137+
138+
try:
139+
self._attr_current_option = self.coordinator.data[self._device_id][
140+
self._attr_name
141+
]["value"]
142+
except KeyError:
143+
self._attr_current_option = None
144+
_LOGGER.warning("Can't find %s", self._attr_unique_id)
145+
_LOGGER.debug("Sensor data %s", self.coordinator.data)
146+
147+
self.async_write_ha_state()
148+
162149
async def async_update(self):
163150
"""Update Entity
164151
Only used by the generic entity update service."""

custom_components/wemportal/sensor.py

+30-55
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
)
1010
from homeassistant.config_entries import ConfigEntry
1111

12-
from homeassistant.core import HomeAssistant
12+
from homeassistant.core import HomeAssistant, callback
1313
from homeassistant.helpers.entity import DeviceInfo
1414
from homeassistant.helpers.entity_platform import AddEntitiesCallback
1515
from homeassistant.helpers.update_coordinator import CoordinatorEntity
@@ -57,31 +57,29 @@ async def async_setup_entry(
5757
coordinator, config_entry, device_id, unique_id, values
5858
)
5959
)
60-
try:
61-
async_add_entities(entities)
62-
except Exception as e:
63-
print(e)
60+
async_add_entities(entities)
6461

6562

6663
class WemPortalSensor(CoordinatorEntity, SensorEntity):
6764
"""Representation of a WEM Portal Sensor."""
6865

6966
def __init__(
7067
self, coordinator, config_entry: ConfigEntry, device_id, _unique_id, entity_data
71-
):
68+
) -> None:
7269
"""Initialize the sensor."""
7370
super().__init__(coordinator)
7471
self._last_updated = None
7572
self._config_entry = config_entry
7673
self._device_id = device_id
77-
self._name = _unique_id
78-
self._unique_id = get_wemportal_unique_id(
79-
self._config_entry.entry_id, str(self._device_id), str(self._name)
74+
self._attr_name = _unique_id
75+
self._attr_unique_id = get_wemportal_unique_id(
76+
self._config_entry.entry_id, str(self._device_id), str(self._attr_name)
8077
)
8178
self._parameter_id = entity_data["ParameterID"]
82-
self._icon = entity_data["icon"]
83-
self._unit = entity_data["unit"]
84-
self._state = self.state
79+
self._attr_icon = entity_data["icon"]
80+
self._attr_native_unit_of_measurement = entity_data["unit"]
81+
self._attr_native_value = entity_data["value"]
82+
self._attr_should_poll = False
8583

8684
@property
8785
def device_info(self) -> DeviceInfo:
@@ -95,75 +93,52 @@ def device_info(self) -> DeviceInfo:
9593
"manufacturer": "Weishaupt",
9694
}
9795

98-
@property
99-
def should_poll(self):
100-
"""No need to poll. Coordinator notifies entity of updates."""
101-
return False
102-
10396
@property
10497
def available(self):
10598
"""Return if entity is available."""
10699
return self.coordinator.last_update_success
107100

108-
async def async_added_to_hass(self):
109-
"""When entity is added to hass."""
110-
self.async_on_remove(
111-
self.coordinator.async_add_listener(self.async_write_ha_state)
112-
)
113-
114-
@property
115-
def name(self):
116-
"""Return the name of the sensor."""
117-
return self._name
118-
119-
@property
120-
def unique_id(self):
121-
"""Return the unique ID of the sensor."""
122-
return self._unique_id
101+
# async def async_added_to_hass(self):
102+
# """When entity is added to hass."""
103+
# self.async_on_remove(
104+
# self.coordinator.async_add_listener(self._handle_coordinator_update)
105+
# )
123106

124-
@property
125-
def icon(self):
126-
"""Icon to use in the frontend, if any."""
127-
return self._icon
107+
@callback
108+
def _handle_coordinator_update(self) -> None:
109+
"""Handle updated data from the coordinator."""
128110

129-
@property
130-
def state(self):
131-
"""Return the state of the sensor."""
132111
try:
133-
state = self.coordinator.data[self._device_id][self._name]["value"]
134-
if state:
135-
return state
136-
return 0
112+
self._attr_native_value = self.coordinator.data[self._device_id][
113+
self._attr_name
114+
]["value"]
137115
except KeyError:
138-
_LOGGER.warning("Can't find %s", self._unique_id)
116+
self._attr_native_value = None
117+
_LOGGER.warning("Can't find %s", self._attr_unique_id)
139118
_LOGGER.debug("Sensor data %s", self.coordinator.data)
140-
return None
141119

142-
@property
143-
def unit_of_measurement(self):
144-
"""Return the unit of measurement of this entity, if any."""
145-
return self._unit
120+
self.async_write_ha_state()
146121

147122
@property
148123
def device_class(self):
149124
"""Return the device_class of this entity."""
150-
if self._unit == "°C":
125+
if self._attr_native_unit_of_measurement == "°C":
151126
return SensorDeviceClass.TEMPERATURE
152-
elif self._unit in ("kWh", "Wh"):
127+
elif self._attr_native_unit_of_measurement in ("kWh", "Wh"):
153128
return SensorDeviceClass.ENERGY
154-
elif self._unit in ("kW", "W"):
129+
elif self._attr_native_unit_of_measurement in ("kW", "W"):
155130
return SensorDeviceClass.POWER
156-
elif self._unit == "%":
131+
elif self._attr_native_unit_of_measurement == "%":
157132
return SensorDeviceClass.POWER_FACTOR
158133
else:
159134
return None
160135

161136
@property
162137
def state_class(self):
163138
"""Return the state class of this entity, if any."""
164-
if self._unit in ("°C", "kW", "W", "%"):
139+
if self._attr_native_unit_of_measurement in ("°C", "kW", "W", "%"):
165140
return SensorStateClass.MEASUREMENT
166-
elif self._unit in ("kWh", "Wh"):
141+
elif self._attr_native_unit_of_measurement in ("kWh", "Wh"):
167142
return SensorStateClass.TOTAL_INCREASING
168143
else:
169144
return None

0 commit comments

Comments
 (0)