mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
2023.10.4 (#102397)
This commit is contained in:
commit
aa5c4d8786
@ -1,5 +1,6 @@
|
|||||||
"""The AEMET OpenData component."""
|
"""The AEMET OpenData component."""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from aemet_opendata.exceptions import TownNotFound
|
from aemet_opendata.exceptions import TownNotFound
|
||||||
@ -8,6 +9,7 @@ from aemet_opendata.interface import AEMET, ConnectionOptions
|
|||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
|
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers import aiohttp_client
|
from homeassistant.helpers import aiohttp_client
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -37,6 +39,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
except TownNotFound as err:
|
except TownNotFound as err:
|
||||||
_LOGGER.error(err)
|
_LOGGER.error(err)
|
||||||
return False
|
return False
|
||||||
|
except asyncio.TimeoutError as err:
|
||||||
|
raise ConfigEntryNotReady("AEMET OpenData API timed out") from err
|
||||||
|
|
||||||
weather_coordinator = WeatherUpdateCoordinator(hass, aemet)
|
weather_coordinator = WeatherUpdateCoordinator(hass, aemet)
|
||||||
await weather_coordinator.async_config_entry_first_refresh()
|
await weather_coordinator.async_config_entry_first_refresh()
|
||||||
|
@ -11,5 +11,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/airzone",
|
"documentation": "https://www.home-assistant.io/integrations/airzone",
|
||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
"loggers": ["aioairzone"],
|
"loggers": ["aioairzone"],
|
||||||
"requirements": ["aioairzone==0.6.8"]
|
"requirements": ["aioairzone==0.6.9"]
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
"bleak-retry-connector==3.2.1",
|
"bleak-retry-connector==3.2.1",
|
||||||
"bluetooth-adapters==0.16.1",
|
"bluetooth-adapters==0.16.1",
|
||||||
"bluetooth-auto-recovery==1.2.3",
|
"bluetooth-auto-recovery==1.2.3",
|
||||||
"bluetooth-data-tools==1.12.0",
|
"bluetooth-data-tools==1.13.0",
|
||||||
"dbus-fast==2.11.1"
|
"dbus-fast==2.12.0"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -483,7 +483,7 @@ class CalendarEntity(Entity):
|
|||||||
|
|
||||||
_entity_component_unrecorded_attributes = frozenset({"description"})
|
_entity_component_unrecorded_attributes = frozenset({"description"})
|
||||||
|
|
||||||
_alarm_unsubs: list[CALLBACK_TYPE] = []
|
_alarm_unsubs: list[CALLBACK_TYPE] | None = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def event(self) -> CalendarEvent | None:
|
def event(self) -> CalendarEvent | None:
|
||||||
@ -528,6 +528,8 @@ class CalendarEntity(Entity):
|
|||||||
the current or upcoming event.
|
the current or upcoming event.
|
||||||
"""
|
"""
|
||||||
super().async_write_ha_state()
|
super().async_write_ha_state()
|
||||||
|
if self._alarm_unsubs is None:
|
||||||
|
self._alarm_unsubs = []
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Clearing %s alarms (%s)", self.entity_id, len(self._alarm_unsubs)
|
"Clearing %s alarms (%s)", self.entity_id, len(self._alarm_unsubs)
|
||||||
)
|
)
|
||||||
@ -571,9 +573,9 @@ class CalendarEntity(Entity):
|
|||||||
|
|
||||||
To be extended by integrations.
|
To be extended by integrations.
|
||||||
"""
|
"""
|
||||||
for unsub in self._alarm_unsubs:
|
for unsub in self._alarm_unsubs or ():
|
||||||
unsub()
|
unsub()
|
||||||
self._alarm_unsubs.clear()
|
self._alarm_unsubs = None
|
||||||
|
|
||||||
async def async_get_events(
|
async def async_get_events(
|
||||||
self,
|
self,
|
||||||
|
@ -5,5 +5,5 @@
|
|||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/duotecno",
|
"documentation": "https://www.home-assistant.io/integrations/duotecno",
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
"requirements": ["pyDuotecno==2023.10.0"]
|
"requirements": ["pyDuotecno==2023.10.1"]
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,11 @@ from aioesphomeapi import (
|
|||||||
BluetoothProxyFeature,
|
BluetoothProxyFeature,
|
||||||
DeviceInfo,
|
DeviceInfo,
|
||||||
)
|
)
|
||||||
from aioesphomeapi.connection import APIConnectionError, TimeoutAPIError
|
from aioesphomeapi.core import (
|
||||||
from aioesphomeapi.core import BluetoothGATTAPIError
|
APIConnectionError,
|
||||||
|
BluetoothGATTAPIError,
|
||||||
|
TimeoutAPIError,
|
||||||
|
)
|
||||||
from async_interrupt import interrupt
|
from async_interrupt import interrupt
|
||||||
from bleak.backends.characteristic import BleakGATTCharacteristic
|
from bleak.backends.characteristic import BleakGATTCharacteristic
|
||||||
from bleak.backends.client import BaseBleakClient, NotifyCallback
|
from bleak.backends.client import BaseBleakClient, NotifyCallback
|
||||||
@ -389,8 +392,8 @@ class ESPHomeClient(BaseBleakClient):
|
|||||||
return await self._disconnect()
|
return await self._disconnect()
|
||||||
|
|
||||||
async def _disconnect(self) -> bool:
|
async def _disconnect(self) -> bool:
|
||||||
self._async_disconnected_cleanup()
|
|
||||||
await self._client.bluetooth_device_disconnect(self._address_as_int)
|
await self._client.bluetooth_device_disconnect(self._address_as_int)
|
||||||
|
self._async_ble_device_disconnected()
|
||||||
await self._wait_for_free_connection_slot(DISCONNECT_TIMEOUT)
|
await self._wait_for_free_connection_slot(DISCONNECT_TIMEOUT)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -538,7 +538,7 @@ class ESPHomeManager:
|
|||||||
on_connect=self.on_connect,
|
on_connect=self.on_connect,
|
||||||
on_disconnect=self.on_disconnect,
|
on_disconnect=self.on_disconnect,
|
||||||
zeroconf_instance=self.zeroconf_instance,
|
zeroconf_instance=self.zeroconf_instance,
|
||||||
name=self.host,
|
name=entry.data.get(CONF_DEVICE_NAME, self.host),
|
||||||
on_connect_error=self.on_connect_error,
|
on_connect_error=self.on_connect_error,
|
||||||
)
|
)
|
||||||
self.reconnect_logic = reconnect_logic
|
self.reconnect_logic = reconnect_logic
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
"loggers": ["aioesphomeapi", "noiseprotocol"],
|
"loggers": ["aioesphomeapi", "noiseprotocol"],
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"async-interrupt==1.1.1",
|
"async-interrupt==1.1.1",
|
||||||
"aioesphomeapi==17.0.1",
|
"aioesphomeapi==18.0.7",
|
||||||
"bluetooth-data-tools==1.12.0",
|
"bluetooth-data-tools==1.13.0",
|
||||||
"esphome-dashboard-api==1.2.3"
|
"esphome-dashboard-api==1.2.3"
|
||||||
],
|
],
|
||||||
"zeroconf": ["_esphomelib._tcp.local."]
|
"zeroconf": ["_esphomelib._tcp.local."]
|
||||||
|
@ -55,6 +55,8 @@ _VOICE_ASSISTANT_EVENT_TYPES: EsphomeEnumMapper[
|
|||||||
VoiceAssistantEventType.VOICE_ASSISTANT_TTS_END: PipelineEventType.TTS_END,
|
VoiceAssistantEventType.VOICE_ASSISTANT_TTS_END: PipelineEventType.TTS_END,
|
||||||
VoiceAssistantEventType.VOICE_ASSISTANT_WAKE_WORD_START: PipelineEventType.WAKE_WORD_START,
|
VoiceAssistantEventType.VOICE_ASSISTANT_WAKE_WORD_START: PipelineEventType.WAKE_WORD_START,
|
||||||
VoiceAssistantEventType.VOICE_ASSISTANT_WAKE_WORD_END: PipelineEventType.WAKE_WORD_END,
|
VoiceAssistantEventType.VOICE_ASSISTANT_WAKE_WORD_END: PipelineEventType.WAKE_WORD_END,
|
||||||
|
VoiceAssistantEventType.VOICE_ASSISTANT_STT_VAD_START: PipelineEventType.STT_VAD_START,
|
||||||
|
VoiceAssistantEventType.VOICE_ASSISTANT_STT_VAD_END: PipelineEventType.STT_VAD_END,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -161,7 +163,7 @@ class VoiceAssistantUDPServer(asyncio.DatagramProtocol):
|
|||||||
try:
|
try:
|
||||||
event_type = _VOICE_ASSISTANT_EVENT_TYPES.from_hass(event.type)
|
event_type = _VOICE_ASSISTANT_EVENT_TYPES.from_hass(event.type)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
_LOGGER.warning("Received unknown pipeline event type: %s", event.type)
|
_LOGGER.debug("Received unknown pipeline event type: %s", event.type)
|
||||||
return
|
return
|
||||||
|
|
||||||
data_to_send = None
|
data_to_send = None
|
||||||
@ -296,6 +298,10 @@ class VoiceAssistantUDPServer(asyncio.DatagramProtocol):
|
|||||||
if self.transport is None:
|
if self.transport is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self.handle_event(
|
||||||
|
VoiceAssistantEventType.VOICE_ASSISTANT_TTS_STREAM_START, {}
|
||||||
|
)
|
||||||
|
|
||||||
_extension, audio_bytes = await tts.async_get_media_source_audio(
|
_extension, audio_bytes = await tts.async_get_media_source_audio(
|
||||||
self.hass,
|
self.hass,
|
||||||
media_id,
|
media_id,
|
||||||
@ -321,4 +327,7 @@ class VoiceAssistantUDPServer(asyncio.DatagramProtocol):
|
|||||||
sample_offset += samples_in_chunk
|
sample_offset += samples_in_chunk
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
self.handle_event(
|
||||||
|
VoiceAssistantEventType.VOICE_ASSISTANT_TTS_STREAM_END, {}
|
||||||
|
)
|
||||||
self._tts_done.set()
|
self._tts_done.set()
|
||||||
|
@ -118,9 +118,7 @@ class GoogleMapsScanner:
|
|||||||
)
|
)
|
||||||
_LOGGER.debug("%s < %s", last_seen, self._prev_seen[dev_id])
|
_LOGGER.debug("%s < %s", last_seen, self._prev_seen[dev_id])
|
||||||
continue
|
continue
|
||||||
if last_seen == self._prev_seen.get(dev_id, last_seen) and hasattr(
|
if last_seen == self._prev_seen.get(dev_id):
|
||||||
self, "success_init"
|
|
||||||
):
|
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Ignoring %s update because timestamp "
|
"Ignoring %s update because timestamp "
|
||||||
"is the same as the last timestamp %s",
|
"is the same as the last timestamp %s",
|
||||||
|
@ -20,5 +20,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/ld2410_ble",
|
"documentation": "https://www.home-assistant.io/integrations/ld2410_ble",
|
||||||
"integration_type": "device",
|
"integration_type": "device",
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
"requirements": ["bluetooth-data-tools==1.12.0", "ld2410-ble==0.1.1"]
|
"requirements": ["bluetooth-data-tools==1.13.0", "ld2410-ble==0.1.1"]
|
||||||
}
|
}
|
||||||
|
@ -32,5 +32,5 @@
|
|||||||
"dependencies": ["bluetooth_adapters"],
|
"dependencies": ["bluetooth_adapters"],
|
||||||
"documentation": "https://www.home-assistant.io/integrations/led_ble",
|
"documentation": "https://www.home-assistant.io/integrations/led_ble",
|
||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
"requirements": ["bluetooth-data-tools==1.12.0", "led-ble==1.0.1"]
|
"requirements": ["bluetooth-data-tools==1.13.0", "led-ble==1.0.1"]
|
||||||
}
|
}
|
||||||
|
@ -250,9 +250,9 @@ class MatterClimate(MatterEntity, ClimateEntity):
|
|||||||
self._attr_min_temp = DEFAULT_MIN_TEMP
|
self._attr_min_temp = DEFAULT_MIN_TEMP
|
||||||
# update max_temp
|
# update max_temp
|
||||||
if self._attr_hvac_mode in (HVACMode.COOL, HVACMode.HEAT_COOL):
|
if self._attr_hvac_mode in (HVACMode.COOL, HVACMode.HEAT_COOL):
|
||||||
attribute = clusters.Thermostat.Attributes.AbsMaxHeatSetpointLimit
|
|
||||||
else:
|
|
||||||
attribute = clusters.Thermostat.Attributes.AbsMaxCoolSetpointLimit
|
attribute = clusters.Thermostat.Attributes.AbsMaxCoolSetpointLimit
|
||||||
|
else:
|
||||||
|
attribute = clusters.Thermostat.Attributes.AbsMaxHeatSetpointLimit
|
||||||
if (value := self._get_temperature_in_degrees(attribute)) is not None:
|
if (value := self._get_temperature_in_degrees(attribute)) is not None:
|
||||||
self._attr_max_temp = value
|
self._attr_max_temp = value
|
||||||
else:
|
else:
|
||||||
|
@ -176,7 +176,13 @@ async def async_subscribe(
|
|||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
f"Cannot subscribe to topic '{topic}', MQTT is not enabled"
|
f"Cannot subscribe to topic '{topic}', MQTT is not enabled"
|
||||||
)
|
)
|
||||||
mqtt_data = get_mqtt_data(hass)
|
try:
|
||||||
|
mqtt_data = get_mqtt_data(hass)
|
||||||
|
except KeyError as ex:
|
||||||
|
raise HomeAssistantError(
|
||||||
|
f"Cannot subscribe to topic '{topic}', "
|
||||||
|
"make sure MQTT is set up correctly"
|
||||||
|
) from ex
|
||||||
async_remove = await mqtt_data.client.async_subscribe(
|
async_remove = await mqtt_data.client.async_subscribe(
|
||||||
topic,
|
topic,
|
||||||
catch_log_exception(
|
catch_log_exception(
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/nina",
|
"documentation": "https://www.home-assistant.io/integrations/nina",
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["pynina"],
|
"loggers": ["pynina"],
|
||||||
"requirements": ["PyNINA==0.3.2"]
|
"requirements": ["PyNINA==0.3.3"]
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/opower",
|
"documentation": "https://www.home-assistant.io/integrations/opower",
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["opower"],
|
"loggers": ["opower"],
|
||||||
"requirements": ["opower==0.0.35"]
|
"requirements": ["opower==0.0.36"]
|
||||||
}
|
}
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
"dependencies": ["bluetooth_adapters"],
|
"dependencies": ["bluetooth_adapters"],
|
||||||
"documentation": "https://www.home-assistant.io/integrations/private_ble_device",
|
"documentation": "https://www.home-assistant.io/integrations/private_ble_device",
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
"requirements": ["bluetooth-data-tools==1.12.0"]
|
"requirements": ["bluetooth-data-tools==1.13.0"]
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@
|
|||||||
"integration_type": "service",
|
"integration_type": "service",
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"quality_scale": "platinum",
|
"quality_scale": "platinum",
|
||||||
"requirements": ["vehicle==1.0.1"]
|
"requirements": ["vehicle==2.0.0"]
|
||||||
}
|
}
|
||||||
|
@ -15,5 +15,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/screenlogic",
|
"documentation": "https://www.home-assistant.io/integrations/screenlogic",
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
"loggers": ["screenlogicpy"],
|
"loggers": ["screenlogicpy"],
|
||||||
"requirements": ["screenlogicpy==0.9.2"]
|
"requirements": ["screenlogicpy==0.9.3"]
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from asyncio import run_coroutine_threadsafe
|
from asyncio import run_coroutine_threadsafe
|
||||||
import datetime as dt
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@ -27,7 +26,7 @@ from homeassistant.core import HomeAssistant, callback
|
|||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.util.dt import utc_from_timestamp
|
from homeassistant.util.dt import utcnow
|
||||||
|
|
||||||
from . import HomeAssistantSpotifyData
|
from . import HomeAssistantSpotifyData
|
||||||
from .browse_media import async_browse_media_internal
|
from .browse_media import async_browse_media_internal
|
||||||
@ -199,13 +198,6 @@ class SpotifyMediaPlayer(MediaPlayerEntity):
|
|||||||
return None
|
return None
|
||||||
return self._currently_playing["progress_ms"] / 1000
|
return self._currently_playing["progress_ms"] / 1000
|
||||||
|
|
||||||
@property
|
|
||||||
def media_position_updated_at(self) -> dt.datetime | None:
|
|
||||||
"""When was the position of the current playing media valid."""
|
|
||||||
if not self._currently_playing:
|
|
||||||
return None
|
|
||||||
return utc_from_timestamp(self._currently_playing["timestamp"] / 1000)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def media_image_url(self) -> str | None:
|
def media_image_url(self) -> str | None:
|
||||||
"""Return the media image URL."""
|
"""Return the media image URL."""
|
||||||
@ -413,6 +405,9 @@ class SpotifyMediaPlayer(MediaPlayerEntity):
|
|||||||
additional_types=[MediaType.EPISODE]
|
additional_types=[MediaType.EPISODE]
|
||||||
)
|
)
|
||||||
self._currently_playing = current or {}
|
self._currently_playing = current or {}
|
||||||
|
# Record the last updated time, because Spotify's timestamp property is unreliable
|
||||||
|
# and doesn't actually return the fetch time as is mentioned in the API description
|
||||||
|
self._attr_media_position_updated_at = utcnow() if current is not None else None
|
||||||
|
|
||||||
context = self._currently_playing.get("context") or {}
|
context = self._currently_playing.get("context") or {}
|
||||||
|
|
||||||
|
@ -20,9 +20,14 @@ from homeassistant.const import (
|
|||||||
CONF_PORT,
|
CONF_PORT,
|
||||||
CONF_USERNAME,
|
CONF_USERNAME,
|
||||||
CONF_VERIFY_SSL,
|
CONF_VERIFY_SSL,
|
||||||
|
Platform,
|
||||||
)
|
)
|
||||||
from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, callback
|
from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, callback
|
||||||
from homeassistant.helpers import aiohttp_client, device_registry as dr
|
from homeassistant.helpers import (
|
||||||
|
aiohttp_client,
|
||||||
|
device_registry as dr,
|
||||||
|
entity_registry as er,
|
||||||
|
)
|
||||||
from homeassistant.helpers.device_registry import (
|
from homeassistant.helpers.device_registry import (
|
||||||
DeviceEntry,
|
DeviceEntry,
|
||||||
DeviceEntryType,
|
DeviceEntryType,
|
||||||
@ -33,6 +38,7 @@ from homeassistant.helpers.dispatcher import (
|
|||||||
async_dispatcher_send,
|
async_dispatcher_send,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.helpers.entity_registry import async_entries_for_config_entry
|
||||||
from homeassistant.helpers.event import async_call_later, async_track_time_interval
|
from homeassistant.helpers.event import async_call_later, async_track_time_interval
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
@ -131,7 +137,7 @@ class UniFiController:
|
|||||||
# Client control options
|
# Client control options
|
||||||
|
|
||||||
# Config entry option with list of clients to control network access.
|
# Config entry option with list of clients to control network access.
|
||||||
self.option_block_clients = options.get(CONF_BLOCK_CLIENT, [])
|
self.option_block_clients: list[str] = options.get(CONF_BLOCK_CLIENT, [])
|
||||||
# Config entry option to control DPI restriction groups.
|
# Config entry option to control DPI restriction groups.
|
||||||
self.option_dpi_restrictions: bool = options.get(
|
self.option_dpi_restrictions: bool = options.get(
|
||||||
CONF_DPI_RESTRICTIONS, DEFAULT_DPI_RESTRICTIONS
|
CONF_DPI_RESTRICTIONS, DEFAULT_DPI_RESTRICTIONS
|
||||||
@ -244,7 +250,16 @@ class UniFiController:
|
|||||||
assert self.config_entry.unique_id is not None
|
assert self.config_entry.unique_id is not None
|
||||||
self.is_admin = self.api.sites[self.config_entry.unique_id].role == "admin"
|
self.is_admin = self.api.sites[self.config_entry.unique_id].role == "admin"
|
||||||
|
|
||||||
for mac in self.option_block_clients:
|
# Restore device tracker clients that are not a part of active clients list.
|
||||||
|
macs: list[str] = []
|
||||||
|
entity_registry = er.async_get(self.hass)
|
||||||
|
for entry in async_entries_for_config_entry(
|
||||||
|
entity_registry, self.config_entry.entry_id
|
||||||
|
):
|
||||||
|
if entry.domain == Platform.DEVICE_TRACKER:
|
||||||
|
macs.append(entry.unique_id.split("-", 1)[0])
|
||||||
|
|
||||||
|
for mac in self.option_block_clients + macs:
|
||||||
if mac not in self.api.clients and mac in self.api.clients_all:
|
if mac not in self.api.clients and mac in self.api.clients_all:
|
||||||
self.api.clients.process_raw([dict(self.api.clients_all[mac].raw)])
|
self.api.clients.process_raw([dict(self.api.clients_all[mac].raw)])
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
"velbus-packet",
|
"velbus-packet",
|
||||||
"velbus-protocol"
|
"velbus-protocol"
|
||||||
],
|
],
|
||||||
"requirements": ["velbus-aio==2023.2.0"],
|
"requirements": ["velbus-aio==2023.10.1"],
|
||||||
"usb": [
|
"usb": [
|
||||||
{
|
{
|
||||||
"vid": "10CF",
|
"vid": "10CF",
|
||||||
|
@ -45,25 +45,18 @@ class VelbusSensor(VelbusEntity, SensorEntity):
|
|||||||
"""Initialize a sensor Velbus entity."""
|
"""Initialize a sensor Velbus entity."""
|
||||||
super().__init__(channel)
|
super().__init__(channel)
|
||||||
self._is_counter: bool = counter
|
self._is_counter: bool = counter
|
||||||
# define the unique id
|
|
||||||
if self._is_counter:
|
if self._is_counter:
|
||||||
self._attr_unique_id = f"{self._attr_unique_id}-counter"
|
|
||||||
# define the name
|
|
||||||
if self._is_counter:
|
|
||||||
self._attr_name = f"{self._attr_name}-counter"
|
|
||||||
# define the device class
|
|
||||||
if self._is_counter:
|
|
||||||
self._attr_device_class = SensorDeviceClass.POWER
|
|
||||||
elif channel.is_counter_channel():
|
|
||||||
self._attr_device_class = SensorDeviceClass.ENERGY
|
self._attr_device_class = SensorDeviceClass.ENERGY
|
||||||
|
self._attr_icon = "mdi:counter"
|
||||||
|
self._attr_name = f"{self._attr_name}-counter"
|
||||||
|
self._attr_state_class = SensorStateClass.TOTAL_INCREASING
|
||||||
|
self._attr_unique_id = f"{self._attr_unique_id}-counter"
|
||||||
|
elif channel.is_counter_channel():
|
||||||
|
self._attr_device_class = SensorDeviceClass.POWER
|
||||||
|
self._attr_state_class = SensorStateClass.MEASUREMENT
|
||||||
elif channel.is_temperature():
|
elif channel.is_temperature():
|
||||||
self._attr_device_class = SensorDeviceClass.TEMPERATURE
|
self._attr_device_class = SensorDeviceClass.TEMPERATURE
|
||||||
# define the icon
|
self._attr_state_class = SensorStateClass.MEASUREMENT
|
||||||
if self._is_counter:
|
|
||||||
self._attr_icon = "mdi:counter"
|
|
||||||
# the state class
|
|
||||||
if self._is_counter:
|
|
||||||
self._attr_state_class = SensorStateClass.TOTAL_INCREASING
|
|
||||||
else:
|
else:
|
||||||
self._attr_state_class = SensorStateClass.MEASUREMENT
|
self._attr_state_class = SensorStateClass.MEASUREMENT
|
||||||
# unit
|
# unit
|
||||||
|
@ -146,6 +146,7 @@ class VenstarSensor(VenstarEntity, SensorEntity):
|
|||||||
super().__init__(coordinator, config)
|
super().__init__(coordinator, config)
|
||||||
self.entity_description = entity_description
|
self.entity_description = entity_description
|
||||||
self.sensor_name = sensor_name
|
self.sensor_name = sensor_name
|
||||||
|
self._attr_name = entity_description.name_fn(sensor_name)
|
||||||
self._config = config
|
self._config = config
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -153,11 +154,6 @@ class VenstarSensor(VenstarEntity, SensorEntity):
|
|||||||
"""Return the unique id."""
|
"""Return the unique id."""
|
||||||
return f"{self._config.entry_id}_{self.sensor_name.replace(' ', '_')}_{self.entity_description.key}"
|
return f"{self._config.entry_id}_{self.sensor_name.replace(' ', '_')}_{self.entity_description.key}"
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
"""Return the name of the device."""
|
|
||||||
return self.entity_description.name_fn(self.sensor_name)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self) -> int:
|
def native_value(self) -> int:
|
||||||
"""Return state of the sensor."""
|
"""Return state of the sensor."""
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/waqi",
|
"documentation": "https://www.home-assistant.io/integrations/waqi",
|
||||||
"iot_class": "cloud_polling",
|
"iot_class": "cloud_polling",
|
||||||
"loggers": ["aiowaqi"],
|
"loggers": ["aiowaqi"],
|
||||||
"requirements": ["aiowaqi==2.0.0"]
|
"requirements": ["aiowaqi==2.1.0"]
|
||||||
}
|
}
|
||||||
|
@ -21,15 +21,15 @@
|
|||||||
"universal_silabs_flasher"
|
"universal_silabs_flasher"
|
||||||
],
|
],
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"bellows==0.36.5",
|
"bellows==0.36.7",
|
||||||
"pyserial==3.5",
|
"pyserial==3.5",
|
||||||
"pyserial-asyncio==0.6",
|
"pyserial-asyncio==0.6",
|
||||||
"zha-quirks==0.0.104",
|
"zha-quirks==0.0.105",
|
||||||
"zigpy-deconz==0.21.1",
|
"zigpy-deconz==0.21.1",
|
||||||
"zigpy==0.57.2",
|
"zigpy==0.57.2",
|
||||||
"zigpy-xbee==0.18.3",
|
"zigpy-xbee==0.18.3",
|
||||||
"zigpy-zigate==0.11.0",
|
"zigpy-zigate==0.11.0",
|
||||||
"zigpy-znp==0.11.5",
|
"zigpy-znp==0.11.6",
|
||||||
"universal-silabs-flasher==0.0.14",
|
"universal-silabs-flasher==0.0.14",
|
||||||
"pyserial-asyncio-fast==0.11"
|
"pyserial-asyncio-fast==0.11"
|
||||||
],
|
],
|
||||||
|
@ -259,9 +259,11 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
|
|||||||
def _current_mode_setpoint_enums(self) -> list[ThermostatSetpointType]:
|
def _current_mode_setpoint_enums(self) -> list[ThermostatSetpointType]:
|
||||||
"""Return the list of enums that are relevant to the current thermostat mode."""
|
"""Return the list of enums that are relevant to the current thermostat mode."""
|
||||||
if self._current_mode is None or self._current_mode.value is None:
|
if self._current_mode is None or self._current_mode.value is None:
|
||||||
# Thermostat(valve) with no support for setting a mode
|
# Thermostat with no support for setting a mode is just a setpoint
|
||||||
# is considered heating-only
|
if self.info.primary_value.property_key is None:
|
||||||
return [ThermostatSetpointType.HEATING]
|
return []
|
||||||
|
return [ThermostatSetpointType(int(self.info.primary_value.property_key))]
|
||||||
|
|
||||||
return THERMOSTAT_MODE_SETPOINT_MAP.get(int(self._current_mode.value), [])
|
return THERMOSTAT_MODE_SETPOINT_MAP.get(int(self._current_mode.value), [])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -163,12 +163,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"device_config_file_changed": {
|
"device_config_file_changed": {
|
||||||
"title": "Z-Wave device configuration file changed: {device_name}",
|
"title": "Device configuration file changed: {device_name}",
|
||||||
"fix_flow": {
|
"fix_flow": {
|
||||||
"step": {
|
"step": {
|
||||||
"confirm": {
|
"confirm": {
|
||||||
"title": "Z-Wave device configuration file changed: {device_name}",
|
"title": "Device configuration file changed: {device_name}",
|
||||||
"description": "Z-Wave JS discovers a lot of device metadata by interviewing the device. However, some of the information has to be loaded from a configuration file. Some of this information is only evaluated once, during the device interview.\n\nWhen a device config file is updated, this information may be stale and and the device must be re-interviewed to pick up the changes.\n\n This is not a required operation and device functionality will be impacted during the re-interview process, but you may see improvements for your device once it is complete.\n\nIf you'd like to proceed, click on SUBMIT below. The re-interview will take place in the background."
|
"description": "The device configuration file for {device_name} has changed.\n\nZ-Wave JS discovers a lot of device metadata by interviewing the device. However, some of the information has to be loaded from a configuration file. Some of this information is only evaluated once, during the device interview.\n\nWhen a device config file is updated, this information may be stale and and the device must be re-interviewed to pick up the changes.\n\n This is not a required operation and device functionality will be impacted during the re-interview process, but you may see improvements for your device once it is complete.\n\nIf you'd like to proceed, click on SUBMIT below. The re-interview will take place in the background."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
|
@ -7,7 +7,7 @@ from typing import Final
|
|||||||
APPLICATION_NAME: Final = "HomeAssistant"
|
APPLICATION_NAME: Final = "HomeAssistant"
|
||||||
MAJOR_VERSION: Final = 2023
|
MAJOR_VERSION: Final = 2023
|
||||||
MINOR_VERSION: Final = 10
|
MINOR_VERSION: Final = 10
|
||||||
PATCH_VERSION: Final = "3"
|
PATCH_VERSION: Final = "4"
|
||||||
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
|
||||||
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
|
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
|
||||||
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 11, 0)
|
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 11, 0)
|
||||||
|
@ -11,11 +11,11 @@ bleak-retry-connector==3.2.1
|
|||||||
bleak==0.21.1
|
bleak==0.21.1
|
||||||
bluetooth-adapters==0.16.1
|
bluetooth-adapters==0.16.1
|
||||||
bluetooth-auto-recovery==1.2.3
|
bluetooth-auto-recovery==1.2.3
|
||||||
bluetooth-data-tools==1.12.0
|
bluetooth-data-tools==1.13.0
|
||||||
certifi>=2021.5.30
|
certifi>=2021.5.30
|
||||||
ciso8601==2.3.0
|
ciso8601==2.3.0
|
||||||
cryptography==41.0.4
|
cryptography==41.0.4
|
||||||
dbus-fast==2.11.1
|
dbus-fast==2.12.0
|
||||||
fnv-hash-fast==0.4.1
|
fnv-hash-fast==0.4.1
|
||||||
ha-av==10.1.1
|
ha-av==10.1.1
|
||||||
hass-nabucasa==0.71.0
|
hass-nabucasa==0.71.0
|
||||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "homeassistant"
|
name = "homeassistant"
|
||||||
version = "2023.10.3"
|
version = "2023.10.4"
|
||||||
license = {text = "Apache-2.0"}
|
license = {text = "Apache-2.0"}
|
||||||
description = "Open-source home automation platform running on Python 3."
|
description = "Open-source home automation platform running on Python 3."
|
||||||
readme = "README.rst"
|
readme = "README.rst"
|
||||||
|
@ -80,7 +80,7 @@ PyMetno==0.11.0
|
|||||||
PyMicroBot==0.0.9
|
PyMicroBot==0.0.9
|
||||||
|
|
||||||
# homeassistant.components.nina
|
# homeassistant.components.nina
|
||||||
PyNINA==0.3.2
|
PyNINA==0.3.3
|
||||||
|
|
||||||
# homeassistant.components.mobile_app
|
# homeassistant.components.mobile_app
|
||||||
# homeassistant.components.owntracks
|
# homeassistant.components.owntracks
|
||||||
@ -189,7 +189,7 @@ aioairq==0.2.4
|
|||||||
aioairzone-cloud==0.2.3
|
aioairzone-cloud==0.2.3
|
||||||
|
|
||||||
# homeassistant.components.airzone
|
# homeassistant.components.airzone
|
||||||
aioairzone==0.6.8
|
aioairzone==0.6.9
|
||||||
|
|
||||||
# homeassistant.components.ambient_station
|
# homeassistant.components.ambient_station
|
||||||
aioambient==2023.04.0
|
aioambient==2023.04.0
|
||||||
@ -231,7 +231,7 @@ aioecowitt==2023.5.0
|
|||||||
aioemonitor==1.0.5
|
aioemonitor==1.0.5
|
||||||
|
|
||||||
# homeassistant.components.esphome
|
# homeassistant.components.esphome
|
||||||
aioesphomeapi==17.0.1
|
aioesphomeapi==18.0.7
|
||||||
|
|
||||||
# homeassistant.components.flo
|
# homeassistant.components.flo
|
||||||
aioflo==2021.11.0
|
aioflo==2021.11.0
|
||||||
@ -372,7 +372,7 @@ aiovlc==0.1.0
|
|||||||
aiovodafone==0.3.1
|
aiovodafone==0.3.1
|
||||||
|
|
||||||
# homeassistant.components.waqi
|
# homeassistant.components.waqi
|
||||||
aiowaqi==2.0.0
|
aiowaqi==2.1.0
|
||||||
|
|
||||||
# homeassistant.components.watttime
|
# homeassistant.components.watttime
|
||||||
aiowatttime==0.1.1
|
aiowatttime==0.1.1
|
||||||
@ -512,7 +512,7 @@ beautifulsoup4==4.12.2
|
|||||||
# beewi-smartclim==0.0.10
|
# beewi-smartclim==0.0.10
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
bellows==0.36.5
|
bellows==0.36.7
|
||||||
|
|
||||||
# homeassistant.components.bmw_connected_drive
|
# homeassistant.components.bmw_connected_drive
|
||||||
bimmer-connected==0.14.1
|
bimmer-connected==0.14.1
|
||||||
@ -553,7 +553,7 @@ bluetooth-auto-recovery==1.2.3
|
|||||||
# homeassistant.components.ld2410_ble
|
# homeassistant.components.ld2410_ble
|
||||||
# homeassistant.components.led_ble
|
# homeassistant.components.led_ble
|
||||||
# homeassistant.components.private_ble_device
|
# homeassistant.components.private_ble_device
|
||||||
bluetooth-data-tools==1.12.0
|
bluetooth-data-tools==1.13.0
|
||||||
|
|
||||||
# homeassistant.components.bond
|
# homeassistant.components.bond
|
||||||
bond-async==0.2.1
|
bond-async==0.2.1
|
||||||
@ -645,7 +645,7 @@ datadog==0.15.0
|
|||||||
datapoint==0.9.8
|
datapoint==0.9.8
|
||||||
|
|
||||||
# homeassistant.components.bluetooth
|
# homeassistant.components.bluetooth
|
||||||
dbus-fast==2.11.1
|
dbus-fast==2.12.0
|
||||||
|
|
||||||
# homeassistant.components.debugpy
|
# homeassistant.components.debugpy
|
||||||
debugpy==1.8.0
|
debugpy==1.8.0
|
||||||
@ -1383,7 +1383,7 @@ openwrt-luci-rpc==1.1.16
|
|||||||
openwrt-ubus-rpc==0.0.2
|
openwrt-ubus-rpc==0.0.2
|
||||||
|
|
||||||
# homeassistant.components.opower
|
# homeassistant.components.opower
|
||||||
opower==0.0.35
|
opower==0.0.36
|
||||||
|
|
||||||
# homeassistant.components.oralb
|
# homeassistant.components.oralb
|
||||||
oralb-ble==0.17.6
|
oralb-ble==0.17.6
|
||||||
@ -1538,7 +1538,7 @@ pyCEC==0.5.2
|
|||||||
pyControl4==1.1.0
|
pyControl4==1.1.0
|
||||||
|
|
||||||
# homeassistant.components.duotecno
|
# homeassistant.components.duotecno
|
||||||
pyDuotecno==2023.10.0
|
pyDuotecno==2023.10.1
|
||||||
|
|
||||||
# homeassistant.components.eight_sleep
|
# homeassistant.components.eight_sleep
|
||||||
pyEight==0.3.2
|
pyEight==0.3.2
|
||||||
@ -2372,7 +2372,7 @@ satel-integra==0.3.7
|
|||||||
scapy==2.5.0
|
scapy==2.5.0
|
||||||
|
|
||||||
# homeassistant.components.screenlogic
|
# homeassistant.components.screenlogic
|
||||||
screenlogicpy==0.9.2
|
screenlogicpy==0.9.3
|
||||||
|
|
||||||
# homeassistant.components.scsgate
|
# homeassistant.components.scsgate
|
||||||
scsgate==0.1.0
|
scsgate==0.1.0
|
||||||
@ -2648,10 +2648,10 @@ uvcclient==0.11.0
|
|||||||
vallox-websocket-api==3.3.0
|
vallox-websocket-api==3.3.0
|
||||||
|
|
||||||
# homeassistant.components.rdw
|
# homeassistant.components.rdw
|
||||||
vehicle==1.0.1
|
vehicle==2.0.0
|
||||||
|
|
||||||
# homeassistant.components.velbus
|
# homeassistant.components.velbus
|
||||||
velbus-aio==2023.2.0
|
velbus-aio==2023.10.1
|
||||||
|
|
||||||
# homeassistant.components.venstar
|
# homeassistant.components.venstar
|
||||||
venstarcolortouch==0.19
|
venstarcolortouch==0.19
|
||||||
@ -2787,7 +2787,7 @@ zeroconf==0.115.2
|
|||||||
zeversolar==0.3.1
|
zeversolar==0.3.1
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zha-quirks==0.0.104
|
zha-quirks==0.0.105
|
||||||
|
|
||||||
# homeassistant.components.zhong_hong
|
# homeassistant.components.zhong_hong
|
||||||
zhong-hong-hvac==1.0.9
|
zhong-hong-hvac==1.0.9
|
||||||
@ -2805,7 +2805,7 @@ zigpy-xbee==0.18.3
|
|||||||
zigpy-zigate==0.11.0
|
zigpy-zigate==0.11.0
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy-znp==0.11.5
|
zigpy-znp==0.11.6
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy==0.57.2
|
zigpy==0.57.2
|
||||||
|
@ -70,7 +70,7 @@ PyMetno==0.11.0
|
|||||||
PyMicroBot==0.0.9
|
PyMicroBot==0.0.9
|
||||||
|
|
||||||
# homeassistant.components.nina
|
# homeassistant.components.nina
|
||||||
PyNINA==0.3.2
|
PyNINA==0.3.3
|
||||||
|
|
||||||
# homeassistant.components.mobile_app
|
# homeassistant.components.mobile_app
|
||||||
# homeassistant.components.owntracks
|
# homeassistant.components.owntracks
|
||||||
@ -170,7 +170,7 @@ aioairq==0.2.4
|
|||||||
aioairzone-cloud==0.2.3
|
aioairzone-cloud==0.2.3
|
||||||
|
|
||||||
# homeassistant.components.airzone
|
# homeassistant.components.airzone
|
||||||
aioairzone==0.6.8
|
aioairzone==0.6.9
|
||||||
|
|
||||||
# homeassistant.components.ambient_station
|
# homeassistant.components.ambient_station
|
||||||
aioambient==2023.04.0
|
aioambient==2023.04.0
|
||||||
@ -212,7 +212,7 @@ aioecowitt==2023.5.0
|
|||||||
aioemonitor==1.0.5
|
aioemonitor==1.0.5
|
||||||
|
|
||||||
# homeassistant.components.esphome
|
# homeassistant.components.esphome
|
||||||
aioesphomeapi==17.0.1
|
aioesphomeapi==18.0.7
|
||||||
|
|
||||||
# homeassistant.components.flo
|
# homeassistant.components.flo
|
||||||
aioflo==2021.11.0
|
aioflo==2021.11.0
|
||||||
@ -347,7 +347,7 @@ aiovlc==0.1.0
|
|||||||
aiovodafone==0.3.1
|
aiovodafone==0.3.1
|
||||||
|
|
||||||
# homeassistant.components.waqi
|
# homeassistant.components.waqi
|
||||||
aiowaqi==2.0.0
|
aiowaqi==2.1.0
|
||||||
|
|
||||||
# homeassistant.components.watttime
|
# homeassistant.components.watttime
|
||||||
aiowatttime==0.1.1
|
aiowatttime==0.1.1
|
||||||
@ -436,7 +436,7 @@ base36==0.1.1
|
|||||||
beautifulsoup4==4.12.2
|
beautifulsoup4==4.12.2
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
bellows==0.36.5
|
bellows==0.36.7
|
||||||
|
|
||||||
# homeassistant.components.bmw_connected_drive
|
# homeassistant.components.bmw_connected_drive
|
||||||
bimmer-connected==0.14.1
|
bimmer-connected==0.14.1
|
||||||
@ -467,7 +467,7 @@ bluetooth-auto-recovery==1.2.3
|
|||||||
# homeassistant.components.ld2410_ble
|
# homeassistant.components.ld2410_ble
|
||||||
# homeassistant.components.led_ble
|
# homeassistant.components.led_ble
|
||||||
# homeassistant.components.private_ble_device
|
# homeassistant.components.private_ble_device
|
||||||
bluetooth-data-tools==1.12.0
|
bluetooth-data-tools==1.13.0
|
||||||
|
|
||||||
# homeassistant.components.bond
|
# homeassistant.components.bond
|
||||||
bond-async==0.2.1
|
bond-async==0.2.1
|
||||||
@ -528,7 +528,7 @@ datadog==0.15.0
|
|||||||
datapoint==0.9.8
|
datapoint==0.9.8
|
||||||
|
|
||||||
# homeassistant.components.bluetooth
|
# homeassistant.components.bluetooth
|
||||||
dbus-fast==2.11.1
|
dbus-fast==2.12.0
|
||||||
|
|
||||||
# homeassistant.components.debugpy
|
# homeassistant.components.debugpy
|
||||||
debugpy==1.8.0
|
debugpy==1.8.0
|
||||||
@ -1061,7 +1061,7 @@ openerz-api==0.2.0
|
|||||||
openhomedevice==2.2.0
|
openhomedevice==2.2.0
|
||||||
|
|
||||||
# homeassistant.components.opower
|
# homeassistant.components.opower
|
||||||
opower==0.0.35
|
opower==0.0.36
|
||||||
|
|
||||||
# homeassistant.components.oralb
|
# homeassistant.components.oralb
|
||||||
oralb-ble==0.17.6
|
oralb-ble==0.17.6
|
||||||
@ -1171,7 +1171,7 @@ pyCEC==0.5.2
|
|||||||
pyControl4==1.1.0
|
pyControl4==1.1.0
|
||||||
|
|
||||||
# homeassistant.components.duotecno
|
# homeassistant.components.duotecno
|
||||||
pyDuotecno==2023.10.0
|
pyDuotecno==2023.10.1
|
||||||
|
|
||||||
# homeassistant.components.eight_sleep
|
# homeassistant.components.eight_sleep
|
||||||
pyEight==0.3.2
|
pyEight==0.3.2
|
||||||
@ -1759,7 +1759,7 @@ samsungtvws[async,encrypted]==2.6.0
|
|||||||
scapy==2.5.0
|
scapy==2.5.0
|
||||||
|
|
||||||
# homeassistant.components.screenlogic
|
# homeassistant.components.screenlogic
|
||||||
screenlogicpy==0.9.2
|
screenlogicpy==0.9.3
|
||||||
|
|
||||||
# homeassistant.components.backup
|
# homeassistant.components.backup
|
||||||
securetar==2023.3.0
|
securetar==2023.3.0
|
||||||
@ -1966,10 +1966,10 @@ uvcclient==0.11.0
|
|||||||
vallox-websocket-api==3.3.0
|
vallox-websocket-api==3.3.0
|
||||||
|
|
||||||
# homeassistant.components.rdw
|
# homeassistant.components.rdw
|
||||||
vehicle==1.0.1
|
vehicle==2.0.0
|
||||||
|
|
||||||
# homeassistant.components.velbus
|
# homeassistant.components.velbus
|
||||||
velbus-aio==2023.2.0
|
velbus-aio==2023.10.1
|
||||||
|
|
||||||
# homeassistant.components.venstar
|
# homeassistant.components.venstar
|
||||||
venstarcolortouch==0.19
|
venstarcolortouch==0.19
|
||||||
@ -2081,7 +2081,7 @@ zeroconf==0.115.2
|
|||||||
zeversolar==0.3.1
|
zeversolar==0.3.1
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zha-quirks==0.0.104
|
zha-quirks==0.0.105
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy-deconz==0.21.1
|
zigpy-deconz==0.21.1
|
||||||
@ -2093,7 +2093,7 @@ zigpy-xbee==0.18.3
|
|||||||
zigpy-zigate==0.11.0
|
zigpy-zigate==0.11.0
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy-znp==0.11.5
|
zigpy-znp==0.11.6
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
zigpy==0.57.2
|
zigpy==0.57.2
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""Define tests for the AEMET OpenData init."""
|
"""Define tests for the AEMET OpenData init."""
|
||||||
|
import asyncio
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from freezegun.api import FrozenDateTimeFactory
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
@ -70,3 +71,29 @@ async def test_init_town_not_found(
|
|||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
assert await hass.config_entries.async_setup(config_entry.entry_id) is False
|
assert await hass.config_entries.async_setup(config_entry.entry_id) is False
|
||||||
|
|
||||||
|
|
||||||
|
async def test_init_api_timeout(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
) -> None:
|
||||||
|
"""Test API timeouts when loading the AEMET integration."""
|
||||||
|
|
||||||
|
hass.config.set_time_zone("UTC")
|
||||||
|
freezer.move_to("2021-01-09 12:00:00+00:00")
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.aemet.AEMET.api_call",
|
||||||
|
side_effect=asyncio.TimeoutError,
|
||||||
|
):
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
data={
|
||||||
|
CONF_API_KEY: "api-key",
|
||||||
|
CONF_LATITUDE: "0.0",
|
||||||
|
CONF_LONGITUDE: "0.0",
|
||||||
|
CONF_NAME: "AEMET",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
assert await hass.config_entries.async_setup(config_entry.entry_id) is False
|
||||||
|
@ -129,6 +129,7 @@ def mock_client(mock_device_info) -> APIClient:
|
|||||||
mock_client.connect = AsyncMock()
|
mock_client.connect = AsyncMock()
|
||||||
mock_client.disconnect = AsyncMock()
|
mock_client.disconnect = AsyncMock()
|
||||||
mock_client.list_entities_services = AsyncMock(return_value=([], []))
|
mock_client.list_entities_services = AsyncMock(return_value=([], []))
|
||||||
|
mock_client.address = "127.0.0.1"
|
||||||
mock_client.api_version = APIVersion(99, 99)
|
mock_client.api_version = APIVersion(99, 99)
|
||||||
|
|
||||||
with patch("homeassistant.components.esphome.APIClient", mock_client), patch(
|
with patch("homeassistant.components.esphome.APIClient", mock_client), patch(
|
||||||
|
@ -959,6 +959,17 @@ async def test_subscribe_topic(
|
|||||||
unsub()
|
unsub()
|
||||||
|
|
||||||
|
|
||||||
|
async def test_subscribe_topic_not_initialize(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||||
|
) -> None:
|
||||||
|
"""Test the subscription of a topic when MQTT was not initialized."""
|
||||||
|
with pytest.raises(
|
||||||
|
HomeAssistantError, match=r".*make sure MQTT is set up correctly"
|
||||||
|
):
|
||||||
|
await mqtt.async_subscribe(hass, "test-topic", record_calls)
|
||||||
|
|
||||||
|
|
||||||
@patch("homeassistant.components.mqtt.client.INITIAL_SUBSCRIBE_COOLDOWN", 0.0)
|
@patch("homeassistant.components.mqtt.client.INITIAL_SUBSCRIBE_COOLDOWN", 0.0)
|
||||||
@patch("homeassistant.components.mqtt.client.UNSUBSCRIBE_COOLDOWN", 0.2)
|
@patch("homeassistant.components.mqtt.client.UNSUBSCRIBE_COOLDOWN", 0.2)
|
||||||
async def test_subscribe_and_resubscribe(
|
async def test_subscribe_and_resubscribe(
|
||||||
|
@ -662,6 +662,12 @@ def logic_group_zdb5100_state_fixture():
|
|||||||
return json.loads(load_fixture("zwave_js/logic_group_zdb5100_state.json"))
|
return json.loads(load_fixture("zwave_js/logic_group_zdb5100_state.json"))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="climate_intermatic_pe653_state", scope="session")
|
||||||
|
def climate_intermatic_pe653_state_fixture():
|
||||||
|
"""Load Intermatic PE653 Pool Control node state fixture data."""
|
||||||
|
return json.loads(load_fixture("zwave_js/climate_intermatic_pe653_state.json"))
|
||||||
|
|
||||||
|
|
||||||
# model fixtures
|
# model fixtures
|
||||||
|
|
||||||
|
|
||||||
@ -1290,3 +1296,11 @@ def logic_group_zdb5100_fixture(client, logic_group_zdb5100_state):
|
|||||||
node = Node(client, copy.deepcopy(logic_group_zdb5100_state))
|
node = Node(client, copy.deepcopy(logic_group_zdb5100_state))
|
||||||
client.driver.controller.nodes[node.node_id] = node
|
client.driver.controller.nodes[node.node_id] = node
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="climate_intermatic_pe653")
|
||||||
|
def climate_intermatic_pe653_fixture(client, climate_intermatic_pe653_state):
|
||||||
|
"""Mock an Intermatic PE653 node."""
|
||||||
|
node = Node(client, copy.deepcopy(climate_intermatic_pe653_state))
|
||||||
|
client.driver.controller.nodes[node.node_id] = node
|
||||||
|
return node
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -792,3 +792,196 @@ async def test_thermostat_raise_repair_issue_and_warning_when_setting_fan_preset
|
|||||||
"Dry and Fan preset modes are deprecated and will be removed in Home Assistant 2024.2. Please use the corresponding Dry and Fan HVAC modes instead"
|
"Dry and Fan preset modes are deprecated and will be removed in Home Assistant 2024.2. Please use the corresponding Dry and Fan HVAC modes instead"
|
||||||
in caplog.text
|
in caplog.text
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_multi_setpoint_thermostat(
|
||||||
|
hass: HomeAssistant, client, climate_intermatic_pe653, integration
|
||||||
|
) -> None:
|
||||||
|
"""Test a thermostat with multiple setpoints."""
|
||||||
|
node = climate_intermatic_pe653
|
||||||
|
|
||||||
|
heating_entity_id = "climate.pool_control_2"
|
||||||
|
heating = hass.states.get(heating_entity_id)
|
||||||
|
assert heating
|
||||||
|
assert heating.state == HVACMode.HEAT
|
||||||
|
assert heating.attributes[ATTR_TEMPERATURE] == 3.9
|
||||||
|
assert heating.attributes[ATTR_HVAC_MODES] == [HVACMode.HEAT]
|
||||||
|
assert (
|
||||||
|
heating.attributes[ATTR_SUPPORTED_FEATURES]
|
||||||
|
== ClimateEntityFeature.TARGET_TEMPERATURE
|
||||||
|
)
|
||||||
|
|
||||||
|
furnace_entity_id = "climate.pool_control"
|
||||||
|
furnace = hass.states.get(furnace_entity_id)
|
||||||
|
assert furnace
|
||||||
|
assert furnace.state == HVACMode.HEAT
|
||||||
|
assert furnace.attributes[ATTR_TEMPERATURE] == 15.6
|
||||||
|
assert furnace.attributes[ATTR_HVAC_MODES] == [HVACMode.HEAT]
|
||||||
|
assert (
|
||||||
|
furnace.attributes[ATTR_SUPPORTED_FEATURES]
|
||||||
|
== ClimateEntityFeature.TARGET_TEMPERATURE
|
||||||
|
)
|
||||||
|
|
||||||
|
client.async_send_command_no_wait.reset_mock()
|
||||||
|
|
||||||
|
# Test setting temperature of heating setpoint
|
||||||
|
await hass.services.async_call(
|
||||||
|
CLIMATE_DOMAIN,
|
||||||
|
SERVICE_SET_TEMPERATURE,
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: heating_entity_id,
|
||||||
|
ATTR_TEMPERATURE: 20.0,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test setting temperature of furnace setpoint
|
||||||
|
await hass.services.async_call(
|
||||||
|
CLIMATE_DOMAIN,
|
||||||
|
SERVICE_SET_TEMPERATURE,
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: furnace_entity_id,
|
||||||
|
ATTR_TEMPERATURE: 2.0,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test setting illegal mode raises an error
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
await hass.services.async_call(
|
||||||
|
CLIMATE_DOMAIN,
|
||||||
|
SERVICE_SET_HVAC_MODE,
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: heating_entity_id,
|
||||||
|
ATTR_HVAC_MODE: HVACMode.COOL,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
await hass.services.async_call(
|
||||||
|
CLIMATE_DOMAIN,
|
||||||
|
SERVICE_SET_HVAC_MODE,
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: furnace_entity_id,
|
||||||
|
ATTR_HVAC_MODE: HVACMode.COOL,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# this is a no-op since there's no mode
|
||||||
|
await hass.services.async_call(
|
||||||
|
CLIMATE_DOMAIN,
|
||||||
|
SERVICE_SET_HVAC_MODE,
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: heating_entity_id,
|
||||||
|
ATTR_HVAC_MODE: HVACMode.HEAT,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# this is a no-op since there's no mode
|
||||||
|
await hass.services.async_call(
|
||||||
|
CLIMATE_DOMAIN,
|
||||||
|
SERVICE_SET_HVAC_MODE,
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: furnace_entity_id,
|
||||||
|
ATTR_HVAC_MODE: HVACMode.HEAT,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(client.async_send_command.call_args_list) == 2
|
||||||
|
args = client.async_send_command.call_args_list[0][0][0]
|
||||||
|
assert args["command"] == "node.set_value"
|
||||||
|
assert args["nodeId"] == 19
|
||||||
|
assert args["valueId"] == {
|
||||||
|
"endpoint": 1,
|
||||||
|
"commandClass": 67,
|
||||||
|
"property": "setpoint",
|
||||||
|
"propertyKey": 1,
|
||||||
|
}
|
||||||
|
assert args["value"] == 68.0
|
||||||
|
|
||||||
|
args = client.async_send_command.call_args_list[1][0][0]
|
||||||
|
assert args["command"] == "node.set_value"
|
||||||
|
assert args["nodeId"] == 19
|
||||||
|
assert args["valueId"] == {
|
||||||
|
"endpoint": 0,
|
||||||
|
"commandClass": 67,
|
||||||
|
"property": "setpoint",
|
||||||
|
"propertyKey": 7,
|
||||||
|
}
|
||||||
|
assert args["value"] == 35.6
|
||||||
|
|
||||||
|
client.async_send_command.reset_mock()
|
||||||
|
|
||||||
|
# Test heating setpoint value update from value updated event
|
||||||
|
event = Event(
|
||||||
|
type="value updated",
|
||||||
|
data={
|
||||||
|
"source": "node",
|
||||||
|
"event": "value updated",
|
||||||
|
"nodeId": 19,
|
||||||
|
"args": {
|
||||||
|
"commandClassName": "Thermostat Setpoint",
|
||||||
|
"commandClass": 67,
|
||||||
|
"endpoint": 1,
|
||||||
|
"property": "setpoint",
|
||||||
|
"propertyKey": 1,
|
||||||
|
"propertyKeyName": "Heating",
|
||||||
|
"propertyName": "setpoint",
|
||||||
|
"newValue": 23,
|
||||||
|
"prevValue": 21.5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
node.receive_event(event)
|
||||||
|
|
||||||
|
state = hass.states.get(heating_entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state == HVACMode.HEAT
|
||||||
|
assert state.attributes[ATTR_TEMPERATURE] == -5
|
||||||
|
|
||||||
|
# furnace not changed
|
||||||
|
state = hass.states.get(furnace_entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state == HVACMode.HEAT
|
||||||
|
assert state.attributes[ATTR_TEMPERATURE] == 15.6
|
||||||
|
|
||||||
|
client.async_send_command.reset_mock()
|
||||||
|
|
||||||
|
# Test furnace setpoint value update from value updated event
|
||||||
|
event = Event(
|
||||||
|
type="value updated",
|
||||||
|
data={
|
||||||
|
"source": "node",
|
||||||
|
"event": "value updated",
|
||||||
|
"nodeId": 19,
|
||||||
|
"args": {
|
||||||
|
"commandClassName": "Thermostat Setpoint",
|
||||||
|
"commandClass": 67,
|
||||||
|
"endpoint": 0,
|
||||||
|
"property": "setpoint",
|
||||||
|
"propertyKey": 7,
|
||||||
|
"propertyKeyName": "Furnace",
|
||||||
|
"propertyName": "setpoint",
|
||||||
|
"newValue": 68,
|
||||||
|
"prevValue": 21.5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
node.receive_event(event)
|
||||||
|
|
||||||
|
# heating not changed
|
||||||
|
state = hass.states.get(heating_entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state == HVACMode.HEAT
|
||||||
|
assert state.attributes[ATTR_TEMPERATURE] == -5
|
||||||
|
|
||||||
|
state = hass.states.get(furnace_entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state == HVACMode.HEAT
|
||||||
|
assert state.attributes[ATTR_TEMPERATURE] == 20
|
||||||
|
|
||||||
|
client.async_send_command.reset_mock()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user