Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c13cfe9
Re-add AGENTS.md as symlink (#153804)
zweckj Oct 6, 2025
e6203df
Bump actions/stale from 10.0.0 to 10.1.0 (#153799)
dependabot[bot] Oct 6, 2025
da89617
Google Assistant SDK: improve init tests (#153795)
tronikos Oct 6, 2025
e971000
Add new test fixture for Tuya cl category (#153800)
epenet Oct 6, 2025
c0aa9bf
Update Mealie quality scale to platinum (#153810)
andrew-codechimp Oct 6, 2025
ac79b30
Use customized miele device name if set (#153835)
astrandb Oct 6, 2025
553d896
Add Ecovacs active map select entity (#153748)
edenhaus Oct 6, 2025
c36341e
vesync correct fan set modes (#153761)
cdnninja Oct 6, 2025
425bdc0
Vesync add oscillation to fan (#153297)
cdnninja Oct 6, 2025
cb6e65f
Refactor Telegram bot entity (#153609)
hanwg Oct 6, 2025
645f32f
Bump pySmartThings to 3.3.1 (#153826)
joostlek Oct 6, 2025
9640ebb
Add support for Wave Enhance and Corentium Home 2 in Airthings BLE in…
LaStrada Oct 6, 2025
66cca98
Expose climate current temp as dedicated sensor in FRITZ!SmartHome (#…
mib1185 Oct 6, 2025
d9691c2
Add sensor for hydraulic separator temperature in ViCare integration …
CFenner Oct 6, 2025
42370ba
Synology DSM: Don't reinitialize API during configuration (#153739)
oyvindwe Oct 6, 2025
ad238da
Enphase_envoy to use alternate data source for current transformers (…
catsmanac Oct 6, 2025
77a267b
Updated VRM client and accounted for missing forecasts (#153464)
AndyTempel Oct 6, 2025
72f8ac7
Add BME680 sensor support for Altruist Insight (#153463)
PaTara43 Oct 6, 2025
d2851ea
Deduplicate ONVIF sensor and binary sensor entity names (#153505)
felipecrs Oct 6, 2025
fa03f61
Remove log file write check (#153842)
abmantis Oct 6, 2025
a2837e6
Add MQTT number subentry support (#153358)
jbouwh Oct 6, 2025
08a9377
Update the MCP Server API endpoint to `mcp` (#153845)
allenporter Oct 6, 2025
7eaa559
Bump aiocomelit to 1.1.1 (#153843)
chemelli74 Oct 6, 2025
ece77cf
Fix PIN validation for Comelit SimpleHome (#153840)
chemelli74 Oct 6, 2025
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
6 changes: 3 additions & 3 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
# - No PRs marked as no-stale
# - No issues (-1)
- name: 60 days stale PRs policy
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 60
Expand Down Expand Up @@ -57,7 +57,7 @@ jobs:
# - No issues marked as no-stale or help-wanted
# - No PRs (-1)
- name: 90 days stale issues
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
with:
repo-token: ${{ steps.token.outputs.token }}
days-before-stale: 90
Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:
# - No Issues marked as no-stale or help-wanted
# - No PRs (-1)
- name: Needs more information stale issues policy
uses: actions/stale@3a9db7e6a41a89f618792c92c0e97cc736e1b13f # v10.0.0
uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
with:
repo-token: ${{ steps.token.outputs.token }}
only-labels: "needs-more-information"
Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
24 changes: 7 additions & 17 deletions homeassistant/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,25 +635,15 @@ async def async_enable_logging(
err_log_path = os.path.abspath(log_file)

if err_log_path:
err_path_exists = os.path.isfile(err_log_path)
err_dir = os.path.dirname(err_log_path)

# Check if we can write to the error log if it exists or that
# we can create files in the containing directory if not.
if (err_path_exists and os.access(err_log_path, os.W_OK)) or (
not err_path_exists and os.access(err_dir, os.W_OK)
):
err_handler = await hass.async_add_executor_job(
_create_log_file, err_log_path, log_rotate_days
)
err_handler = await hass.async_add_executor_job(
_create_log_file, err_log_path, log_rotate_days
)

err_handler.setFormatter(logging.Formatter(fmt, datefmt=FORMAT_DATETIME))
logger.addHandler(err_handler)
err_handler.setFormatter(logging.Formatter(fmt, datefmt=FORMAT_DATETIME))
logger.addHandler(err_handler)

# Save the log file location for access by other components.
hass.data[DATA_LOGGING] = err_log_path
else:
_LOGGER.error("Unable to set up error log %s (access denied)", err_log_path)
# Save the log file location for access by other components.
hass.data[DATA_LOGGING] = err_log_path

async_activate_log_queue_handler(hass)

Expand Down
50 changes: 38 additions & 12 deletions homeassistant/components/airthings_ble/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
import logging
from typing import Any

from airthings_ble import AirthingsBluetoothDeviceData, AirthingsDevice
from airthings_ble import (
AirthingsBluetoothDeviceData,
AirthingsDevice,
UnsupportedDeviceError,
)
from bleak import BleakError
from habluetooth import BluetoothServiceInfoBleak
import voluptuous as vol
Expand All @@ -28,6 +32,7 @@
"b42e4a8e-ade7-11e4-89d3-123b93f75cba",
"b42e1c08-ade7-11e4-89d3-123b93f75cba",
"b42e3882-ade7-11e4-89d3-123b93f75cba",
"b42e90a2-ade7-11e4-89d3-123b93f75cba",
]


Expand All @@ -38,6 +43,7 @@ class Discovery:
name: str
discovery_info: BluetoothServiceInfo
device: AirthingsDevice
data: AirthingsBluetoothDeviceData


def get_name(device: AirthingsDevice) -> str:
Expand All @@ -63,8 +69,8 @@ def __init__(self) -> None:
self._discovered_device: Discovery | None = None
self._discovered_devices: dict[str, Discovery] = {}

async def _get_device_data(
self, discovery_info: BluetoothServiceInfo
async def _get_device(
self, data: AirthingsBluetoothDeviceData, discovery_info: BluetoothServiceInfo
) -> AirthingsDevice:
ble_device = bluetooth.async_ble_device_from_address(
self.hass, discovery_info.address
Expand All @@ -73,23 +79,24 @@ async def _get_device_data(
_LOGGER.debug("no ble_device in _get_device_data")
raise AirthingsDeviceUpdateError("No ble_device")

airthings = AirthingsBluetoothDeviceData(_LOGGER)

try:
data = await airthings.update_device(ble_device)
device = await data.update_device(ble_device)
except BleakError as err:
_LOGGER.error(
"Error connecting to and getting data from %s: %s",
discovery_info.address,
err,
)
raise AirthingsDeviceUpdateError("Failed getting device data") from err
except UnsupportedDeviceError:
_LOGGER.debug("Skipping unsupported device: %s", discovery_info.name)
raise
except Exception as err:
_LOGGER.error(
"Unknown error occurred from %s: %s", discovery_info.address, err
)
raise
return data
return device

async def async_step_bluetooth(
self, discovery_info: BluetoothServiceInfo
Expand All @@ -99,17 +106,21 @@ async def async_step_bluetooth(
await self.async_set_unique_id(discovery_info.address)
self._abort_if_unique_id_configured()

data = AirthingsBluetoothDeviceData(logger=_LOGGER)

try:
device = await self._get_device_data(discovery_info)
device = await self._get_device(data=data, discovery_info=discovery_info)
except AirthingsDeviceUpdateError:
return self.async_abort(reason="cannot_connect")
except UnsupportedDeviceError:
return self.async_abort(reason="unsupported_device")
except Exception:
_LOGGER.exception("Unknown error occurred")
return self.async_abort(reason="unknown")

name = get_name(device)
self.context["title_placeholders"] = {"name": name}
self._discovered_device = Discovery(name, discovery_info, device)
self._discovered_device = Discovery(name, discovery_info, device, data=data)

return await self.async_step_bluetooth_confirm()

Expand Down Expand Up @@ -164,24 +175,39 @@ async def async_step_user(
if MFCT_ID not in discovery_info.manufacturer_data:
continue
if not any(uuid in SERVICE_UUIDS for uuid in discovery_info.service_uuids):
_LOGGER.debug(
"Skipping unsupported device: %s (%s)", discovery_info.name, address
)
continue
devices.append(discovery_info)

for discovery_info in devices:
address = discovery_info.address
data = AirthingsBluetoothDeviceData(logger=_LOGGER)
try:
device = await self._get_device_data(discovery_info)
device = await self._get_device(data, discovery_info)
except AirthingsDeviceUpdateError:
_LOGGER.error(
"Error connecting to and getting data from %s",
"Error connecting to and getting data from %s (%s)",
discovery_info.name,
discovery_info.address,
)
continue
except UnsupportedDeviceError:
_LOGGER.debug(
"Skipping unsupported device: %s (%s)",
discovery_info.name,
discovery_info.address,
)
continue
except Exception:
_LOGGER.exception("Unknown error occurred")
return self.async_abort(reason="unknown")
name = get_name(device)
self._discovered_devices[address] = Discovery(name, discovery_info, device)
_LOGGER.debug("Discovered Airthings device: %s (%s)", name, address)
self._discovered_devices[address] = Discovery(
name, discovery_info, device, data
)

if not self._discovered_devices:
return self.async_abort(reason="no_devices_found")
Expand Down
4 changes: 4 additions & 0 deletions homeassistant/components/airthings_ble/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
{
"manufacturer_id": 820,
"service_uuid": "b42e3882-ade7-11e4-89d3-123b93f75cba"
},
{
"manufacturer_id": 820,
"service_uuid": "b42e90a2-ade7-11e4-89d3-123b93f75cba"
}
],
"codeowners": ["@vincegio", "@LaStrada"],
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/airthings_ble/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"firmware_upgrade_required": "Your device requires a firmware upgrade. Please use the Airthings app (Android/iOS) to upgrade it.",
"unsupported_device": "Unsupported device",
"unknown": "[%key:common::config_flow::error::unknown%]"
}
},
Expand Down
25 changes: 25 additions & 0 deletions homeassistant/components/altruist/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,31 @@ class AltruistSensorEntityDescription(SensorEntityDescription):
suggested_display_precision=2,
translation_placeholders={"sensor_name": "BME280"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.HUMIDITY,
key="BME680_humidity",
translation_key="humidity",
native_unit_of_measurement=PERCENTAGE,
suggested_display_precision=2,
translation_placeholders={"sensor_name": "BME680"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.PRESSURE,
key="BME680_pressure",
translation_key="pressure",
native_unit_of_measurement=UnitOfPressure.PA,
suggested_unit_of_measurement=UnitOfPressure.MMHG,
suggested_display_precision=0,
translation_placeholders={"sensor_name": "BME680"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.TEMPERATURE,
key="BME680_temperature",
translation_key="temperature",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
suggested_display_precision=2,
translation_placeholders={"sensor_name": "BME680"},
),
AltruistSensorEntityDescription(
device_class=SensorDeviceClass.PRESSURE,
key="BMP_pressure",
Expand Down
25 changes: 17 additions & 8 deletions homeassistant/components/comelit/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from asyncio.exceptions import TimeoutError
from collections.abc import Mapping
import re
from typing import Any

from aiocomelit import (
Expand All @@ -27,25 +28,20 @@
DEFAULT_HOST = "192.168.1.252"
DEFAULT_PIN = "111111"


pin_regex = r"^[0-9]{4,10}$"

USER_SCHEMA = vol.Schema(
{
vol.Required(CONF_HOST, default=DEFAULT_HOST): cv.string,
vol.Required(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_PIN, default=DEFAULT_PIN): cv.matches_regex(pin_regex),
vol.Optional(CONF_PIN, default=DEFAULT_PIN): cv.string,
vol.Required(CONF_TYPE, default=BRIDGE): vol.In(DEVICE_TYPE_LIST),
}
)
STEP_REAUTH_DATA_SCHEMA = vol.Schema(
{vol.Required(CONF_PIN): cv.matches_regex(pin_regex)}
)
STEP_REAUTH_DATA_SCHEMA = vol.Schema({vol.Required(CONF_PIN): cv.string})
STEP_RECONFIGURE = vol.Schema(
{
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PORT): cv.port,
vol.Optional(CONF_PIN, default=DEFAULT_PIN): cv.matches_regex(pin_regex),
vol.Optional(CONF_PIN, default=DEFAULT_PIN): cv.string,
}
)

Expand All @@ -55,6 +51,9 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,

api: ComelitCommonApi

if not re.fullmatch(r"[0-9]{4,10}", data[CONF_PIN]):
raise InvalidPin

session = await async_client_session(hass)
if data.get(CONF_TYPE, BRIDGE) == BRIDGE:
api = ComeliteSerialBridgeApi(
Expand Down Expand Up @@ -105,6 +104,8 @@ async def async_step_user(
errors["base"] = "cannot_connect"
except InvalidAuth:
errors["base"] = "invalid_auth"
except InvalidPin:
errors["base"] = "invalid_pin"
except Exception: # noqa: BLE001
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
Expand Down Expand Up @@ -146,6 +147,8 @@ async def async_step_reauth_confirm(
errors["base"] = "cannot_connect"
except InvalidAuth:
errors["base"] = "invalid_auth"
except InvalidPin:
errors["base"] = "invalid_pin"
except Exception: # noqa: BLE001
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
Expand Down Expand Up @@ -189,6 +192,8 @@ async def async_step_reconfigure(
errors["base"] = "cannot_connect"
except InvalidAuth:
errors["base"] = "invalid_auth"
except InvalidPin:
errors["base"] = "invalid_pin"
except Exception: # noqa: BLE001
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
Expand All @@ -210,3 +215,7 @@ class CannotConnect(HomeAssistantError):

class InvalidAuth(HomeAssistantError):
"""Error to indicate there is invalid auth."""


class InvalidPin(HomeAssistantError):
"""Error to indicate an invalid pin."""
4 changes: 2 additions & 2 deletions homeassistant/components/comelit/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def __init__(
entry: ComelitConfigEntry,
host: str,
port: int,
pin: int,
pin: str,
session: ClientSession,
) -> None:
"""Initialize the scanner."""
Expand Down Expand Up @@ -195,7 +195,7 @@ def __init__(
entry: ComelitConfigEntry,
host: str,
port: int,
pin: int,
pin: str,
session: ClientSession,
) -> None:
"""Initialize the scanner."""
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/comelit/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"iot_class": "local_polling",
"loggers": ["aiocomelit"],
"quality_scale": "platinum",
"requirements": ["aiocomelit==0.12.3"]
"requirements": ["aiocomelit==1.1.1"]
}
2 changes: 2 additions & 0 deletions homeassistant/components/comelit/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"invalid_pin": "The provided PIN is invalid. It must be a 4-10 digit number.",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"invalid_pin": "[%key:component::comelit::config::abort::invalid_pin%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
}
},
Expand Down
3 changes: 3 additions & 0 deletions homeassistant/components/ecovacs/icons.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@
}
},
"select": {
"active_map": {
"default": "mdi:floor-plan"
},
"water_amount": {
"default": "mdi:water"
},
Expand Down
Loading
Loading