Update plugwise to async and config_flow sensor part (#36219)
Co-authored-by: J. Nick Koston <nick@koston.org>pull/36347/head
parent
5d7720832b
commit
d0fedad000
|
@ -606,6 +606,7 @@ omit =
|
|||
homeassistant/components/plex/sensor.py
|
||||
homeassistant/components/plugwise/__init__.py
|
||||
homeassistant/components/plugwise/climate.py
|
||||
homeassistant/components/plugwise/sensor.py
|
||||
homeassistant/components/plum_lightpad/*
|
||||
homeassistant/components/pocketcasts/sensor.py
|
||||
homeassistant/components/point/*
|
||||
|
|
|
@ -3,13 +3,14 @@
|
|||
import asyncio
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from Plugwise_Smile.Smile import Smile
|
||||
import async_timeout
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
@ -22,7 +23,8 @@ CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA)
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ALL_PLATFORMS = ["climate"]
|
||||
SENSOR_PLATFORMS = ["sensor"]
|
||||
ALL_PLATFORMS = ["climate", "sensor"]
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: dict):
|
||||
|
@ -100,7 +102,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
sw_version=api.smile_version[0],
|
||||
)
|
||||
|
||||
for component in ALL_PLATFORMS:
|
||||
platforms = ALL_PLATFORMS
|
||||
|
||||
single_master_thermostat = api.single_master_thermostat()
|
||||
if single_master_thermostat is None:
|
||||
platforms = SENSOR_PLATFORMS
|
||||
|
||||
for component in platforms:
|
||||
hass.async_create_task(
|
||||
hass.config_entries.async_forward_entry_setup(entry, component)
|
||||
)
|
||||
|
@ -127,11 +135,17 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
class SmileGateway(Entity):
|
||||
"""Represent Smile Gateway."""
|
||||
|
||||
def __init__(self, api, coordinator):
|
||||
"""Initialise the sensor."""
|
||||
def __init__(self, api, coordinator, name, dev_id):
|
||||
"""Initialise the gateway."""
|
||||
self._api = api
|
||||
self._coordinator = coordinator
|
||||
self._name = name
|
||||
self._dev_id = dev_id
|
||||
|
||||
self._unique_id = None
|
||||
self._model = None
|
||||
|
||||
self._entity_name = self._name
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
|
@ -148,11 +162,40 @@ class SmileGateway(Entity):
|
|||
"""Return True if entity is available."""
|
||||
return self._coordinator.last_update_success
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the entity, if any."""
|
||||
if not self._name:
|
||||
return None
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def device_info(self) -> Dict[str, any]:
|
||||
"""Return the device information."""
|
||||
|
||||
device_information = {
|
||||
"identifiers": {(DOMAIN, self._dev_id)},
|
||||
"name": self._entity_name,
|
||||
"manufacturer": "Plugwise",
|
||||
}
|
||||
|
||||
if self._model is not None:
|
||||
device_information["model"] = self._model.replace("_", " ").title()
|
||||
|
||||
if self._dev_id != self._api.gateway_id:
|
||||
device_information["via_device"] = (DOMAIN, self._api.gateway_id)
|
||||
|
||||
return device_information
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Subscribe to updates."""
|
||||
self.async_on_remove(self._coordinator.async_add_listener(self._process_data))
|
||||
self._async_process_data()
|
||||
self.async_on_remove(
|
||||
self._coordinator.async_add_listener(self._async_process_data)
|
||||
)
|
||||
|
||||
def _process_data(self):
|
||||
@callback
|
||||
def _async_process_data(self):
|
||||
"""Interpret and process API data."""
|
||||
raise NotImplementedError
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""Plugwise Climate component for Home Assistant."""
|
||||
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
from Plugwise_Smile.Smile import Smile
|
||||
|
||||
|
@ -17,16 +16,10 @@ from homeassistant.components.climate.const import (
|
|||
SUPPORT_TARGET_TEMPERATURE,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
|
||||
from homeassistant.core import callback
|
||||
|
||||
from . import SmileGateway
|
||||
from .const import (
|
||||
DEFAULT_MAX_TEMP,
|
||||
DEFAULT_MIN_TEMP,
|
||||
DOMAIN,
|
||||
SCHEDULE_OFF,
|
||||
SCHEDULE_ON,
|
||||
THERMOSTAT_ICON,
|
||||
)
|
||||
from .const import DEFAULT_MAX_TEMP, DEFAULT_MIN_TEMP, DOMAIN, SCHEDULE_OFF, SCHEDULE_ON
|
||||
|
||||
HVAC_MODES_HEAT_ONLY = [HVAC_MODE_HEAT, HVAC_MODE_AUTO]
|
||||
HVAC_MODES_HEAT_COOL = [HVAC_MODE_HEAT_COOL, HVAC_MODE_AUTO]
|
||||
|
@ -47,20 +40,20 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
"zone_thermostat",
|
||||
"thermostatic_radiator_valve",
|
||||
]
|
||||
all_entities = api.get_all_devices()
|
||||
all_devices = api.get_all_devices()
|
||||
|
||||
for dev_id, device in all_entities.items():
|
||||
for dev_id, device_properties in all_devices.items():
|
||||
|
||||
if device["class"] not in thermostat_classes:
|
||||
if device_properties["class"] not in thermostat_classes:
|
||||
continue
|
||||
|
||||
thermostat = PwThermostat(
|
||||
api,
|
||||
coordinator,
|
||||
device["name"],
|
||||
device_properties["name"],
|
||||
dev_id,
|
||||
device["location"],
|
||||
device["class"],
|
||||
device_properties["location"],
|
||||
device_properties["class"],
|
||||
DEFAULT_MIN_TEMP,
|
||||
DEFAULT_MAX_TEMP,
|
||||
)
|
||||
|
@ -77,11 +70,9 @@ class PwThermostat(SmileGateway, ClimateEntity):
|
|||
self, api, coordinator, name, dev_id, loc_id, model, min_temp, max_temp
|
||||
):
|
||||
"""Set up the Plugwise API."""
|
||||
super().__init__(api, coordinator)
|
||||
super().__init__(api, coordinator, name, dev_id)
|
||||
|
||||
self._api = api
|
||||
self._name = name
|
||||
self._dev_id = dev_id
|
||||
self._loc_id = loc_id
|
||||
self._model = model
|
||||
self._min_temp = min_temp
|
||||
|
@ -92,9 +83,9 @@ class PwThermostat(SmileGateway, ClimateEntity):
|
|||
self._preset_mode = None
|
||||
self._presets = None
|
||||
self._presets_list = None
|
||||
self._boiler_state = None
|
||||
self._heating_state = None
|
||||
self._cooling_state = None
|
||||
self._compressor_state = None
|
||||
self._dhw_state = None
|
||||
self._hvac_mode = None
|
||||
self._schema_names = None
|
||||
|
@ -111,43 +102,16 @@ class PwThermostat(SmileGateway, ClimateEntity):
|
|||
def hvac_action(self):
|
||||
"""Return the current action."""
|
||||
if self._single_thermostat:
|
||||
if self._heating_state or self._boiler_state:
|
||||
if self._heating_state:
|
||||
return CURRENT_HVAC_HEAT
|
||||
if self._cooling_state:
|
||||
return CURRENT_HVAC_COOL
|
||||
return CURRENT_HVAC_IDLE
|
||||
if self._heating_state is not None or self._boiler_state is not None:
|
||||
if self._heating_state is not None:
|
||||
if self._setpoint > self._temperature:
|
||||
return CURRENT_HVAC_HEAT
|
||||
return CURRENT_HVAC_IDLE
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the thermostat, if any."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def device_info(self) -> Dict[str, any]:
|
||||
"""Return the device information."""
|
||||
|
||||
device_information = {
|
||||
"identifiers": {(DOMAIN, self._dev_id)},
|
||||
"name": self._name,
|
||||
"manufacturer": "Plugwise",
|
||||
"model": self._model.replace("_", " ").title(),
|
||||
}
|
||||
|
||||
if self._dev_id != self._api.gateway_id:
|
||||
device_information["via_device"] = (DOMAIN, self._api.gateway_id)
|
||||
del device_information["via_device"]
|
||||
|
||||
return device_information
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon to use in the frontend."""
|
||||
return THERMOSTAT_ICON
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Return the list of supported features."""
|
||||
|
@ -172,8 +136,8 @@ class PwThermostat(SmileGateway, ClimateEntity):
|
|||
@property
|
||||
def hvac_modes(self):
|
||||
"""Return the available hvac modes list."""
|
||||
if self._heating_state is not None or self._boiler_state is not None:
|
||||
if self._cooling_state is not None:
|
||||
if self._heating_state is not None:
|
||||
if self._compressor_state is not None:
|
||||
return HVAC_MODES_HEAT_COOL
|
||||
return HVAC_MODES_HEAT_ONLY
|
||||
|
||||
|
@ -258,7 +222,8 @@ class PwThermostat(SmileGateway, ClimateEntity):
|
|||
except Smile.PlugwiseError:
|
||||
_LOGGER.error("Error while communicating to device")
|
||||
|
||||
def _process_data(self):
|
||||
@callback
|
||||
def _async_process_data(self):
|
||||
"""Update the data for this climate device."""
|
||||
climate_data = self._api.get_device_data(self._dev_id)
|
||||
heater_central_data = self._api.get_device_data(self._api.heater_id)
|
||||
|
@ -286,21 +251,18 @@ class PwThermostat(SmileGateway, ClimateEntity):
|
|||
if "active_preset" in climate_data:
|
||||
self._preset_mode = climate_data["active_preset"]
|
||||
|
||||
if "boiler_state" in heater_central_data:
|
||||
if heater_central_data["boiler_state"] is not None:
|
||||
self._boiler_state = heater_central_data["boiler_state"]
|
||||
if "heating_state" in heater_central_data:
|
||||
if heater_central_data["heating_state"] is not None:
|
||||
self._heating_state = heater_central_data["heating_state"]
|
||||
if "cooling_state" in heater_central_data:
|
||||
if heater_central_data["cooling_state"] is not None:
|
||||
self._cooling_state = heater_central_data["cooling_state"]
|
||||
if heater_central_data.get("heating_state") is not None:
|
||||
self._heating_state = heater_central_data["heating_state"]
|
||||
if heater_central_data.get("cooling_state") is not None:
|
||||
self._cooling_state = heater_central_data["cooling_state"]
|
||||
if heater_central_data.get("compressor_state") is not None:
|
||||
self._compressor_state = heater_central_data["compressor_state"]
|
||||
|
||||
if self._schema_status:
|
||||
self._hvac_mode = HVAC_MODE_AUTO
|
||||
elif self._heating_state is not None or self._boiler_state is not None:
|
||||
elif self._heating_state is not None:
|
||||
self._hvac_mode = HVAC_MODE_HEAT
|
||||
if self._cooling_state is not None:
|
||||
if self._compressor_state is not None:
|
||||
self._hvac_mode = HVAC_MODE_HEAT_COOL
|
||||
|
||||
self.async_write_ha_state()
|
||||
|
|
|
@ -47,7 +47,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
async def async_step_user(self, user_input=None):
|
||||
"""Handle the initial step."""
|
||||
errors = {}
|
||||
api = None
|
||||
|
||||
if user_input is not None:
|
||||
|
||||
try:
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
"""Constant for Plugwise component."""
|
||||
DOMAIN = "plugwise"
|
||||
|
||||
# Sensor mapping
|
||||
SENSOR_MAP_MODEL = 0
|
||||
SENSOR_MAP_UOM = 1
|
||||
SENSOR_MAP_DEVICE_CLASS = 2
|
||||
|
||||
# Default directives
|
||||
DEFAULT_NAME = "Smile"
|
||||
DEFAULT_USERNAME = "smile"
|
||||
|
@ -10,8 +15,6 @@ DEFAULT_MIN_TEMP = 4
|
|||
DEFAULT_MAX_TEMP = 30
|
||||
DEFAULT_SCAN_INTERVAL = {"thermostat": 60, "power": 10}
|
||||
|
||||
DEVICE_CLASS_GAS = "gas"
|
||||
|
||||
# Configuration directives
|
||||
CONF_MIN_TEMP = "min_temp"
|
||||
CONF_MAX_TEMP = "max_temp"
|
||||
|
@ -22,21 +25,15 @@ CONF_SOLAR = "solar"
|
|||
CONF_GAS = "gas"
|
||||
|
||||
ATTR_ILLUMINANCE = "illuminance"
|
||||
UNIT_LUMEN = "lm"
|
||||
|
||||
CURRENT_HVAC_DHW = "hot_water"
|
||||
|
||||
DEVICE_STATE = "device_state"
|
||||
|
||||
SCHEDULE_ON = "true"
|
||||
SCHEDULE_OFF = "false"
|
||||
|
||||
# Icons
|
||||
SWITCH_ICON = "mdi:electric-switch"
|
||||
THERMOSTAT_ICON = "mdi:thermometer"
|
||||
WATER_ICON = "mdi:water-pump"
|
||||
FLAME_ICON = "mdi:fire"
|
||||
COOL_ICON = "mdi:snowflake"
|
||||
FLAME_ICON = "mdi:fire"
|
||||
IDLE_ICON = "mdi:circle-off-outline"
|
||||
GAS_ICON = "mdi:fire"
|
||||
POWER_ICON = "mdi:flash"
|
||||
POWER_FAILURE_ICON = "mdi:flash-off"
|
||||
SWELL_SAG_ICON = "mdi:pulse"
|
||||
VALVE_ICON = "mdi:valve"
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"name": "Plugwise",
|
||||
"documentation": "https://www.home-assistant.io/integrations/plugwise",
|
||||
"requirements": ["Plugwise_Smile==0.2.10"],
|
||||
"dependencies": [],
|
||||
"codeowners": ["@CoMPaTech", "@bouwew"],
|
||||
"config_flow": true
|
||||
}
|
||||
|
|
|
@ -0,0 +1,354 @@
|
|||
"""Plugwise Sensor component for Home Assistant."""
|
||||
|
||||
import logging
|
||||
|
||||
from homeassistant.const import (
|
||||
DEVICE_CLASS_BATTERY,
|
||||
DEVICE_CLASS_ILLUMINANCE,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_PRESSURE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ENERGY_KILO_WATT_HOUR,
|
||||
ENERGY_WATT_HOUR,
|
||||
POWER_WATT,
|
||||
PRESSURE_BAR,
|
||||
TEMP_CELSIUS,
|
||||
UNIT_PERCENTAGE,
|
||||
VOLUME_CUBIC_METERS,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
from . import SmileGateway
|
||||
from .const import (
|
||||
COOL_ICON,
|
||||
DEVICE_STATE,
|
||||
DOMAIN,
|
||||
FLAME_ICON,
|
||||
IDLE_ICON,
|
||||
SENSOR_MAP_DEVICE_CLASS,
|
||||
SENSOR_MAP_MODEL,
|
||||
SENSOR_MAP_UOM,
|
||||
UNIT_LUMEN,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ATTR_TEMPERATURE = [
|
||||
"Temperature",
|
||||
TEMP_CELSIUS,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
]
|
||||
ATTR_BATTERY_LEVEL = [
|
||||
"Charge",
|
||||
UNIT_PERCENTAGE,
|
||||
DEVICE_CLASS_BATTERY,
|
||||
]
|
||||
ATTR_ILLUMINANCE = [
|
||||
"Illuminance",
|
||||
UNIT_LUMEN,
|
||||
DEVICE_CLASS_ILLUMINANCE,
|
||||
]
|
||||
ATTR_PRESSURE = ["Pressure", PRESSURE_BAR, DEVICE_CLASS_PRESSURE]
|
||||
|
||||
TEMP_SENSOR_MAP = {
|
||||
"setpoint": ATTR_TEMPERATURE,
|
||||
"temperature": ATTR_TEMPERATURE,
|
||||
"intended_boiler_temperature": ATTR_TEMPERATURE,
|
||||
"temperature_difference": ATTR_TEMPERATURE,
|
||||
"outdoor_temperature": ATTR_TEMPERATURE,
|
||||
"water_temperature": ATTR_TEMPERATURE,
|
||||
"return_temperature": ATTR_TEMPERATURE,
|
||||
}
|
||||
|
||||
ENERGY_SENSOR_MAP = {
|
||||
"electricity_consumed": ["Current Consumed Power", POWER_WATT, DEVICE_CLASS_POWER],
|
||||
"electricity_produced": ["Current Produced Power", POWER_WATT, DEVICE_CLASS_POWER],
|
||||
"electricity_consumed_interval": [
|
||||
"Consumed Power Interval",
|
||||
ENERGY_WATT_HOUR,
|
||||
DEVICE_CLASS_POWER,
|
||||
],
|
||||
"electricity_produced_interval": [
|
||||
"Produced Power Interval",
|
||||
ENERGY_WATT_HOUR,
|
||||
DEVICE_CLASS_POWER,
|
||||
],
|
||||
"electricity_consumed_off_peak_point": [
|
||||
"Current Consumed Power (off peak)",
|
||||
POWER_WATT,
|
||||
DEVICE_CLASS_POWER,
|
||||
],
|
||||
"electricity_consumed_peak_point": [
|
||||
"Current Consumed Power",
|
||||
POWER_WATT,
|
||||
DEVICE_CLASS_POWER,
|
||||
],
|
||||
"electricity_consumed_off_peak_cumulative": [
|
||||
"Cumulative Consumed Power (off peak)",
|
||||
ENERGY_KILO_WATT_HOUR,
|
||||
DEVICE_CLASS_POWER,
|
||||
],
|
||||
"electricity_consumed_peak_cumulative": [
|
||||
"Cumulative Consumed Power",
|
||||
ENERGY_KILO_WATT_HOUR,
|
||||
DEVICE_CLASS_POWER,
|
||||
],
|
||||
"electricity_produced_off_peak_point": [
|
||||
"Current Consumed Power (off peak)",
|
||||
POWER_WATT,
|
||||
DEVICE_CLASS_POWER,
|
||||
],
|
||||
"electricity_produced_peak_point": [
|
||||
"Current Consumed Power",
|
||||
POWER_WATT,
|
||||
DEVICE_CLASS_POWER,
|
||||
],
|
||||
"electricity_produced_off_peak_cumulative": [
|
||||
"Cumulative Consumed Power (off peak)",
|
||||
ENERGY_KILO_WATT_HOUR,
|
||||
DEVICE_CLASS_POWER,
|
||||
],
|
||||
"electricity_produced_peak_cumulative": [
|
||||
"Cumulative Consumed Power",
|
||||
ENERGY_KILO_WATT_HOUR,
|
||||
DEVICE_CLASS_POWER,
|
||||
],
|
||||
"gas_consumed_interval": ["Current Consumed Gas", VOLUME_CUBIC_METERS, None],
|
||||
"gas_consumed_cumulative": ["Cumulative Consumed Gas", VOLUME_CUBIC_METERS, None],
|
||||
"net_electricity_point": ["Current net Power", POWER_WATT, DEVICE_CLASS_POWER],
|
||||
"net_electricity_cumulative": [
|
||||
"Cumulative net Power",
|
||||
ENERGY_KILO_WATT_HOUR,
|
||||
DEVICE_CLASS_POWER,
|
||||
],
|
||||
}
|
||||
|
||||
MISC_SENSOR_MAP = {
|
||||
"battery": ATTR_BATTERY_LEVEL,
|
||||
"illuminance": ATTR_ILLUMINANCE,
|
||||
"modulation_level": ["Heater Modulation Level", UNIT_PERCENTAGE, None],
|
||||
"valve_position": ["Valve Position", UNIT_PERCENTAGE, None],
|
||||
"water_pressure": ATTR_PRESSURE,
|
||||
}
|
||||
|
||||
INDICATE_ACTIVE_LOCAL_DEVICE = [
|
||||
"cooling_state",
|
||||
"flame_state",
|
||||
]
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up the Smile sensors from a config entry."""
|
||||
api = hass.data[DOMAIN][config_entry.entry_id]["api"]
|
||||
coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"]
|
||||
|
||||
entities = []
|
||||
all_devices = api.get_all_devices()
|
||||
single_thermostat = api.single_master_thermostat()
|
||||
for dev_id, device_properties in all_devices.items():
|
||||
data = api.get_device_data(dev_id)
|
||||
for sensor, sensor_type in {
|
||||
**TEMP_SENSOR_MAP,
|
||||
**ENERGY_SENSOR_MAP,
|
||||
**MISC_SENSOR_MAP,
|
||||
}.items():
|
||||
if sensor in data:
|
||||
if data[sensor] is None:
|
||||
continue
|
||||
|
||||
if "power" in device_properties["types"]:
|
||||
model = None
|
||||
|
||||
if "plug" in device_properties["types"]:
|
||||
model = "Metered Switch"
|
||||
|
||||
entities.append(
|
||||
PwPowerSensor(
|
||||
api,
|
||||
coordinator,
|
||||
device_properties["name"],
|
||||
dev_id,
|
||||
sensor,
|
||||
sensor_type,
|
||||
model,
|
||||
)
|
||||
)
|
||||
else:
|
||||
entities.append(
|
||||
PwThermostatSensor(
|
||||
api,
|
||||
coordinator,
|
||||
device_properties["name"],
|
||||
dev_id,
|
||||
sensor,
|
||||
sensor_type,
|
||||
)
|
||||
)
|
||||
|
||||
if single_thermostat is False:
|
||||
for state in INDICATE_ACTIVE_LOCAL_DEVICE:
|
||||
if state in data:
|
||||
entities.append(
|
||||
PwAuxDeviceSensor(
|
||||
api,
|
||||
coordinator,
|
||||
device_properties["name"],
|
||||
dev_id,
|
||||
DEVICE_STATE,
|
||||
)
|
||||
)
|
||||
break
|
||||
|
||||
async_add_entities(entities, True)
|
||||
|
||||
|
||||
class SmileSensor(SmileGateway):
|
||||
"""Represent Smile Sensors."""
|
||||
|
||||
def __init__(self, api, coordinator, name, dev_id, sensor):
|
||||
"""Initialise the sensor."""
|
||||
super().__init__(api, coordinator, name, dev_id)
|
||||
|
||||
self._sensor = sensor
|
||||
|
||||
self._dev_class = None
|
||||
self._state = None
|
||||
self._unit_of_measurement = None
|
||||
|
||||
if dev_id == self._api.heater_id:
|
||||
self._entity_name = "Auxiliary"
|
||||
|
||||
sensorname = sensor.replace("_", " ").title()
|
||||
self._name = f"{self._entity_name} {sensorname}"
|
||||
|
||||
if dev_id == self._api.gateway_id:
|
||||
self._entity_name = f"Smile {self._entity_name}"
|
||||
|
||||
self._unique_id = f"{dev_id}-{sensor}"
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Device class of this entity."""
|
||||
return self._dev_class
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Device class of this entity."""
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit of measurement of this entity, if any."""
|
||||
return self._unit_of_measurement
|
||||
|
||||
|
||||
class PwThermostatSensor(SmileSensor, Entity):
|
||||
"""Thermostat and climate sensor entities."""
|
||||
|
||||
def __init__(self, api, coordinator, name, dev_id, sensor, sensor_type):
|
||||
"""Set up the Plugwise API."""
|
||||
super().__init__(api, coordinator, name, dev_id, sensor)
|
||||
|
||||
self._model = sensor_type[SENSOR_MAP_MODEL]
|
||||
self._unit_of_measurement = sensor_type[SENSOR_MAP_UOM]
|
||||
self._dev_class = sensor_type[SENSOR_MAP_DEVICE_CLASS]
|
||||
|
||||
@callback
|
||||
def _async_process_data(self):
|
||||
"""Update the entity."""
|
||||
data = self._api.get_device_data(self._dev_id)
|
||||
|
||||
if not data:
|
||||
_LOGGER.error("Received no data for device %s.", self._entity_name)
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
if data.get(self._sensor) is not None:
|
||||
measurement = data[self._sensor]
|
||||
if self._sensor == "battery" or self._sensor == "valve_position":
|
||||
measurement = measurement * 100
|
||||
if self._unit_of_measurement == UNIT_PERCENTAGE:
|
||||
measurement = int(measurement)
|
||||
self._state = measurement
|
||||
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class PwAuxDeviceSensor(SmileSensor, Entity):
|
||||
"""Auxiliary sensor entities for the heating/cooling device."""
|
||||
|
||||
def __init__(self, api, coordinator, name, dev_id, sensor):
|
||||
"""Set up the Plugwise API."""
|
||||
super().__init__(api, coordinator, name, dev_id, sensor)
|
||||
|
||||
self._cooling_state = False
|
||||
self._heating_state = False
|
||||
self._icon = None
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon to use in the frontend."""
|
||||
return self._icon
|
||||
|
||||
@callback
|
||||
def _async_process_data(self):
|
||||
"""Update the entity."""
|
||||
data = self._api.get_device_data(self._dev_id)
|
||||
|
||||
if not data:
|
||||
_LOGGER.error("Received no data for device %s.", self._entity_name)
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
if data.get("heating_state") is not None:
|
||||
self._heating_state = data["heating_state"]
|
||||
if data.get("cooling_state") is not None:
|
||||
self._cooling_state = data["cooling_state"]
|
||||
|
||||
self._state = "idle"
|
||||
self._icon = IDLE_ICON
|
||||
if self._heating_state:
|
||||
self._state = "heating"
|
||||
self._icon = FLAME_ICON
|
||||
if self._cooling_state:
|
||||
self._state = "cooling"
|
||||
self._icon = COOL_ICON
|
||||
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class PwPowerSensor(SmileSensor, Entity):
|
||||
"""Power sensor entities."""
|
||||
|
||||
def __init__(self, api, coordinator, name, dev_id, sensor, sensor_type, model):
|
||||
"""Set up the Plugwise API."""
|
||||
super().__init__(api, coordinator, name, dev_id, sensor)
|
||||
|
||||
self._model = model
|
||||
if model is None:
|
||||
self._model = sensor_type[SENSOR_MAP_MODEL]
|
||||
|
||||
self._unit_of_measurement = sensor_type[SENSOR_MAP_UOM]
|
||||
self._dev_class = sensor_type[SENSOR_MAP_DEVICE_CLASS]
|
||||
|
||||
if dev_id == self._api.gateway_id:
|
||||
self._model = "P1 DSMR"
|
||||
|
||||
@callback
|
||||
def _async_process_data(self):
|
||||
"""Update the entity."""
|
||||
data = self._api.get_device_data(self._dev_id)
|
||||
|
||||
if not data:
|
||||
_LOGGER.error("Received no data for device %s.", self._entity_name)
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
if data.get(self._sensor) is not None:
|
||||
measurement = data[self._sensor]
|
||||
if self._unit_of_measurement == ENERGY_KILO_WATT_HOUR:
|
||||
measurement = int(measurement / 1000)
|
||||
self._state = measurement
|
||||
|
||||
self.async_write_ha_state()
|
Loading…
Reference in New Issue