Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f3cf760

Browse files
authored
Drop IoTaWatt Accumulated sensors (home-assistant#86611)
1 parent d0b6768 commit f3cf760

File tree

4 files changed

+3
-278
lines changed

4 files changed

+3
-278
lines changed

‎homeassistant/components/iotawatt/const.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,4 @@
99
VOLT_AMPERE_REACTIVE = "VAR"
1010
VOLT_AMPERE_REACTIVE_HOURS = "VARh"
1111

12-
ATTR_LAST_UPDATE = "last_update"
13-
1412
CONNECTION_ERRORS = (KeyError, json.JSONDecodeError, httpx.HTTPError)

‎homeassistant/components/iotawatt/sensor.py‎

Lines changed: 1 addition & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,11 @@
2727
from homeassistant.helpers import entity, entity_registry
2828
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
2929
from homeassistant.helpers.entity_platform import AddEntitiesCallback
30-
from homeassistant.helpers.restore_state import RestoreEntity
3130
from homeassistant.helpers.typing import StateType
3231
from homeassistant.helpers.update_coordinator import CoordinatorEntity
3332
from homeassistant.util import dt
3433

35-
from .const import (
36-
ATTR_LAST_UPDATE,
37-
DOMAIN,
38-
VOLT_AMPERE_REACTIVE,
39-
VOLT_AMPERE_REACTIVE_HOURS,
40-
)
34+
from .const import DOMAIN, VOLT_AMPERE_REACTIVE, VOLT_AMPERE_REACTIVE_HOURS
4135
from .coordinator import IotawattUpdater
4236

4337
_LOGGER = logging.getLogger(__name__)
@@ -134,10 +128,6 @@ def _create_entity(key: str) -> IotaWattSensor:
134128
description = ENTITY_DESCRIPTION_KEY_MAP.get(
135129
data.getUnit(), IotaWattSensorEntityDescription("base_sensor")
136130
)
137-
if data.getUnit() == "WattHours" and not data.getFromStart():
138-
return IotaWattAccumulatingSensor(
139-
coordinator=coordinator, key=key, entity_description=description
140-
)
141131

142132
return IotaWattSensor(
143133
coordinator=coordinator,
@@ -235,77 +225,3 @@ def native_value(self) -> StateType:
235225
return func(self._sensor_data.getValue())
236226

237227
return self._sensor_data.getValue()
238-
239-
240-
class IotaWattAccumulatingSensor(IotaWattSensor, RestoreEntity):
241-
"""Defines a IoTaWatt Accumulative Energy (High Accuracy) Sensor."""
242-
243-
def __init__(
244-
self,
245-
coordinator: IotawattUpdater,
246-
key: str,
247-
entity_description: IotaWattSensorEntityDescription,
248-
) -> None:
249-
"""Initialize the sensor."""
250-
251-
super().__init__(coordinator, key, entity_description)
252-
253-
if self._attr_unique_id is not None:
254-
self._attr_unique_id += ".accumulated"
255-
256-
self._accumulated_value: float | None = None
257-
258-
@callback
259-
def _handle_coordinator_update(self) -> None:
260-
"""Handle updated data from the coordinator."""
261-
assert (
262-
self._accumulated_value is not None
263-
), "async_added_to_hass must have been called first"
264-
self._accumulated_value += float(self._sensor_data.getValue())
265-
266-
super()._handle_coordinator_update()
267-
268-
@property
269-
def native_value(self) -> StateType:
270-
"""Return the state of the sensor."""
271-
if self._accumulated_value is None:
272-
return None
273-
return round(self._accumulated_value, 1)
274-
275-
async def async_added_to_hass(self) -> None:
276-
"""Load the last known state value of the entity if the accumulated type."""
277-
await super().async_added_to_hass()
278-
state = await self.async_get_last_state()
279-
self._accumulated_value = 0.0
280-
if state:
281-
try:
282-
# Previous value could be `unknown` if the connection didn't originally
283-
# complete.
284-
self._accumulated_value = float(state.state)
285-
except (ValueError) as err:
286-
_LOGGER.warning("Could not restore last state: %s", err)
287-
else:
288-
if ATTR_LAST_UPDATE in state.attributes:
289-
last_run = dt.parse_datetime(state.attributes[ATTR_LAST_UPDATE])
290-
if last_run is not None:
291-
self.coordinator.update_last_run(last_run)
292-
# Force a second update from the iotawatt to ensure that sensors are up to date.
293-
await self.coordinator.async_request_refresh()
294-
295-
@property
296-
def name(self) -> str | None:
297-
"""Return name of the entity."""
298-
return f"{self._sensor_data.getSourceName()} Accumulated"
299-
300-
@property
301-
def extra_state_attributes(self) -> dict[str, str]:
302-
"""Return the extra state attributes of the entity."""
303-
attrs = super().extra_state_attributes
304-
305-
assert (
306-
self.coordinator.api is not None
307-
and self.coordinator.api.getLastUpdateTime() is not None
308-
)
309-
attrs[ATTR_LAST_UPDATE] = self.coordinator.api.getLastUpdateTime().isoformat()
310-
311-
return attrs

‎tests/components/iotawatt/__init__.py‎

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,3 @@
2222
mac_addr="mock-mac",
2323
fromStart=True,
2424
)
25-
26-
INPUT_ACCUMULATED_SENSOR = Sensor(
27-
channel="N/A",
28-
base_name="My WattHour Accumulated Input Sensor",
29-
suffix=".wh",
30-
io_type="Input",
31-
unit="WattHours",
32-
value=500,
33-
begin="",
34-
mac_addr="mock-mac",
35-
fromStart=False,
36-
)
37-
38-
OUTPUT_ACCUMULATED_SENSOR = Sensor(
39-
channel="N/A",
40-
base_name="My WattHour Accumulated Output Sensor",
41-
suffix=".wh",
42-
io_type="Output",
43-
unit="WattHours",
44-
value=200,
45-
begin="",
46-
mac_addr="mock-mac",
47-
fromStart=False,
48-
)
Lines changed: 2 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""Test setting up sensors."""
22
from datetime import timedelta
33

4-
from homeassistant.components.iotawatt.const import ATTR_LAST_UPDATE
54
from homeassistant.components.sensor import (
65
ATTR_STATE_CLASS,
76
SensorDeviceClass,
@@ -14,18 +13,12 @@
1413
UnitOfEnergy,
1514
UnitOfPower,
1615
)
17-
from homeassistant.core import State
1816
from homeassistant.setup import async_setup_component
1917
from homeassistant.util.dt import utcnow
2018

21-
from . import (
22-
INPUT_ACCUMULATED_SENSOR,
23-
INPUT_SENSOR,
24-
OUTPUT_ACCUMULATED_SENSOR,
25-
OUTPUT_SENSOR,
26-
)
19+
from . import INPUT_SENSOR, OUTPUT_SENSOR
2720

28-
from tests.common import async_fire_time_changed, mock_restore_cache
21+
from tests.common import async_fire_time_changed
2922

3023

3124
async def test_sensor_type_input(hass, mock_iotawatt):
@@ -83,161 +76,3 @@ async def test_sensor_type_output(hass, mock_iotawatt):
8376
await hass.async_block_till_done()
8477

8578
assert hass.states.get("sensor.my_watthour_sensor") is None
86-
87-
88-
async def test_sensor_type_accumulated_output(hass, mock_iotawatt):
89-
"""Tests the sensor type of Accumulated Output and that it's properly restored from saved state."""
90-
mock_iotawatt.getSensors.return_value["sensors"][
91-
"my_watthour_accumulated_output_sensor_key"
92-
] = OUTPUT_ACCUMULATED_SENSOR
93-
94-
DUMMY_DATE = "2021年09月01日T14:00:00+10:00"
95-
96-
mock_restore_cache(
97-
hass,
98-
(
99-
State(
100-
"sensor.my_watthour_accumulated_output_sensor_wh_accumulated",
101-
"100.0",
102-
{
103-
"device_class": SensorDeviceClass.ENERGY,
104-
"unit_of_measurement": UnitOfEnergy.WATT_HOUR,
105-
"last_update": DUMMY_DATE,
106-
},
107-
),
108-
),
109-
)
110-
111-
assert await async_setup_component(hass, "iotawatt", {})
112-
await hass.async_block_till_done()
113-
114-
assert len(hass.states.async_entity_ids()) == 1
115-
116-
state = hass.states.get(
117-
"sensor.my_watthour_accumulated_output_sensor_wh_accumulated"
118-
)
119-
assert state is not None
120-
121-
assert state.state == "300.0" # 100 + 200
122-
assert (
123-
state.attributes[ATTR_FRIENDLY_NAME]
124-
== "My WattHour Accumulated Output Sensor.wh Accumulated"
125-
)
126-
assert state.attributes[ATTR_STATE_CLASS] is SensorStateClass.TOTAL
127-
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == UnitOfEnergy.WATT_HOUR
128-
assert state.attributes[ATTR_DEVICE_CLASS] == SensorDeviceClass.ENERGY
129-
assert state.attributes["type"] == "Output"
130-
assert state.attributes[ATTR_LAST_UPDATE] is not None
131-
assert state.attributes[ATTR_LAST_UPDATE] != DUMMY_DATE
132-
133-
134-
async def test_sensor_type_accumulated_output_error_restore(hass, mock_iotawatt):
135-
"""Tests the sensor type of Accumulated Output and that it's properly restored from saved state."""
136-
mock_iotawatt.getSensors.return_value["sensors"][
137-
"my_watthour_accumulated_output_sensor_key"
138-
] = OUTPUT_ACCUMULATED_SENSOR
139-
140-
DUMMY_DATE = "2021年09月01日T14:00:00+10:00"
141-
142-
mock_restore_cache(
143-
hass,
144-
(
145-
State(
146-
"sensor.my_watthour_accumulated_output_sensor_wh_accumulated",
147-
"unknown",
148-
),
149-
),
150-
)
151-
152-
assert await async_setup_component(hass, "iotawatt", {})
153-
await hass.async_block_till_done()
154-
155-
assert len(hass.states.async_entity_ids()) == 1
156-
157-
state = hass.states.get(
158-
"sensor.my_watthour_accumulated_output_sensor_wh_accumulated"
159-
)
160-
assert state is not None
161-
162-
assert state.state == "200.0" # Returns the new read as restore failed.
163-
assert (
164-
state.attributes[ATTR_FRIENDLY_NAME]
165-
== "My WattHour Accumulated Output Sensor.wh Accumulated"
166-
)
167-
assert state.attributes[ATTR_STATE_CLASS] is SensorStateClass.TOTAL
168-
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == UnitOfEnergy.WATT_HOUR
169-
assert state.attributes[ATTR_DEVICE_CLASS] == SensorDeviceClass.ENERGY
170-
assert state.attributes["type"] == "Output"
171-
assert state.attributes[ATTR_LAST_UPDATE] is not None
172-
assert state.attributes[ATTR_LAST_UPDATE] != DUMMY_DATE
173-
174-
175-
async def test_sensor_type_multiple_accumulated_output(hass, mock_iotawatt):
176-
"""Tests the sensor type of Accumulated Output and that it's properly restored from saved state."""
177-
mock_iotawatt.getSensors.return_value["sensors"][
178-
"my_watthour_accumulated_output_sensor_key"
179-
] = OUTPUT_ACCUMULATED_SENSOR
180-
mock_iotawatt.getSensors.return_value["sensors"][
181-
"my_watthour_accumulated_input_sensor_key"
182-
] = INPUT_ACCUMULATED_SENSOR
183-
184-
DUMMY_DATE = "2021年09月01日T14:00:00+10:00"
185-
186-
mock_restore_cache(
187-
hass,
188-
(
189-
State(
190-
"sensor.my_watthour_accumulated_output_sensor_wh_accumulated",
191-
"100.0",
192-
{
193-
"device_class": SensorDeviceClass.ENERGY,
194-
"unit_of_measurement": UnitOfEnergy.WATT_HOUR,
195-
"last_update": DUMMY_DATE,
196-
},
197-
),
198-
State(
199-
"sensor.my_watthour_accumulated_input_sensor_wh_accumulated",
200-
"50.0",
201-
{
202-
"device_class": SensorDeviceClass.ENERGY,
203-
"unit_of_measurement": UnitOfEnergy.WATT_HOUR,
204-
"last_update": DUMMY_DATE,
205-
},
206-
),
207-
),
208-
)
209-
210-
assert await async_setup_component(hass, "iotawatt", {})
211-
await hass.async_block_till_done()
212-
213-
assert len(hass.states.async_entity_ids()) == 2
214-
215-
state = hass.states.get(
216-
"sensor.my_watthour_accumulated_output_sensor_wh_accumulated"
217-
)
218-
assert state is not None
219-
220-
assert state.state == "300.0" # 100 + 200
221-
assert (
222-
state.attributes[ATTR_FRIENDLY_NAME]
223-
== "My WattHour Accumulated Output Sensor.wh Accumulated"
224-
)
225-
assert state.attributes[ATTR_STATE_CLASS] is SensorStateClass.TOTAL
226-
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == UnitOfEnergy.WATT_HOUR
227-
assert state.attributes[ATTR_DEVICE_CLASS] == SensorDeviceClass.ENERGY
228-
assert state.attributes["type"] == "Output"
229-
assert state.attributes[ATTR_LAST_UPDATE] is not None
230-
assert state.attributes[ATTR_LAST_UPDATE] != DUMMY_DATE
231-
232-
state = hass.states.get(
233-
"sensor.my_watthour_accumulated_input_sensor_wh_accumulated"
234-
)
235-
assert state is not None
236-
237-
assert state.state == "550.0" # 50 + 500
238-
assert (
239-
state.attributes[ATTR_FRIENDLY_NAME]
240-
== "My WattHour Accumulated Input Sensor.wh Accumulated"
241-
)
242-
assert state.attributes[ATTR_LAST_UPDATE] is not None
243-
assert state.attributes[ATTR_LAST_UPDATE] != DUMMY_DATE

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /