mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 00:37:53 +00:00
Update plugwise 0.16.2 (#65933)
This commit is contained in:
parent
0ea82bdbfb
commit
d12a392767
@ -50,35 +50,33 @@ async def async_setup_entry(
|
||||
config_entry.entry_id
|
||||
][COORDINATOR]
|
||||
|
||||
entities: list[BinarySensorEntity] = []
|
||||
is_thermostat = api.single_master_thermostat()
|
||||
|
||||
all_devices = api.get_all_devices()
|
||||
for dev_id, device_properties in all_devices.items():
|
||||
|
||||
entities: list[PlugwiseBinarySensorEntity] = []
|
||||
for device_id, device_properties in coordinator.data.devices.items():
|
||||
if device_properties["class"] == "heater_central":
|
||||
data = api.get_device_data(dev_id)
|
||||
for description in BINARY_SENSORS:
|
||||
if description.key not in data:
|
||||
if (
|
||||
"binary_sensors" not in device_properties
|
||||
or description.key not in device_properties["binary_sensors"]
|
||||
):
|
||||
continue
|
||||
|
||||
entities.append(
|
||||
PwBinarySensor(
|
||||
PlugwiseBinarySensorEntity(
|
||||
api,
|
||||
coordinator,
|
||||
device_properties["name"],
|
||||
dev_id,
|
||||
device_id,
|
||||
description,
|
||||
)
|
||||
)
|
||||
|
||||
if device_properties["class"] == "gateway" and is_thermostat is not None:
|
||||
if device_properties["class"] == "gateway":
|
||||
entities.append(
|
||||
PwNotifySensor(
|
||||
PlugwiseNotifyBinarySensorEntity(
|
||||
api,
|
||||
coordinator,
|
||||
device_properties["name"],
|
||||
dev_id,
|
||||
device_id,
|
||||
BinarySensorEntityDescription(
|
||||
key="plugwise_notification",
|
||||
name="Plugwise Notification",
|
||||
@ -89,7 +87,7 @@ async def async_setup_entry(
|
||||
async_add_entities(entities, True)
|
||||
|
||||
|
||||
class SmileBinarySensor(PlugwiseEntity, BinarySensorEntity):
|
||||
class PlugwiseBinarySensorEntity(PlugwiseEntity, BinarySensorEntity):
|
||||
"""Represent Smile Binary Sensors."""
|
||||
|
||||
def __init__(
|
||||
@ -106,36 +104,23 @@ class SmileBinarySensor(PlugwiseEntity, BinarySensorEntity):
|
||||
self._attr_is_on = False
|
||||
self._attr_unique_id = f"{dev_id}-{description.key}"
|
||||
|
||||
if dev_id == self._api.heater_id:
|
||||
if dev_id == coordinator.data.gateway["heater_id"]:
|
||||
self._entity_name = "Auxiliary"
|
||||
|
||||
self._name = f"{self._entity_name} {description.name}"
|
||||
|
||||
if dev_id == self._api.gateway_id:
|
||||
if dev_id == coordinator.data.gateway["gateway_id"]:
|
||||
self._entity_name = f"Smile {self._entity_name}"
|
||||
|
||||
@callback
|
||||
def _async_process_data(self) -> None:
|
||||
"""Update the entity."""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class PwBinarySensor(SmileBinarySensor):
|
||||
"""Representation of a Plugwise binary_sensor."""
|
||||
|
||||
@callback
|
||||
def _async_process_data(self) -> None:
|
||||
"""Update the entity."""
|
||||
if not (data := self._api.get_device_data(self._dev_id)):
|
||||
if not (data := self.coordinator.data.devices.get(self._dev_id)):
|
||||
LOGGER.error("Received no data for device %s", self._dev_id)
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
if self.entity_description.key not in data:
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
self._attr_is_on = data[self.entity_description.key]
|
||||
self._attr_is_on = data["binary_sensors"].get(self.entity_description.key)
|
||||
|
||||
if self.entity_description.key == "dhw_state":
|
||||
self._attr_icon = FLOW_ON_ICON if self._attr_is_on else FLOW_OFF_ICON
|
||||
@ -145,27 +130,15 @@ class PwBinarySensor(SmileBinarySensor):
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class PwNotifySensor(SmileBinarySensor):
|
||||
class PlugwiseNotifyBinarySensorEntity(PlugwiseBinarySensorEntity):
|
||||
"""Representation of a Plugwise Notification binary_sensor."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
api: Smile,
|
||||
coordinator: PlugwiseDataUpdateCoordinator,
|
||||
name: str,
|
||||
dev_id: str,
|
||||
description: BinarySensorEntityDescription,
|
||||
) -> None:
|
||||
"""Set up the Plugwise API."""
|
||||
super().__init__(api, coordinator, name, dev_id, description)
|
||||
|
||||
self._attr_extra_state_attributes = {}
|
||||
|
||||
@callback
|
||||
def _async_process_data(self) -> None:
|
||||
"""Update the entity."""
|
||||
notify = self._api.notifications
|
||||
notify = self.coordinator.data.gateway["notifications"]
|
||||
|
||||
self._attr_extra_state_attributes = {}
|
||||
for severity in SEVERITIES:
|
||||
self._attr_extra_state_attributes[f"{severity}_msg"] = []
|
||||
|
||||
|
@ -10,8 +10,9 @@ from homeassistant.components.climate.const import (
|
||||
CURRENT_HVAC_HEAT,
|
||||
CURRENT_HVAC_IDLE,
|
||||
HVAC_MODE_AUTO,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_HEAT_COOL,
|
||||
HVAC_MODE_OFF,
|
||||
SUPPORT_PRESET_MODE,
|
||||
SUPPORT_TARGET_TEMPERATURE,
|
||||
)
|
||||
@ -32,8 +33,8 @@ from .const import (
|
||||
from .coordinator import PlugwiseDataUpdateCoordinator
|
||||
from .entity import PlugwiseEntity
|
||||
|
||||
HVAC_MODES_HEAT_ONLY = [HVAC_MODE_HEAT, HVAC_MODE_AUTO]
|
||||
HVAC_MODES_HEAT_COOL = [HVAC_MODE_HEAT_COOL, HVAC_MODE_AUTO]
|
||||
HVAC_MODES_HEAT_ONLY = [HVAC_MODE_HEAT, HVAC_MODE_AUTO, HVAC_MODE_OFF]
|
||||
HVAC_MODES_HEAT_COOL = [HVAC_MODE_HEAT, HVAC_MODE_COOL, HVAC_MODE_AUTO, HVAC_MODE_OFF]
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -45,24 +46,21 @@ async def async_setup_entry(
|
||||
api = hass.data[DOMAIN][config_entry.entry_id]["api"]
|
||||
coordinator = hass.data[DOMAIN][config_entry.entry_id][COORDINATOR]
|
||||
|
||||
entities = []
|
||||
entities: list[PlugwiseClimateEntity] = []
|
||||
thermostat_classes = [
|
||||
"thermostat",
|
||||
"zone_thermostat",
|
||||
"thermostatic_radiator_valve",
|
||||
]
|
||||
all_devices = api.get_all_devices()
|
||||
|
||||
for dev_id, device_properties in all_devices.items():
|
||||
|
||||
for device_id, device_properties in coordinator.data.devices.items():
|
||||
if device_properties["class"] not in thermostat_classes:
|
||||
continue
|
||||
|
||||
thermostat = PwThermostat(
|
||||
thermostat = PlugwiseClimateEntity(
|
||||
api,
|
||||
coordinator,
|
||||
device_properties["name"],
|
||||
dev_id,
|
||||
device_id,
|
||||
device_properties["location"],
|
||||
device_properties["class"],
|
||||
)
|
||||
@ -72,7 +70,7 @@ async def async_setup_entry(
|
||||
async_add_entities(entities, True)
|
||||
|
||||
|
||||
class PwThermostat(PlugwiseEntity, ClimateEntity):
|
||||
class PlugwiseClimateEntity(PlugwiseEntity, ClimateEntity):
|
||||
"""Representation of an Plugwise thermostat."""
|
||||
|
||||
_attr_hvac_mode = HVAC_MODE_HEAT
|
||||
@ -90,21 +88,19 @@ class PwThermostat(PlugwiseEntity, ClimateEntity):
|
||||
api: Smile,
|
||||
coordinator: PlugwiseDataUpdateCoordinator,
|
||||
name: str,
|
||||
dev_id: str,
|
||||
device_id: str,
|
||||
loc_id: str,
|
||||
model: str,
|
||||
) -> None:
|
||||
"""Set up the Plugwise API."""
|
||||
super().__init__(api, coordinator, name, dev_id)
|
||||
super().__init__(api, coordinator, name, device_id)
|
||||
self._attr_extra_state_attributes = {}
|
||||
self._attr_unique_id = f"{dev_id}-climate"
|
||||
self._attr_unique_id = f"{device_id}-climate"
|
||||
|
||||
self._api = api
|
||||
self._loc_id = loc_id
|
||||
self._model = model
|
||||
|
||||
self._presets = None
|
||||
self._single_thermostat = self._api.single_master_thermostat()
|
||||
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set new target temperature."""
|
||||
@ -124,7 +120,7 @@ class PwThermostat(PlugwiseEntity, ClimateEntity):
|
||||
async def async_set_hvac_mode(self, hvac_mode: str) -> None:
|
||||
"""Set the hvac mode."""
|
||||
state = SCHEDULE_OFF
|
||||
climate_data = self._api.get_device_data(self._dev_id)
|
||||
climate_data = self.coordinator.data.devices[self._dev_id]
|
||||
|
||||
if hvac_mode == HVAC_MODE_AUTO:
|
||||
state = SCHEDULE_ON
|
||||
@ -161,18 +157,20 @@ class PwThermostat(PlugwiseEntity, ClimateEntity):
|
||||
@callback
|
||||
def _async_process_data(self) -> None:
|
||||
"""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)
|
||||
data = self.coordinator.data.devices[self._dev_id]
|
||||
heater_central_data = self.coordinator.data.devices[
|
||||
self.coordinator.data.gateway["heater_id"]
|
||||
]
|
||||
|
||||
# Current & set temperatures
|
||||
if setpoint := climate_data.get("setpoint"):
|
||||
if setpoint := data["sensors"].get("setpoint"):
|
||||
self._attr_target_temperature = setpoint
|
||||
if temperature := climate_data.get("temperature"):
|
||||
if temperature := data["sensors"].get("temperature"):
|
||||
self._attr_current_temperature = temperature
|
||||
|
||||
# Presets handling
|
||||
self._attr_preset_mode = climate_data.get("active_preset")
|
||||
if presets := climate_data.get("presets"):
|
||||
self._attr_preset_mode = data.get("active_preset")
|
||||
if presets := data.get("presets"):
|
||||
self._presets = presets
|
||||
self._attr_preset_modes = list(presets)
|
||||
else:
|
||||
@ -181,31 +179,22 @@ class PwThermostat(PlugwiseEntity, ClimateEntity):
|
||||
|
||||
# Determine current hvac action
|
||||
self._attr_hvac_action = CURRENT_HVAC_IDLE
|
||||
if self._single_thermostat:
|
||||
if heater_central_data.get("heating_state"):
|
||||
self._attr_hvac_action = CURRENT_HVAC_HEAT
|
||||
elif heater_central_data.get("cooling_state"):
|
||||
self._attr_hvac_action = CURRENT_HVAC_COOL
|
||||
elif (
|
||||
self.target_temperature is not None
|
||||
and self.current_temperature is not None
|
||||
and self.target_temperature > self.current_temperature
|
||||
):
|
||||
if heater_central_data.get("heating_state"):
|
||||
self._attr_hvac_action = CURRENT_HVAC_HEAT
|
||||
elif heater_central_data.get("cooling_state"):
|
||||
self._attr_hvac_action = CURRENT_HVAC_COOL
|
||||
|
||||
# Determine hvac modes and current hvac mode
|
||||
self._attr_hvac_mode = HVAC_MODE_HEAT
|
||||
self._attr_hvac_modes = HVAC_MODES_HEAT_ONLY
|
||||
if heater_central_data.get("compressor_state") is not None:
|
||||
self._attr_hvac_mode = HVAC_MODE_HEAT_COOL
|
||||
if self.coordinator.data.gateway.get("cooling_present"):
|
||||
self._attr_hvac_modes = HVAC_MODES_HEAT_COOL
|
||||
if climate_data.get("selected_schedule") is not None:
|
||||
self._attr_hvac_mode = HVAC_MODE_AUTO
|
||||
if data.get("mode") in self._attr_hvac_modes:
|
||||
self._attr_hvac_mode = data["mode"]
|
||||
|
||||
# Extra attributes
|
||||
self._attr_extra_state_attributes = {
|
||||
"available_schemas": climate_data.get("available_schedules"),
|
||||
"selected_schema": climate_data.get("selected_schedule"),
|
||||
"available_schemas": data.get("available_schedules"),
|
||||
"selected_schema": data.get("selected_schedule"),
|
||||
}
|
||||
|
||||
self.async_write_ha_state()
|
||||
|
@ -1,17 +1,24 @@
|
||||
"""DataUpdateCoordinator for Plugwise."""
|
||||
from datetime import timedelta
|
||||
from typing import Any, NamedTuple
|
||||
|
||||
import async_timeout
|
||||
from plugwise import Smile
|
||||
from plugwise.exceptions import XMLDataMissingError
|
||||
from plugwise.exceptions import PlugwiseException, XMLDataMissingError
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
from .const import DEFAULT_SCAN_INTERVAL, DEFAULT_TIMEOUT, DOMAIN, LOGGER
|
||||
from .const import DEFAULT_SCAN_INTERVAL, DOMAIN, LOGGER
|
||||
|
||||
|
||||
class PlugwiseDataUpdateCoordinator(DataUpdateCoordinator[bool]):
|
||||
class PlugwiseData(NamedTuple):
|
||||
"""Plugwise data stored in the DataUpdateCoordinator."""
|
||||
|
||||
gateway: dict[str, Any]
|
||||
devices: dict[str, dict[str, Any]]
|
||||
|
||||
|
||||
class PlugwiseDataUpdateCoordinator(DataUpdateCoordinator[PlugwiseData]):
|
||||
"""Class to manage fetching Plugwise data from single endpoint."""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, api: Smile) -> None:
|
||||
@ -26,11 +33,14 @@ class PlugwiseDataUpdateCoordinator(DataUpdateCoordinator[bool]):
|
||||
)
|
||||
self.api = api
|
||||
|
||||
async def _async_update_data(self) -> bool:
|
||||
async def _async_update_data(self) -> PlugwiseData:
|
||||
"""Fetch data from Plugwise."""
|
||||
try:
|
||||
async with async_timeout.timeout(DEFAULT_TIMEOUT):
|
||||
await self.api.full_update_device()
|
||||
data = await self.api.async_update()
|
||||
except XMLDataMissingError as err:
|
||||
raise UpdateFailed("Smile update failed") from err
|
||||
return True
|
||||
raise UpdateFailed(
|
||||
f"No XML data received for: {self.api.smile_name}"
|
||||
) from err
|
||||
except PlugwiseException as err:
|
||||
raise UpdateFailed(f"Updated failed for: {self.api.smile_name}") from err
|
||||
return PlugwiseData(*data)
|
||||
|
@ -14,14 +14,12 @@ from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import PlugwiseDataUpdateCoordinator
|
||||
from .coordinator import PlugwiseData, PlugwiseDataUpdateCoordinator
|
||||
|
||||
|
||||
class PlugwiseEntity(CoordinatorEntity[bool]):
|
||||
class PlugwiseEntity(CoordinatorEntity[PlugwiseData]):
|
||||
"""Represent a PlugWise Entity."""
|
||||
|
||||
_model: str | None = None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
api: Smile,
|
||||
@ -45,6 +43,7 @@ class PlugwiseEntity(CoordinatorEntity[bool]):
|
||||
@property
|
||||
def device_info(self) -> DeviceInfo:
|
||||
"""Return the device information."""
|
||||
data = self.coordinator.data.devices[self._dev_id]
|
||||
device_information = DeviceInfo(
|
||||
identifiers={(DOMAIN, self._dev_id)},
|
||||
name=self._entity_name,
|
||||
@ -56,11 +55,14 @@ class PlugwiseEntity(CoordinatorEntity[bool]):
|
||||
ATTR_CONFIGURATION_URL
|
||||
] = f"http://{entry.data[CONF_HOST]}"
|
||||
|
||||
if self._model is not None:
|
||||
device_information[ATTR_MODEL] = self._model.replace("_", " ").title()
|
||||
if model := data.get("model"):
|
||||
device_information[ATTR_MODEL] = model
|
||||
|
||||
if self._dev_id != self._api.gateway_id:
|
||||
device_information[ATTR_VIA_DEVICE] = (DOMAIN, str(self._api.gateway_id))
|
||||
if self._dev_id != self.coordinator.data.gateway["gateway_id"]:
|
||||
device_information[ATTR_VIA_DEVICE] = (
|
||||
DOMAIN,
|
||||
str(self.coordinator.data.gateway["gateway_id"]),
|
||||
)
|
||||
|
||||
return device_information
|
||||
|
||||
|
@ -55,15 +55,14 @@ async def async_setup_entry_gw(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
|
||||
if not connected:
|
||||
raise ConfigEntryNotReady("Unable to connect to Smile")
|
||||
|
||||
coordinator = PlugwiseDataUpdateCoordinator(hass, api)
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
api.get_all_devices()
|
||||
|
||||
if entry.unique_id is None and api.smile_version[0] != "1.8.0":
|
||||
hass.config_entries.async_update_entry(entry, unique_id=api.smile_hostname)
|
||||
|
||||
coordinator = PlugwiseDataUpdateCoordinator(hass, api)
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
|
||||
"api": api,
|
||||
COORDINATOR: coordinator,
|
||||
@ -80,10 +79,8 @@ async def async_setup_entry_gw(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
sw_version=api.smile_version[0],
|
||||
)
|
||||
|
||||
single_master_thermostat = api.single_master_thermostat()
|
||||
|
||||
platforms = PLATFORMS_GATEWAY
|
||||
if single_master_thermostat is None:
|
||||
if coordinator.data.gateway["single_master_thermostat"] is None:
|
||||
platforms = SENSOR_PLATFORMS
|
||||
|
||||
hass.config_entries.async_setup_platforms(entry, platforms)
|
||||
|
@ -2,7 +2,7 @@
|
||||
"domain": "plugwise",
|
||||
"name": "Plugwise",
|
||||
"documentation": "https://www.home-assistant.io/integrations/plugwise",
|
||||
"requirements": ["plugwise==0.8.5"],
|
||||
"requirements": ["plugwise==0.16.2"],
|
||||
"codeowners": ["@CoMPaTech", "@bouwew", "@brefra"],
|
||||
"zeroconf": ["_plugwise._tcp.local."],
|
||||
"config_flow": true,
|
||||
|
@ -289,53 +289,37 @@ async def async_setup_entry(
|
||||
api = hass.data[DOMAIN][config_entry.entry_id]["api"]
|
||||
coordinator = hass.data[DOMAIN][config_entry.entry_id][COORDINATOR]
|
||||
|
||||
entities: list[SmileSensor] = []
|
||||
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)
|
||||
entities: list[PlugwiseSensorEnity] = []
|
||||
for device_id, device_properties in coordinator.data.devices.items():
|
||||
for description in SENSORS:
|
||||
if data.get(description.key) is None:
|
||||
if (
|
||||
"sensors" not in device_properties
|
||||
or device_properties["sensors"].get(description.key) 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,
|
||||
model,
|
||||
description,
|
||||
)
|
||||
)
|
||||
else:
|
||||
entities.append(
|
||||
PwThermostatSensor(
|
||||
api,
|
||||
coordinator,
|
||||
device_properties["name"],
|
||||
dev_id,
|
||||
description,
|
||||
)
|
||||
entities.append(
|
||||
PlugwiseSensorEnity(
|
||||
api,
|
||||
coordinator,
|
||||
device_properties["name"],
|
||||
device_id,
|
||||
description,
|
||||
)
|
||||
)
|
||||
|
||||
if single_thermostat is False:
|
||||
if coordinator.data.gateway["single_master_thermostat"] is False:
|
||||
# These sensors should actually be binary sensors.
|
||||
for description in INDICATE_ACTIVE_LOCAL_DEVICE_SENSORS:
|
||||
if description.key not in data:
|
||||
if description.key not in device_properties:
|
||||
continue
|
||||
|
||||
entities.append(
|
||||
PwAuxDeviceSensor(
|
||||
PlugwiseAuxSensorEntity(
|
||||
api,
|
||||
coordinator,
|
||||
device_properties["name"],
|
||||
dev_id,
|
||||
device_id,
|
||||
description,
|
||||
)
|
||||
)
|
||||
@ -344,47 +328,43 @@ async def async_setup_entry(
|
||||
async_add_entities(entities, True)
|
||||
|
||||
|
||||
class SmileSensor(PlugwiseEntity, SensorEntity):
|
||||
"""Represent Smile Sensors."""
|
||||
class PlugwiseSensorEnity(PlugwiseEntity, SensorEntity):
|
||||
"""Represent Plugwise Sensors."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
api: Smile,
|
||||
coordinator: PlugwiseDataUpdateCoordinator,
|
||||
name: str,
|
||||
dev_id: str,
|
||||
device_id: str,
|
||||
description: SensorEntityDescription,
|
||||
) -> None:
|
||||
"""Initialise the sensor."""
|
||||
super().__init__(api, coordinator, name, dev_id)
|
||||
super().__init__(api, coordinator, name, device_id)
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{dev_id}-{description.key}"
|
||||
self._attr_unique_id = f"{device_id}-{description.key}"
|
||||
|
||||
if dev_id == self._api.heater_id:
|
||||
if device_id == coordinator.data.gateway["heater_id"]:
|
||||
self._entity_name = "Auxiliary"
|
||||
|
||||
self._name = f"{self._entity_name} {description.name}"
|
||||
|
||||
if dev_id == self._api.gateway_id:
|
||||
if device_id == coordinator.data.gateway["gateway_id"]:
|
||||
self._entity_name = f"Smile {self._entity_name}"
|
||||
|
||||
|
||||
class PwThermostatSensor(SmileSensor):
|
||||
"""Thermostat (or generic) sensor devices."""
|
||||
|
||||
@callback
|
||||
def _async_process_data(self) -> None:
|
||||
"""Update the entity."""
|
||||
if not (data := self._api.get_device_data(self._dev_id)):
|
||||
if not (data := self.coordinator.data.devices.get(self._dev_id)):
|
||||
LOGGER.error("Received no data for device %s", self._entity_name)
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
self._attr_native_value = data.get(self.entity_description.key)
|
||||
self._attr_native_value = data["sensors"].get(self.entity_description.key)
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class PwAuxDeviceSensor(SmileSensor):
|
||||
class PlugwiseAuxSensorEntity(PlugwiseSensorEnity):
|
||||
"""Auxiliary Device Sensors."""
|
||||
|
||||
_cooling_state = False
|
||||
@ -393,7 +373,7 @@ class PwAuxDeviceSensor(SmileSensor):
|
||||
@callback
|
||||
def _async_process_data(self) -> None:
|
||||
"""Update the entity."""
|
||||
if not (data := self._api.get_device_data(self._dev_id)):
|
||||
if not (data := self.coordinator.data.devices.get(self._dev_id)):
|
||||
LOGGER.error("Received no data for device %s", self._entity_name)
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
@ -413,33 +393,3 @@ class PwAuxDeviceSensor(SmileSensor):
|
||||
self._attr_icon = COOL_ICON
|
||||
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class PwPowerSensor(SmileSensor):
|
||||
"""Power sensor entities."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
api: Smile,
|
||||
coordinator: PlugwiseDataUpdateCoordinator,
|
||||
name: str,
|
||||
dev_id: str,
|
||||
model: str | None,
|
||||
description: SensorEntityDescription,
|
||||
) -> None:
|
||||
"""Set up the Plugwise API."""
|
||||
super().__init__(api, coordinator, name, dev_id, description)
|
||||
self._model = model
|
||||
if dev_id == self._api.gateway_id:
|
||||
self._model = "P1 DSMR"
|
||||
|
||||
@callback
|
||||
def _async_process_data(self) -> None:
|
||||
"""Update the entity."""
|
||||
if not (data := self._api.get_device_data(self._dev_id)):
|
||||
LOGGER.error("Received no data for device %s", self._entity_name)
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
self._attr_native_value = data.get(self.entity_description.key)
|
||||
self.async_write_ha_state()
|
||||
|
@ -25,34 +25,27 @@ async def async_setup_entry(
|
||||
api = hass.data[DOMAIN][config_entry.entry_id]["api"]
|
||||
coordinator = hass.data[DOMAIN][config_entry.entry_id][COORDINATOR]
|
||||
|
||||
entities = []
|
||||
switch_classes = ["plug", "switch_group"]
|
||||
|
||||
all_devices = api.get_all_devices()
|
||||
for dev_id, device_properties in all_devices.items():
|
||||
members = None
|
||||
model = None
|
||||
|
||||
if any(
|
||||
switch_class in device_properties["types"]
|
||||
for switch_class in switch_classes
|
||||
entities: list[PlugwiseSwitchEntity] = []
|
||||
for device_id, device_properties in coordinator.data.devices.items():
|
||||
if (
|
||||
"switches" not in device_properties
|
||||
or "relay" not in device_properties["switches"]
|
||||
):
|
||||
if "plug" in device_properties["types"]:
|
||||
model = "Metered Switch"
|
||||
if "switch_group" in device_properties["types"]:
|
||||
members = device_properties["members"]
|
||||
model = "Switch Group"
|
||||
continue
|
||||
|
||||
entities.append(
|
||||
GwSwitch(
|
||||
api, coordinator, device_properties["name"], dev_id, members, model
|
||||
)
|
||||
entities.append(
|
||||
PlugwiseSwitchEntity(
|
||||
api,
|
||||
coordinator,
|
||||
device_properties["name"],
|
||||
device_id,
|
||||
)
|
||||
)
|
||||
|
||||
async_add_entities(entities, True)
|
||||
|
||||
|
||||
class GwSwitch(PlugwiseEntity, SwitchEntity):
|
||||
class PlugwiseSwitchEntity(PlugwiseEntity, SwitchEntity):
|
||||
"""Representation of a Plugwise plug."""
|
||||
|
||||
_attr_icon = SWITCH_ICON
|
||||
@ -62,24 +55,19 @@ class GwSwitch(PlugwiseEntity, SwitchEntity):
|
||||
api: Smile,
|
||||
coordinator: PlugwiseDataUpdateCoordinator,
|
||||
name: str,
|
||||
dev_id: str,
|
||||
members: list[str] | None,
|
||||
model: str | None,
|
||||
device_id: str,
|
||||
) -> None:
|
||||
"""Set up the Plugwise API."""
|
||||
super().__init__(api, coordinator, name, dev_id)
|
||||
self._attr_unique_id = f"{dev_id}-plug"
|
||||
|
||||
self._members = members
|
||||
self._model = model
|
||||
|
||||
super().__init__(api, coordinator, name, device_id)
|
||||
self._attr_unique_id = f"{device_id}-plug"
|
||||
self._members = coordinator.data.devices[device_id].get("members")
|
||||
self._attr_is_on = False
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the device on."""
|
||||
try:
|
||||
state_on = await self._api.set_relay_state(
|
||||
self._dev_id, self._members, "on"
|
||||
state_on = await self._api.set_switch_state(
|
||||
self._dev_id, self._members, "relay", "on"
|
||||
)
|
||||
except PlugwiseException:
|
||||
LOGGER.error("Error while communicating to device")
|
||||
@ -91,8 +79,8 @@ class GwSwitch(PlugwiseEntity, SwitchEntity):
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the device off."""
|
||||
try:
|
||||
state_off = await self._api.set_relay_state(
|
||||
self._dev_id, self._members, "off"
|
||||
state_off = await self._api.set_switch_state(
|
||||
self._dev_id, self._members, "relay", "off"
|
||||
)
|
||||
except PlugwiseException:
|
||||
LOGGER.error("Error while communicating to device")
|
||||
@ -104,12 +92,10 @@ class GwSwitch(PlugwiseEntity, SwitchEntity):
|
||||
@callback
|
||||
def _async_process_data(self) -> None:
|
||||
"""Update the data from the Plugs."""
|
||||
if not (data := self._api.get_device_data(self._dev_id)):
|
||||
if not (data := self.coordinator.data.devices.get(self._dev_id)):
|
||||
LOGGER.error("Received no data for device %s", self._name)
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
if "relay" in data:
|
||||
self._attr_is_on = data["relay"]
|
||||
|
||||
self._attr_is_on = data["switches"].get("relay")
|
||||
self.async_write_ha_state()
|
||||
|
@ -1264,7 +1264,7 @@ plexauth==0.0.6
|
||||
plexwebsocket==0.0.13
|
||||
|
||||
# homeassistant.components.plugwise
|
||||
plugwise==0.8.5
|
||||
plugwise==0.16.2
|
||||
|
||||
# homeassistant.components.plum_lightpad
|
||||
plumlightpad==0.0.11
|
||||
|
@ -10,7 +10,6 @@
|
||||
codecov==2.1.12
|
||||
coverage==6.3.1
|
||||
freezegun==1.1.0
|
||||
jsonpickle==1.4.1
|
||||
mock-open==1.4.0
|
||||
mypy==0.931
|
||||
pre-commit==2.17.0
|
||||
|
@ -786,7 +786,7 @@ plexauth==0.0.6
|
||||
plexwebsocket==0.0.13
|
||||
|
||||
# homeassistant.components.plugwise
|
||||
plugwise==0.8.5
|
||||
plugwise==0.16.2
|
||||
|
||||
# homeassistant.components.plum_lightpad
|
||||
plumlightpad==0.0.11
|
||||
|
@ -3,7 +3,7 @@ PIP_CACHE=$1
|
||||
|
||||
# Number of existing dependency conflicts
|
||||
# Update if a PR resolve one!
|
||||
DEPENDENCY_CONFLICTS=11
|
||||
DEPENDENCY_CONFLICTS=10
|
||||
|
||||
PIP_CHECK=$(pip check --cache-dir=$PIP_CACHE)
|
||||
LINE_COUNT=$(echo "$PIP_CHECK" | wc -l)
|
||||
|
@ -4,10 +4,10 @@ from __future__ import annotations
|
||||
from collections.abc import Generator
|
||||
from functools import partial
|
||||
from http import HTTPStatus
|
||||
import json
|
||||
import re
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import jsonpickle
|
||||
from plugwise.exceptions import (
|
||||
ConnectionFailedError,
|
||||
InvalidAuthentication,
|
||||
@ -23,7 +23,7 @@ from tests.test_util.aiohttp import AiohttpClientMocker
|
||||
def _read_json(environment, call):
|
||||
"""Undecode the json data."""
|
||||
fixture = load_fixture(f"plugwise/{environment}/{call}.json")
|
||||
return jsonpickle.decode(fixture)
|
||||
return json.loads(fixture)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -93,13 +93,11 @@ def mock_smile_adam():
|
||||
smile_mock.return_value.smile_version = "3.0.15"
|
||||
smile_mock.return_value.smile_type = "thermostat"
|
||||
smile_mock.return_value.smile_hostname = "smile98765"
|
||||
smile_mock.return_value.smile_name = "Adam"
|
||||
|
||||
smile_mock.return_value.notifications = _read_json(chosen_env, "notifications")
|
||||
|
||||
smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True)
|
||||
smile_mock.return_value.full_update_device.side_effect = AsyncMock(
|
||||
return_value=True
|
||||
)
|
||||
smile_mock.return_value.single_master_thermostat.side_effect = Mock(
|
||||
return_value=False
|
||||
)
|
||||
@ -110,17 +108,13 @@ def mock_smile_adam():
|
||||
smile_mock.return_value.set_temperature.side_effect = AsyncMock(
|
||||
return_value=True
|
||||
)
|
||||
smile_mock.return_value.set_relay_state.side_effect = AsyncMock(
|
||||
smile_mock.return_value.async_update.side_effect = AsyncMock(
|
||||
return_value=_read_json(chosen_env, "all_data")
|
||||
)
|
||||
smile_mock.return_value.set_switch_state.side_effect = AsyncMock(
|
||||
return_value=True
|
||||
)
|
||||
|
||||
smile_mock.return_value.get_all_devices.return_value = _read_json(
|
||||
chosen_env, "get_all_devices"
|
||||
)
|
||||
smile_mock.return_value.get_device_data.side_effect = partial(
|
||||
_get_device_data, chosen_env
|
||||
)
|
||||
|
||||
yield smile_mock.return_value
|
||||
|
||||
|
||||
@ -138,13 +132,11 @@ def mock_smile_anna():
|
||||
smile_mock.return_value.smile_version = "4.0.15"
|
||||
smile_mock.return_value.smile_type = "thermostat"
|
||||
smile_mock.return_value.smile_hostname = "smile98765"
|
||||
smile_mock.return_value.smile_name = "Anna"
|
||||
|
||||
smile_mock.return_value.notifications = _read_json(chosen_env, "notifications")
|
||||
|
||||
smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True)
|
||||
smile_mock.return_value.full_update_device.side_effect = AsyncMock(
|
||||
return_value=True
|
||||
)
|
||||
smile_mock.return_value.single_master_thermostat.side_effect = Mock(
|
||||
return_value=True
|
||||
)
|
||||
@ -155,12 +147,12 @@ def mock_smile_anna():
|
||||
smile_mock.return_value.set_temperature.side_effect = AsyncMock(
|
||||
return_value=True
|
||||
)
|
||||
smile_mock.return_value.set_relay_state.side_effect = AsyncMock(
|
||||
smile_mock.return_value.set_switch_state.side_effect = AsyncMock(
|
||||
return_value=True
|
||||
)
|
||||
|
||||
smile_mock.return_value.get_all_devices.return_value = _read_json(
|
||||
chosen_env, "get_all_devices"
|
||||
smile_mock.return_value.async_update.side_effect = AsyncMock(
|
||||
return_value=_read_json(chosen_env, "all_data")
|
||||
)
|
||||
smile_mock.return_value.get_device_data.side_effect = partial(
|
||||
_get_device_data, chosen_env
|
||||
@ -183,25 +175,24 @@ def mock_smile_p1():
|
||||
smile_mock.return_value.smile_version = "3.3.9"
|
||||
smile_mock.return_value.smile_type = "power"
|
||||
smile_mock.return_value.smile_hostname = "smile98765"
|
||||
smile_mock.return_value.smile_name = "Smile P1"
|
||||
|
||||
smile_mock.return_value.notifications = _read_json(chosen_env, "notifications")
|
||||
|
||||
smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True)
|
||||
smile_mock.return_value.full_update_device.side_effect = AsyncMock(
|
||||
return_value=True
|
||||
)
|
||||
|
||||
smile_mock.return_value.single_master_thermostat.side_effect = Mock(
|
||||
return_value=None
|
||||
)
|
||||
|
||||
smile_mock.return_value.get_all_devices.return_value = _read_json(
|
||||
chosen_env, "get_all_devices"
|
||||
)
|
||||
smile_mock.return_value.get_device_data.side_effect = partial(
|
||||
_get_device_data, chosen_env
|
||||
)
|
||||
|
||||
smile_mock.return_value.async_update.side_effect = AsyncMock(
|
||||
return_value=_read_json(chosen_env, "all_data")
|
||||
)
|
||||
|
||||
yield smile_mock.return_value
|
||||
|
||||
|
||||
@ -219,20 +210,18 @@ def mock_stretch():
|
||||
smile_mock.return_value.smile_version = "3.1.11"
|
||||
smile_mock.return_value.smile_type = "stretch"
|
||||
smile_mock.return_value.smile_hostname = "stretch98765"
|
||||
smile_mock.return_value.smile_name = "Stretch"
|
||||
|
||||
smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True)
|
||||
smile_mock.return_value.full_update_device.side_effect = AsyncMock(
|
||||
smile_mock.return_value.set_switch_state.side_effect = AsyncMock(
|
||||
return_value=True
|
||||
)
|
||||
smile_mock.return_value.set_relay_state.side_effect = AsyncMock(
|
||||
return_value=True
|
||||
)
|
||||
|
||||
smile_mock.return_value.get_all_devices.return_value = _read_json(
|
||||
chosen_env, "get_all_devices"
|
||||
)
|
||||
smile_mock.return_value.get_device_data.side_effect = partial(
|
||||
_get_device_data, chosen_env
|
||||
)
|
||||
|
||||
smile_mock.return_value.async_update.side_effect = AsyncMock(
|
||||
return_value=_read_json(chosen_env, "all_data")
|
||||
)
|
||||
|
||||
yield smile_mock.return_value
|
||||
|
@ -0,0 +1,358 @@
|
||||
[
|
||||
{
|
||||
"active_device": true,
|
||||
"cooling_present": null,
|
||||
"gateway_id": "fe799307f1624099878210aa0b9f1475",
|
||||
"heater_id": "90986d591dcd426cae3ec3e8111ff730",
|
||||
"single_master_thermostat": false,
|
||||
"smile_name": "Adam",
|
||||
"notifications": {
|
||||
"af82e4ccf9c548528166d38e560662a4": {
|
||||
"warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18. Please check the connection and restart the device."
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"df4a4a8169904cdb9c03d61a21f42140": {
|
||||
"class": "zone_thermostat",
|
||||
"fw": "2016-10-27T02:00:00+02:00",
|
||||
"location": "12493538af164a409c6a1c79e38afe1c",
|
||||
"model": "Lisa",
|
||||
"name": "Zone Lisa Bios",
|
||||
"vendor": "Plugwise",
|
||||
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
|
||||
"active_preset": "away",
|
||||
"presets": {
|
||||
"home": [20.0, 22.0],
|
||||
"asleep": [17.0, 24.0],
|
||||
"away": [15.0, 25.0],
|
||||
"vacation": [15.0, 28.0],
|
||||
"no_frost": [10.0, 30.0]
|
||||
},
|
||||
"available_schedules": [
|
||||
"CV Roan",
|
||||
"Bios Schema met Film Avond",
|
||||
"GF7 Woonkamer",
|
||||
"Badkamer Schema",
|
||||
"CV Jessie"
|
||||
],
|
||||
"selected_schedule": "None",
|
||||
"schedule_temperature": 15.0,
|
||||
"last_used": "Badkamer Schema",
|
||||
"mode": "off",
|
||||
"sensors": { "temperature": 16.5, "setpoint": 13.0, "battery": 67 }
|
||||
},
|
||||
"b310b72a0e354bfab43089919b9a88bf": {
|
||||
"class": "thermo_sensor",
|
||||
"fw": "2019-03-27T01:00:00+01:00",
|
||||
"location": "c50f167537524366a5af7aa3942feb1e",
|
||||
"model": "Tom/Floor",
|
||||
"name": "Floor kraan",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"temperature": 26.0,
|
||||
"setpoint": 21.5,
|
||||
"temperature_difference": 3.5,
|
||||
"valve_position": 100
|
||||
}
|
||||
},
|
||||
"a2c3583e0a6349358998b760cea82d2a": {
|
||||
"class": "thermo_sensor",
|
||||
"fw": "2019-03-27T01:00:00+01:00",
|
||||
"location": "12493538af164a409c6a1c79e38afe1c",
|
||||
"model": "Tom/Floor",
|
||||
"name": "Bios Cv Thermostatic Radiator ",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"temperature": 17.2,
|
||||
"setpoint": 13.0,
|
||||
"battery": 62,
|
||||
"temperature_difference": -0.2,
|
||||
"valve_position": 0.0
|
||||
}
|
||||
},
|
||||
"b59bcebaf94b499ea7d46e4a66fb62d8": {
|
||||
"class": "zone_thermostat",
|
||||
"fw": "2016-08-02T02:00:00+02:00",
|
||||
"location": "c50f167537524366a5af7aa3942feb1e",
|
||||
"model": "Lisa",
|
||||
"name": "Zone Lisa WK",
|
||||
"vendor": "Plugwise",
|
||||
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
|
||||
"active_preset": "home",
|
||||
"presets": {
|
||||
"home": [20.0, 22.0],
|
||||
"asleep": [17.0, 24.0],
|
||||
"away": [15.0, 25.0],
|
||||
"vacation": [15.0, 28.0],
|
||||
"no_frost": [10.0, 30.0]
|
||||
},
|
||||
"available_schedules": [
|
||||
"CV Roan",
|
||||
"Bios Schema met Film Avond",
|
||||
"GF7 Woonkamer",
|
||||
"Badkamer Schema",
|
||||
"CV Jessie"
|
||||
],
|
||||
"selected_schedule": "GF7 Woonkamer",
|
||||
"schedule_temperature": 20.0,
|
||||
"last_used": "GF7 Woonkamer",
|
||||
"mode": "auto",
|
||||
"sensors": { "temperature": 20.9, "setpoint": 21.5, "battery": 34 }
|
||||
},
|
||||
"fe799307f1624099878210aa0b9f1475": {
|
||||
"class": "gateway",
|
||||
"fw": "3.0.15",
|
||||
"location": "1f9dcf83fd4e4b66b72ff787957bfe5d",
|
||||
"model": "Adam",
|
||||
"name": "Adam",
|
||||
"vendor": "Plugwise B.V.",
|
||||
"binary_sensors": { "plugwise_notification": true },
|
||||
"sensors": { "outdoor_temperature": 7.81 }
|
||||
},
|
||||
"d3da73bde12a47d5a6b8f9dad971f2ec": {
|
||||
"class": "thermo_sensor",
|
||||
"fw": "2019-03-27T01:00:00+01:00",
|
||||
"location": "82fa13f017d240daa0d0ea1775420f24",
|
||||
"model": "Tom/Floor",
|
||||
"name": "Thermostatic Radiator Jessie",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"temperature": 17.1,
|
||||
"setpoint": 15.0,
|
||||
"battery": 62,
|
||||
"temperature_difference": 0.1,
|
||||
"valve_position": 0.0
|
||||
}
|
||||
},
|
||||
"21f2b542c49845e6bb416884c55778d6": {
|
||||
"class": "game_console",
|
||||
"fw": "2019-06-21T02:00:00+02:00",
|
||||
"location": "cd143c07248f491493cea0533bc3d669",
|
||||
"model": "Plug",
|
||||
"name": "Playstation Smart Plug",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 82.6,
|
||||
"electricity_consumed_interval": 8.6,
|
||||
"electricity_produced": 0.0,
|
||||
"electricity_produced_interval": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": false }
|
||||
},
|
||||
"78d1126fc4c743db81b61c20e88342a7": {
|
||||
"class": "central_heating_pump",
|
||||
"fw": "2019-06-21T02:00:00+02:00",
|
||||
"location": "c50f167537524366a5af7aa3942feb1e",
|
||||
"model": "Plug",
|
||||
"name": "CV Pomp",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 35.6,
|
||||
"electricity_consumed_interval": 7.37,
|
||||
"electricity_produced": 0.0,
|
||||
"electricity_produced_interval": 0.0
|
||||
},
|
||||
"switches": { "relay": true }
|
||||
},
|
||||
"90986d591dcd426cae3ec3e8111ff730": {
|
||||
"class": "heater_central",
|
||||
"fw": null,
|
||||
"location": "1f9dcf83fd4e4b66b72ff787957bfe5d",
|
||||
"model": "Unknown",
|
||||
"name": "OnOff",
|
||||
"vendor": null,
|
||||
"cooling_active": false,
|
||||
"heating_state": true,
|
||||
"sensors": {
|
||||
"water_temperature": 70.0,
|
||||
"intended_boiler_temperature": 70.0,
|
||||
"modulation_level": 1,
|
||||
"device_state": "heating"
|
||||
}
|
||||
},
|
||||
"cd0ddb54ef694e11ac18ed1cbce5dbbd": {
|
||||
"class": "vcr",
|
||||
"fw": "2019-06-21T02:00:00+02:00",
|
||||
"location": "cd143c07248f491493cea0533bc3d669",
|
||||
"model": "Plug",
|
||||
"name": "NAS",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 16.5,
|
||||
"electricity_consumed_interval": 0.5,
|
||||
"electricity_produced": 0.0,
|
||||
"electricity_produced_interval": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": true }
|
||||
},
|
||||
"4a810418d5394b3f82727340b91ba740": {
|
||||
"class": "router",
|
||||
"fw": "2019-06-21T02:00:00+02:00",
|
||||
"location": "cd143c07248f491493cea0533bc3d669",
|
||||
"model": "Plug",
|
||||
"name": "USG Smart Plug",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 8.5,
|
||||
"electricity_consumed_interval": 0.0,
|
||||
"electricity_produced": 0.0,
|
||||
"electricity_produced_interval": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": true }
|
||||
},
|
||||
"02cf28bfec924855854c544690a609ef": {
|
||||
"class": "vcr",
|
||||
"fw": "2019-06-21T02:00:00+02:00",
|
||||
"location": "cd143c07248f491493cea0533bc3d669",
|
||||
"model": "Plug",
|
||||
"name": "NVR",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 34.0,
|
||||
"electricity_consumed_interval": 9.15,
|
||||
"electricity_produced": 0.0,
|
||||
"electricity_produced_interval": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": true }
|
||||
},
|
||||
"a28f588dc4a049a483fd03a30361ad3a": {
|
||||
"class": "settop",
|
||||
"fw": "2019-06-21T02:00:00+02:00",
|
||||
"location": "cd143c07248f491493cea0533bc3d669",
|
||||
"model": "Plug",
|
||||
"name": "Fibaro HC2",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 12.5,
|
||||
"electricity_consumed_interval": 3.8,
|
||||
"electricity_produced": 0.0,
|
||||
"electricity_produced_interval": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": true }
|
||||
},
|
||||
"6a3bf693d05e48e0b460c815a4fdd09d": {
|
||||
"class": "zone_thermostat",
|
||||
"fw": "2016-10-27T02:00:00+02:00",
|
||||
"location": "82fa13f017d240daa0d0ea1775420f24",
|
||||
"model": "Lisa",
|
||||
"name": "Zone Thermostat Jessie",
|
||||
"vendor": "Plugwise",
|
||||
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
|
||||
"active_preset": "asleep",
|
||||
"presets": {
|
||||
"home": [20.0, 22.0],
|
||||
"asleep": [17.0, 24.0],
|
||||
"away": [15.0, 25.0],
|
||||
"vacation": [15.0, 28.0],
|
||||
"no_frost": [10.0, 30.0]
|
||||
},
|
||||
"available_schedules": [
|
||||
"CV Roan",
|
||||
"Bios Schema met Film Avond",
|
||||
"GF7 Woonkamer",
|
||||
"Badkamer Schema",
|
||||
"CV Jessie"
|
||||
],
|
||||
"selected_schedule": "CV Jessie",
|
||||
"schedule_temperature": 15.0,
|
||||
"last_used": "CV Jessie",
|
||||
"mode": "auto",
|
||||
"sensors": { "temperature": 17.2, "setpoint": 15.0, "battery": 37 }
|
||||
},
|
||||
"680423ff840043738f42cc7f1ff97a36": {
|
||||
"class": "thermo_sensor",
|
||||
"fw": "2019-03-27T01:00:00+01:00",
|
||||
"location": "08963fec7c53423ca5680aa4cb502c63",
|
||||
"model": "Tom/Floor",
|
||||
"name": "Thermostatic Radiator Badkamer",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"temperature": 19.1,
|
||||
"setpoint": 14.0,
|
||||
"battery": 51,
|
||||
"temperature_difference": -0.4,
|
||||
"valve_position": 0.0
|
||||
}
|
||||
},
|
||||
"f1fee6043d3642a9b0a65297455f008e": {
|
||||
"class": "zone_thermostat",
|
||||
"fw": "2016-10-27T02:00:00+02:00",
|
||||
"location": "08963fec7c53423ca5680aa4cb502c63",
|
||||
"model": "Lisa",
|
||||
"name": "Zone Thermostat Badkamer",
|
||||
"vendor": "Plugwise",
|
||||
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
|
||||
"active_preset": "away",
|
||||
"presets": {
|
||||
"home": [20.0, 22.0],
|
||||
"asleep": [17.0, 24.0],
|
||||
"away": [15.0, 25.0],
|
||||
"vacation": [15.0, 28.0],
|
||||
"no_frost": [10.0, 30.0]
|
||||
},
|
||||
"available_schedules": [
|
||||
"CV Roan",
|
||||
"Bios Schema met Film Avond",
|
||||
"GF7 Woonkamer",
|
||||
"Badkamer Schema",
|
||||
"CV Jessie"
|
||||
],
|
||||
"selected_schedule": "Badkamer Schema",
|
||||
"schedule_temperature": 15.0,
|
||||
"last_used": "Badkamer Schema",
|
||||
"mode": "auto",
|
||||
"sensors": { "temperature": 18.9, "setpoint": 14.0, "battery": 92 }
|
||||
},
|
||||
"675416a629f343c495449970e2ca37b5": {
|
||||
"class": "router",
|
||||
"fw": "2019-06-21T02:00:00+02:00",
|
||||
"location": "cd143c07248f491493cea0533bc3d669",
|
||||
"model": "Plug",
|
||||
"name": "Ziggo Modem",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 12.2,
|
||||
"electricity_consumed_interval": 2.97,
|
||||
"electricity_produced": 0.0,
|
||||
"electricity_produced_interval": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": true }
|
||||
},
|
||||
"e7693eb9582644e5b865dba8d4447cf1": {
|
||||
"class": "thermostatic_radiator_valve",
|
||||
"fw": "2019-03-27T01:00:00+01:00",
|
||||
"location": "446ac08dd04d4eff8ac57489757b7314",
|
||||
"model": "Tom/Floor",
|
||||
"name": "CV Kraan Garage",
|
||||
"vendor": "Plugwise",
|
||||
"preset_modes": ["home", "asleep", "away", "vacation", "no_frost"],
|
||||
"active_preset": "no_frost",
|
||||
"presets": {
|
||||
"home": [20.0, 22.0],
|
||||
"asleep": [17.0, 24.0],
|
||||
"away": [15.0, 25.0],
|
||||
"vacation": [15.0, 28.0],
|
||||
"no_frost": [10.0, 30.0]
|
||||
},
|
||||
"available_schedules": [
|
||||
"CV Roan",
|
||||
"Bios Schema met Film Avond",
|
||||
"GF7 Woonkamer",
|
||||
"Badkamer Schema",
|
||||
"CV Jessie"
|
||||
],
|
||||
"selected_schedule": "None",
|
||||
"schedule_temperature": 15.0,
|
||||
"last_used": "Badkamer Schema",
|
||||
"mode": "heat",
|
||||
"sensors": {
|
||||
"temperature": 15.6,
|
||||
"setpoint": 5.5,
|
||||
"battery": 68,
|
||||
"temperature_difference": 0.0,
|
||||
"valve_position": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
@ -1 +0,0 @@
|
||||
{"df4a4a8169904cdb9c03d61a21f42140": {"name": "Zone Lisa Bios", "model": "Zone Thermostat", "types": {"py/set": ["thermostat"]}, "class": "zone_thermostat", "location": "12493538af164a409c6a1c79e38afe1c"}, "b310b72a0e354bfab43089919b9a88bf": {"name": "Floor kraan", "model": "Thermostatic Radiator Valve", "types": {"py/set": ["thermostat"]}, "class": "thermo_sensor", "location": "c50f167537524366a5af7aa3942feb1e"}, "a2c3583e0a6349358998b760cea82d2a": {"name": "Bios Cv Thermostatic Radiator ", "model": "Thermostatic Radiator Valve", "types": {"py/set": ["thermostat"]}, "class": "thermo_sensor", "location": "12493538af164a409c6a1c79e38afe1c"}, "b59bcebaf94b499ea7d46e4a66fb62d8": {"name": "Zone Lisa WK", "model": "Zone Thermostat", "types": {"py/set": ["thermostat"]}, "class": "zone_thermostat", "location": "c50f167537524366a5af7aa3942feb1e"}, "fe799307f1624099878210aa0b9f1475": {"name": "Adam", "model": "Smile Adam", "types": {"py/set": ["temperature", "thermostat", "home"]}, "class": "gateway", "location": "1f9dcf83fd4e4b66b72ff787957bfe5d"}, "d3da73bde12a47d5a6b8f9dad971f2ec": {"name": "Thermostatic Radiator Jessie", "model": "Thermostatic Radiator Valve", "types": {"py/set": ["thermostat"]}, "class": "thermo_sensor", "location": "82fa13f017d240daa0d0ea1775420f24"}, "21f2b542c49845e6bb416884c55778d6": {"name": "Playstation Smart Plug", "model": "Plug", "types": {"py/set": ["plug", "power"]}, "class": "game_console", "location": "cd143c07248f491493cea0533bc3d669"}, "78d1126fc4c743db81b61c20e88342a7": {"name": "CV Pomp", "model": "Plug", "types": {"py/set": ["plug", "power"]}, "class": "central_heating_pump", "location": "c50f167537524366a5af7aa3942feb1e"}, "90986d591dcd426cae3ec3e8111ff730": {"name": "Adam", "model": "Heater Central", "types": {"py/set": ["temperature", "thermostat", "home"]}, "class": "heater_central", "location": "1f9dcf83fd4e4b66b72ff787957bfe5d"}, "cd0ddb54ef694e11ac18ed1cbce5dbbd": {"name": "NAS", "model": "Plug", "types": {"py/set": ["plug", "power"]}, "class": "vcr", "location": "cd143c07248f491493cea0533bc3d669"}, "4a810418d5394b3f82727340b91ba740": {"name": "USG Smart Plug", "model": "Plug", "types": {"py/set": ["plug", "power"]}, "class": "router", "location": "cd143c07248f491493cea0533bc3d669"}, "02cf28bfec924855854c544690a609ef": {"name": "NVR", "model": "Plug", "types": {"py/set": ["plug", "power"]}, "class": "vcr", "location": "cd143c07248f491493cea0533bc3d669"}, "a28f588dc4a049a483fd03a30361ad3a": {"name": "Fibaro HC2", "model": "Plug", "types": {"py/set": ["plug", "power"]}, "class": "settop", "location": "cd143c07248f491493cea0533bc3d669"}, "6a3bf693d05e48e0b460c815a4fdd09d": {"name": "Zone Thermostat Jessie", "model": "Zone Thermostat", "types": {"py/set": ["thermostat"]}, "class": "zone_thermostat", "location": "82fa13f017d240daa0d0ea1775420f24"}, "680423ff840043738f42cc7f1ff97a36": {"name": "Thermostatic Radiator Badkamer", "model": "Thermostatic Radiator Valve", "types": {"py/set": ["thermostat"]}, "class": "thermo_sensor", "location": "08963fec7c53423ca5680aa4cb502c63"}, "f1fee6043d3642a9b0a65297455f008e": {"name": "Zone Thermostat Badkamer", "model": "Zone Thermostat", "types": {"py/set": ["thermostat"]}, "class": "zone_thermostat", "location": "08963fec7c53423ca5680aa4cb502c63"}, "675416a629f343c495449970e2ca37b5": {"name": "Ziggo Modem", "model": "Plug", "types": {"py/set": ["plug", "power"]}, "class": "router", "location": "cd143c07248f491493cea0533bc3d669"}, "e7693eb9582644e5b865dba8d4447cf1": {"name": "CV Kraan Garage", "model": "Thermostatic Radiator Valve", "types": {"py/set": ["thermostat"]}, "class": "thermostatic_radiator_valve", "location": "446ac08dd04d4eff8ac57489757b7314"}}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 34.0, "electricity_consumed_interval": 9.15, "electricity_produced": 0.0, "electricity_produced_interval": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 82.6, "electricity_consumed_interval": 8.6, "electricity_produced": 0.0, "electricity_produced_interval": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 8.5, "electricity_consumed_interval": 0.0, "electricity_produced": 0.0, "electricity_produced_interval": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 12.2, "electricity_consumed_interval": 2.97, "electricity_produced": 0.0, "electricity_produced_interval": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"temperature": 19.1, "setpoint": 14.0, "battery": 51, "temperature_difference": -0.4, "valve_position": 0.0}
|
@ -1 +0,0 @@
|
||||
{"temperature": 17.2, "setpoint": 15.0, "battery": 37, "active_preset": "asleep", "presets": {"home": [20.0, 22.0], "no_frost": [10.0, 30.0], "away": [12.0, 25.0], "vacation": [11.0, 28.0], "asleep": [16.0, 24.0]}, "schedule_temperature": 15.0, "available_schedules": ["CV Jessie"], "selected_schedule": "CV Jessie", "last_used": "CV Jessie"}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 35.6, "electricity_consumed_interval": 7.37, "electricity_produced": 0.0, "electricity_produced_interval": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"water_temperature": 70.0, "intended_boiler_temperature": 70.0, "modulation_level": 1, "heating_state": true}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 12.5, "electricity_consumed_interval": 3.8, "electricity_produced": 0.0, "electricity_produced_interval": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"temperature": 17.2, "setpoint": 13.0, "battery": 62, "temperature_difference": -0.2, "valve_position": 0.0}
|
@ -1 +0,0 @@
|
||||
{"temperature": 26.0, "setpoint": 21.5, "temperature_difference": 3.5, "valve_position": 100}
|
@ -1 +0,0 @@
|
||||
{"temperature": 20.9, "setpoint": 21.5, "battery": 34, "active_preset": "home", "presets": {"vacation": [15.0, 28.0], "asleep": [18.0, 24.0], "no_frost": [12.0, 30.0], "away": [17.0, 25.0], "home": [21.5, 22.0]}, "schedule_temperature": 21.5, "available_schedules": ["GF7 Woonkamer"], "selected_schedule": "GF7 Woonkamer", "last_used": "GF7 Woonkamer"}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 16.5, "electricity_consumed_interval": 0.5, "electricity_produced": 0.0, "electricity_produced_interval": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"temperature": 17.1, "setpoint": 15.0, "battery": 62, "temperature_difference": 0.1, "valve_position": 0.0}
|
@ -1 +0,0 @@
|
||||
{"temperature": 16.5, "setpoint": 13.0, "battery": 67, "active_preset": "away", "presets": {"home": [20.0, 22.0], "away": [12.0, 25.0], "vacation": [12.0, 28.0], "no_frost": [8.0, 30.0], "asleep": [15.0, 24.0]}, "schedule_temperature": null, "available_schedules": [], "selected_schedule": null, "last_used": null}
|
@ -1 +0,0 @@
|
||||
{"temperature": 15.6, "setpoint": 5.5, "battery": 68, "temperature_difference": 0.0, "valve_position": 0.0, "active_preset": "no_frost", "presets": {"home": [20.0, 22.0], "asleep": [17.0, 24.0], "away": [15.0, 25.0], "vacation": [15.0, 28.0], "no_frost": [10.0, 30.0]}, "schedule_temperature": null, "available_schedules": [], "selected_schedule": null, "last_used": null}
|
@ -1 +0,0 @@
|
||||
{"temperature": 18.9, "setpoint": 14.0, "battery": 92, "active_preset": "away", "presets": {"asleep": [17.0, 24.0], "no_frost": [10.0, 30.0], "away": [14.0, 25.0], "home": [21.0, 22.0], "vacation": [12.0, 28.0]}, "schedule_temperature": 14.0, "available_schedules": ["Badkamer Schema"], "selected_schedule": "Badkamer Schema", "last_used": "Badkamer Schema"}
|
@ -1 +0,0 @@
|
||||
{"outdoor_temperature": 7.81}
|
@ -1 +1,5 @@
|
||||
{"af82e4ccf9c548528166d38e560662a4": {"warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18. Please check the connection and restart the device."}}
|
||||
{
|
||||
"af82e4ccf9c548528166d38e560662a4": {
|
||||
"warning": "Node Plug (with MAC address 000D6F000D13CB01, in room 'n.a.') has been unreachable since 23:03 2020-01-18. Please check the connection and restart the device."
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,79 @@
|
||||
[
|
||||
{
|
||||
"active_device": true,
|
||||
"cooling_present": true,
|
||||
"gateway_id": "015ae9ea3f964e668e490fa39da3870b",
|
||||
"heater_id": "1cbf783bb11e4a7c8a6843dee3a86927",
|
||||
"single_master_thermostat": true,
|
||||
"smile_name": "Anna",
|
||||
"notifications": {}
|
||||
},
|
||||
{
|
||||
"1cbf783bb11e4a7c8a6843dee3a86927": {
|
||||
"class": "heater_central",
|
||||
"fw": null,
|
||||
"location": "a57efe5f145f498c9be62a9b63626fbf",
|
||||
"model": "Generic heater",
|
||||
"name": "OpenTherm",
|
||||
"vendor": "Techneco",
|
||||
"heating_state": true,
|
||||
"compressor_state": true,
|
||||
"cooling_state": false,
|
||||
"cooling_active": false,
|
||||
"binary_sensors": {
|
||||
"dhw_state": false,
|
||||
"slave_boiler_state": false,
|
||||
"flame_state": false
|
||||
},
|
||||
"sensors": {
|
||||
"outdoor_temperature": 3.0,
|
||||
"water_temperature": 29.1,
|
||||
"intended_boiler_temperature": 0.0,
|
||||
"modulation_level": 52,
|
||||
"return_temperature": 25.1,
|
||||
"water_pressure": 1.57,
|
||||
"device_state": "heating"
|
||||
},
|
||||
"switches": { "dhw_cm_switch": false }
|
||||
},
|
||||
"015ae9ea3f964e668e490fa39da3870b": {
|
||||
"class": "gateway",
|
||||
"fw": "4.0.15",
|
||||
"location": "a57efe5f145f498c9be62a9b63626fbf",
|
||||
"model": "Anna",
|
||||
"name": "Anna",
|
||||
"vendor": "Plugwise B.V.",
|
||||
"binary_sensors": { "plugwise_notification": false },
|
||||
"sensors": { "outdoor_temperature": 20.2 }
|
||||
},
|
||||
"3cb70739631c4d17a86b8b12e8a5161b": {
|
||||
"class": "thermostat",
|
||||
"fw": "2018-02-08T11:15:53+01:00",
|
||||
"location": "c784ee9fdab44e1395b8dee7d7a497d5",
|
||||
"model": "Anna",
|
||||
"name": "Anna",
|
||||
"vendor": "Plugwise",
|
||||
"preset_modes": ["no_frost", "home", "away", "asleep", "vacation"],
|
||||
"active_preset": "home",
|
||||
"presets": {
|
||||
"no_frost": [10.0, 30.0],
|
||||
"home": [21.0, 22.0],
|
||||
"away": [20.0, 25.0],
|
||||
"asleep": [20.5, 24.0],
|
||||
"vacation": [17.0, 28.0]
|
||||
},
|
||||
"available_schedules": ["None"],
|
||||
"selected_schedule": "None",
|
||||
"schedule_temperature": null,
|
||||
"last_used": null,
|
||||
"mode": "heat",
|
||||
"sensors": {
|
||||
"temperature": 19.3,
|
||||
"setpoint": 21.0,
|
||||
"illuminance": 86.0,
|
||||
"cooling_activation_outdoor_temperature": 21.0,
|
||||
"cooling_deactivation_threshold": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
@ -1 +0,0 @@
|
||||
{"1cbf783bb11e4a7c8a6843dee3a86927": {"name": "Anna", "model": "Heater Central", "types": {"py/set": ["temperature", "thermostat", "home"]}, "class": "heater_central", "location": "a57efe5f145f498c9be62a9b63626fbf"}, "015ae9ea3f964e668e490fa39da3870b": {"name": "Anna", "model": "Smile Anna", "types": {"py/set": ["temperature", "thermostat", "home"]}, "class": "gateway", "location": "a57efe5f145f498c9be62a9b63626fbf"}, "3cb70739631c4d17a86b8b12e8a5161b": {"name": "Anna", "model": "Thermostat", "types": {"py/set": ["thermostat"]}, "class": "thermostat", "location": "c784ee9fdab44e1395b8dee7d7a497d5"}}
|
@ -1 +0,0 @@
|
||||
{"outdoor_temperature": 20.2}
|
@ -1 +0,0 @@
|
||||
{"water_temperature": 29.1, "dhw_state": false, "intended_boiler_temperature": 0.0, "heating_state": false, "modulation_level": 52, "return_temperature": 25.1, "compressor_state": true, "cooling_state": false, "slave_boiler_state": false, "flame_state": false, "water_pressure": 1.57, "outdoor_temperature": 18.0}
|
@ -1 +0,0 @@
|
||||
{"temperature": 23.3, "setpoint": 21.0, "heating_state": false, "active_preset": "home", "presets": {"no_frost": [10.0, 30.0], "home": [21.0, 22.0], "away": [20.0, 25.0], "asleep": [20.5, 24.0], "vacation": [17.0, 28.0]}, "schedule_temperature": null, "available_schedules": ["standaard"], "selected_schedule": "standaard", "last_used": "standaard", "illuminance": 86.0}
|
@ -0,0 +1,39 @@
|
||||
[
|
||||
{
|
||||
"active_device": false,
|
||||
"cooling_present": null,
|
||||
"gateway_id": "e950c7d5e1ee407a858e2a8b5016c8b3",
|
||||
"heater_id": null,
|
||||
"single_master_thermostat": null,
|
||||
"smile_name": "P1",
|
||||
"notifications": {}
|
||||
},
|
||||
{
|
||||
"e950c7d5e1ee407a858e2a8b5016c8b3": {
|
||||
"class": "gateway",
|
||||
"fw": "3.3.9",
|
||||
"location": "cd3e822288064775a7c4afcdd70bdda2",
|
||||
"model": "P1",
|
||||
"name": "P1",
|
||||
"vendor": "Plugwise B.V.",
|
||||
"sensors": {
|
||||
"net_electricity_point": -2816,
|
||||
"electricity_consumed_peak_point": 0,
|
||||
"electricity_consumed_off_peak_point": 0,
|
||||
"net_electricity_cumulative": 442.972,
|
||||
"electricity_consumed_peak_cumulative": 442.932,
|
||||
"electricity_consumed_off_peak_cumulative": 551.09,
|
||||
"electricity_consumed_peak_interval": 0,
|
||||
"electricity_consumed_off_peak_interval": 0,
|
||||
"electricity_produced_peak_point": 2816,
|
||||
"electricity_produced_off_peak_point": 0,
|
||||
"electricity_produced_peak_cumulative": 396.559,
|
||||
"electricity_produced_off_peak_cumulative": 154.491,
|
||||
"electricity_produced_peak_interval": 0,
|
||||
"electricity_produced_off_peak_interval": 0,
|
||||
"gas_consumed_cumulative": 584.85,
|
||||
"gas_consumed_interval": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
@ -1 +0,0 @@
|
||||
{"e950c7d5e1ee407a858e2a8b5016c8b3": {"name": "P1", "model": "Smile P1", "types": {"py/set": ["home", "power"]}, "class": "gateway", "location": "cd3e822288064775a7c4afcdd70bdda2"}}
|
@ -1 +0,0 @@
|
||||
{"net_electricity_point": -2761, "electricity_consumed_peak_point": 0, "electricity_consumed_off_peak_point": 0, "net_electricity_cumulative": 442.972, "electricity_consumed_peak_cumulative": 442.932, "electricity_consumed_off_peak_cumulative": 551.09, "net_electricity_interval": 0, "electricity_consumed_peak_interval": 0, "electricity_consumed_off_peak_interval": 0, "electricity_produced_peak_point": 2761, "electricity_produced_off_peak_point": 0, "electricity_produced_peak_cumulative": 396.559, "electricity_produced_off_peak_cumulative": 154.491, "electricity_produced_peak_interval": 0, "electricity_produced_off_peak_interval": 0, "gas_consumed_cumulative": 584.85, "gas_consumed_interval": 0.0}
|
178
tests/components/plugwise/fixtures/stretch_v31/all_data.json
Normal file
178
tests/components/plugwise/fixtures/stretch_v31/all_data.json
Normal file
@ -0,0 +1,178 @@
|
||||
[
|
||||
{
|
||||
"active_device": false,
|
||||
"cooling_present": null,
|
||||
"gateway_id": "0000aaaa0000aaaa0000aaaa0000aa00",
|
||||
"heater_id": null,
|
||||
"single_master_thermostat": null,
|
||||
"smile_name": "Stretch",
|
||||
"notifications": {}
|
||||
},
|
||||
{
|
||||
"0000aaaa0000aaaa0000aaaa0000aa00": {
|
||||
"class": "gateway",
|
||||
"fw": "3.1.11",
|
||||
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
|
||||
"vendor": "Plugwise B.V.",
|
||||
"model": "Stretch",
|
||||
"name": "Stretch"
|
||||
},
|
||||
"5ca521ac179d468e91d772eeeb8a2117": {
|
||||
"class": "zz_misc",
|
||||
"fw": null,
|
||||
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
|
||||
"model": null,
|
||||
"name": "Oven (793F84)",
|
||||
"vendor": null,
|
||||
"sensors": {
|
||||
"electricity_consumed": 0.0,
|
||||
"electricity_consumed_interval": 0.0,
|
||||
"electricity_produced": 0.0,
|
||||
"electricity_produced_interval": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": false }
|
||||
},
|
||||
"5871317346d045bc9f6b987ef25ee638": {
|
||||
"class": "water_heater_vessel",
|
||||
"fw": "2011-06-27T10:52:18+02:00",
|
||||
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
|
||||
"model": "Circle type F",
|
||||
"name": "Boiler (1EB31)",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 1.19,
|
||||
"electricity_consumed_interval": 0.0,
|
||||
"electricity_produced": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": false }
|
||||
},
|
||||
"e1c884e7dede431dadee09506ec4f859": {
|
||||
"class": "refrigerator",
|
||||
"fw": "2011-06-27T10:47:37+02:00",
|
||||
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
|
||||
"model": "Circle+ type F",
|
||||
"name": "Koelkast (92C4A)",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 50.5,
|
||||
"electricity_consumed_interval": 0.08,
|
||||
"electricity_produced": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": false }
|
||||
},
|
||||
"aac7b735042c4832ac9ff33aae4f453b": {
|
||||
"class": "dishwasher",
|
||||
"fw": "2011-06-27T10:52:18+02:00",
|
||||
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
|
||||
"model": "Circle type F",
|
||||
"name": "Vaatwasser (2a1ab)",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 0.0,
|
||||
"electricity_consumed_interval": 0.71,
|
||||
"electricity_produced": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": false }
|
||||
},
|
||||
"cfe95cf3de1948c0b8955125bf754614": {
|
||||
"class": "dryer",
|
||||
"fw": "2011-06-27T10:52:18+02:00",
|
||||
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
|
||||
"model": "Circle type F",
|
||||
"name": "Droger (52559)",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 0.0,
|
||||
"electricity_consumed_interval": 0.0,
|
||||
"electricity_produced": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": false }
|
||||
},
|
||||
"99f89d097be34fca88d8598c6dbc18ea": {
|
||||
"class": "router",
|
||||
"fw": null,
|
||||
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
|
||||
"model": null,
|
||||
"name": "Meterkast (787BFB)",
|
||||
"vendor": null,
|
||||
"sensors": {
|
||||
"electricity_consumed": 27.6,
|
||||
"electricity_consumed_interval": 28.2,
|
||||
"electricity_produced": 0.0,
|
||||
"electricity_produced_interval": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": true }
|
||||
},
|
||||
"059e4d03c7a34d278add5c7a4a781d19": {
|
||||
"class": "washingmachine",
|
||||
"fw": "2011-06-27T10:52:18+02:00",
|
||||
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
|
||||
"model": "Circle type F",
|
||||
"name": "Wasmachine (52AC1)",
|
||||
"vendor": "Plugwise",
|
||||
"sensors": {
|
||||
"electricity_consumed": 0.0,
|
||||
"electricity_consumed_interval": 0.0,
|
||||
"electricity_produced": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": false }
|
||||
},
|
||||
"e309b52ea5684cf1a22f30cf0cd15051": {
|
||||
"class": "computer_desktop",
|
||||
"fw": null,
|
||||
"location": "0000aaaa0000aaaa0000aaaa0000aa00",
|
||||
"model": null,
|
||||
"name": "Computer (788618)",
|
||||
"vendor": null,
|
||||
"sensors": {
|
||||
"electricity_consumed": 156,
|
||||
"electricity_consumed_interval": 163,
|
||||
"electricity_produced": 0.0,
|
||||
"electricity_produced_interval": 0.0
|
||||
},
|
||||
"switches": { "relay": true, "lock": true }
|
||||
},
|
||||
"71e1944f2a944b26ad73323e399efef0": {
|
||||
"class": "switching",
|
||||
"fw": null,
|
||||
"location": null,
|
||||
"model": "Switchgroup",
|
||||
"name": "Test",
|
||||
"members": ["5ca521ac179d468e91d772eeeb8a2117"],
|
||||
"types": ["switch_group"],
|
||||
"vendor": null,
|
||||
"switches": { "relay": true }
|
||||
},
|
||||
"d950b314e9d8499f968e6db8d82ef78c": {
|
||||
"class": "report",
|
||||
"fw": null,
|
||||
"location": null,
|
||||
"model": "Switchgroup",
|
||||
"name": "Stroomvreters",
|
||||
"members": [
|
||||
"059e4d03c7a34d278add5c7a4a781d19",
|
||||
"5871317346d045bc9f6b987ef25ee638",
|
||||
"aac7b735042c4832ac9ff33aae4f453b",
|
||||
"cfe95cf3de1948c0b8955125bf754614",
|
||||
"e1c884e7dede431dadee09506ec4f859"
|
||||
],
|
||||
"types": ["switch_group"],
|
||||
"vendor": null,
|
||||
"switches": { "relay": true }
|
||||
},
|
||||
"d03738edfcc947f7b8f4573571d90d2d": {
|
||||
"class": "switching",
|
||||
"fw": null,
|
||||
"location": null,
|
||||
"model": "Switchgroup",
|
||||
"name": "Schakel",
|
||||
"members": [
|
||||
"059e4d03c7a34d278add5c7a4a781d19",
|
||||
"cfe95cf3de1948c0b8955125bf754614"
|
||||
],
|
||||
"types": ["switch_group"],
|
||||
"vendor": null,
|
||||
"switches": { "relay": true }
|
||||
}
|
||||
}
|
||||
]
|
@ -1 +0,0 @@
|
||||
{"5ca521ac179d468e91d772eeeb8a2117": {"name": "Oven (793F84)", "model": "Circle", "types": {"py/set": ["plug", "power"]}, "class": "zz_misc", "location": 0}, "5871317346d045bc9f6b987ef25ee638": {"name": "Boiler (1EB31)", "model": "Circle", "types": {"py/set": ["plug", "power"]}, "class": "water_heater_vessel", "location": 0}, "e1c884e7dede431dadee09506ec4f859": {"name": "Koelkast (92C4A)", "model": "Circle+", "types": {"py/set": ["plug", "power"]}, "class": "refrigerator", "location": 0}, "aac7b735042c4832ac9ff33aae4f453b": {"name": "Vaatwasser (2a1ab)", "model": "Circle", "types": {"py/set": ["plug", "power"]}, "class": "dishwasher", "location": 0}, "cfe95cf3de1948c0b8955125bf754614": {"name": "Droger (52559)", "model": "Circle", "types": {"py/set": ["plug", "power"]}, "class": "dryer", "location": 0}, "99f89d097be34fca88d8598c6dbc18ea": {"name": "Meterkast (787BFB)", "model": "Circle", "types": {"py/set": ["plug", "power"]}, "class": "router", "location": 0}, "059e4d03c7a34d278add5c7a4a781d19": {"name": "Wasmachine (52AC1)", "model": "Circle", "types": {"py/set": ["plug", "power"]}, "class": "washingmachine", "location": 0}, "e309b52ea5684cf1a22f30cf0cd15051": {"name": "Computer (788618)", "model": "Circle", "types": {"py/set": ["plug", "power"]}, "class": "computer_desktop", "location": 0}, "71e1944f2a944b26ad73323e399efef0": {"name": "Test", "model": "group_switch", "types": {"py/set": ["switch_group"]}, "class": "switching", "members": ["5ca521ac179d468e91d772eeeb8a2117"], "location": null}, "d950b314e9d8499f968e6db8d82ef78c": {"name": "Stroomvreters", "model": "group_switch", "types": {"py/set": ["switch_group"]}, "class": "report", "members": ["059e4d03c7a34d278add5c7a4a781d19", "5871317346d045bc9f6b987ef25ee638", "aac7b735042c4832ac9ff33aae4f453b", "cfe95cf3de1948c0b8955125bf754614", "e1c884e7dede431dadee09506ec4f859"], "location": null}, "d03738edfcc947f7b8f4573571d90d2d": {"name": "Schakel", "model": "group_switch", "types": {"py/set": ["switch_group"]}, "class": "switching", "members": ["059e4d03c7a34d278add5c7a4a781d19", "cfe95cf3de1948c0b8955125bf754614"], "location": null}}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 0.0, "electricity_consumed_interval": 0.0, "electricity_produced": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 1.19, "electricity_consumed_interval": 0.0, "electricity_produced": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 0.0, "electricity_consumed_interval": 0.0, "electricity_produced": 0.0, "electricity_produced_interval": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"relay": true}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 27.6, "electricity_consumed_interval": 28.2, "electricity_produced": 0.0, "electricity_produced_interval": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 0.0, "electricity_consumed_interval": 0.71, "electricity_produced": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 0.0, "electricity_consumed_interval": 0.0, "electricity_produced": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"relay": true}
|
@ -1 +0,0 @@
|
||||
{"relay": true}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 50.5, "electricity_consumed_interval": 0.08, "electricity_produced": 0.0, "relay": true}
|
@ -1 +0,0 @@
|
||||
{"electricity_consumed": 156, "electricity_consumed_interval": 163, "electricity_produced": 0.0, "electricity_produced_interval": 0.0, "relay": true}
|
@ -2,7 +2,11 @@
|
||||
|
||||
from plugwise.exceptions import PlugwiseException
|
||||
|
||||
from homeassistant.components.climate.const import HVAC_MODE_AUTO, HVAC_MODE_HEAT
|
||||
from homeassistant.components.climate.const import (
|
||||
HVAC_MODE_AUTO,
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_OFF,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
|
||||
from tests.components.plugwise.common import async_init_integration
|
||||
@ -16,7 +20,7 @@ async def test_adam_climate_entity_attributes(hass, mock_smile_adam):
|
||||
state = hass.states.get("climate.zone_lisa_wk")
|
||||
attrs = state.attributes
|
||||
|
||||
assert attrs["hvac_modes"] == [HVAC_MODE_HEAT, HVAC_MODE_AUTO]
|
||||
assert attrs["hvac_modes"] == [HVAC_MODE_HEAT, HVAC_MODE_AUTO, HVAC_MODE_OFF]
|
||||
|
||||
assert "preset_modes" in attrs
|
||||
assert "no_frost" in attrs["preset_modes"]
|
||||
@ -32,7 +36,7 @@ async def test_adam_climate_entity_attributes(hass, mock_smile_adam):
|
||||
state = hass.states.get("climate.zone_thermostat_jessie")
|
||||
attrs = state.attributes
|
||||
|
||||
assert attrs["hvac_modes"] == [HVAC_MODE_HEAT, HVAC_MODE_AUTO]
|
||||
assert attrs["hvac_modes"] == [HVAC_MODE_HEAT, HVAC_MODE_AUTO, HVAC_MODE_OFF]
|
||||
|
||||
assert "preset_modes" in attrs
|
||||
assert "no_frost" in attrs["preset_modes"]
|
||||
@ -144,17 +148,17 @@ async def test_anna_climate_entity_attributes(hass, mock_smile_anna):
|
||||
attrs = state.attributes
|
||||
|
||||
assert "hvac_modes" in attrs
|
||||
assert "heat_cool" in attrs["hvac_modes"]
|
||||
assert "heat" in attrs["hvac_modes"]
|
||||
|
||||
assert "preset_modes" in attrs
|
||||
assert "no_frost" in attrs["preset_modes"]
|
||||
assert "home" in attrs["preset_modes"]
|
||||
|
||||
assert attrs["current_temperature"] == 23.3
|
||||
assert attrs["current_temperature"] == 19.3
|
||||
assert attrs["temperature"] == 21.0
|
||||
|
||||
assert state.state == HVAC_MODE_AUTO
|
||||
assert attrs["hvac_action"] == "idle"
|
||||
assert state.state == HVAC_MODE_HEAT
|
||||
assert attrs["hvac_action"] == "heating"
|
||||
assert attrs["preset_mode"] == "home"
|
||||
|
||||
assert attrs["supported_features"] == 17
|
||||
|
@ -39,7 +39,7 @@ async def test_smile_timeout(hass, mock_smile_notconnect):
|
||||
|
||||
async def test_smile_adam_xmlerror(hass, mock_smile_adam):
|
||||
"""Detect malformed XML by Smile in Adam environment."""
|
||||
mock_smile_adam.full_update_device.side_effect = XMLDataMissingError
|
||||
mock_smile_adam.async_update.side_effect = XMLDataMissingError
|
||||
entry = await async_init_integration(hass, mock_smile_adam)
|
||||
assert entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
@ -37,7 +37,7 @@ async def test_anna_as_smt_climate_sensor_entities(hass, mock_smile_anna):
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
|
||||
state = hass.states.get("sensor.auxiliary_outdoor_temperature")
|
||||
assert float(state.state) == 18.0
|
||||
assert float(state.state) == 3.0
|
||||
|
||||
state = hass.states.get("sensor.auxiliary_water_temperature")
|
||||
assert float(state.state) == 29.1
|
||||
@ -53,7 +53,7 @@ async def test_anna_climate_sensor_entities(hass, mock_smile_anna):
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
|
||||
state = hass.states.get("sensor.auxiliary_outdoor_temperature")
|
||||
assert float(state.state) == 18.0
|
||||
assert float(state.state) == 3.0
|
||||
|
||||
|
||||
async def test_p1_dsmr_sensor_entities(hass, mock_smile_p1):
|
||||
@ -62,13 +62,13 @@ async def test_p1_dsmr_sensor_entities(hass, mock_smile_p1):
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
|
||||
state = hass.states.get("sensor.p1_net_electricity_point")
|
||||
assert float(state.state) == -2761.0
|
||||
assert float(state.state) == -2816.0
|
||||
|
||||
state = hass.states.get("sensor.p1_electricity_consumed_off_peak_cumulative")
|
||||
assert float(state.state) == 551.09
|
||||
|
||||
state = hass.states.get("sensor.p1_electricity_produced_peak_point")
|
||||
assert float(state.state) == 2761.0
|
||||
assert float(state.state) == 2816.0
|
||||
|
||||
state = hass.states.get("sensor.p1_electricity_consumed_peak_cumulative")
|
||||
assert float(state.state) == 442.932
|
||||
|
@ -21,7 +21,7 @@ async def test_adam_climate_switch_entities(hass, mock_smile_adam):
|
||||
|
||||
async def test_adam_climate_switch_negative_testing(hass, mock_smile_adam):
|
||||
"""Test exceptions of climate related switch entities."""
|
||||
mock_smile_adam.set_relay_state.side_effect = PlugwiseException
|
||||
mock_smile_adam.set_switch_state.side_effect = PlugwiseException
|
||||
entry = await async_init_integration(hass, mock_smile_adam)
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user