Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2023.6.3 #95119

Merged
merged 27 commits into from
Jun 23, 2023
Merged

2023.6.3 #95119

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3f93699
Register Fully Kiosk services regardless of setup result (#88647)
mheath Jun 19, 2023
bd0b8dc
Fortios device tracker updates (#92331)
kimfrellsen Jun 15, 2023
d2385f9
Handle LastFM unavailable (#94456)
joostlek Jun 23, 2023
ffe35c7
Handle Insteon events correctly (#94549)
teharris1 Jun 16, 2023
78bbec0
Fix unit for Habitica text sensors (#94550)
atudor2 Jun 16, 2023
e1c486f
Bump minimum typing_extensions to 4.6.3 (#94587)
Jun 15, 2023
203820d
Fix glances raid plugin data (#94597)
Jun 23, 2023
57dd62e
Make YouTube select lower quality thumbnails (#94652)
joostlek Jun 18, 2023
6329f6b
Add strings for YouTube reauthentication (#94655)
joostlek Jun 16, 2023
b52cfd3
Fix bluetooth tracker asyncio usage (#94695)
d03n3rfr1tz3 Jun 16, 2023
89c6494
Fix zwave_js trigger event reattach logic (#94702)
raman325 Jun 16, 2023
254b1fd
Fix warning from rapt_ble caused by payload version 2 (#94718)
sairon Jun 16, 2023
f33d671
Fix Totalconnect BinarySensorDeviceClass logic (#94772)
austinmroczek Jun 20, 2023
e175164
Bump HAP-python to 4.7.0 (#94812)
bdraco Jun 20, 2023
cee8004
Bump bthome to 2.12.0 (#94822)
Ernst79 Jun 18, 2023
5da5522
Update aioairzone to v0.6.4 (#94873)
Noltari Jun 20, 2023
f8cfaa6
Bump ical to 4.5.4 (#94894)
allenporter Jun 20, 2023
34ef89b
Fix Meteo France blocked config entry when weather alert API fails (#…
Quentame Jun 22, 2023
cda784c
Add error handling to hassio issues (#94951)
epenet Jun 21, 2023
bbbc9f6
Bump Matter Server to 3.5.1: some small fixes and stability improveme…
marcelveldt Jun 21, 2023
44e7243
Fix zwave_js device diagnostics dump (#94999)
raman325 Jun 22, 2023
ced6968
Bump bimmer_connected to 0.13.7 (#95017)
rikroe Jun 21, 2023
e26b8e1
Fix goodwe midnight error (#95041)
hmmbob Jun 22, 2023
0fa9540
Fix removal of orphaned Matter devices (#95044)
marcelveldt Jun 22, 2023
8f9425f
Fix KNX device trigger passing info data (#95076)
farmio Jun 22, 2023
4cf9bec
Bumped version to 2023.6.3
frenck Jun 23, 2023
9f6dab0
Remove incompatible config schema for Fully Kiosk
frenck Jun 23, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion homeassistant/components/airzone/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
"documentation": "https://www.home-assistant.io/integrations/airzone",
"iot_class": "local_polling",
"loggers": ["aioairzone"],
"requirements": ["aioairzone==0.6.3"]
"requirements": ["aioairzone==0.6.4"]
}
6 changes: 5 additions & 1 deletion homeassistant/components/bluetooth_tracker/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,11 @@ async def perform_bluetooth_update() -> None:
rssi = await hass.async_add_executor_job(client.request_rssi)
client.close()

tasks.append(see_device(hass, async_see, mac, friendly_name, rssi))
tasks.append(
asyncio.create_task(
see_device(hass, async_see, mac, friendly_name, rssi)
)
)

if tasks:
await asyncio.wait(tasks)
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/bmw_connected_drive/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/bmw_connected_drive",
"iot_class": "cloud_polling",
"loggers": ["bimmer_connected"],
"requirements": ["bimmer_connected==0.13.6"]
"requirements": ["bimmer-connected==0.13.7"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/bthome/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
"dependencies": ["bluetooth_adapters"],
"documentation": "https://www.home-assistant.io/integrations/bthome",
"iot_class": "local_push",
"requirements": ["bthome-ble==2.11.3"]
"requirements": ["bthome-ble==2.12.0"]
}
27 changes: 27 additions & 0 deletions homeassistant/components/bthome/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@
from .device import device_key_to_bluetooth_entity_key

SENSOR_DESCRIPTIONS = {
# Acceleration (m/s²)
(
BTHomeSensorDeviceClass.ACCELERATION,
Units.ACCELERATION_METERS_PER_SQUARE_SECOND,
): SensorEntityDescription(
key=f"{BTHomeSensorDeviceClass.ACCELERATION}_{Units.ACCELERATION_METERS_PER_SQUARE_SECOND}",
native_unit_of_measurement=Units.ACCELERATION_METERS_PER_SQUARE_SECOND,
state_class=SensorStateClass.MEASUREMENT,
),
# Battery (percent)
(BTHomeSensorDeviceClass.BATTERY, Units.PERCENTAGE): SensorEntityDescription(
key=f"{BTHomeSensorDeviceClass.BATTERY}_{Units.PERCENTAGE}",
Expand Down Expand Up @@ -131,6 +140,15 @@
native_unit_of_measurement=UnitOfVolume.CUBIC_METERS,
state_class=SensorStateClass.TOTAL,
),
# Gyroscope (°/s)
(
BTHomeSensorDeviceClass.GYROSCOPE,
Units.GYROSCOPE_DEGREES_PER_SECOND,
): SensorEntityDescription(
key=f"{BTHomeSensorDeviceClass.GYROSCOPE}_{Units.GYROSCOPE_DEGREES_PER_SECOND}",
native_unit_of_measurement=Units.GYROSCOPE_DEGREES_PER_SECOND,
state_class=SensorStateClass.MEASUREMENT,
),
# Humidity in (percent)
(BTHomeSensorDeviceClass.HUMIDITY, Units.PERCENTAGE): SensorEntityDescription(
key=f"{BTHomeSensorDeviceClass.HUMIDITY}_{Units.PERCENTAGE}",
Expand Down Expand Up @@ -242,6 +260,15 @@
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
state_class=SensorStateClass.MEASUREMENT,
),
# Timestamp (datetime object)
(
BTHomeSensorDeviceClass.TIMESTAMP,
None,
): SensorEntityDescription(
key=f"{BTHomeSensorDeviceClass.TIMESTAMP}",
device_class=SensorDeviceClass.TIMESTAMP,
state_class=SensorStateClass.MEASUREMENT,
),
# UV index (-)
(
BTHomeSensorDeviceClass.UV_INDEX,
Expand Down
34 changes: 18 additions & 16 deletions homeassistant/components/fortios/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def get_scanner(hass: HomeAssistant, config: ConfigType) -> FortiOSDeviceScanner
fgt = FortiOSAPI()

try:
fgt.tokenlogin(host, token, verify_ssl)
fgt.tokenlogin(host, token, verify_ssl, None, 12, "root")
except ConnectionError as ex:
_LOGGER.error("ConnectionError to FortiOS API: %s", ex)
return None
Expand Down Expand Up @@ -77,16 +77,25 @@ def __init__(self, fgt) -> None:

def update(self):
"""Update clients from the device."""
clients_json = self._fgt.monitor("user/device/query", "")
clients_json = self._fgt.monitor(
"user/device/query",
"",
parameters={"filter": "format=master_mac|hostname|is_online"},
)

self._clients_json = clients_json

self._clients = []

if clients_json:
try:
for client in clients_json["results"]:
if client["is_online"]:
self._clients.append(client["mac"].upper())
if (
"is_online" in client
and "master_mac" in client
and client["is_online"]
):
self._clients.append(client["master_mac"].upper())
except KeyError as kex:
_LOGGER.error("Key not found in clients: %s", kex)

Expand All @@ -106,17 +115,10 @@ def get_device_name(self, device):
return None

for client in data["results"]:
if client["mac"] == device:
try:
if "master_mac" in client and client["master_mac"] == device:
if "hostname" in client:
name = client["hostname"]
_LOGGER.debug("Getting device name=%s", name)
return name
except KeyError as kex:
_LOGGER.debug(
"No hostname found for %s in client data: %s",
device,
kex,
)
return device.replace(":", "_")

else:
name = client["master_mac"].replace(":", "_")
return name
return None
11 changes: 9 additions & 2 deletions homeassistant/components/fully_kiosk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.typing import ConfigType

from .const import DOMAIN
from .coordinator import FullyKioskDataUpdateCoordinator
Expand All @@ -17,6 +18,14 @@
]


async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up Fully Kiosk Browser."""

await async_setup_services(hass)

return True


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Fully Kiosk Browser from a config entry."""

Expand All @@ -28,8 +37,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
coordinator.async_update_listeners()

await async_setup_services(hass)

return True


Expand Down
70 changes: 31 additions & 39 deletions homeassistant/components/fully_kiosk/services.py
Original file line number Diff line number Diff line change
@@ -1,74 +1,66 @@
"""Services for the Fully Kiosk Browser integration."""
from __future__ import annotations

from collections.abc import Callable
from typing import Any

from fullykiosk import FullyKiosk
import voluptuous as vol

from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.const import ATTR_DEVICE_ID
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.exceptions import HomeAssistantError
import homeassistant.helpers.config_validation as cv
import homeassistant.helpers.device_registry as dr

from .const import (
ATTR_APPLICATION,
ATTR_URL,
DOMAIN,
LOGGER,
SERVICE_LOAD_URL,
SERVICE_START_APPLICATION,
)
from .coordinator import FullyKioskDataUpdateCoordinator


async def async_setup_services(hass: HomeAssistant) -> None:
"""Set up the services for the Fully Kiosk Browser integration."""

async def execute_service(
call: ServiceCall,
fully_method: Callable,
*args: list[str],
**kwargs: dict[str, Any],
) -> None:
"""Execute a Fully service call.

:param call: {ServiceCall} HA service call.
:param fully_method: {Callable} A method of the FullyKiosk class.
:param args: Arguments for fully_method.
:param kwargs: Key-word arguments for fully_method.
:return: None
"""
LOGGER.debug(
"Calling Fully service %s with args: %s, %s", ServiceCall, args, kwargs
)
async def collect_coordinators(
device_ids: list[str],
) -> list[FullyKioskDataUpdateCoordinator]:
config_entries = list[ConfigEntry]()
registry = dr.async_get(hass)
for target in call.data[ATTR_DEVICE_ID]:
for target in device_ids:
device = registry.async_get(target)
if device:
for key in device.config_entries:
entry = hass.config_entries.async_get_entry(key)
if not entry:
continue
if entry.domain != DOMAIN:
continue
coordinator = hass.data[DOMAIN][key]
# fully_method(coordinator.fully, *args, **kwargs) would make
# test_services.py fail.
await getattr(coordinator.fully, fully_method.__name__)(
*args, **kwargs
device_entries = list[ConfigEntry]()
for entry_id in device.config_entries:
entry = hass.config_entries.async_get_entry(entry_id)
if entry and entry.domain == DOMAIN:
device_entries.append(entry)
if not device_entries:
raise HomeAssistantError(
f"Device '{target}' is not a {DOMAIN} device"
)
break
config_entries.extend(device_entries)
else:
raise HomeAssistantError(
f"Device '{target}' not found in device registry"
)
coordinators = list[FullyKioskDataUpdateCoordinator]()
for config_entry in config_entries:
if config_entry.state != ConfigEntryState.LOADED:
raise HomeAssistantError(f"{config_entry.title} is not loaded")
coordinators.append(hass.data[DOMAIN][config_entry.entry_id])
return coordinators

async def async_load_url(call: ServiceCall) -> None:
"""Load a URL on the Fully Kiosk Browser."""
await execute_service(call, FullyKiosk.loadUrl, call.data[ATTR_URL])
for coordinator in await collect_coordinators(call.data[ATTR_DEVICE_ID]):
await coordinator.fully.loadUrl(call.data[ATTR_URL])

async def async_start_app(call: ServiceCall) -> None:
"""Start an app on the device."""
await execute_service(
call, FullyKiosk.startApplication, call.data[ATTR_APPLICATION]
)
for coordinator in await collect_coordinators(call.data[ATTR_DEVICE_ID]):
await coordinator.fully.startApplication(call.data[ATTR_APPLICATION])

# Register all the above services
service_mapping = [
Expand Down
52 changes: 26 additions & 26 deletions homeassistant/components/glances/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,17 +223,17 @@ class GlancesSensorEntityDescription(
icon="mdi:docker",
state_class=SensorStateClass.MEASUREMENT,
),
("raid", "used"): GlancesSensorEntityDescription(
key="used",
("raid", "available"): GlancesSensorEntityDescription(
key="available",
type="raid",
name_suffix="Raid used",
name_suffix="Raid available",
icon="mdi:harddisk",
state_class=SensorStateClass.MEASUREMENT,
),
("raid", "available"): GlancesSensorEntityDescription(
key="available",
("raid", "used"): GlancesSensorEntityDescription(
key="used",
type="raid",
name_suffix="Raid available",
name_suffix="Raid used",
icon="mdi:harddisk",
state_class=SensorStateClass.MEASUREMENT,
),
Expand Down Expand Up @@ -269,36 +269,36 @@ def _migrate_old_unique_ids(
if sensor_type in ["fs", "sensors", "raid"]:
for sensor_label, params in sensors.items():
for param in params:
sensor_description = SENSOR_TYPES[(sensor_type, param)]
if sensor_description := SENSOR_TYPES.get((sensor_type, param)):
_migrate_old_unique_ids(
hass,
f"{coordinator.host}-{name} {sensor_label} {sensor_description.name_suffix}",
f"{sensor_label}-{sensor_description.key}",
)
entities.append(
GlancesSensor(
coordinator,
name,
sensor_label,
sensor_description,
)
)
else:
for sensor in sensors:
if sensor_description := SENSOR_TYPES.get((sensor_type, sensor)):
_migrate_old_unique_ids(
hass,
f"{coordinator.host}-{name} {sensor_label} {sensor_description.name_suffix}",
f"{sensor_label}-{sensor_description.key}",
f"{coordinator.host}-{name} {sensor_description.name_suffix}",
f"-{sensor_description.key}",
)
entities.append(
GlancesSensor(
coordinator,
name,
sensor_label,
"",
sensor_description,
)
)
else:
for sensor in sensors:
sensor_description = SENSOR_TYPES[(sensor_type, sensor)]
_migrate_old_unique_ids(
hass,
f"{coordinator.host}-{name} {sensor_description.name_suffix}",
f"-{sensor_description.key}",
)
entities.append(
GlancesSensor(
coordinator,
name,
"",
sensor_description,
)
)

async_add_entities(entities)

Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/goodwe/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ def async_reset(self, now):
In contrast to "total" sensors, these "daily" sensors need to be reset to 0 on midnight.
"""
if not self.coordinator.last_update_success:
self.coordinator.reset_sensor(self._sensor.id)
self.coordinator.reset_sensor(self._sensor.id_)
self.async_write_ha_state()
_LOGGER.debug("Goodwe reset %s to 0", self.name)
next_midnight = dt_util.start_of_local_day(
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/habitica/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
SensorType = namedtuple("SensorType", ["name", "icon", "unit", "path"])

SENSORS_TYPES = {
"name": SensorType("Name", None, "", ["profile", "name"]),
"name": SensorType("Name", None, None, ["profile", "name"]),
"hp": SensorType("HP", "mdi:heart", "HP", ["stats", "hp"]),
"maxHealth": SensorType("max HP", "mdi:heart", "HP", ["stats", "maxHealth"]),
"mp": SensorType("Mana", "mdi:auto-fix", "MP", ["stats", "mp"]),
Expand All @@ -35,7 +35,7 @@
"Lvl", "mdi:arrow-up-bold-circle-outline", "Lvl", ["stats", "lvl"]
),
"gp": SensorType("Gold", "mdi:circle-multiple", "Gold", ["stats", "gp"]),
"class": SensorType("Class", "mdi:sword", "", ["stats", "class"]),
"class": SensorType("Class", "mdi:sword", None, ["stats", "class"]),
}

TASKS_TYPES = {
Expand Down
Loading