mirror of
https://github.com/home-assistant/core.git
synced 2025-08-03 18:48:22 +00:00
Add sensor platform to Qbus integration (#149389)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
fa476d4e34
commit
755864f9f3
@ -22,7 +22,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .coordinator import QbusConfigEntry
|
from .coordinator import QbusConfigEntry
|
||||||
from .entity import QbusEntity, add_new_outputs
|
from .entity import QbusEntity, create_new_entities
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
@ -42,13 +42,13 @@ async def async_setup_entry(
|
|||||||
added_outputs: list[QbusMqttOutput] = []
|
added_outputs: list[QbusMqttOutput] = []
|
||||||
|
|
||||||
def _check_outputs() -> None:
|
def _check_outputs() -> None:
|
||||||
add_new_outputs(
|
entities = create_new_entities(
|
||||||
coordinator,
|
coordinator,
|
||||||
added_outputs,
|
added_outputs,
|
||||||
lambda output: output.type == "thermo",
|
lambda output: output.type == "thermo",
|
||||||
QbusClimate,
|
QbusClimate,
|
||||||
async_add_entities,
|
|
||||||
)
|
)
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
_check_outputs()
|
_check_outputs()
|
||||||
entry.async_on_unload(coordinator.async_add_listener(_check_outputs))
|
entry.async_on_unload(coordinator.async_add_listener(_check_outputs))
|
||||||
|
@ -10,6 +10,7 @@ PLATFORMS: list[Platform] = [
|
|||||||
Platform.COVER,
|
Platform.COVER,
|
||||||
Platform.LIGHT,
|
Platform.LIGHT,
|
||||||
Platform.SCENE,
|
Platform.SCENE,
|
||||||
|
Platform.SENSOR,
|
||||||
Platform.SWITCH,
|
Platform.SWITCH,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
|
|
||||||
from .coordinator import QbusConfigEntry
|
from .coordinator import QbusConfigEntry
|
||||||
from .entity import QbusEntity, add_new_outputs
|
from .entity import QbusEntity, create_new_entities
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
@ -36,13 +36,13 @@ async def async_setup_entry(
|
|||||||
added_outputs: list[QbusMqttOutput] = []
|
added_outputs: list[QbusMqttOutput] = []
|
||||||
|
|
||||||
def _check_outputs() -> None:
|
def _check_outputs() -> None:
|
||||||
add_new_outputs(
|
entities = create_new_entities(
|
||||||
coordinator,
|
coordinator,
|
||||||
added_outputs,
|
added_outputs,
|
||||||
lambda output: output.type == "shutter",
|
lambda output: output.type == "shutter",
|
||||||
QbusCover,
|
QbusCover,
|
||||||
async_add_entities,
|
|
||||||
)
|
)
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
_check_outputs()
|
_check_outputs()
|
||||||
entry.async_on_unload(coordinator.async_add_listener(_check_outputs))
|
entry.async_on_unload(coordinator.async_add_listener(_check_outputs))
|
||||||
|
@ -14,7 +14,6 @@ from qbusmqttapi.state import QbusMqttState
|
|||||||
from homeassistant.components.mqtt import ReceiveMessage, client as mqtt
|
from homeassistant.components.mqtt import ReceiveMessage, client as mqtt
|
||||||
from homeassistant.helpers.device_registry import DeviceInfo, format_mac
|
from homeassistant.helpers.device_registry import DeviceInfo, format_mac
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
||||||
|
|
||||||
from .const import DOMAIN, MANUFACTURER
|
from .const import DOMAIN, MANUFACTURER
|
||||||
from .coordinator import QbusControllerCoordinator
|
from .coordinator import QbusControllerCoordinator
|
||||||
@ -24,14 +23,24 @@ _REFID_REGEX = re.compile(r"^\d+\/(\d+(?:\/\d+)?)$")
|
|||||||
StateT = TypeVar("StateT", bound=QbusMqttState)
|
StateT = TypeVar("StateT", bound=QbusMqttState)
|
||||||
|
|
||||||
|
|
||||||
def add_new_outputs(
|
def create_new_entities(
|
||||||
coordinator: QbusControllerCoordinator,
|
coordinator: QbusControllerCoordinator,
|
||||||
added_outputs: list[QbusMqttOutput],
|
added_outputs: list[QbusMqttOutput],
|
||||||
filter_fn: Callable[[QbusMqttOutput], bool],
|
filter_fn: Callable[[QbusMqttOutput], bool],
|
||||||
entity_type: type[QbusEntity],
|
entity_type: type[QbusEntity],
|
||||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
) -> list[QbusEntity]:
|
||||||
) -> None:
|
"""Create entities for new outputs."""
|
||||||
"""Call async_add_entities for new outputs."""
|
|
||||||
|
new_outputs = determine_new_outputs(coordinator, added_outputs, filter_fn)
|
||||||
|
return [entity_type(output) for output in new_outputs]
|
||||||
|
|
||||||
|
|
||||||
|
def determine_new_outputs(
|
||||||
|
coordinator: QbusControllerCoordinator,
|
||||||
|
added_outputs: list[QbusMqttOutput],
|
||||||
|
filter_fn: Callable[[QbusMqttOutput], bool],
|
||||||
|
) -> list[QbusMqttOutput]:
|
||||||
|
"""Determine new outputs."""
|
||||||
|
|
||||||
added_ref_ids = {k.ref_id for k in added_outputs}
|
added_ref_ids = {k.ref_id for k in added_outputs}
|
||||||
|
|
||||||
@ -43,7 +52,8 @@ def add_new_outputs(
|
|||||||
|
|
||||||
if new_outputs:
|
if new_outputs:
|
||||||
added_outputs.extend(new_outputs)
|
added_outputs.extend(new_outputs)
|
||||||
async_add_entities([entity_type(output) for output in new_outputs])
|
|
||||||
|
return new_outputs
|
||||||
|
|
||||||
|
|
||||||
def format_ref_id(ref_id: str) -> str | None:
|
def format_ref_id(ref_id: str) -> str | None:
|
||||||
@ -67,7 +77,13 @@ class QbusEntity(Entity, Generic[StateT], ABC):
|
|||||||
_attr_has_entity_name = True
|
_attr_has_entity_name = True
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
|
||||||
def __init__(self, mqtt_output: QbusMqttOutput) -> None:
|
def __init__(
|
||||||
|
self,
|
||||||
|
mqtt_output: QbusMqttOutput,
|
||||||
|
*,
|
||||||
|
id_suffix: str = "",
|
||||||
|
link_to_main_device: bool = False,
|
||||||
|
) -> None:
|
||||||
"""Initialize the Qbus entity."""
|
"""Initialize the Qbus entity."""
|
||||||
|
|
||||||
self._mqtt_output = mqtt_output
|
self._mqtt_output = mqtt_output
|
||||||
@ -79,17 +95,25 @@ class QbusEntity(Entity, Generic[StateT], ABC):
|
|||||||
)
|
)
|
||||||
|
|
||||||
ref_id = format_ref_id(mqtt_output.ref_id)
|
ref_id = format_ref_id(mqtt_output.ref_id)
|
||||||
|
unique_id = f"ctd_{mqtt_output.device.serial_number}_{ref_id}"
|
||||||
|
|
||||||
self._attr_unique_id = f"ctd_{mqtt_output.device.serial_number}_{ref_id}"
|
if id_suffix:
|
||||||
|
unique_id += f"_{id_suffix}"
|
||||||
|
|
||||||
# Create linked device
|
self._attr_unique_id = unique_id
|
||||||
self._attr_device_info = DeviceInfo(
|
|
||||||
name=mqtt_output.name.title(),
|
if link_to_main_device:
|
||||||
manufacturer=MANUFACTURER,
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, f"{mqtt_output.device.serial_number}_{ref_id}")},
|
identifiers={create_main_device_identifier(mqtt_output)}
|
||||||
suggested_area=mqtt_output.location.title(),
|
)
|
||||||
via_device=create_main_device_identifier(mqtt_output),
|
else:
|
||||||
)
|
self._attr_device_info = DeviceInfo(
|
||||||
|
name=mqtt_output.name.title(),
|
||||||
|
manufacturer=MANUFACTURER,
|
||||||
|
identifiers={(DOMAIN, f"{mqtt_output.device.serial_number}_{ref_id}")},
|
||||||
|
suggested_area=mqtt_output.location.title(),
|
||||||
|
via_device=create_main_device_identifier(mqtt_output),
|
||||||
|
)
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Run when entity about to be added to hass."""
|
"""Run when entity about to be added to hass."""
|
||||||
|
@ -11,7 +11,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|||||||
from homeassistant.util.color import brightness_to_value, value_to_brightness
|
from homeassistant.util.color import brightness_to_value, value_to_brightness
|
||||||
|
|
||||||
from .coordinator import QbusConfigEntry
|
from .coordinator import QbusConfigEntry
|
||||||
from .entity import QbusEntity, add_new_outputs
|
from .entity import QbusEntity, create_new_entities
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
@ -27,13 +27,13 @@ async def async_setup_entry(
|
|||||||
added_outputs: list[QbusMqttOutput] = []
|
added_outputs: list[QbusMqttOutput] = []
|
||||||
|
|
||||||
def _check_outputs() -> None:
|
def _check_outputs() -> None:
|
||||||
add_new_outputs(
|
entities = create_new_entities(
|
||||||
coordinator,
|
coordinator,
|
||||||
added_outputs,
|
added_outputs,
|
||||||
lambda output: output.type == "analog",
|
lambda output: output.type == "analog",
|
||||||
QbusLight,
|
QbusLight,
|
||||||
async_add_entities,
|
|
||||||
)
|
)
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
_check_outputs()
|
_check_outputs()
|
||||||
entry.async_on_unload(coordinator.async_add_listener(_check_outputs))
|
entry.async_on_unload(coordinator.async_add_listener(_check_outputs))
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/qbus",
|
"documentation": "https://www.home-assistant.io/integrations/qbus",
|
||||||
"integration_type": "hub",
|
"integration_type": "hub",
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
|
"loggers": ["qbusmqttapi"],
|
||||||
"mqtt": [
|
"mqtt": [
|
||||||
"cloudapp/QBUSMQTTGW/state",
|
"cloudapp/QBUSMQTTGW/state",
|
||||||
"cloudapp/QBUSMQTTGW/config",
|
"cloudapp/QBUSMQTTGW/config",
|
||||||
|
@ -7,11 +7,10 @@ from qbusmqttapi.state import QbusMqttState, StateAction, StateType
|
|||||||
|
|
||||||
from homeassistant.components.scene import Scene
|
from homeassistant.components.scene import Scene
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.device_registry import DeviceInfo
|
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
|
|
||||||
from .coordinator import QbusConfigEntry
|
from .coordinator import QbusConfigEntry
|
||||||
from .entity import QbusEntity, add_new_outputs, create_main_device_identifier
|
from .entity import QbusEntity, create_new_entities
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
@ -27,13 +26,13 @@ async def async_setup_entry(
|
|||||||
added_outputs: list[QbusMqttOutput] = []
|
added_outputs: list[QbusMqttOutput] = []
|
||||||
|
|
||||||
def _check_outputs() -> None:
|
def _check_outputs() -> None:
|
||||||
add_new_outputs(
|
entities = create_new_entities(
|
||||||
coordinator,
|
coordinator,
|
||||||
added_outputs,
|
added_outputs,
|
||||||
lambda output: output.type == "scene",
|
lambda output: output.type == "scene",
|
||||||
QbusScene,
|
QbusScene,
|
||||||
async_add_entities,
|
|
||||||
)
|
)
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
_check_outputs()
|
_check_outputs()
|
||||||
entry.async_on_unload(coordinator.async_add_listener(_check_outputs))
|
entry.async_on_unload(coordinator.async_add_listener(_check_outputs))
|
||||||
@ -45,12 +44,8 @@ class QbusScene(QbusEntity, Scene):
|
|||||||
def __init__(self, mqtt_output: QbusMqttOutput) -> None:
|
def __init__(self, mqtt_output: QbusMqttOutput) -> None:
|
||||||
"""Initialize scene entity."""
|
"""Initialize scene entity."""
|
||||||
|
|
||||||
super().__init__(mqtt_output)
|
super().__init__(mqtt_output, link_to_main_device=True)
|
||||||
|
|
||||||
# Add to main controller device
|
|
||||||
self._attr_device_info = DeviceInfo(
|
|
||||||
identifiers={create_main_device_identifier(mqtt_output)}
|
|
||||||
)
|
|
||||||
self._attr_name = mqtt_output.name.title()
|
self._attr_name = mqtt_output.name.title()
|
||||||
|
|
||||||
async def async_activate(self, **kwargs: Any) -> None:
|
async def async_activate(self, **kwargs: Any) -> None:
|
||||||
|
378
homeassistant/components/qbus/sensor.py
Normal file
378
homeassistant/components/qbus/sensor.py
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
"""Support for Qbus sensor."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from qbusmqttapi.discovery import QbusMqttOutput
|
||||||
|
from qbusmqttapi.state import (
|
||||||
|
GaugeStateProperty,
|
||||||
|
QbusMqttGaugeState,
|
||||||
|
QbusMqttHumidityState,
|
||||||
|
QbusMqttThermoState,
|
||||||
|
QbusMqttVentilationState,
|
||||||
|
QbusMqttWeatherState,
|
||||||
|
)
|
||||||
|
|
||||||
|
from homeassistant.components.sensor import (
|
||||||
|
SensorDeviceClass,
|
||||||
|
SensorEntity,
|
||||||
|
SensorEntityDescription,
|
||||||
|
SensorStateClass,
|
||||||
|
)
|
||||||
|
from homeassistant.const import (
|
||||||
|
CONCENTRATION_PARTS_PER_MILLION,
|
||||||
|
LIGHT_LUX,
|
||||||
|
PERCENTAGE,
|
||||||
|
UnitOfElectricCurrent,
|
||||||
|
UnitOfElectricPotential,
|
||||||
|
UnitOfEnergy,
|
||||||
|
UnitOfLength,
|
||||||
|
UnitOfPower,
|
||||||
|
UnitOfPressure,
|
||||||
|
UnitOfSoundPressure,
|
||||||
|
UnitOfSpeed,
|
||||||
|
UnitOfTemperature,
|
||||||
|
UnitOfVolume,
|
||||||
|
UnitOfVolumeFlowRate,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
|
|
||||||
|
from .coordinator import QbusConfigEntry
|
||||||
|
from .entity import QbusEntity, create_new_entities, determine_new_outputs
|
||||||
|
|
||||||
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
class QbusWeatherDescription(SensorEntityDescription):
|
||||||
|
"""Description for Qbus weather entities."""
|
||||||
|
|
||||||
|
property: str
|
||||||
|
|
||||||
|
|
||||||
|
_WEATHER_DESCRIPTIONS = (
|
||||||
|
QbusWeatherDescription(
|
||||||
|
key="daylight",
|
||||||
|
property="dayLight",
|
||||||
|
translation_key="daylight",
|
||||||
|
device_class=SensorDeviceClass.ILLUMINANCE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=LIGHT_LUX,
|
||||||
|
),
|
||||||
|
QbusWeatherDescription(
|
||||||
|
key="light",
|
||||||
|
property="light",
|
||||||
|
device_class=SensorDeviceClass.ILLUMINANCE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=LIGHT_LUX,
|
||||||
|
),
|
||||||
|
QbusWeatherDescription(
|
||||||
|
key="light_east",
|
||||||
|
property="lightEast",
|
||||||
|
translation_key="light_east",
|
||||||
|
device_class=SensorDeviceClass.ILLUMINANCE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=LIGHT_LUX,
|
||||||
|
),
|
||||||
|
QbusWeatherDescription(
|
||||||
|
key="light_south",
|
||||||
|
property="lightSouth",
|
||||||
|
translation_key="light_south",
|
||||||
|
device_class=SensorDeviceClass.ILLUMINANCE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=LIGHT_LUX,
|
||||||
|
),
|
||||||
|
QbusWeatherDescription(
|
||||||
|
key="light_west",
|
||||||
|
property="lightWest",
|
||||||
|
translation_key="light_west",
|
||||||
|
device_class=SensorDeviceClass.ILLUMINANCE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=LIGHT_LUX,
|
||||||
|
),
|
||||||
|
QbusWeatherDescription(
|
||||||
|
key="temperature",
|
||||||
|
property="temperature",
|
||||||
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
),
|
||||||
|
QbusWeatherDescription(
|
||||||
|
key="wind",
|
||||||
|
property="wind",
|
||||||
|
device_class=SensorDeviceClass.WIND_SPEED,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
_GAUGE_VARIANT_DESCRIPTIONS = {
|
||||||
|
"AIRPRESSURE": SensorEntityDescription(
|
||||||
|
key="airpressure",
|
||||||
|
device_class=SensorDeviceClass.PRESSURE,
|
||||||
|
native_unit_of_measurement=UnitOfPressure.MBAR,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"AIRQUALITY": SensorEntityDescription(
|
||||||
|
key="airquality",
|
||||||
|
device_class=SensorDeviceClass.CO2,
|
||||||
|
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"CURRENT": SensorEntityDescription(
|
||||||
|
key="current",
|
||||||
|
device_class=SensorDeviceClass.CURRENT,
|
||||||
|
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"ENERGY": SensorEntityDescription(
|
||||||
|
key="energy",
|
||||||
|
device_class=SensorDeviceClass.ENERGY,
|
||||||
|
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||||
|
state_class=SensorStateClass.TOTAL,
|
||||||
|
),
|
||||||
|
"GAS": SensorEntityDescription(
|
||||||
|
key="gas",
|
||||||
|
device_class=SensorDeviceClass.VOLUME_FLOW_RATE,
|
||||||
|
native_unit_of_measurement=UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"GASFLOW": SensorEntityDescription(
|
||||||
|
key="gasflow",
|
||||||
|
device_class=SensorDeviceClass.VOLUME_FLOW_RATE,
|
||||||
|
native_unit_of_measurement=UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"HUMIDITY": SensorEntityDescription(
|
||||||
|
key="humidity",
|
||||||
|
device_class=SensorDeviceClass.HUMIDITY,
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"LIGHT": SensorEntityDescription(
|
||||||
|
key="light",
|
||||||
|
device_class=SensorDeviceClass.ILLUMINANCE,
|
||||||
|
native_unit_of_measurement=LIGHT_LUX,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"LOUDNESS": SensorEntityDescription(
|
||||||
|
key="loudness",
|
||||||
|
device_class=SensorDeviceClass.SOUND_PRESSURE,
|
||||||
|
native_unit_of_measurement=UnitOfSoundPressure.DECIBEL,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"POWER": SensorEntityDescription(
|
||||||
|
key="power",
|
||||||
|
device_class=SensorDeviceClass.POWER,
|
||||||
|
native_unit_of_measurement=UnitOfPower.KILO_WATT,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"PRESSURE": SensorEntityDescription(
|
||||||
|
key="pressure",
|
||||||
|
device_class=SensorDeviceClass.PRESSURE,
|
||||||
|
native_unit_of_measurement=UnitOfPressure.KPA,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"TEMPERATURE": SensorEntityDescription(
|
||||||
|
key="temperature",
|
||||||
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"VOLTAGE": SensorEntityDescription(
|
||||||
|
key="voltage",
|
||||||
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"VOLUME": SensorEntityDescription(
|
||||||
|
key="volume",
|
||||||
|
device_class=SensorDeviceClass.VOLUME_STORAGE,
|
||||||
|
native_unit_of_measurement=UnitOfVolume.LITERS,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"WATER": SensorEntityDescription(
|
||||||
|
key="water",
|
||||||
|
device_class=SensorDeviceClass.WATER,
|
||||||
|
native_unit_of_measurement=UnitOfVolume.LITERS,
|
||||||
|
state_class=SensorStateClass.TOTAL,
|
||||||
|
),
|
||||||
|
"WATERFLOW": SensorEntityDescription(
|
||||||
|
key="waterflow",
|
||||||
|
device_class=SensorDeviceClass.VOLUME_FLOW_RATE,
|
||||||
|
native_unit_of_measurement=UnitOfVolumeFlowRate.LITERS_PER_HOUR,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"WATERLEVEL": SensorEntityDescription(
|
||||||
|
key="waterlevel",
|
||||||
|
device_class=SensorDeviceClass.DISTANCE,
|
||||||
|
native_unit_of_measurement=UnitOfLength.METERS,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"WATERPRESSURE": SensorEntityDescription(
|
||||||
|
key="waterpressure",
|
||||||
|
device_class=SensorDeviceClass.PRESSURE,
|
||||||
|
native_unit_of_measurement=UnitOfPressure.MBAR,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
"WIND": SensorEntityDescription(
|
||||||
|
key="wind",
|
||||||
|
device_class=SensorDeviceClass.WIND_SPEED,
|
||||||
|
native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _is_gauge_with_variant(output: QbusMqttOutput) -> bool:
|
||||||
|
return (
|
||||||
|
output.type == "gauge"
|
||||||
|
and isinstance(output.variant, str)
|
||||||
|
and _GAUGE_VARIANT_DESCRIPTIONS.get(output.variant.upper()) is not None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _is_ventilation_with_co2(output: QbusMqttOutput) -> bool:
|
||||||
|
return output.type == "ventilation" and output.properties.get("co2") is not None
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entry: QbusConfigEntry,
|
||||||
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up sensor entities."""
|
||||||
|
|
||||||
|
coordinator = entry.runtime_data
|
||||||
|
added_outputs: list[QbusMqttOutput] = []
|
||||||
|
|
||||||
|
def _create_weather_entities() -> list[QbusEntity]:
|
||||||
|
new_outputs = determine_new_outputs(
|
||||||
|
coordinator, added_outputs, lambda output: output.type == "weatherstation"
|
||||||
|
)
|
||||||
|
|
||||||
|
return [
|
||||||
|
QbusWeatherSensor(output, description)
|
||||||
|
for output in new_outputs
|
||||||
|
for description in _WEATHER_DESCRIPTIONS
|
||||||
|
]
|
||||||
|
|
||||||
|
def _check_outputs() -> None:
|
||||||
|
entities: list[QbusEntity] = [
|
||||||
|
*create_new_entities(
|
||||||
|
coordinator,
|
||||||
|
added_outputs,
|
||||||
|
_is_gauge_with_variant,
|
||||||
|
QbusGaugeVariantSensor,
|
||||||
|
),
|
||||||
|
*create_new_entities(
|
||||||
|
coordinator,
|
||||||
|
added_outputs,
|
||||||
|
lambda output: output.type == "humidity",
|
||||||
|
QbusHumiditySensor,
|
||||||
|
),
|
||||||
|
*create_new_entities(
|
||||||
|
coordinator,
|
||||||
|
added_outputs,
|
||||||
|
lambda output: output.type == "thermo",
|
||||||
|
QbusThermoSensor,
|
||||||
|
),
|
||||||
|
*create_new_entities(
|
||||||
|
coordinator,
|
||||||
|
added_outputs,
|
||||||
|
_is_ventilation_with_co2,
|
||||||
|
QbusVentilationSensor,
|
||||||
|
),
|
||||||
|
*_create_weather_entities(),
|
||||||
|
]
|
||||||
|
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
_check_outputs()
|
||||||
|
entry.async_on_unload(coordinator.async_add_listener(_check_outputs))
|
||||||
|
|
||||||
|
|
||||||
|
class QbusGaugeVariantSensor(QbusEntity, SensorEntity):
|
||||||
|
"""Representation of a Qbus sensor entity for gauges with variant."""
|
||||||
|
|
||||||
|
_state_cls = QbusMqttGaugeState
|
||||||
|
|
||||||
|
_attr_name = None
|
||||||
|
_attr_suggested_display_precision = 2
|
||||||
|
|
||||||
|
def __init__(self, mqtt_output: QbusMqttOutput) -> None:
|
||||||
|
"""Initialize sensor entity."""
|
||||||
|
|
||||||
|
super().__init__(mqtt_output)
|
||||||
|
|
||||||
|
variant = str(mqtt_output.variant)
|
||||||
|
self.entity_description = _GAUGE_VARIANT_DESCRIPTIONS[variant.upper()]
|
||||||
|
|
||||||
|
async def _handle_state_received(self, state: QbusMqttGaugeState) -> None:
|
||||||
|
self._attr_native_value = state.read_value(GaugeStateProperty.CURRENT_VALUE)
|
||||||
|
|
||||||
|
|
||||||
|
class QbusHumiditySensor(QbusEntity, SensorEntity):
|
||||||
|
"""Representation of a Qbus sensor entity for humidity modules."""
|
||||||
|
|
||||||
|
_state_cls = QbusMqttHumidityState
|
||||||
|
|
||||||
|
_attr_device_class = SensorDeviceClass.HUMIDITY
|
||||||
|
_attr_name = None
|
||||||
|
_attr_native_unit_of_measurement = PERCENTAGE
|
||||||
|
_attr_state_class = SensorStateClass.MEASUREMENT
|
||||||
|
|
||||||
|
async def _handle_state_received(self, state: QbusMqttHumidityState) -> None:
|
||||||
|
self._attr_native_value = state.read_value()
|
||||||
|
|
||||||
|
|
||||||
|
class QbusThermoSensor(QbusEntity, SensorEntity):
|
||||||
|
"""Representation of a Qbus sensor entity for thermostats."""
|
||||||
|
|
||||||
|
_state_cls = QbusMqttThermoState
|
||||||
|
|
||||||
|
_attr_device_class = SensorDeviceClass.TEMPERATURE
|
||||||
|
_attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS
|
||||||
|
_attr_state_class = SensorStateClass.MEASUREMENT
|
||||||
|
|
||||||
|
async def _handle_state_received(self, state: QbusMqttThermoState) -> None:
|
||||||
|
self._attr_native_value = state.read_current_temperature()
|
||||||
|
|
||||||
|
|
||||||
|
class QbusVentilationSensor(QbusEntity, SensorEntity):
|
||||||
|
"""Representation of a Qbus sensor entity for ventilations."""
|
||||||
|
|
||||||
|
_state_cls = QbusMqttVentilationState
|
||||||
|
|
||||||
|
_attr_device_class = SensorDeviceClass.CO2
|
||||||
|
_attr_name = None
|
||||||
|
_attr_native_unit_of_measurement = CONCENTRATION_PARTS_PER_MILLION
|
||||||
|
_attr_state_class = SensorStateClass.MEASUREMENT
|
||||||
|
_attr_suggested_display_precision = 0
|
||||||
|
|
||||||
|
async def _handle_state_received(self, state: QbusMqttVentilationState) -> None:
|
||||||
|
self._attr_native_value = state.read_co2()
|
||||||
|
|
||||||
|
|
||||||
|
class QbusWeatherSensor(QbusEntity, SensorEntity):
|
||||||
|
"""Representation of a Qbus weather sensor."""
|
||||||
|
|
||||||
|
_state_cls = QbusMqttWeatherState
|
||||||
|
|
||||||
|
entity_description: QbusWeatherDescription
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, mqtt_output: QbusMqttOutput, description: QbusWeatherDescription
|
||||||
|
) -> None:
|
||||||
|
"""Initialize sensor entity."""
|
||||||
|
|
||||||
|
super().__init__(mqtt_output, id_suffix=description.key)
|
||||||
|
|
||||||
|
self.entity_description = description
|
||||||
|
|
||||||
|
if description.key == "temperature":
|
||||||
|
self._attr_name = None
|
||||||
|
|
||||||
|
async def _handle_state_received(self, state: QbusMqttWeatherState) -> None:
|
||||||
|
if value := state.read_property(self.entity_description.property, None):
|
||||||
|
self.native_value = value
|
@ -16,6 +16,22 @@
|
|||||||
"no_controller": "No controllers were found"
|
"no_controller": "No controllers were found"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"daylight": {
|
||||||
|
"name": "Daylight"
|
||||||
|
},
|
||||||
|
"light_east": {
|
||||||
|
"name": "Illuminance east"
|
||||||
|
},
|
||||||
|
"light_south": {
|
||||||
|
"name": "Illuminance south"
|
||||||
|
},
|
||||||
|
"light_west": {
|
||||||
|
"name": "Illuminance west"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"exceptions": {
|
"exceptions": {
|
||||||
"invalid_preset": {
|
"invalid_preset": {
|
||||||
"message": "Preset mode \"{preset}\" is not valid. Valid preset modes are: {options}."
|
"message": "Preset mode \"{preset}\" is not valid. Valid preset modes are: {options}."
|
||||||
|
@ -10,7 +10,7 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
|
|
||||||
from .coordinator import QbusConfigEntry
|
from .coordinator import QbusConfigEntry
|
||||||
from .entity import QbusEntity, add_new_outputs
|
from .entity import QbusEntity, create_new_entities
|
||||||
|
|
||||||
PARALLEL_UPDATES = 0
|
PARALLEL_UPDATES = 0
|
||||||
|
|
||||||
@ -26,13 +26,13 @@ async def async_setup_entry(
|
|||||||
added_outputs: list[QbusMqttOutput] = []
|
added_outputs: list[QbusMqttOutput] = []
|
||||||
|
|
||||||
def _check_outputs() -> None:
|
def _check_outputs() -> None:
|
||||||
add_new_outputs(
|
entities = create_new_entities(
|
||||||
coordinator,
|
coordinator,
|
||||||
added_outputs,
|
added_outputs,
|
||||||
lambda output: output.type == "onoff",
|
lambda output: output.type == "onoff",
|
||||||
QbusSwitch,
|
QbusSwitch,
|
||||||
async_add_entities,
|
|
||||||
)
|
)
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
_check_outputs()
|
_check_outputs()
|
||||||
entry.async_on_unload(coordinator.async_add_listener(_check_outputs))
|
entry.async_on_unload(coordinator.async_add_listener(_check_outputs))
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""Test fixtures for qbus."""
|
"""Test fixtures for qbus."""
|
||||||
|
|
||||||
from collections.abc import Generator
|
from collections.abc import Awaitable, Callable, Generator
|
||||||
import json
|
import json
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
@ -64,3 +64,22 @@ async def setup_integration(
|
|||||||
|
|
||||||
async_fire_mqtt_message(hass, TOPIC_CONFIG, json.dumps(payload_config))
|
async_fire_mqtt_message(hass, TOPIC_CONFIG, json.dumps(payload_config))
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
async def setup_integration_deferred(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mqtt_mock: MqttMockHAClient,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
payload_config: JsonObjectType,
|
||||||
|
) -> Callable[[], Awaitable]:
|
||||||
|
"""Set up the integration."""
|
||||||
|
|
||||||
|
async def run() -> None:
|
||||||
|
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
async_fire_mqtt_message(hass, TOPIC_CONFIG, json.dumps(payload_config))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
return run
|
||||||
|
@ -116,7 +116,7 @@
|
|||||||
{
|
{
|
||||||
"id": "UL30",
|
"id": "UL30",
|
||||||
"location": "Guest bedroom",
|
"location": "Guest bedroom",
|
||||||
"locationId": 0,
|
"locationId": 3,
|
||||||
"name": "CURTAINS",
|
"name": "CURTAINS",
|
||||||
"originalName": "CURTAINS",
|
"originalName": "CURTAINS",
|
||||||
"refId": "000001/108",
|
"refId": "000001/108",
|
||||||
@ -144,7 +144,7 @@
|
|||||||
},
|
},
|
||||||
"id": "UL31",
|
"id": "UL31",
|
||||||
"location": "Living",
|
"location": "Living",
|
||||||
"locationId": 8,
|
"locationId": 0,
|
||||||
"name": "SLATS",
|
"name": "SLATS",
|
||||||
"originalName": "SLATS",
|
"originalName": "SLATS",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -183,6 +183,340 @@
|
|||||||
},
|
},
|
||||||
"refId": "000001/4",
|
"refId": "000001/4",
|
||||||
"type": "shutter"
|
"type": "shutter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL40",
|
||||||
|
"location": "Tuin",
|
||||||
|
"locationId": 12,
|
||||||
|
"name": "Luchtdruk",
|
||||||
|
"originalName": "Luchtdruk",
|
||||||
|
"refId": "000001/81",
|
||||||
|
"type": "gauge",
|
||||||
|
"variant": "AirPressure",
|
||||||
|
"actions": {},
|
||||||
|
"properties": {
|
||||||
|
"currentValue": {
|
||||||
|
"max": 1500,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"unit": "mbar",
|
||||||
|
"write": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL41",
|
||||||
|
"location": "Tuin",
|
||||||
|
"locationId": 12,
|
||||||
|
"name": "Luchtkwaliteit",
|
||||||
|
"originalName": "Luchtkwaliteit",
|
||||||
|
"refId": "000001/82",
|
||||||
|
"type": "gauge",
|
||||||
|
"variant": "AirQuality",
|
||||||
|
"actions": {},
|
||||||
|
"properties": {
|
||||||
|
"currentValue": {
|
||||||
|
"max": 1500,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"unit": "ppm",
|
||||||
|
"write": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL42",
|
||||||
|
"location": "Garage",
|
||||||
|
"locationId": 27,
|
||||||
|
"name": "Stroom",
|
||||||
|
"originalName": "Stroom",
|
||||||
|
"refId": "000001/83",
|
||||||
|
"type": "gauge",
|
||||||
|
"variant": "Current",
|
||||||
|
"actions": {},
|
||||||
|
"properties": {
|
||||||
|
"currentValue": {
|
||||||
|
"max": 100,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"unit": "kWh",
|
||||||
|
"write": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL43",
|
||||||
|
"location": "Garage",
|
||||||
|
"locationId": 27,
|
||||||
|
"name": "Energie",
|
||||||
|
"originalName": "Energie",
|
||||||
|
"refId": "000001/84",
|
||||||
|
"type": "gauge",
|
||||||
|
"variant": "Energy",
|
||||||
|
"actions": {},
|
||||||
|
"properties": {
|
||||||
|
"currentValue": {
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"unit": "A",
|
||||||
|
"write": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL44",
|
||||||
|
"location": "Garage",
|
||||||
|
"locationId": 27,
|
||||||
|
"name": "Gas",
|
||||||
|
"originalName": "Gas",
|
||||||
|
"refId": "000001/85",
|
||||||
|
"type": "gauge",
|
||||||
|
"variant": "Gas",
|
||||||
|
"actions": {},
|
||||||
|
"properties": {
|
||||||
|
"currentValue": {
|
||||||
|
"max": 5,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.001,
|
||||||
|
"type": "number",
|
||||||
|
"unit": "m³/h",
|
||||||
|
"write": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL45",
|
||||||
|
"location": "Garage",
|
||||||
|
"locationId": 27,
|
||||||
|
"name": "Gas flow",
|
||||||
|
"originalName": "Gas flow",
|
||||||
|
"refId": "000001/86",
|
||||||
|
"type": "gauge",
|
||||||
|
"variant": "GasFlow",
|
||||||
|
"actions": {},
|
||||||
|
"properties": {
|
||||||
|
"currentValue": {
|
||||||
|
"max": 10,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"unit": "m³/h",
|
||||||
|
"write": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL46",
|
||||||
|
"location": "Living",
|
||||||
|
"locationId": 0,
|
||||||
|
"name": "Vochtigheid living",
|
||||||
|
"originalName": "Vochtigheid living",
|
||||||
|
"refId": "000001/87",
|
||||||
|
"type": "gauge",
|
||||||
|
"variant": "Humidity",
|
||||||
|
"actions": {},
|
||||||
|
"properties": {
|
||||||
|
"currentValue": {
|
||||||
|
"max": 100,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"unit": "%",
|
||||||
|
"write": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL47",
|
||||||
|
"location": "Tuin",
|
||||||
|
"locationId": 12,
|
||||||
|
"name": "Lichtsterkte tuin",
|
||||||
|
"originalName": "Lichtsterkte tuin",
|
||||||
|
"refId": "000001/88",
|
||||||
|
"type": "gauge",
|
||||||
|
"variant": "Light",
|
||||||
|
"actions": {},
|
||||||
|
"properties": {
|
||||||
|
"currentValue": {
|
||||||
|
"max": 100000,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"unit": "lx",
|
||||||
|
"write": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL40",
|
||||||
|
"location": "Tuin",
|
||||||
|
"locationId": 12,
|
||||||
|
"name": "Regenput",
|
||||||
|
"originalName": "Regenput",
|
||||||
|
"refId": "000001/40",
|
||||||
|
"type": "gauge",
|
||||||
|
"variant": "WaterLevel",
|
||||||
|
"actions": {},
|
||||||
|
"properties": {
|
||||||
|
"currentValue": {
|
||||||
|
"max": 100,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"unit": "m",
|
||||||
|
"write": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL60",
|
||||||
|
"location": "Tuin",
|
||||||
|
"locationId": 12,
|
||||||
|
"name": "Weersensor",
|
||||||
|
"originalName": "Weersensor",
|
||||||
|
"refId": "000001/21007",
|
||||||
|
"type": "weatherstation",
|
||||||
|
"variant": [null],
|
||||||
|
"actions": {},
|
||||||
|
"properties": {
|
||||||
|
"dayLight": {
|
||||||
|
"max": 1000,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"write": false
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"max": 100000,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"write": false
|
||||||
|
},
|
||||||
|
"lightEast": {
|
||||||
|
"max": 100000,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"write": false
|
||||||
|
},
|
||||||
|
"lightSouth": {
|
||||||
|
"max": 100000,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"write": false
|
||||||
|
},
|
||||||
|
"lightWest": {
|
||||||
|
"max": 100000,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"write": false
|
||||||
|
},
|
||||||
|
"raining": {
|
||||||
|
"read": true,
|
||||||
|
"type": "boolean",
|
||||||
|
"write": false
|
||||||
|
},
|
||||||
|
"temperature": {
|
||||||
|
"max": 100,
|
||||||
|
"min": -100,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"write": false
|
||||||
|
},
|
||||||
|
"twilight": {
|
||||||
|
"read": true,
|
||||||
|
"type": "boolean",
|
||||||
|
"write": false
|
||||||
|
},
|
||||||
|
"wind": {
|
||||||
|
"max": 1000,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 0.1,
|
||||||
|
"type": "number",
|
||||||
|
"write": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL70",
|
||||||
|
"location": "",
|
||||||
|
"locationId": 0,
|
||||||
|
"name": "Luchtsensor",
|
||||||
|
"originalName": "Luchtsensor",
|
||||||
|
"refId": "000001/224",
|
||||||
|
"type": "ventilation",
|
||||||
|
"variant": [null],
|
||||||
|
"actions": {},
|
||||||
|
"properties": {
|
||||||
|
"co2": {
|
||||||
|
"max": 5000,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 16,
|
||||||
|
"type": "number",
|
||||||
|
"unit": "ppm",
|
||||||
|
"write": false
|
||||||
|
},
|
||||||
|
"currRegime": {
|
||||||
|
"enumValues": ["Manueel", "Nacht", "Boost", "Uit", "Auto"],
|
||||||
|
"read": true,
|
||||||
|
"type": "enumString",
|
||||||
|
"write": true
|
||||||
|
},
|
||||||
|
"refresh": {
|
||||||
|
"max": 100,
|
||||||
|
"min": 0,
|
||||||
|
"read": true,
|
||||||
|
"step": 1,
|
||||||
|
"type": "number",
|
||||||
|
"write": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "UL80",
|
||||||
|
"location": "Kitchen",
|
||||||
|
"locationId": 8,
|
||||||
|
"name": "Vochtigheid keuken",
|
||||||
|
"originalName": "Vochtigheid keuken",
|
||||||
|
"properties": {
|
||||||
|
"currRegime": {
|
||||||
|
"enumValues": ["Manual", "Cook", "Boost", "Off", "Auto"],
|
||||||
|
"read": true,
|
||||||
|
"type": "enumString",
|
||||||
|
"write": true
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"read": true,
|
||||||
|
"step": 1,
|
||||||
|
"type": "percent",
|
||||||
|
"write": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"refId": "000001/94/1",
|
||||||
|
"type": "humidity"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
1047
tests/components/qbus/snapshots/test_sensor.ambr
Normal file
1047
tests/components/qbus/snapshots/test_sensor.ambr
Normal file
File diff suppressed because it is too large
Load Diff
27
tests/components/qbus/test_sensor.py
Normal file
27
tests/components/qbus/test_sensor.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
"""Test Qbus sensors."""
|
||||||
|
|
||||||
|
from collections.abc import Awaitable, Callable
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from syrupy.assertion import SnapshotAssertion
|
||||||
|
|
||||||
|
from homeassistant.const import Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry, snapshot_platform
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensor(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
setup_integration_deferred: Callable[[], Awaitable],
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test sensor."""
|
||||||
|
|
||||||
|
with patch("homeassistant.components.qbus.PLATFORMS", [Platform.SENSOR]):
|
||||||
|
await setup_integration_deferred()
|
||||||
|
|
||||||
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
Loading…
x
Reference in New Issue
Block a user