diff --git a/homeassistant/components/esphome/__init__.py b/homeassistant/components/esphome/__init__.py index acbcc0f57dc..894928e597a 100644 --- a/homeassistant/components/esphome/__init__.py +++ b/homeassistant/components/esphome/__init__.py @@ -24,6 +24,7 @@ from aioesphomeapi import ( UserService, UserServiceArgType, ) +from awesomeversion import AwesomeVersion import voluptuous as vol from homeassistant import const @@ -46,6 +47,11 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import DeviceInfo, Entity, EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import async_track_state_change_event +from homeassistant.helpers.issue_registry import ( + IssueSeverity, + async_create_issue, + async_delete_issue, +) from homeassistant.helpers.service import async_set_service_schema from homeassistant.helpers.template import Template @@ -59,6 +65,37 @@ CONF_NOISE_PSK = "noise_psk" _LOGGER = logging.getLogger(__name__) _R = TypeVar("_R") +STABLE_BLE_VERSION_STR = "2022.11.0" +STABLE_BLE_VERSION = AwesomeVersion(STABLE_BLE_VERSION_STR) + + +@callback +def _async_check_firmware_version( + hass: HomeAssistant, device_info: EsphomeDeviceInfo +) -> None: + """Create or delete an the ble_firmware_outdated issue.""" + # ESPHome device_info.name is the unique_id + issue = f"ble_firmware_outdated-{device_info.name}" + if ( + not device_info.bluetooth_proxy_version + # If the device has a project name its up to that project + # to tell them about the firmware version update so we don't notify here + or device_info.project_name + or AwesomeVersion(device_info.esphome_version) >= STABLE_BLE_VERSION + ): + async_delete_issue(hass, DOMAIN, issue) + return + async_create_issue( + hass, + DOMAIN, + issue, + is_fixable=False, + severity=IssueSeverity.WARNING, + learn_more_url=f"https://esphome.io/changelog/{STABLE_BLE_VERSION_STR}.html", + translation_key="ble_firmware_outdated", + translation_placeholders={"name": device_info.name}, + ) + async def async_setup_entry( # noqa: C901 hass: HomeAssistant, entry: ConfigEntry @@ -215,7 +252,8 @@ async def async_setup_entry( # noqa: C901 """Subscribe to states and list entities on successful API login.""" nonlocal device_id try: - entry_data.device_info = await cli.device_info() + device_info = await cli.device_info() + entry_data.device_info = device_info assert cli.api_version is not None entry_data.api_version = cli.api_version entry_data.available = True @@ -243,6 +281,8 @@ async def async_setup_entry( # noqa: C901 _LOGGER.warning("Error getting initial data for %s: %s", host, err) # Re-connection logic will trigger after this await cli.disconnect() + else: + _async_check_firmware_version(hass, device_info) async def on_disconnect() -> None: """Run disconnect callbacks on API disconnect.""" diff --git a/homeassistant/components/esphome/strings.json b/homeassistant/components/esphome/strings.json index b1b1ba94e3f..0ec4d93b405 100644 --- a/homeassistant/components/esphome/strings.json +++ b/homeassistant/components/esphome/strings.json @@ -43,5 +43,11 @@ } }, "flow_title": "{name}" + }, + "issues": { + "ble_firmware_outdated": { + "title": "Update {name} with ESPHome 2022.11.0 or later", + "description": "To improve Bluetooth reliability and performance, we highly recommend updating {name} with ESPHome 2022.11.0 or later." + } } } diff --git a/homeassistant/components/esphome/translations/en.json b/homeassistant/components/esphome/translations/en.json index b0b502631df..173113f64cd 100644 --- a/homeassistant/components/esphome/translations/en.json +++ b/homeassistant/components/esphome/translations/en.json @@ -43,5 +43,11 @@ "description": "Please enter connection settings of your [ESPHome]({esphome_url}) node." } } + }, + "issues": { + "ble_firmware_outdated": { + "description": "To improve Bluetooth reliability and performance, we highly recommend updating {name} with ESPHome 2022.11.0 or later.", + "title": "Update {name} with ESPHome 2022.11.0 or later" + } } } \ No newline at end of file