diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6ba1afd --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter" + }, + "python.formatting.provider": "none" +} \ No newline at end of file diff --git a/custom_components/bluetti-bt/__init__.py b/custom_components/bluetti-bt/__init__.py new file mode 100644 index 0000000..b7aa424 --- /dev/null +++ b/custom_components/bluetti-bt/__init__.py @@ -0,0 +1,24 @@ +"""Bluetti Bluetooth Integration""" + +from __future__ import annotations + +import logging + +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_ADDRESS, Platform +from homeassistant.core import HomeAssistant + +_LOGGER = logging.getLogger(__name__) +PLATFORMS: [Platform] = [] + + +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + """Set up Bluetti Powerstation from a config entry.""" + + address = entry.data.get(CONF_ADDRESS) + + if address is None: + return False + + _LOGGER.error(f"Device address: {address}") + return True diff --git a/custom_components/bluetti-bt/config_flow.py b/custom_components/bluetti-bt/config_flow.py new file mode 100644 index 0000000..201e729 --- /dev/null +++ b/custom_components/bluetti-bt/config_flow.py @@ -0,0 +1,79 @@ +"""Bluetti Bluetooth Config Flow""" + +from __future__ import annotations + +import logging + +import voluptuous as vol + +from homeassistant import config_entries +from homeassistant.components import ( + BluetoothServiceInfoBleak, + async_discovered_service_info, +) +from homeassistant.const import CONF_ADDRESS +from homeassistant.data_entry_flow import FlowResult + +from .const import DOMAIN + +_LOGGER = logging.getLogger(__name__) + + +class BluettiConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): + """Handle config flow for Bluetti BT devices.""" + + def __init__(self) -> None: + _LOGGER.info("Initialize config flow") + self._discovery_info: BluetoothServiceInfoBleak | None = None + self._discovered_devices: dict[str, BluetoothServiceInfoBleak] = {} + + async def async_step_bluetooth( + self, discovery_info: BluetoothServiceInfoBleak + ) -> FlowResult: + """Handle bluetooth discovery.""" + await self.async_set_unique_id(discovery_info.address) + self._abort_if_unique_id_configured() + self._discovery_info = discovery_info + return await self.async_step_user() + + async def async_step_user(self, user_input: dict[str, Any] | None = None) -> FlowResult: + """Handle user input.""" + + if user_input is not None: + address = user_input[CONF_ADDRESS] + discovery_info = self._discovered_devices[address] + await self.async_set_unique_id(address, raise_on_progress=False) + self._abort_if_unique_id_configured() + return self.async_create_entry( + title=discovery_info.name, + data={ + CONF_ADDRESS: discovery_info.address, + }, + ) + + if discovery := self._discovery_info: + self._discovered_devices[discovery.address] = discovery + else: + current_addresses = self._async_current_ids() + for discovery in async_discovered_service_info(self.hass): + if address in current_addresses or address in self._discovered_devices: + continue + self._discovered_devices[discovery.address] = discovery + + if not self._discovered_devices: + return self.async_abort(reason="no_unconfigured_devices") + + data_schema = vol.Schema( + { + vol.Required(CONF_ADDRESS): vol.In( + { + service_info.address: service_info.name + for service_info in self._discovered_devices.values() + } + ), + } + ) + return self.async_show_form( + step_id="user", + data_schema=data_schema, + ) diff --git a/custom_components/bluetti-bt/const.py b/custom_components/bluetti-bt/const.py new file mode 100644 index 0000000..978dd05 --- /dev/null +++ b/custom_components/bluetti-bt/const.py @@ -0,0 +1,3 @@ +"""Constants for the Bluetti BT integration.""" + +DOMAIN = "bluetti-bt" diff --git a/custom_components/bluetti-bt/manifest.json b/custom_components/bluetti-bt/manifest.json new file mode 100644 index 0000000..2002cb1 --- /dev/null +++ b/custom_components/bluetti-bt/manifest.json @@ -0,0 +1,20 @@ +{ + "domain": "bluetti-bt", + "name": "Bluetti BT", + "codeowners": ["@Patrick762"], + "config_flow": true, + "dependencies": ["bluetooth"], + "documentation": "https://github.com/Patrick762/hassio-bluetti-bt", + "integration_type": "device", + "iot_class": "local_polling", + "issue_tracker": "https://github.com/Patrick762/hassio-bluetti-bt/issues", + "requirements": ["bluetti_mqtt==0.15.0"], + "bluetooth": [ + { "local_name": "AC200M*" }, + { "local_name": "AC300*" }, + { "local_name": "EB3A*" }, + { "local_name": "EP500*" }, + { "local_name": "EP600*" } + ], + "version": "0.0.1" +} diff --git a/hacs.json b/hacs.json new file mode 100644 index 0000000..ba6dd0c --- /dev/null +++ b/hacs.json @@ -0,0 +1,4 @@ +{ + "name": "Bluetti BT", + "render_readme": true +}