forked from home-assistant/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add eq3btsmart integration (home-assistant#109291)
Co-authored-by: Sid <[email protected]> Co-authored-by: J. Nick Koston <[email protected]>
- Loading branch information
1 parent
4adbf7c
commit 282cbfc
Showing
23 changed files
with
965 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"domain": "eq3", | ||
"name": "eQ-3", | ||
"integrations": ["maxcube"] | ||
"integrations": ["maxcube", "eq3btsmart"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
"""Support for EQ3 devices.""" | ||
|
||
import asyncio | ||
import logging | ||
from typing import TYPE_CHECKING | ||
|
||
from eq3btsmart import Thermostat | ||
from eq3btsmart.exceptions import Eq3Exception | ||
from eq3btsmart.thermostat_config import ThermostatConfig | ||
|
||
from homeassistant.components import bluetooth | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.const import Platform | ||
from homeassistant.core import HomeAssistant | ||
from homeassistant.exceptions import ConfigEntryNotReady | ||
from homeassistant.helpers.dispatcher import async_dispatcher_send | ||
|
||
from .const import DOMAIN, SIGNAL_THERMOSTAT_CONNECTED, SIGNAL_THERMOSTAT_DISCONNECTED | ||
from .models import Eq3Config, Eq3ConfigEntryData | ||
|
||
PLATFORMS = [ | ||
Platform.CLIMATE, | ||
] | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: | ||
"""Handle config entry setup.""" | ||
|
||
mac_address: str | None = entry.unique_id | ||
|
||
if TYPE_CHECKING: | ||
assert mac_address is not None | ||
|
||
eq3_config = Eq3Config( | ||
mac_address=mac_address, | ||
) | ||
|
||
device = bluetooth.async_ble_device_from_address( | ||
hass, mac_address.upper(), connectable=True | ||
) | ||
|
||
if device is None: | ||
raise ConfigEntryNotReady( | ||
f"[{eq3_config.mac_address}] Device could not be found" | ||
) | ||
|
||
thermostat = Thermostat( | ||
thermostat_config=ThermostatConfig( | ||
mac_address=mac_address, | ||
), | ||
ble_device=device, | ||
) | ||
|
||
eq3_config_entry = Eq3ConfigEntryData(eq3_config=eq3_config, thermostat=thermostat) | ||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = eq3_config_entry | ||
|
||
entry.async_on_unload(entry.add_update_listener(update_listener)) | ||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) | ||
|
||
entry.async_create_background_task( | ||
hass, _async_run_thermostat(hass, entry), entry.entry_id | ||
) | ||
|
||
return True | ||
|
||
|
||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: | ||
"""Handle config entry unload.""" | ||
|
||
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): | ||
eq3_config_entry: Eq3ConfigEntryData = hass.data[DOMAIN].pop(entry.entry_id) | ||
await eq3_config_entry.thermostat.async_disconnect() | ||
|
||
return unload_ok | ||
|
||
|
||
async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: | ||
"""Handle config entry update.""" | ||
|
||
await hass.config_entries.async_reload(entry.entry_id) | ||
|
||
|
||
async def _async_run_thermostat(hass: HomeAssistant, entry: ConfigEntry) -> None: | ||
"""Run the thermostat.""" | ||
|
||
eq3_config_entry: Eq3ConfigEntryData = hass.data[DOMAIN][entry.entry_id] | ||
thermostat = eq3_config_entry.thermostat | ||
mac_address = eq3_config_entry.eq3_config.mac_address | ||
scan_interval = eq3_config_entry.eq3_config.scan_interval | ||
|
||
await _async_reconnect_thermostat(hass, entry) | ||
|
||
while True: | ||
try: | ||
await thermostat.async_get_status() | ||
except Eq3Exception as e: | ||
if not thermostat.is_connected: | ||
_LOGGER.error( | ||
"[%s] eQ-3 device disconnected", | ||
mac_address, | ||
) | ||
async_dispatcher_send( | ||
hass, | ||
f"{SIGNAL_THERMOSTAT_DISCONNECTED}_{mac_address}", | ||
) | ||
await _async_reconnect_thermostat(hass, entry) | ||
continue | ||
|
||
_LOGGER.error( | ||
"[%s] Error updating eQ-3 device: %s", | ||
mac_address, | ||
e, | ||
) | ||
|
||
await asyncio.sleep(scan_interval) | ||
|
||
|
||
async def _async_reconnect_thermostat(hass: HomeAssistant, entry: ConfigEntry) -> None: | ||
"""Reconnect the thermostat.""" | ||
|
||
eq3_config_entry: Eq3ConfigEntryData = hass.data[DOMAIN][entry.entry_id] | ||
thermostat = eq3_config_entry.thermostat | ||
mac_address = eq3_config_entry.eq3_config.mac_address | ||
scan_interval = eq3_config_entry.eq3_config.scan_interval | ||
|
||
while True: | ||
try: | ||
await thermostat.async_connect() | ||
except Eq3Exception: | ||
await asyncio.sleep(scan_interval) | ||
continue | ||
|
||
_LOGGER.debug( | ||
"[%s] eQ-3 device connected", | ||
mac_address, | ||
) | ||
|
||
async_dispatcher_send( | ||
hass, | ||
f"{SIGNAL_THERMOSTAT_CONNECTED}_{mac_address}", | ||
) | ||
|
||
return |
Oops, something went wrong.