Skip to content

Commit

Permalink
version core-2022.8.0, Solved issue #6
Browse files Browse the repository at this point in the history
New version working with version core-2022.8.0 and greatest,  Solved issue #6
  • Loading branch information
dave-code-ruiz committed Oct 4, 2022
1 parent 50b7dc6 commit da501df
Show file tree
Hide file tree
Showing 5 changed files with 341 additions and 79 deletions.
28 changes: 22 additions & 6 deletions custom_components/elkbledom/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from __future__ import annotations

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.const import CONF_MAC
from homeassistant.core import HomeAssistant, Event
from homeassistant.const import CONF_MAC, EVENT_HOMEASSISTANT_STOP

from .const import DOMAIN
from .elkbledom import BLEDOMInstance
Expand All @@ -11,15 +11,31 @@

async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up ElkBLEDOM from a config entry."""
instance = BLEDOMInstance(entry.data[CONF_MAC])
instance = BLEDOMInstance(entry.data[CONF_MAC], hass)
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = instance
hass.config_entries.async_setup_platforms(entry, PLATFORMS)

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
entry.async_on_unload(entry.add_update_listener(_async_update_listener))

async def _async_stop(event: Event) -> None:
"""Close the connection."""
await instance.stop()

entry.async_on_unload(
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _async_stop)
)
return True

async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
instance = hass.data[DOMAIN].pop(entry.entry_id)
await instance.disconnect()
return unload_ok
await instance.stop()
return unload_ok

async def _async_update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Handle options update."""
instance = hass.data[DOMAIN].pop(entry.entry_id)
if entry.title != instance.name:
await hass.config_entries.async_reload(entry.entry_id)
119 changes: 100 additions & 19 deletions custom_components/elkbledom/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import asyncio
from .elkbledom import discover, BLEDOMInstance
from .elkbledom import BLEDOMInstance
from typing import Any

from homeassistant import config_entries
from homeassistant.const import CONF_MAC
import voluptuous as vol
from homeassistant.helpers.device_registry import format_mac
from homeassistant.data_entry_flow import FlowResult
from homeassistant.components.bluetooth import (
BluetoothServiceInfoBleak,
async_discovered_service_info,
)
from bluetooth_sensor_state_data import BluetoothData
from home_assistant_bluetooth import BluetoothServiceInfo

from .const import DOMAIN
import logging

Expand All @@ -14,39 +22,112 @@

MANUAL_MAC = "manual"

class DeviceData(BluetoothData):
def __init__(self, discovery_info) -> None:
self._discovery = discovery_info

def supported(self):
return self._discovery.name.lower().startswith("elk-bledom")

def address(self):
return self._discovery.address

def get_device_name(self):
return self._discovery.name

def name(self):
return self._discovery.name

def rssi(self):
return self._discovery.rssi

def _start_update(self, service_info: BluetoothServiceInfo) -> None:
"""Update from BLE advertisement data."""
LOGGER.debug("Parsing Govee BLE advertisement data: %s", service_info)

class BLEDOMFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL

def __init__(self) -> None:
self.mac = None
self._device = None
self._instance = None
self.name = None
self._discovery_info: BluetoothServiceInfoBleak | None = None
self._discovered_device: DeviceData | None = None
self._discovered_devices = []

async def async_step_bluetooth(
self, discovery_info: BluetoothServiceInfoBleak
) -> FlowResult:
"""Handle the bluetooth discovery step."""
LOGGER.debug("Discovered bluetooth devices, step bluetooth, : %s", discovery_info)
await self.async_set_unique_id(discovery_info.address)
self._abort_if_unique_id_configured()
device = DeviceData(discovery_info)
if not device.supported():
return self.async_abort(reason="not_supported")
self._discovery_info = discovery_info
self._discovered_device = device
return await self.async_step_bluetooth_confirm()

async def async_step_user(self, user_input=None):
"""Handle the initial step."""
async def async_step_bluetooth_confirm(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Confirm discovery."""
LOGGER.debug("Discovered bluetooth devices, step bluetooth confirm, : %s", user_input)
assert self._discovered_device is not None
device = self._discovered_device
assert self._discovery_info is not None
discovery_info = self._discovery_info
title = device.title or device.get_device_name() or discovery_info.name
if user_input is not None:
if user_input["mac"] == MANUAL_MAC:
return self.async_create_entry(title=self.name, data={CONF_MAC: self.mac, "name": self.name})

self._set_confirm_only()
placeholders = {"name": title}
self.context["title_placeholders"] = placeholders
return await self.async_step_user()

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle the user step to pick discovered device."""
if user_input is not None:
if user_input[CONF_MAC] == MANUAL_MAC:
return await self.async_step_manual()

self.mac = user_input["mac"]
self.mac = user_input[CONF_MAC]
self.name = user_input["name"]
await self.async_set_unique_id(format_mac(self.mac))
await self.async_set_unique_id(self.mac, raise_on_progress=False)
self._abort_if_unique_id_configured()
return await self.async_step_validate()

already_configured = self._async_current_ids(False)
devices = await discover()
devices = [device for device in devices if format_mac(device.address) not in already_configured]

if not devices:
return await self.async_step_manual()
current_addresses = self._async_current_ids()
for discovery_info in async_discovered_service_info(self.hass):
self.mac = discovery_info.address
if self.mac in current_addresses:
LOGGER.debug("Device %s in current_addresses", (self.mac))
continue
if (device for device in self._discovered_devices if device.address == self.mac) == ([]):
LOGGER.debug("Device %s in discovered_devices", (device))
continue
device = DeviceData(discovery_info)
if device.supported():
self._discovered_devices.append(device)

if not self._discovered_devices:
return await self.async_step_manual()

LOGGER.debug("Discovered supported devices: %s - %s", self._discovered_devices[0].name(), self._discovered_devices[0].address())

return self.async_show_form(
step_id="user", data_schema=vol.Schema(
{
vol.Required("mac"): vol.In(
vol.Required(CONF_MAC): vol.In(
{
**{device.address: device.name for device in devices},
##TODO: Show all supported devices
self._discovered_devices[0].address(): self._discovered_devices[0].name(),
MANUAL_MAC: "Manually add a MAC address",
}
),
Expand Down Expand Up @@ -84,22 +165,22 @@ async def async_step_validate(self, user_input: "dict[str, Any] | None" = None):

async def async_step_manual(self, user_input: "dict[str, Any] | None" = None):
if user_input is not None:
self.mac = user_input["mac"]
self.mac = user_input[CONF_MAC]
self.name = user_input["name"]
await self.async_set_unique_id(format_mac(self.mac))
return await self.async_step_validate()

return self.async_show_form(
step_id="manual", data_schema=vol.Schema(
{
vol.Required("mac"): str,
vol.Required(CONF_MAC): str,
vol.Required("name"): str
}
), errors={})

async def toggle_light(self):
if not self._instance:
self._instance = BLEDOMInstance(self.mac)
self._instance = BLEDOMInstance(self.mac, self.hass)
try:
await self._instance.update()
if self._instance.is_on:
Expand All @@ -115,4 +196,4 @@ async def toggle_light(self):
except (Exception) as error:
return error
finally:
await self._instance.disconnect()
await self._instance.stop()
Loading

0 comments on commit da501df

Please sign in to comment.