mirror of
https://github.com/home-assistant/core.git
synced 2026-03-24 16:28:14 +01:00
Compare commits
14 Commits
knx-defaul
...
handle-pip
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3906e1a3a | ||
|
|
21863cd9d7 | ||
|
|
d67caec5c1 | ||
|
|
8286014ae1 | ||
|
|
1ff8d2279a | ||
|
|
5dcbc1d5d9 | ||
|
|
3068653cc7 | ||
|
|
61b1a45889 | ||
|
|
573d4eba02 | ||
|
|
09895aa601 | ||
|
|
aa6a4c7eab | ||
|
|
662c44b125 | ||
|
|
5a80087cf4 | ||
|
|
c28dc32168 |
@@ -24,7 +24,7 @@ from .const import (
|
||||
SAMPLE_WIDTH,
|
||||
SAMPLES_PER_CHUNK,
|
||||
)
|
||||
from .error import PipelineNotFound
|
||||
from .error import PipelineError, PipelineNotFound
|
||||
from .pipeline import (
|
||||
AudioSettings,
|
||||
Pipeline,
|
||||
@@ -137,5 +137,21 @@ async def async_pipeline_from_audio_stream(
|
||||
audio_settings=audio_settings or AudioSettings(),
|
||||
),
|
||||
)
|
||||
await pipeline_input.validate()
|
||||
try:
|
||||
await pipeline_input.validate()
|
||||
except PipelineError as err:
|
||||
pipeline_input.run.start(
|
||||
conversation_id=session.conversation_id,
|
||||
device_id=device_id,
|
||||
satellite_id=satellite_id,
|
||||
)
|
||||
pipeline_input.run.process_event(
|
||||
PipelineEvent(
|
||||
PipelineEventType.ERROR,
|
||||
{"code": err.code, "message": err.message},
|
||||
)
|
||||
)
|
||||
await pipeline_input.run.end()
|
||||
return
|
||||
|
||||
await pipeline_input.execute()
|
||||
|
||||
@@ -21,6 +21,6 @@
|
||||
"bluetooth-auto-recovery==1.5.3",
|
||||
"bluetooth-data-tools==1.28.4",
|
||||
"dbus-fast==3.1.2",
|
||||
"habluetooth==5.10.2"
|
||||
"habluetooth==5.11.1"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ from fritzconnection.core.exceptions import (
|
||||
FritzSecurityError,
|
||||
FritzServiceError,
|
||||
)
|
||||
from requests.exceptions import ConnectionError
|
||||
|
||||
from homeassistant.const import Platform
|
||||
|
||||
@@ -68,6 +69,7 @@ BUTTON_TYPE_WOL = "WakeOnLan"
|
||||
UPTIME_DEVIATION = 5
|
||||
|
||||
FRITZ_EXCEPTIONS = (
|
||||
ConnectionError,
|
||||
FritzActionError,
|
||||
FritzActionFailedError,
|
||||
FritzConnectionException,
|
||||
|
||||
@@ -617,8 +617,10 @@ class OvenProgramId(MieleEnum, missing_to_none=True):
|
||||
pyrolytic = 323
|
||||
descale = 326
|
||||
evaporate_water = 327
|
||||
rinse = 333
|
||||
shabbat_program = 335
|
||||
yom_tov = 336
|
||||
hydroclean = 341
|
||||
drying = 357, 2028
|
||||
heat_crockery = 358
|
||||
prove_dough = 359, 2023
|
||||
@@ -723,7 +725,7 @@ class OvenProgramId(MieleEnum, missing_to_none=True):
|
||||
belgian_sponge_cake = 624
|
||||
goose_unstuffed = 625
|
||||
rack_of_lamb_with_vegetables = 634
|
||||
yorkshire_pudding = 635
|
||||
yorkshire_pudding = 635, 2352
|
||||
meat_loaf = 636
|
||||
defrost_meat = 647
|
||||
defrost_vegetables = 654
|
||||
@@ -1123,7 +1125,7 @@ class OvenProgramId(MieleEnum, missing_to_none=True):
|
||||
wholegrain_rice = 3376
|
||||
parboiled_rice_steam_cooking = 3380
|
||||
parboiled_rice_rapid_steam_cooking = 3381
|
||||
basmati_rice_steam_cooking = 3383
|
||||
basmati_rice_steam_cooking = 3382, 3383
|
||||
basmati_rice_rapid_steam_cooking = 3384
|
||||
jasmine_rice_steam_cooking = 3386
|
||||
jasmine_rice_rapid_steam_cooking = 3387
|
||||
@@ -1131,7 +1133,7 @@ class OvenProgramId(MieleEnum, missing_to_none=True):
|
||||
huanghuanian_rapid_steam_cooking = 3390
|
||||
simiao_steam_cooking = 3392
|
||||
simiao_rapid_steam_cooking = 3393
|
||||
long_grain_rice_general_steam_cooking = 3395
|
||||
long_grain_rice_general_steam_cooking = 3394, 3395
|
||||
long_grain_rice_general_rapid_steam_cooking = 3396
|
||||
chongming_steam_cooking = 3398
|
||||
chongming_rapid_steam_cooking = 3399
|
||||
|
||||
@@ -560,6 +560,7 @@
|
||||
"hot_water": "Hot water",
|
||||
"huanghuanian_rapid_steam_cooking": "Huanghuanian (rapid steam cooking)",
|
||||
"huanghuanian_steam_cooking": "Huanghuanian (steam cooking)",
|
||||
"hydroclean": "HydroClean",
|
||||
"hygiene": "Hygiene",
|
||||
"intensive": "Intensive",
|
||||
"intensive_bake": "Intensive bake",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/opendisplay",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["opendisplay"],
|
||||
"quality_scale": "silver",
|
||||
"requirements": ["py-opendisplay==5.5.0"]
|
||||
}
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["oralb_ble"],
|
||||
"requirements": ["oralb-ble==1.0.2"]
|
||||
"requirements": ["oralb-ble==1.1.0"]
|
||||
}
|
||||
|
||||
@@ -20,12 +20,18 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import (
|
||||
RoborockB01Q10UpdateCoordinator,
|
||||
RoborockConfigEntry,
|
||||
RoborockDataUpdateCoordinator,
|
||||
RoborockDataUpdateCoordinatorA01,
|
||||
RoborockWashingMachineUpdateCoordinator,
|
||||
)
|
||||
from .entity import RoborockCoordinatedEntityA01, RoborockEntity, RoborockEntityV1
|
||||
from .entity import (
|
||||
RoborockCoordinatedEntityA01,
|
||||
RoborockCoordinatedEntityB01Q10,
|
||||
RoborockEntity,
|
||||
RoborockEntityV1,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -97,6 +103,14 @@ ZEO_BUTTON_DESCRIPTIONS = [
|
||||
]
|
||||
|
||||
|
||||
Q10_BUTTON_DESCRIPTIONS = [
|
||||
ButtonEntityDescription(
|
||||
key="empty_dustbin",
|
||||
translation_key="empty_dustbin",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: RoborockConfigEntry,
|
||||
@@ -139,6 +153,15 @@ async def async_setup_entry(
|
||||
if isinstance(coordinator, RoborockWashingMachineUpdateCoordinator)
|
||||
for description in ZEO_BUTTON_DESCRIPTIONS
|
||||
),
|
||||
(
|
||||
RoborockQ10EmptyDustbinButtonEntity(
|
||||
coordinator,
|
||||
description,
|
||||
)
|
||||
for coordinator in config_entry.runtime_data.b01_q10
|
||||
if isinstance(coordinator, RoborockB01Q10UpdateCoordinator)
|
||||
for description in Q10_BUTTON_DESCRIPTIONS
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
@@ -233,3 +256,37 @@ class RoborockButtonEntityA01(RoborockCoordinatedEntityA01, ButtonEntity):
|
||||
) from err
|
||||
finally:
|
||||
await self.coordinator.async_request_refresh()
|
||||
|
||||
|
||||
class RoborockQ10EmptyDustbinButtonEntity(
|
||||
RoborockCoordinatedEntityB01Q10, ButtonEntity
|
||||
):
|
||||
"""A class to define Q10 empty dustbin button entity."""
|
||||
|
||||
entity_description: ButtonEntityDescription
|
||||
coordinator: RoborockB01Q10UpdateCoordinator
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: RoborockB01Q10UpdateCoordinator,
|
||||
entity_description: ButtonEntityDescription,
|
||||
) -> None:
|
||||
"""Create a Q10 empty dustbin button entity."""
|
||||
self.entity_description = entity_description
|
||||
super().__init__(
|
||||
f"{entity_description.key}_{coordinator.duid_slug}",
|
||||
coordinator,
|
||||
)
|
||||
|
||||
async def async_press(self, **kwargs: Any) -> None:
|
||||
"""Press the button to empty dustbin."""
|
||||
try:
|
||||
await self.coordinator.api.vacuum.empty_dustbin()
|
||||
except RoborockException as err:
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="command_failed",
|
||||
translation_placeholders={
|
||||
"command": "empty_dustbin",
|
||||
},
|
||||
) from err
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"loggers": ["roborock"],
|
||||
"quality_scale": "silver",
|
||||
"requirements": [
|
||||
"python-roborock==4.25.0",
|
||||
"python-roborock==4.26.2",
|
||||
"vacuum-map-parser-roborock==0.1.4"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -84,6 +84,9 @@
|
||||
}
|
||||
},
|
||||
"button": {
|
||||
"empty_dustbin": {
|
||||
"name": "Empty dustbin"
|
||||
},
|
||||
"pause": {
|
||||
"name": "Pause"
|
||||
},
|
||||
|
||||
@@ -208,6 +208,16 @@ CAPABILITY_TO_SENSORS: dict[
|
||||
supported_states_attributes=Attribute.SUPPORTED_COOKTOP_OPERATING_STATE,
|
||||
)
|
||||
},
|
||||
Capability.SAMSUNG_CE_CLEAN_STATION_STICK_STATUS: {
|
||||
Attribute.STATUS: SmartThingsBinarySensorEntityDescription(
|
||||
key=Attribute.STATUS,
|
||||
component_translation_key={
|
||||
"station": "stick_cleaner_status",
|
||||
},
|
||||
exists_fn=lambda component, _: component == "station",
|
||||
is_on_key="attached",
|
||||
)
|
||||
},
|
||||
Capability.SAMSUNG_CE_MICROFIBER_FILTER_STATUS: {
|
||||
Attribute.STATUS: SmartThingsBinarySensorEntityDescription(
|
||||
key=Attribute.STATUS,
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
"robot_cleaner_dust_bag": {
|
||||
"name": "Dust bag full"
|
||||
},
|
||||
"stick_cleaner_status": {
|
||||
"name": "Stick cleaner in station"
|
||||
},
|
||||
"sub_remote_control": {
|
||||
"name": "Upper washer remote control"
|
||||
},
|
||||
|
||||
@@ -105,6 +105,7 @@ SENSORS: list[SmSensorEntityDescription] = [
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
EXTRA_SENSOR = SmSensorEntityDescription(
|
||||
key="zigbee_temperature_2",
|
||||
translation_key="zigbee_temperature",
|
||||
@@ -115,6 +116,15 @@ EXTRA_SENSOR = SmSensorEntityDescription(
|
||||
value_fn=lambda x: x.zb_temp2,
|
||||
)
|
||||
|
||||
PSRAM_SENSOR = SmSensorEntityDescription(
|
||||
key="psram_usage",
|
||||
translation_key="psram_usage",
|
||||
device_class=SensorDeviceClass.DATA_SIZE,
|
||||
native_unit_of_measurement=UnitOfInformation.KILOBYTES,
|
||||
entity_registry_enabled_default=False,
|
||||
value_fn=lambda x: x.psram_usage,
|
||||
)
|
||||
|
||||
UPTIME: list[SmSensorEntityDescription] = [
|
||||
SmSensorEntityDescription(
|
||||
key="core_uptime",
|
||||
@@ -156,6 +166,9 @@ async def async_setup_entry(
|
||||
if coordinator.data.sensors.zb_temp2 is not None:
|
||||
entities.append(SmSensorEntity(coordinator, EXTRA_SENSOR))
|
||||
|
||||
if coordinator.data.info.u_device:
|
||||
entities.append(SmSensorEntity(coordinator, PSRAM_SENSOR))
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
|
||||
@@ -104,6 +104,9 @@
|
||||
"fs_usage": {
|
||||
"name": "Filesystem usage"
|
||||
},
|
||||
"psram_usage": {
|
||||
"name": "PSRAM usage"
|
||||
},
|
||||
"ram_usage": {
|
||||
"name": "RAM usage"
|
||||
},
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["aiotedee"],
|
||||
"quality_scale": "platinum",
|
||||
"requirements": ["aiotedee==0.2.25"]
|
||||
"requirements": ["aiotedee==0.2.27"]
|
||||
}
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
"integration_type": "device",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["wolf_comm"],
|
||||
"requirements": ["wolf-comm==0.0.23"]
|
||||
"requirements": ["wolf-comm==0.0.48"]
|
||||
}
|
||||
|
||||
@@ -25,5 +25,5 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/xiaomi_ble",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
"requirements": ["xiaomi-ble==1.6.0"]
|
||||
"requirements": ["xiaomi-ble==1.10.0"]
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ file-read-backwards==2.0.0
|
||||
fnv-hash-fast==2.0.0
|
||||
go2rtc-client==0.4.0
|
||||
ha-ffmpeg==3.2.2
|
||||
habluetooth==5.10.2
|
||||
habluetooth==5.11.1
|
||||
hass-nabucasa==2.0.0
|
||||
hassil==3.5.0
|
||||
home-assistant-bluetooth==1.13.1
|
||||
|
||||
12
requirements_all.txt
generated
12
requirements_all.txt
generated
@@ -422,7 +422,7 @@ aiosyncthing==0.7.1
|
||||
aiotankerkoenig==0.5.1
|
||||
|
||||
# homeassistant.components.tedee
|
||||
aiotedee==0.2.25
|
||||
aiotedee==0.2.27
|
||||
|
||||
# homeassistant.components.tractive
|
||||
aiotractive==1.0.0
|
||||
@@ -1176,7 +1176,7 @@ ha-silabs-firmware-client==0.3.0
|
||||
habiticalib==0.4.6
|
||||
|
||||
# homeassistant.components.bluetooth
|
||||
habluetooth==5.10.2
|
||||
habluetooth==5.11.1
|
||||
|
||||
# homeassistant.components.hanna
|
||||
hanna-cloud==0.0.7
|
||||
@@ -1732,7 +1732,7 @@ openwrt-ubus-rpc==0.0.2
|
||||
opower==0.17.1
|
||||
|
||||
# homeassistant.components.oralb
|
||||
oralb-ble==1.0.2
|
||||
oralb-ble==1.1.0
|
||||
|
||||
# homeassistant.components.oru
|
||||
oru==0.1.11
|
||||
@@ -2660,7 +2660,7 @@ python-rabbitair==0.0.8
|
||||
python-ripple-api==0.0.3
|
||||
|
||||
# homeassistant.components.roborock
|
||||
python-roborock==4.25.0
|
||||
python-roborock==4.26.2
|
||||
|
||||
# homeassistant.components.smarttub
|
||||
python-smarttub==0.0.47
|
||||
@@ -3310,7 +3310,7 @@ wirelesstagpy==0.8.1
|
||||
wled==0.21.0
|
||||
|
||||
# homeassistant.components.wolflink
|
||||
wolf-comm==0.0.23
|
||||
wolf-comm==0.0.48
|
||||
|
||||
# homeassistant.components.wsdot
|
||||
wsdot==0.0.1
|
||||
@@ -3319,7 +3319,7 @@ wsdot==0.0.1
|
||||
wyoming==1.7.2
|
||||
|
||||
# homeassistant.components.xiaomi_ble
|
||||
xiaomi-ble==1.6.0
|
||||
xiaomi-ble==1.10.0
|
||||
|
||||
# homeassistant.components.knx
|
||||
xknx==3.15.0
|
||||
|
||||
12
requirements_test_all.txt
generated
12
requirements_test_all.txt
generated
@@ -407,7 +407,7 @@ aiosyncthing==0.7.1
|
||||
aiotankerkoenig==0.5.1
|
||||
|
||||
# homeassistant.components.tedee
|
||||
aiotedee==0.2.25
|
||||
aiotedee==0.2.27
|
||||
|
||||
# homeassistant.components.tractive
|
||||
aiotractive==1.0.0
|
||||
@@ -1046,7 +1046,7 @@ ha-silabs-firmware-client==0.3.0
|
||||
habiticalib==0.4.6
|
||||
|
||||
# homeassistant.components.bluetooth
|
||||
habluetooth==5.10.2
|
||||
habluetooth==5.11.1
|
||||
|
||||
# homeassistant.components.hanna
|
||||
hanna-cloud==0.0.7
|
||||
@@ -1509,7 +1509,7 @@ openwebifpy==4.3.1
|
||||
opower==0.17.1
|
||||
|
||||
# homeassistant.components.oralb
|
||||
oralb-ble==1.0.2
|
||||
oralb-ble==1.1.0
|
||||
|
||||
# homeassistant.components.orvibo
|
||||
orvibo==1.1.2
|
||||
@@ -2256,7 +2256,7 @@ python-pooldose==0.8.6
|
||||
python-rabbitair==0.0.8
|
||||
|
||||
# homeassistant.components.roborock
|
||||
python-roborock==4.25.0
|
||||
python-roborock==4.26.2
|
||||
|
||||
# homeassistant.components.smarttub
|
||||
python-smarttub==0.0.47
|
||||
@@ -2792,7 +2792,7 @@ wiim==0.1.0
|
||||
wled==0.21.0
|
||||
|
||||
# homeassistant.components.wolflink
|
||||
wolf-comm==0.0.23
|
||||
wolf-comm==0.0.48
|
||||
|
||||
# homeassistant.components.wsdot
|
||||
wsdot==0.0.1
|
||||
@@ -2801,7 +2801,7 @@ wsdot==0.0.1
|
||||
wyoming==1.7.2
|
||||
|
||||
# homeassistant.components.xiaomi_ble
|
||||
xiaomi-ble==1.6.0
|
||||
xiaomi-ble==1.10.0
|
||||
|
||||
# homeassistant.components.knx
|
||||
xknx==3.15.0
|
||||
|
||||
@@ -330,6 +330,49 @@ async def test_pipeline_from_audio_stream_unknown_pipeline(
|
||||
assert not events
|
||||
|
||||
|
||||
async def test_pipeline_from_audio_stream_validation_pipeline_error(
|
||||
hass: HomeAssistant,
|
||||
mock_stt_provider_entity: MockSTTProviderEntity,
|
||||
init_components,
|
||||
) -> None:
|
||||
"""Test validation pipeline errors are emitted as terminal events."""
|
||||
events: list[assist_pipeline.PipelineEvent] = []
|
||||
|
||||
await assist_pipeline.async_update_pipeline(
|
||||
hass,
|
||||
assist_pipeline.async_get_pipeline(hass),
|
||||
conversation_engine="conversation.non_existing",
|
||||
)
|
||||
|
||||
async def audio_data():
|
||||
yield b"audio"
|
||||
|
||||
await assist_pipeline.async_pipeline_from_audio_stream(
|
||||
hass,
|
||||
context=Context(),
|
||||
event_callback=events.append,
|
||||
stt_metadata=stt.SpeechMetadata(
|
||||
language="",
|
||||
format=stt.AudioFormats.WAV,
|
||||
codec=stt.AudioCodecs.PCM,
|
||||
bit_rate=stt.AudioBitRates.BITRATE_16,
|
||||
sample_rate=stt.AudioSampleRates.SAMPLERATE_16000,
|
||||
channel=stt.AudioChannels.CHANNEL_MONO,
|
||||
),
|
||||
stt_stream=audio_data(),
|
||||
end_stage=assist_pipeline.PipelineStage.INTENT,
|
||||
)
|
||||
|
||||
assert len(events) == 3
|
||||
assert events[0].type == assist_pipeline.PipelineEventType.RUN_START
|
||||
assert events[1].type == assist_pipeline.PipelineEventType.ERROR
|
||||
assert events[1].data == {
|
||||
"code": "intent-not-supported",
|
||||
"message": "Intent recognition engine conversation.non_existing is not found",
|
||||
}
|
||||
assert events[2].type == assist_pipeline.PipelineEventType.RUN_END
|
||||
|
||||
|
||||
async def test_pipeline_from_audio_stream_wake_word(
|
||||
hass: HomeAssistant,
|
||||
mock_stt_provider_entity: MockSTTProviderEntity,
|
||||
|
||||
@@ -184,6 +184,43 @@ async def test_new_pipeline_cancels_pipeline(
|
||||
await pipeline2_finished.wait()
|
||||
|
||||
|
||||
async def test_pipeline_validation_error_ends_pipeline(
|
||||
hass: HomeAssistant,
|
||||
init_components: ConfigEntry,
|
||||
entity: MockAssistSatellite,
|
||||
) -> None:
|
||||
"""Test validation pipeline errors end the satellite pipeline cleanly."""
|
||||
await async_update_pipeline(
|
||||
hass,
|
||||
async_get_pipeline(hass),
|
||||
stt_engine="test-stt-engine",
|
||||
stt_language="en",
|
||||
conversation_engine="conversation.non_existing",
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.assist_pipeline.pipeline.PipelineRun.prepare_speech_to_text"
|
||||
):
|
||||
await entity.async_accept_pipeline_from_satellite(
|
||||
object(), # type: ignore[arg-type]
|
||||
end_stage=PipelineStage.INTENT,
|
||||
)
|
||||
|
||||
assert [event.type for event in entity.events[-3:]] == [
|
||||
PipelineEventType.RUN_START,
|
||||
PipelineEventType.ERROR,
|
||||
PipelineEventType.RUN_END,
|
||||
]
|
||||
assert entity.events[-2].data == {
|
||||
"code": "intent-not-supported",
|
||||
"message": "Intent recognition engine conversation.non_existing is not found",
|
||||
}
|
||||
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
assert state is not None
|
||||
assert state.state == AssistSatelliteState.IDLE
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("service_data", "expected_params"),
|
||||
[
|
||||
|
||||
@@ -5474,6 +5474,7 @@
|
||||
'hens_eggs_size_xl_soft',
|
||||
'huanghuanian_rapid_steam_cooking',
|
||||
'huanghuanian_steam_cooking',
|
||||
'hydroclean',
|
||||
'intensive_bake',
|
||||
'iridescent_shark_fillet',
|
||||
'jasmine_rice_rapid_steam_cooking',
|
||||
@@ -5675,6 +5676,7 @@
|
||||
'rhubarb_chunks',
|
||||
'rice_pudding_rapid_steam_cooking',
|
||||
'rice_pudding_steam_cooking',
|
||||
'rinse',
|
||||
'risotto',
|
||||
'roast_beef_low_temperature_cooking',
|
||||
'roast_beef_roast',
|
||||
@@ -6085,6 +6087,7 @@
|
||||
'hens_eggs_size_xl_soft',
|
||||
'huanghuanian_rapid_steam_cooking',
|
||||
'huanghuanian_steam_cooking',
|
||||
'hydroclean',
|
||||
'intensive_bake',
|
||||
'iridescent_shark_fillet',
|
||||
'jasmine_rice_rapid_steam_cooking',
|
||||
@@ -6286,6 +6289,7 @@
|
||||
'rhubarb_chunks',
|
||||
'rice_pudding_rapid_steam_cooking',
|
||||
'rice_pudding_steam_cooking',
|
||||
'rinse',
|
||||
'risotto',
|
||||
'roast_beef_low_temperature_cooking',
|
||||
'roast_beef_roast',
|
||||
@@ -9268,6 +9272,7 @@
|
||||
'hens_eggs_size_xl_soft',
|
||||
'huanghuanian_rapid_steam_cooking',
|
||||
'huanghuanian_steam_cooking',
|
||||
'hydroclean',
|
||||
'intensive_bake',
|
||||
'iridescent_shark_fillet',
|
||||
'jasmine_rice_rapid_steam_cooking',
|
||||
@@ -9469,6 +9474,7 @@
|
||||
'rhubarb_chunks',
|
||||
'rice_pudding_rapid_steam_cooking',
|
||||
'rice_pudding_steam_cooking',
|
||||
'rinse',
|
||||
'risotto',
|
||||
'roast_beef_low_temperature_cooking',
|
||||
'roast_beef_roast',
|
||||
@@ -9879,6 +9885,7 @@
|
||||
'hens_eggs_size_xl_soft',
|
||||
'huanghuanian_rapid_steam_cooking',
|
||||
'huanghuanian_steam_cooking',
|
||||
'hydroclean',
|
||||
'intensive_bake',
|
||||
'iridescent_shark_fillet',
|
||||
'jasmine_rice_rapid_steam_cooking',
|
||||
@@ -10080,6 +10087,7 @@
|
||||
'rhubarb_chunks',
|
||||
'rice_pudding_rapid_steam_cooking',
|
||||
'rice_pudding_steam_cooking',
|
||||
'rinse',
|
||||
'risotto',
|
||||
'roast_beef_low_temperature_cooking',
|
||||
'roast_beef_roast',
|
||||
|
||||
@@ -26,7 +26,7 @@ async def test_async_step_bluetooth_valid_device(hass: HomeAssistant) -> None:
|
||||
result["flow_id"], user_input={}
|
||||
)
|
||||
assert result2["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert result2["title"] == "Smart Series 7000 48BE"
|
||||
assert result2["title"] == "Triumph D36 48BE"
|
||||
assert result2["data"] == {}
|
||||
assert result2["result"].unique_id == "78:DB:2F:C2:48:BE"
|
||||
|
||||
@@ -91,7 +91,7 @@ async def test_async_step_user_with_found_devices(hass: HomeAssistant) -> None:
|
||||
user_input={"address": "78:DB:2F:C2:48:BE"},
|
||||
)
|
||||
assert result2["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert result2["title"] == "Smart Series 7000 48BE"
|
||||
assert result2["title"] == "Triumph D36 48BE"
|
||||
assert result2["data"] == {}
|
||||
assert result2["result"].unique_id == "78:DB:2F:C2:48:BE"
|
||||
|
||||
@@ -121,7 +121,7 @@ async def test_async_step_user_replace_ignored(hass: HomeAssistant) -> None:
|
||||
user_input={"address": "78:DB:2F:C2:48:BE"},
|
||||
)
|
||||
assert result2["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert result2["title"] == "Smart Series 7000 48BE"
|
||||
assert result2["title"] == "Triumph D36 48BE"
|
||||
assert result2["data"] == {}
|
||||
assert result2["result"].unique_id == "78:DB:2F:C2:48:BE"
|
||||
|
||||
@@ -240,7 +240,7 @@ async def test_async_step_user_takes_precedence_over_discovery(
|
||||
user_input={"address": "78:DB:2F:C2:48:BE"},
|
||||
)
|
||||
assert result2["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert result2["title"] == "Smart Series 7000 48BE"
|
||||
assert result2["title"] == "Triumph D36 48BE"
|
||||
assert result2["data"] == {}
|
||||
assert result2["result"].unique_id == "78:DB:2F:C2:48:BE"
|
||||
|
||||
|
||||
@@ -47,10 +47,10 @@ async def test_sensors(hass: HomeAssistant) -> None:
|
||||
await hass.async_block_till_done()
|
||||
assert len(hass.states.async_all("sensor")) == 9
|
||||
|
||||
toothbrush_sensor = hass.states.get("sensor.smart_series_7000_48be")
|
||||
toothbrush_sensor = hass.states.get("sensor.triumph_d36_48be")
|
||||
toothbrush_sensor_attrs = toothbrush_sensor.attributes
|
||||
assert toothbrush_sensor.state == "running"
|
||||
assert toothbrush_sensor_attrs[ATTR_FRIENDLY_NAME] == "Smart Series 7000 48BE"
|
||||
assert toothbrush_sensor_attrs[ATTR_FRIENDLY_NAME] == "Triumph D36 48BE"
|
||||
assert ATTR_ASSUMED_STATE not in toothbrush_sensor_attrs
|
||||
|
||||
assert await hass.config_entries.async_unload(entry.entry_id)
|
||||
@@ -76,7 +76,7 @@ async def test_sensors(hass: HomeAssistant) -> None:
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# All of these devices are sleepy so we should still be available
|
||||
toothbrush_sensor = hass.states.get("sensor.smart_series_7000_48be")
|
||||
toothbrush_sensor = hass.states.get("sensor.triumph_d36_48be")
|
||||
assert toothbrush_sensor.state == "running"
|
||||
|
||||
|
||||
@@ -155,9 +155,9 @@ async def test_sensors_battery(hass: HomeAssistant) -> None:
|
||||
await hass.async_block_till_done()
|
||||
assert len(hass.states.async_all()) == 7
|
||||
|
||||
bat_sensor = hass.states.get("sensor.io_series_6_7_1dcf_battery")
|
||||
bat_sensor = hass.states.get("sensor.io_series_1dcf_battery")
|
||||
assert bat_sensor.state == "49"
|
||||
assert bat_sensor.name == "IO Series 6/7 1DCF Battery"
|
||||
assert bat_sensor.name == "IO Series 1DCF Battery"
|
||||
|
||||
assert await hass.config_entries.async_unload(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
@@ -1,4 +1,54 @@
|
||||
# serializer version: 1
|
||||
# name: test_buttons[button.roborock_q10_s5_empty_dustbin-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'button',
|
||||
'entity_category': None,
|
||||
'entity_id': 'button.roborock_q10_s5_empty_dustbin',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Empty dustbin',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Empty dustbin',
|
||||
'platform': 'roborock',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'empty_dustbin',
|
||||
'unique_id': 'empty_dustbin_q10_duid',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_buttons[button.roborock_q10_s5_empty_dustbin-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Roborock Q10 S5+ Empty dustbin',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'button.roborock_q10_s5_empty_dustbin',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_buttons[button.roborock_s7_2_reset_air_filter_consumable-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
|
||||
@@ -272,3 +272,55 @@ async def test_press_a01_button_failure(
|
||||
|
||||
washing_machine.zeo.set_value.assert_called_once()
|
||||
assert hass.states.get(entity_id).state == "2023-10-30T08:50:00+00:00"
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2023-10-30 08:50:00")
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
async def test_press_q10_empty_dustbin_button_success(
|
||||
hass: HomeAssistant,
|
||||
bypass_api_client_fixture: None,
|
||||
setup_entry: MockConfigEntry,
|
||||
fake_q10_vacuum: FakeDevice,
|
||||
) -> None:
|
||||
"""Test pressing Q10 empty dustbin button entity."""
|
||||
entity_id = "button.roborock_q10_s5_empty_dustbin"
|
||||
|
||||
assert hass.states.get(entity_id) is not None
|
||||
await hass.services.async_call(
|
||||
"button",
|
||||
SERVICE_PRESS,
|
||||
blocking=True,
|
||||
target={"entity_id": entity_id},
|
||||
)
|
||||
|
||||
assert fake_q10_vacuum.b01_q10_properties is not None
|
||||
fake_q10_vacuum.b01_q10_properties.vacuum.empty_dustbin.assert_called_once()
|
||||
assert hass.states.get(entity_id).state == "2023-10-30T08:50:00+00:00"
|
||||
|
||||
|
||||
@pytest.mark.freeze_time("2023-10-30 08:50:00")
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
async def test_press_q10_empty_dustbin_button_failure(
|
||||
hass: HomeAssistant,
|
||||
bypass_api_client_fixture: None,
|
||||
setup_entry: MockConfigEntry,
|
||||
fake_q10_vacuum: FakeDevice,
|
||||
) -> None:
|
||||
"""Test failure while pressing Q10 empty dustbin button entity."""
|
||||
entity_id = "button.roborock_q10_s5_empty_dustbin"
|
||||
assert fake_q10_vacuum.b01_q10_properties is not None
|
||||
fake_q10_vacuum.b01_q10_properties.vacuum.empty_dustbin.side_effect = (
|
||||
RoborockException
|
||||
)
|
||||
|
||||
assert hass.states.get(entity_id) is not None
|
||||
with pytest.raises(HomeAssistantError, match="Error while calling empty_dustbin"):
|
||||
await hass.services.async_call(
|
||||
"button",
|
||||
SERVICE_PRESS,
|
||||
blocking=True,
|
||||
target={"entity_id": entity_id},
|
||||
)
|
||||
|
||||
fake_q10_vacuum.b01_q10_properties.vacuum.empty_dustbin.assert_called_once()
|
||||
assert hass.states.get(entity_id).state == "2023-10-30T08:50:00+00:00"
|
||||
|
||||
@@ -2023,6 +2023,56 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_vc_stick_01001][binary_sensor.stick_vacuum_stick_cleaner_in_station-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
None,
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.stick_vacuum_stick_cleaner_in_station',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Stick cleaner in station',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Stick cleaner in station',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'stick_cleaner_status',
|
||||
'unique_id': 'e1f93c0c-6fe0-c65a-a314-c8f7b163c86b_station_samsungce.cleanStationStickStatus_status_status',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_vc_stick_01001][binary_sensor.stick_vacuum_stick_cleaner_in_station-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Stick vacuum Stick cleaner in station',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.stick_vacuum_stick_cleaner_in_station',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_wm_dw_000001][binary_sensor.dishwasher_child_lock-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': list([
|
||||
|
||||
@@ -6,6 +6,7 @@ from pysmlight import Info, Sensors
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.components.smlight.const import DOMAIN
|
||||
from homeassistant.const import STATE_UNKNOWN, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -113,3 +114,55 @@ async def test_zigbee_type_sensors(
|
||||
state = hass.states.get("sensor.mock_title_zigbee_type_2")
|
||||
assert state
|
||||
assert state.state == "router"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
async def test_psram_usage_sensor(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_smlight_client: MagicMock,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test PSRAM usage sensor creation for u-devices."""
|
||||
mock_smlight_client.get_info.side_effect = None
|
||||
mock_smlight_client.get_info.return_value = Info(
|
||||
MAC="AA:BB:CC:DD:EE:FF",
|
||||
model="SLZB-MR3U",
|
||||
u_device=True,
|
||||
)
|
||||
mock_smlight_client.get_sensors.return_value = Sensors(psram_usage=156)
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
entity_id = entity_registry.async_get_entity_id(
|
||||
SENSOR_DOMAIN, DOMAIN, "aa:bb:cc:dd:ee:ff_psram_usage"
|
||||
)
|
||||
assert entity_id is not None
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state is not None
|
||||
assert state.state == "156"
|
||||
assert state.attributes["unit_of_measurement"] == "kB"
|
||||
|
||||
|
||||
async def test_psram_usage_sensor_not_created(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_smlight_client: MagicMock,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test PSRAM usage sensor is not created for non-u devices."""
|
||||
mock_smlight_client.get_info.side_effect = None
|
||||
mock_smlight_client.get_info.return_value = Info(
|
||||
MAC="AA:BB:CC:DD:EE:FF",
|
||||
model="SLZB-MR3",
|
||||
u_device=False,
|
||||
)
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert hass.states.get("sensor.mock_title_psram_usage") is None
|
||||
|
||||
entity_id = entity_registry.async_get_entity_id(
|
||||
SENSOR_DOMAIN, DOMAIN, "aa:bb:cc:dd:ee:ff_psram_usage"
|
||||
)
|
||||
assert entity_id is None
|
||||
|
||||
@@ -71,7 +71,7 @@ def mock_wolflink() -> Generator[MagicMock]:
|
||||
|
||||
wolflink.fetch_parameters.return_value = [
|
||||
EnergyParameter(
|
||||
6002800000, "Energy Parameter", "Heating", 6005200000, 2000
|
||||
6002800000, "Energy Parameter", "Heating", 6005200000, 2000, True
|
||||
),
|
||||
ListItemParameter(
|
||||
8002800000,
|
||||
@@ -80,22 +80,35 @@ def mock_wolflink() -> Generator[MagicMock]:
|
||||
[ListItem("0", "Aus"), ListItem("1", "Ein")],
|
||||
8005200000,
|
||||
3001,
|
||||
True,
|
||||
),
|
||||
PowerParameter(
|
||||
5002800000, "Power Parameter", "Heating", 5005200000, 1000, True
|
||||
),
|
||||
Pressure(
|
||||
4002800000, "Pressure Parameter", "Heating", 4005200000, 1000, True
|
||||
),
|
||||
Temperature(
|
||||
3002800000, "Temperature Parameter", "Solar", 3005200000, 1000, True
|
||||
),
|
||||
PowerParameter(5002800000, "Power Parameter", "Heating", 5005200000, 1000),
|
||||
Pressure(4002800000, "Pressure Parameter", "Heating", 4005200000, 1000),
|
||||
Temperature(3002800000, "Temperature Parameter", "Solar", 3005200000, 1000),
|
||||
PercentageParameter(
|
||||
2002800000, "Percentage Parameter", "Solar", 2005200000, 1000
|
||||
2002800000, "Percentage Parameter", "Solar", 2005200000, 1000, True
|
||||
),
|
||||
HoursParameter(
|
||||
7002800000, "Hours Parameter", "Heating", 7005200000, 1000, True
|
||||
),
|
||||
SimpleParameter(
|
||||
1002800000, "Simple Parameter", "DHW", 1005200000, 1000, True
|
||||
),
|
||||
HoursParameter(7002800000, "Hours Parameter", "Heating", 7005200000, 1000),
|
||||
SimpleParameter(1002800000, "Simple Parameter", "DHW", 1005200000, 1000),
|
||||
FrequencyParameter(
|
||||
9002800000, "Frequency Parameter", "Heating", 9005200000, 1000
|
||||
9002800000, "Frequency Parameter", "Heating", 9005200000, 1000, True
|
||||
),
|
||||
RPMParameter(
|
||||
1000280001, "RPM Parameter", "Heating", 10005200000, 7000, True
|
||||
),
|
||||
FlowParameter(
|
||||
1100280001, "Flow Parameter", "Heating", 11005200000, 8000, True
|
||||
),
|
||||
RPMParameter(1000280001, "RPM Parameter", "Heating", 10005200000, 7000),
|
||||
FlowParameter(1100280001, "Flow Parameter", "Heating", 11005200000, 8000),
|
||||
HoursParameter(7002800000, "Hours Parameter", "Heating", 7005200000, 1000),
|
||||
SimpleParameter(1002800000, "Simple Parameter", "DHW", 1005200000, 1000),
|
||||
]
|
||||
|
||||
wolflink.fetch_value.return_value = [
|
||||
|
||||
Reference in New Issue
Block a user