Add support for standby quickmode to ViCare integration (#133156)

This commit is contained in:
Christopher Fenner 2025-01-31 12:45:58 +01:00 committed by GitHub
parent 50f3d79fb2
commit d83c335ed6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 754 additions and 17 deletions

View File

@ -125,7 +125,7 @@ def _build_entities(
device.api, device.api,
) )
for description in GLOBAL_SENSORS for description in GLOBAL_SENSORS
if is_supported(description.key, description, device.api) if is_supported(description.key, description.value_getter, device.api)
) )
# add component entities # add component entities
for component_list, entity_description_list in ( for component_list, entity_description_list in (
@ -143,7 +143,7 @@ def _build_entities(
) )
for component in component_list for component in component_list
for description in entity_description_list for description in entity_description_list
if is_supported(description.key, description, component) if is_supported(description.key, description.value_getter, component)
) )
return entities return entities

View File

@ -59,7 +59,7 @@ def _build_entities(
) )
for device in device_list for device in device_list
for description in BUTTON_DESCRIPTIONS for description in BUTTON_DESCRIPTIONS
if is_supported(description.key, description, device.api) if is_supported(description.key, description.value_getter, device.api)
] ]

View File

@ -5,6 +5,7 @@ from __future__ import annotations
from contextlib import suppress from contextlib import suppress
import enum import enum
import logging import logging
from typing import Any
from PyViCare.PyViCareDevice import Device as PyViCareDevice from PyViCare.PyViCareDevice import Device as PyViCareDevice
from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig from PyViCare.PyViCareDeviceConfig import PyViCareDeviceConfig
@ -25,7 +26,7 @@ from homeassistant.util.percentage import (
from .entity import ViCareEntity from .entity import ViCareEntity
from .types import ViCareConfigEntry, ViCareDevice from .types import ViCareConfigEntry, ViCareDevice
from .utils import filter_state, get_device_serial from .utils import filter_state, get_device_serial, is_supported
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -73,6 +74,12 @@ class VentilationMode(enum.StrEnum):
return None return None
class VentilationQuickmode(enum.StrEnum):
"""ViCare ventilation quickmodes."""
STANDBY = "standby"
HA_TO_VICARE_MODE_VENTILATION = { HA_TO_VICARE_MODE_VENTILATION = {
VentilationMode.PERMANENT: "permanent", VentilationMode.PERMANENT: "permanent",
VentilationMode.VENTILATION: "ventilation", VentilationMode.VENTILATION: "ventilation",
@ -147,6 +154,19 @@ class ViCareFan(ViCareEntity, FanEntity):
if supported_levels is not None and len(supported_levels) > 0: if supported_levels is not None and len(supported_levels) > 0:
self._attr_supported_features |= FanEntityFeature.SET_SPEED self._attr_supported_features |= FanEntityFeature.SET_SPEED
# evaluate quickmodes
quickmodes: list[str] = (
device.getVentilationQuickmodes()
if is_supported(
"getVentilationQuickmodes",
lambda api: api.getVentilationQuickmodes(),
device,
)
else []
)
if VentilationQuickmode.STANDBY in quickmodes:
self._attr_supported_features |= FanEntityFeature.TURN_OFF
def update(self) -> None: def update(self) -> None:
"""Update state of fan.""" """Update state of fan."""
level: str | None = None level: str | None = None
@ -155,6 +175,7 @@ class ViCareFan(ViCareEntity, FanEntity):
self._attr_preset_mode = VentilationMode.from_vicare_mode( self._attr_preset_mode = VentilationMode.from_vicare_mode(
self._api.getActiveVentilationMode() self._api.getActiveVentilationMode()
) )
with suppress(PyViCareNotSupportedFeatureError): with suppress(PyViCareNotSupportedFeatureError):
level = filter_state(self._api.getVentilationLevel()) level = filter_state(self._api.getVentilationLevel())
if level is not None and level in ORDERED_NAMED_FAN_SPEEDS: if level is not None and level in ORDERED_NAMED_FAN_SPEEDS:
@ -175,8 +196,12 @@ class ViCareFan(ViCareEntity, FanEntity):
@property @property
def is_on(self) -> bool | None: def is_on(self) -> bool | None:
"""Return true if the entity is on.""" """Return true if the entity is on."""
# Viessmann ventilation unit cannot be turned off return self.percentage is not None and self.percentage > 0
return True
def turn_off(self, **kwargs: Any) -> None:
"""Turn the entity off."""
self._api.activateVentilationQuickmode(str(VentilationQuickmode.STANDBY))
@property @property
def icon(self) -> str | None: def icon(self) -> str | None:
@ -206,6 +231,8 @@ class ViCareFan(ViCareEntity, FanEntity):
"""Set the speed of the fan, as a percentage.""" """Set the speed of the fan, as a percentage."""
if self._attr_preset_mode != str(VentilationMode.PERMANENT): if self._attr_preset_mode != str(VentilationMode.PERMANENT):
self.set_preset_mode(VentilationMode.PERMANENT) self.set_preset_mode(VentilationMode.PERMANENT)
elif self._api.getVentilationQuickmode(VentilationQuickmode.STANDBY):
self._api.deactivateVentilationQuickmode(str(VentilationQuickmode.STANDBY))
level = percentage_to_ordered_list_item(ORDERED_NAMED_FAN_SPEEDS, percentage) level = percentage_to_ordered_list_item(ORDERED_NAMED_FAN_SPEEDS, percentage)
_LOGGER.debug("changing ventilation level to %s", level) _LOGGER.debug("changing ventilation level to %s", level)

View File

@ -353,7 +353,7 @@ def _build_entities(
device.api, device.api,
) )
for description in DEVICE_ENTITY_DESCRIPTIONS for description in DEVICE_ENTITY_DESCRIPTIONS
if is_supported(description.key, description, device.api) if is_supported(description.key, description.value_getter, device.api)
) )
# add component entities # add component entities
entities.extend( entities.extend(
@ -366,7 +366,7 @@ def _build_entities(
) )
for circuit in get_circuits(device.api) for circuit in get_circuits(device.api)
for description in CIRCUIT_ENTITY_DESCRIPTIONS for description in CIRCUIT_ENTITY_DESCRIPTIONS
if is_supported(description.key, description, circuit) if is_supported(description.key, description.value_getter, circuit)
) )
return entities return entities

View File

@ -1007,7 +1007,7 @@ def _build_entities(
device.api, device.api,
) )
for description in GLOBAL_SENSORS for description in GLOBAL_SENSORS
if is_supported(description.key, description, device.api) if is_supported(description.key, description.value_getter, device.api)
) )
# add component entities # add component entities
for component_list, entity_description_list in ( for component_list, entity_description_list in (
@ -1025,7 +1025,7 @@ def _build_entities(
) )
for component in component_list for component in component_list
for description in entity_description_list for description in entity_description_list
if is_supported(description.key, description, component) if is_supported(description.key, description.value_getter, component)
) )
return entities return entities

View File

@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Mapping from collections.abc import Callable, Mapping
import logging import logging
from typing import Any from typing import Any
@ -30,7 +30,7 @@ from .const import (
VICARE_TOKEN_FILENAME, VICARE_TOKEN_FILENAME,
HeatingType, HeatingType,
) )
from .types import ViCareConfigEntry, ViCareRequiredKeysMixin from .types import ViCareConfigEntry
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -81,12 +81,12 @@ def get_device_serial(device: PyViCareDevice) -> str | None:
def is_supported( def is_supported(
name: str, name: str,
entity_description: ViCareRequiredKeysMixin, getter: Callable[[PyViCareDevice], Any],
vicare_device, vicare_device,
) -> bool: ) -> bool:
"""Check if the PyViCare device supports the requested sensor.""" """Check if the PyViCare device supports the requested sensor."""
try: try:
entity_description.value_getter(vicare_device) getter(vicare_device)
except PyViCareNotSupportedFeatureError: except PyViCareNotSupportedFeatureError:
_LOGGER.debug("Feature not supported %s", name) _LOGGER.debug("Feature not supported %s", name)
return False return False
@ -131,5 +131,5 @@ def get_compressors(device: PyViCareDevice) -> list[PyViCareHeatingDeviceCompone
def filter_state(state: str) -> str | None: def filter_state(state: str) -> str | None:
"""Remove invalid states.""" """Return the state if not 'nothing' or 'unknown'."""
return None if state in ("nothing", "unknown") else state return None if state in ("nothing", "unknown") else state

View File

@ -0,0 +1,645 @@
{
"data": [
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "ventilation",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"active": {
"type": "boolean",
"value": true
}
},
"timestamp": "2024-12-17T07:50:28.062Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "ventilation.levels.levelFour",
"gatewayId": "################",
"isEnabled": false,
"isReady": true,
"properties": {},
"timestamp": "2024-12-17T08:16:15.525Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.levels.levelFour"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "ventilation.levels.levelOne",
"gatewayId": "################",
"isEnabled": false,
"isReady": true,
"properties": {},
"timestamp": "2024-12-17T08:16:15.525Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.levels.levelOne"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "ventilation.levels.levelThree",
"gatewayId": "################",
"isEnabled": false,
"isReady": true,
"properties": {},
"timestamp": "2024-12-17T08:16:15.525Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.levels.levelThree"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "ventilation.levels.levelTwo",
"gatewayId": "################",
"isEnabled": false,
"isReady": true,
"properties": {},
"timestamp": "2024-12-17T08:16:15.525Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.levels.levelTwo"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "ventilation.operating.modes.filterChange",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"active": {
"type": "boolean",
"value": false
}
},
"timestamp": "2024-12-17T07:50:28.062Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.operating.modes.filterChange"
},
{
"apiVersion": 1,
"commands": {
"setLevel": {
"isExecutable": true,
"name": "setLevel",
"params": {
"level": {
"constraints": {
"enum": ["levelOne", "levelTwo", "levelThree", "levelFour"]
},
"required": true,
"type": "string"
}
},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.operating.modes.permanent/commands/setLevel"
}
},
"deviceId": "0",
"feature": "ventilation.operating.modes.permanent",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"active": {
"type": "boolean",
"value": false
}
},
"timestamp": "2024-12-17T13:24:03.411Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.operating.modes.permanent"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "ventilation.operating.modes.sensorDriven",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"active": {
"type": "boolean",
"value": true
}
},
"timestamp": "2024-12-17T08:16:15.525Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.operating.modes.sensorDriven"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "ventilation.operating.modes.ventilation",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"active": {
"type": "boolean",
"value": false
}
},
"timestamp": "2024-12-17T07:50:28.062Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.operating.modes.ventilation"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "ventilation.operating.programs.active",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"value": {
"type": "string",
"value": "levelTwo"
}
},
"timestamp": "2024-12-17T13:24:03.411Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.operating.programs.active"
},
{
"apiVersion": 1,
"commands": {
"activate": {
"isExecutable": true,
"name": "activate",
"params": {
"timeout": {
"constraints": {
"max": 1440,
"min": 1,
"stepping": 1
},
"required": false,
"type": "number"
}
},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.forcedLevelFour/commands/activate"
},
"deactivate": {
"isExecutable": true,
"name": "deactivate",
"params": {},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.forcedLevelFour/commands/deactivate"
},
"setDefaultRuntime": {
"isExecutable": true,
"name": "setDefaultRuntime",
"params": {
"defaultRuntime": {
"constraints": {
"max": 1440,
"min": 1,
"stepping": 1
},
"required": true,
"type": "number"
}
},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.forcedLevelFour/commands/setDefaultRuntime"
},
"setTimeout": {
"isExecutable": true,
"name": "setTimeout",
"params": {
"timeout": {
"constraints": {
"max": 1440,
"min": 1,
"stepping": 1
},
"required": true,
"type": "number"
}
},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.forcedLevelFour/commands/setTimeout"
}
},
"deviceId": "0",
"feature": "ventilation.quickmodes.forcedLevelFour",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"active": {
"type": "boolean",
"value": false
},
"defaultRuntime": {
"type": "number",
"unit": "minutes",
"value": 30
},
"isActiveWritable": {
"type": "boolean",
"value": true
}
},
"timestamp": "2024-12-17T13:24:04.515Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.forcedLevelFour"
},
{
"apiVersion": 1,
"commands": {
"activate": {
"isExecutable": true,
"name": "activate",
"params": {
"timeout": {
"constraints": {
"max": 1440,
"min": 1,
"stepping": 1
},
"required": false,
"type": "number"
}
},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.silent/commands/activate"
},
"deactivate": {
"isExecutable": true,
"name": "deactivate",
"params": {},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.silent/commands/deactivate"
},
"setDefaultRuntime": {
"isExecutable": true,
"name": "setDefaultRuntime",
"params": {
"defaultRuntime": {
"constraints": {
"max": 1440,
"min": 1,
"stepping": 1
},
"required": true,
"type": "number"
}
},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.silent/commands/setDefaultRuntime"
},
"setTimeout": {
"isExecutable": true,
"name": "setTimeout",
"params": {
"timeout": {
"constraints": {
"max": 1440,
"min": 1,
"stepping": 1
},
"required": true,
"type": "number"
}
},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.silent/commands/setTimeout"
}
},
"deviceId": "0",
"feature": "ventilation.quickmodes.silent",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"active": {
"type": "boolean",
"value": false
},
"defaultRuntime": {
"type": "number",
"unit": "minutes",
"value": 30
},
"isActiveWritable": {
"type": "boolean",
"value": true
}
},
"timestamp": "2024-12-17T13:24:04.515Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.silent"
},
{
"apiVersion": 1,
"commands": {
"activate": {
"isExecutable": true,
"name": "activate",
"params": {},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.standby/commands/activate"
},
"deactivate": {
"isExecutable": true,
"name": "deactivate",
"params": {},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.standby/commands/deactivate"
}
},
"deviceId": "0",
"feature": "ventilation.quickmodes.standby",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"active": {
"type": "boolean",
"value": true
}
},
"timestamp": "2024-12-17T13:24:04.515Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.quickmodes.standby"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "device.productIdentification",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"product": {
"type": "object",
"value": {
"busAddress": 0,
"busType": "OwnBus",
"productFamily": "B_00059_VP300",
"viessmannIdentificationNumber": "################"
}
}
},
"timestamp": "2024-12-17T07:50:28.062Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/device.productIdentification"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "device.messages.errors.raw",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"entries": {
"type": "array",
"value": []
}
},
"timestamp": "2024-12-17T07:50:28.062Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/device.messages.errors.raw"
},
{
"apiVersion": 1,
"commands": {
"activate": {
"isExecutable": true,
"name": "activate",
"params": {
"begin": {
"constraints": {
"regEx": "^[\\d]{2}-[\\d]{2}$"
},
"required": true,
"type": "string"
},
"end": {
"constraints": {
"regEx": "^[\\d]{2}-[\\d]{2}$"
},
"required": true,
"type": "string"
}
},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/device.time.daylightSaving/commands/activate"
},
"deactivate": {
"isExecutable": true,
"name": "deactivate",
"params": {},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/device.time.daylightSaving/commands/deactivate"
}
},
"deviceId": "0",
"feature": "device.time.daylightSaving",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"active": {
"type": "boolean",
"value": false
}
},
"timestamp": "2024-12-17T07:50:28.062Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/device.time.daylightSaving"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "heating.boiler.serial",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"value": {
"type": "string",
"value": "################"
}
},
"timestamp": "2024-12-17T07:50:28.062Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/heating.boiler.serial"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "heating.device.variant",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"value": {
"type": "string",
"value": "Vitopure350"
}
},
"timestamp": "2024-12-17T07:50:28.062Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/heating.device.variant"
},
{
"apiVersion": 1,
"commands": {
"setMode": {
"isExecutable": true,
"name": "setMode",
"params": {
"mode": {
"constraints": {
"enum": ["permanent", "ventilation", "sensorDriven"]
},
"required": true,
"type": "string"
}
},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.operating.modes.active/commands/setMode"
},
"setModeContinuousSensorOverride": {
"isExecutable": false,
"name": "setModeContinuousSensorOverride",
"params": {},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.operating.modes.active/commands/setModeContinuousSensorOverride"
}
},
"deviceId": "0",
"feature": "ventilation.operating.modes.active",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"value": {
"type": "string",
"value": "sensorDriven"
}
},
"timestamp": "2024-12-17T08:16:15.525Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.operating.modes.active"
},
{
"apiVersion": 1,
"commands": {},
"deviceId": "0",
"feature": "ventilation.operating.state",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"demand": {
"type": "string",
"value": "unknown"
},
"level": {
"type": "string",
"value": "unknown"
},
"reason": {
"type": "string",
"value": "standby"
}
},
"timestamp": "2024-12-17T13:24:04.515Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.operating.state"
},
{
"apiVersion": 1,
"commands": {
"resetSchedule": {
"isExecutable": false,
"name": "resetSchedule",
"params": {},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.schedule/commands/resetSchedule"
},
"setSchedule": {
"isExecutable": true,
"name": "setSchedule",
"params": {
"newSchedule": {
"constraints": {
"defaultMode": "standby",
"maxEntries": 4,
"modes": ["levelOne", "levelTwo", "levelThree", "levelFour"],
"overlapAllowed": false,
"resolution": 10
},
"required": true,
"type": "Schedule"
}
},
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.schedule/commands/setSchedule"
}
},
"deviceId": "0",
"feature": "ventilation.schedule",
"gatewayId": "################",
"isEnabled": true,
"isReady": true,
"properties": {
"active": {
"type": "boolean",
"value": true
},
"entries": {
"type": "Schedule",
"value": {
"fri": [
{
"end": "22:00",
"mode": "levelTwo",
"position": 0,
"start": "06:00"
}
],
"mon": [
{
"end": "22:00",
"mode": "levelTwo",
"position": 0,
"start": "06:00"
}
],
"sat": [
{
"end": "22:00",
"mode": "levelTwo",
"position": 0,
"start": "06:00"
}
],
"sun": [
{
"end": "22:00",
"mode": "levelTwo",
"position": 0,
"start": "06:00"
}
],
"thu": [
{
"end": "22:00",
"mode": "levelTwo",
"position": 0,
"start": "06:00"
}
],
"tue": [
{
"end": "22:00",
"mode": "levelTwo",
"position": 0,
"start": "06:00"
}
],
"wed": [
{
"end": "22:00",
"mode": "levelTwo",
"position": 0,
"start": "06:00"
}
]
}
}
},
"timestamp": "2024-12-17T07:50:28.062Z",
"uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/0/features/ventilation.schedule"
}
]
}

View File

@ -60,6 +60,68 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': 'on', 'state': 'off',
})
# ---
# name: test_all_entities[fan.model1_ventilation-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'preset_modes': list([
<VentilationMode.PERMANENT: 'permanent'>,
<VentilationMode.VENTILATION: 'ventilation'>,
<VentilationMode.SENSOR_DRIVEN: 'sensor_driven'>,
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'fan',
'entity_category': None,
'entity_id': 'fan.model1_ventilation',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': 'mdi:fan',
'original_name': 'Ventilation',
'platform': 'vicare',
'previous_unique_id': None,
'supported_features': <FanEntityFeature: 25>,
'translation_key': 'ventilation',
'unique_id': 'gateway1_deviceId1-ventilation',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[fan.model1_ventilation-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'model1 Ventilation',
'icon': 'mdi:fan',
'percentage': 0,
'percentage_step': 25.0,
'preset_mode': None,
'preset_modes': list([
<VentilationMode.PERMANENT: 'permanent'>,
<VentilationMode.VENTILATION: 'ventilation'>,
<VentilationMode.SENSOR_DRIVEN: 'sensor_driven'>,
]),
'supported_features': <FanEntityFeature: 25>,
}),
'context': <ANY>,
'entity_id': 'fan.model1_ventilation',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
}) })
# --- # ---

View File

@ -23,7 +23,10 @@ async def test_all_entities(
entity_registry: er.EntityRegistry, entity_registry: er.EntityRegistry,
) -> None: ) -> None:
"""Test all entities.""" """Test all entities."""
fixtures: list[Fixture] = [Fixture({"type:ventilation"}, "vicare/ViAir300F.json")] fixtures: list[Fixture] = [
Fixture({"type:ventilation"}, "vicare/ViAir300F.json"),
Fixture({"type:ventilation"}, "vicare/VitoPure.json"),
]
with ( with (
patch(f"{MODULE}.login", return_value=MockPyViCare(fixtures)), patch(f"{MODULE}.login", return_value=MockPyViCare(fixtures)),
patch(f"{MODULE}.PLATFORMS", [Platform.FAN]), patch(f"{MODULE}.PLATFORMS", [Platform.FAN]),