Remove energy usage from the switch base class (#68821)

* Remove energy usage from the switch base class

* Remove unused attributes from integrations
pull/68806/head^2
Paulus Schoutsen 2022-03-28 21:56:04 -07:00 committed by GitHub
parent c6ba987995
commit 69fcce3b2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 11 additions and 328 deletions

View File

@ -116,7 +116,5 @@ class AtenSwitch(SwitchEntity):
status = await self._device.displayOutletStatus(self._outlet)
if status == "on":
self._attr_is_on = True
self._attr_current_power_w = await self._device.outletPower(self._outlet)
elif status == "off":
self._attr_is_on = False
self._attr_current_power_w = 0.0

View File

@ -101,14 +101,6 @@ class SmartPlugSwitch(SwitchEntity):
return attrs
@property
def current_power_w(self):
"""Return the current power usage in Watt."""
try:
return float(self.data.current_consumption)
except (ValueError, TypeError):
return None
@property
def is_on(self):
"""Return true if switch is on."""

View File

@ -48,10 +48,7 @@ class SmartPlugSwitch(SwitchEntity):
"""Initialize the switch."""
self.smartplug = smartplug
self._name = name
self._now_power = None
self._now_energy_day = None
self._state = False
self._supports_power_monitoring = False
self._info = None
self._mac = None
@ -65,16 +62,6 @@ class SmartPlugSwitch(SwitchEntity):
"""Return the name of the Smart Plug, if any."""
return self._name
@property
def current_power_w(self):
"""Return the current power usage in W."""
return self._now_power
@property
def today_energy_kwh(self):
"""Return the today total energy usage in kWh."""
return self._now_energy_day
@property
def is_on(self):
"""Return true if switch is on."""
@ -93,17 +80,5 @@ class SmartPlugSwitch(SwitchEntity):
if not self._info:
self._info = self.smartplug.info
self._mac = self._info["mac"]
self._supports_power_monitoring = self._info["model"] != "SP1101W"
if self._supports_power_monitoring:
try:
self._now_power = float(self.smartplug.now_power)
except (TypeError, ValueError):
self._now_power = None
try:
self._now_energy_day = float(self.smartplug.now_energy_day)
except (TypeError, ValueError):
self._now_energy_day = None
self._state = self.smartplug.state == "ON"

View File

@ -6,7 +6,7 @@ import logging
import pypca
from serial import SerialException
from homeassistant.components.switch import ATTR_CURRENT_POWER_W, SwitchEntity
from homeassistant.components.switch import SwitchEntity
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -14,8 +14,6 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
_LOGGER = logging.getLogger(__name__)
ATTR_TOTAL_ENERGY_KWH = "total_energy_kwh"
DEFAULT_NAME = "PCA 301"
@ -57,7 +55,6 @@ class SmartPlugSwitch(SwitchEntity):
self._name = "PCA 301"
self._state = None
self._available = True
self._emeter_params = {}
self._pca = pca
@property
@ -83,23 +80,11 @@ class SmartPlugSwitch(SwitchEntity):
"""Turn the switch off."""
self._pca.turn_off(self._device_id)
@property
def extra_state_attributes(self):
"""Return the state attributes of the device."""
return self._emeter_params
def update(self):
"""Update the PCA switch's state."""
try:
self._emeter_params[
ATTR_CURRENT_POWER_W
] = f"{self._pca.get_current_power(self._device_id):.1f}"
self._emeter_params[
ATTR_TOTAL_ENERGY_KWH
] = f"{self._pca.get_total_consumption(self._device_id):.2f}"
self._available = True
self._state = self._pca.get_state(self._device_id)
self._available = True
except (OSError) as ex:
if self._available:

View File

@ -5,7 +5,6 @@ from sense_energy import PlugInstance, SenseLink
import voluptuous as vol
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.components.switch import ATTR_CURRENT_POWER_W
from homeassistant.const import (
CONF_ENTITIES,
CONF_NAME,
@ -105,8 +104,6 @@ async def validate_configs(hass, entity_configs):
entity_config[CONF_POWER] = power_val
elif state.domain == SENSOR_DOMAIN:
pass
elif ATTR_CURRENT_POWER_W in state.attributes:
pass
else:
_LOGGER.debug("No power value defined for: %s", entity_id)
@ -132,8 +129,6 @@ def get_plug_devices(hass, entity_configs):
power = float(hass.states.get(power_val).state)
elif isinstance(power_val, Template):
power = float(power_val.async_render())
elif ATTR_CURRENT_POWER_W in state.attributes:
power = float(state.attributes[ATTR_CURRENT_POWER_W])
elif state.domain == SENSOR_DOMAIN:
power = float(state.state)
else:

View File

@ -27,14 +27,12 @@ from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.typing import ConfigType
from homeassistant.util import convert, slugify
from homeassistant.util import slugify
from .const import CONF_IMPORT_PLUGINS, DOMAIN
_LOGGER = logging.getLogger(__name__)
ATTR_CURRENT_POWER_W = "current_power_w"
CONF_COLOR = "color"
CONF_DEVICE_CONFIG = "device_config"
CONF_DIMMING = "dimming"
@ -529,15 +527,6 @@ class FibaroDevice(Entity):
else:
self.dont_know_message(cmd)
@property
def current_power_w(self):
"""Return the current power usage in W."""
if "power" in self.fibaro_device.properties and (
power := self.fibaro_device.properties.power
):
return convert(power, float, 0.0)
return None
@property
def current_binary_state(self):
"""Return the current binary state."""
@ -567,10 +556,6 @@ class FibaroDevice(Entity):
)
if "fibaroAlarmArm" in self.fibaro_device.interfaces:
attr[ATTR_ARMED] = bool(self.fibaro_device.properties.armed)
if "power" in self.fibaro_device.interfaces:
attr[ATTR_CURRENT_POWER_W] = convert(
self.fibaro_device.properties.power, float, 0.0
)
except (ValueError, KeyError):
pass

View File

@ -5,7 +5,6 @@ from homeassistant.components.switch import ENTITY_ID_FORMAT, SwitchEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util import convert
from . import FIBARO_DEVICES, FibaroDevice
from .const import DOMAIN
@ -45,20 +44,6 @@ class FibaroSwitch(FibaroDevice, SwitchEntity):
self.call_turn_off()
self._state = False
@property
def current_power_w(self):
"""Return the current power usage in W."""
if "power" in self.fibaro_device.interfaces:
return convert(self.fibaro_device.properties.power, float, 0.0)
return None
@property
def today_energy_kwh(self):
"""Return the today total energy usage in kWh."""
if "energy" in self.fibaro_device.interfaces:
return convert(self.fibaro_device.properties.energy, float, 0.0)
return None
@property
def is_on(self):
"""Return true if device is on."""

View File

@ -69,11 +69,6 @@ class HiveDevicePlug(HiveEntity, SwitchEntity):
ATTR_MODE: self.attributes.get(ATTR_MODE),
}
@property
def current_power_w(self):
"""Return the current power usage in W."""
return self.device["status"].get("power_usage")
@property
def is_on(self):
"""Return true if switch is on."""

View File

@ -32,9 +32,6 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import DOMAIN as HMIPC_DOMAIN, HomematicipGenericEntity
from .hap import HomematicipHAP
ATTR_TODAY_ENERGY_KWH = "today_energy_kwh"
ATTR_CURRENT_POWER_W = "current_power_w"
async def async_setup_entry(
hass: HomeAssistant,
@ -94,19 +91,6 @@ class HomematicipLight(HomematicipGenericEntity, LightEntity):
class HomematicipLightMeasuring(HomematicipLight):
"""Representation of the HomematicIP measuring light."""
@property
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes of the light."""
state_attr = super().extra_state_attributes
current_power_w = self._device.currentPowerConsumption
if current_power_w > 0.05:
state_attr[ATTR_CURRENT_POWER_W] = round(current_power_w, 2)
state_attr[ATTR_TODAY_ENERGY_KWH] = round(self._device.energyCounter, 2)
return state_attr
class HomematicipMultiDimmer(HomematicipGenericEntity, LightEntity):
"""Representation of HomematicIP Cloud dimmer."""

View File

@ -166,15 +166,3 @@ class HomematicipGroupSwitch(HomematicipGenericEntity, SwitchEntity):
class HomematicipSwitchMeasuring(HomematicipSwitch):
"""Representation of the HomematicIP measuring switch."""
@property
def current_power_w(self) -> float:
"""Return the current power usage in W."""
return self._device.currentPowerConsumption
@property
def today_energy_kwh(self) -> int:
"""Return the today total energy usage in kWh."""
if self._device.energyCounter is None:
return 0
return round(self._device.energyCounter)

View File

@ -110,16 +110,3 @@ class MfiSwitch(SwitchEntity):
"""Turn the switch off."""
self._port.control(False)
self._target_state = False
@property
def current_power_w(self):
"""Return the current power usage in W."""
return int(self._port.data.get("active_pwr", 0))
@property
def extra_state_attributes(self):
"""Return the state attributes for the device."""
return {
"volts": round(self._port.data.get("v_rms", 0), 1),
"amps": round(self._port.data.get("i_rms", 0), 1),
}

View File

@ -41,13 +41,6 @@ from .mixins import (
async_setup_platform_helper,
)
MQTT_SWITCH_ATTRIBUTES_BLOCKED = frozenset(
{
switch.ATTR_CURRENT_POWER_W,
switch.ATTR_TODAY_ENERGY_KWH,
}
)
DEFAULT_NAME = "MQTT Switch"
DEFAULT_PAYLOAD_ON = "ON"
DEFAULT_PAYLOAD_OFF = "OFF"
@ -106,7 +99,6 @@ class MqttSwitch(MqttEntity, SwitchEntity, RestoreEntity):
"""Representation of a switch that can be toggled using MQTT."""
_entity_id_format = switch.ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_SWITCH_ATTRIBUTES_BLOCKED
def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the MQTT switch."""

View File

@ -72,11 +72,6 @@ class MyStromSwitch(SwitchEntity):
"""Return a unique ID."""
return self.plug._mac # pylint: disable=protected-access
@property
def current_power_w(self):
"""Return the current power consumption in W."""
return self.plug.consumption
@property
def available(self):
"""Could the device be accessed during the last update call."""
@ -103,5 +98,6 @@ class MyStromSwitch(SwitchEntity):
self.relay = self.plug.relay
self._available = True
except MyStromConnectionError:
self._available = False
_LOGGER.error("No route to myStrom plug")
if self._available:
self._available = False
_LOGGER.error("No route to myStrom plug")

View File

@ -175,26 +175,3 @@ class NetioSwitch(SwitchEntity):
def update(self):
"""Update the state."""
self.netio.update()
@property
def extra_state_attributes(self):
"""Return optional state attributes."""
return {
ATTR_TOTAL_CONSUMPTION_KWH: self.cumulated_consumption_kwh,
ATTR_START_DATE: self.start_date.split("|")[0],
}
@property
def current_power_w(self):
"""Return actual power."""
return self.netio.consumptions[int(self.outlet) - 1]
@property
def cumulated_consumption_kwh(self):
"""Return the total enerygy consumption since start_date."""
return self.netio.cumulated_consumptions[int(self.outlet) - 1]
@property
def start_date(self):
"""Point in time when the energy accumulation started."""
return self.netio.start_dates[int(self.outlet) - 1]

View File

@ -4,7 +4,6 @@ from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
import logging
from typing import Any, final
import voluptuous as vol
@ -32,16 +31,8 @@ SCAN_INTERVAL = timedelta(seconds=30)
ENTITY_ID_FORMAT = DOMAIN + ".{}"
ATTR_TODAY_ENERGY_KWH = "today_energy_kwh"
ATTR_CURRENT_POWER_W = "current_power_w"
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
PROP_TO_ATTR = {
"current_power_w": ATTR_CURRENT_POWER_W,
"today_energy_kwh": ATTR_TODAY_ENERGY_KWH,
}
_LOGGER = logging.getLogger(__name__)
@ -107,14 +98,7 @@ class SwitchEntity(ToggleEntity):
"""Base class for switch entities."""
entity_description: SwitchEntityDescription
_attr_current_power_w: float | None = None
_attr_device_class: SwitchDeviceClass | str | None
_attr_today_energy_kwh: float | None = None
@property
def current_power_w(self) -> float | None:
"""Return the current power usage in W."""
return self._attr_current_power_w
@property
def device_class(self) -> SwitchDeviceClass | str | None:
@ -124,20 +108,3 @@ class SwitchEntity(ToggleEntity):
if hasattr(self, "entity_description"):
return self.entity_description.device_class
return None
@property
def today_energy_kwh(self) -> float | None:
"""Return the today total energy usage in kWh."""
return self._attr_today_energy_kwh
@final
@property
def state_attributes(self) -> dict[str, Any] | None:
"""Return the optional state attributes."""
data = {}
for prop, attr in PROP_TO_ATTR.items():
if (value := getattr(self, prop)) is not None:
data[attr] = value
return data

View File

@ -28,7 +28,7 @@ from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.typing import ConfigType
from homeassistant.util import convert, slugify
from homeassistant.util import slugify
from homeassistant.util.dt import utc_from_timestamp
from .common import (
@ -39,14 +39,7 @@ from .common import (
set_controller_data,
)
from .config_flow import fix_device_id_list, new_options
from .const import (
ATTR_CURRENT_ENERGY_KWH,
ATTR_CURRENT_POWER_W,
CONF_CONTROLLER,
CONF_LEGACY_UNIQUE_ID,
DOMAIN,
VERA_ID_FORMAT,
)
from .const import CONF_CONTROLLER, CONF_LEGACY_UNIQUE_ID, DOMAIN, VERA_ID_FORMAT
_LOGGER = logging.getLogger(__name__)
@ -279,12 +272,6 @@ class VeraDevice(Generic[_DeviceTypeT], Entity):
tripped = self.vera_device.is_tripped
attr[ATTR_TRIPPED] = "True" if tripped else "False"
if power := self.vera_device.power:
attr[ATTR_CURRENT_POWER_W] = convert(power, float, 0.0)
if energy := self.vera_device.energy:
attr[ATTR_CURRENT_ENERGY_KWH] = convert(energy, float, 0.0)
attr["Vera Device Id"] = self.vera_device.vera_device_id
return attr

View File

@ -25,7 +25,6 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util import convert
from . import VeraDevice
from .common import ControllerData, get_controller_data
@ -111,13 +110,6 @@ class VeraThermostat(VeraDevice[veraApi.VeraThermostat], ClimateEntity):
self.schedule_update_ha_state()
@property
def current_power_w(self) -> float | None:
"""Return the current power usage in W."""
if power := self.vera_device.power:
return convert(power, float, 0.0)
return None
@property
def temperature_unit(self) -> str:
"""Return the unit of measurement."""

View File

@ -10,7 +10,6 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util import convert
from . import VeraDevice
from .common import ControllerData, get_controller_data
@ -55,13 +54,6 @@ class VeraSwitch(VeraDevice[veraApi.VeraSwitch], SwitchEntity):
self._state = False
self.schedule_update_ha_state()
@property
def current_power_w(self) -> float | None:
"""Return the current power usage in W."""
if power := self.vera_device.power:
return convert(power, float, 0.0)
return None
@property
def is_on(self) -> bool:
"""Return true if device is on."""

View File

@ -111,24 +111,6 @@ class WemoSwitch(WemoBinaryStateEntity, SwitchEntity):
uptime.day - 1, uptime.hour, uptime.minute, uptime.second
)
@property
def current_power_w(self) -> float | None:
"""Return the current power usage in W."""
if not isinstance(self.wemo, Insight):
return None
milliwatts = convert(self.wemo.insight_params.get("currentpower"), float, 0.0)
assert isinstance(milliwatts, float)
return milliwatts / 1000.0
@property
def today_energy_kwh(self) -> float | None:
"""Return the today total energy usage in kWh."""
if not isinstance(self.wemo, Insight):
return None
milliwatt_seconds = convert(self.wemo.insight_params.get("todaymw"), float, 0.0)
assert isinstance(milliwatt_seconds, float)
return round(milliwatt_seconds / (1000.0 * 1000.0 * 60), 2)
@property
def detail_state(self) -> str:
"""Return the state of the device."""

View File

@ -15,13 +15,9 @@ from homeassistant.components.fan import (
)
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.components.switch import (
ATTR_CURRENT_POWER_W,
DOMAIN as SWITCH_DOMAIN,
)
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_FRIENDLY_NAME,
CONF_ENTITIES,
CONF_NAME,
SERVICE_TURN_OFF,
@ -218,38 +214,6 @@ async def test_switch_power(hass):
SWITCH_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_SWITCH}, blocking=True
)
hass.states.async_set(
ENTITY_SWITCH,
STATE_ON,
attributes={ATTR_CURRENT_POWER_W: 100, ATTR_FRIENDLY_NAME: "AC"},
)
switch = hass.states.get(ENTITY_SWITCH)
assert switch.state == STATE_ON
power = switch.attributes[ATTR_CURRENT_POWER_W]
assert power == 100
assert switch.name == "AC"
plug_it = emulated_kasa.get_plug_devices(hass, config)
plug = next(plug_it).generate_response()
assert nested_value(plug, "system", "get_sysinfo", "alias") == "AC"
power = nested_value(plug, "emeter", "get_realtime", "power")
assert math.isclose(power, power)
hass.states.async_set(
ENTITY_SWITCH,
STATE_ON,
attributes={ATTR_CURRENT_POWER_W: 120, ATTR_FRIENDLY_NAME: "AC"},
)
plug_it = emulated_kasa.get_plug_devices(hass, config)
plug = next(plug_it).generate_response()
assert nested_value(plug, "system", "get_sysinfo", "alias") == "AC"
power = nested_value(plug, "emeter", "get_realtime", "power")
assert math.isclose(power, 120)
# Turn off
await hass.services.async_call(
SWITCH_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_SWITCH}, blocking=True

View File

@ -2,10 +2,6 @@
from homematicip.base.enums import RGBColorState
from homeassistant.components.homematicip_cloud import DOMAIN as HMIPC_DOMAIN
from homeassistant.components.homematicip_cloud.light import (
ATTR_CURRENT_POWER_W,
ATTR_TODAY_ENERGY_KWH,
)
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_COLOR_NAME,
@ -233,8 +229,6 @@ async def test_hmip_light_measuring(hass, default_mock_hap_factory):
await async_manipulate_test_data(hass, hmip_device, "currentPowerConsumption", 50)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_ON
assert ha_state.attributes[ATTR_CURRENT_POWER_W] == 50
assert ha_state.attributes[ATTR_TODAY_ENERGY_KWH] == 6.33
await hass.services.async_call(
"light", "turn_off", {"entity_id": entity_id}, blocking=True

View File

@ -3,11 +3,7 @@ from homeassistant.components.homematicip_cloud import DOMAIN as HMIPC_DOMAIN
from homeassistant.components.homematicip_cloud.generic_entity import (
ATTR_GROUP_MEMBER_UNREACHABLE,
)
from homeassistant.components.switch import (
ATTR_CURRENT_POWER_W,
ATTR_TODAY_ENERGY_KWH,
DOMAIN as SWITCH_DOMAIN,
)
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.setup import async_setup_component
@ -132,12 +128,6 @@ async def test_hmip_switch_measuring(hass, default_mock_hap_factory):
await async_manipulate_test_data(hass, hmip_device, "currentPowerConsumption", 50)
ha_state = hass.states.get(entity_id)
assert ha_state.state == STATE_ON
assert ha_state.attributes[ATTR_CURRENT_POWER_W] == 50
assert ha_state.attributes[ATTR_TODAY_ENERGY_KWH] == 36
await async_manipulate_test_data(hass, hmip_device, "energyCounter", None)
ha_state = hass.states.get(entity_id)
assert not ha_state.attributes.get(ATTR_TODAY_ENERGY_KWH)
async def test_hmip_group_switch(hass, default_mock_hap_factory):

View File

@ -103,21 +103,3 @@ async def test_turn_off(port, switch):
assert port.control.call_args == mock.call(False)
# pylint: disable=protected-access
assert not switch._target_state
async def test_current_power_w(port, switch):
"""Test current power."""
port.data = {"active_pwr": 10}
assert switch.current_power_w == 10
async def test_current_power_w_no_data(port, switch):
"""Test current power if there is no data."""
port.data = {"notpower": 123}
assert switch.current_power_w == 0
async def test_extra_state_attributes(port, switch):
"""Test the state attributes."""
port.data = {"v_rms": 1.25, "i_rms": 2.75}
assert switch.extra_state_attributes == {"volts": 1.2, "amps": 2.8}

View File

@ -5,7 +5,6 @@ from unittest.mock import patch
import pytest
from homeassistant.components import switch
from homeassistant.components.mqtt.switch import MQTT_SWITCH_ATTRIBUTES_BLOCKED
from homeassistant.const import (
ATTR_ASSUMED_STATE,
ATTR_DEVICE_CLASS,
@ -292,7 +291,7 @@ async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock):
async def test_setting_blocked_attribute_via_mqtt_json_message(hass, mqtt_mock):
"""Test the setting of attribute via MQTT with JSON payload."""
await help_test_setting_blocked_attribute_via_mqtt_json_message(
hass, mqtt_mock, switch.DOMAIN, DEFAULT_CONFIG, MQTT_SWITCH_ATTRIBUTES_BLOCKED
hass, mqtt_mock, switch.DOMAIN, DEFAULT_CONFIG, {}
)