From e2ac4cf8f5351731c3b9360a76a1d7a4f4d759c6 Mon Sep 17 00:00:00 2001 From: Patrick762 Date: Thu, 12 Jun 2025 12:01:54 +0200 Subject: [PATCH] added option to enable encryption --- custom_components/bluetti_bt/__init__.py | 4 +++- .../bluetti_bt/bluetti_bt_lib/bluetooth/device_reader.py | 2 ++ custom_components/bluetti_bt/config_flow.py | 7 +++++++ custom_components/bluetti_bt/const.py | 1 + custom_components/bluetti_bt/coordinator.py | 2 ++ custom_components/bluetti_bt/translations/de.json | 3 ++- custom_components/bluetti_bt/translations/en.json | 3 ++- deploy.sh | 1 + 8 files changed, 20 insertions(+), 3 deletions(-) diff --git a/custom_components/bluetti_bt/__init__.py b/custom_components/bluetti_bt/__init__.py index 16fb215..2496e4b 100644 --- a/custom_components/bluetti_bt/__init__.py +++ b/custom_components/bluetti_bt/__init__.py @@ -14,6 +14,7 @@ from homeassistant.helpers.entity import DeviceInfo from homeassistant.exceptions import ConfigEntryNotReady from .const import ( + CONF_ENCRYPTION, CONF_MAX_RETRIES, CONF_PERSISTENT_CONN, CONF_POLLING_INTERVAL, @@ -42,6 +43,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: persistent_conn = entry.data.get(CONF_PERSISTENT_CONN, False) polling_timeout = entry.data.get(CONF_POLLING_TIMEOUT, 120) max_retries = entry.data.get(CONF_MAX_RETRIES, 5) + use_encryption = entry.data.get(CONF_ENCRYPTION, False) if address is None: return False @@ -56,7 +58,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: # Create coordinator for polling _LOGGER.debug("Creating coordinator") - coordinator = PollingCoordinator(hass, address, device_name, polling_interval, persistent_conn, polling_timeout, max_retries) + coordinator = PollingCoordinator(hass, address, device_name, polling_interval, persistent_conn, polling_timeout, max_retries, use_encryption) await coordinator.async_config_entry_first_refresh() hass.data[DOMAIN][entry.entry_id].setdefault(DATA_COORDINATOR, coordinator) diff --git a/custom_components/bluetti_bt/bluetti_bt_lib/bluetooth/device_reader.py b/custom_components/bluetti_bt/bluetti_bt_lib/bluetooth/device_reader.py index 92b6162..3d333ab 100644 --- a/custom_components/bluetti_bt/bluetti_bt_lib/bluetooth/device_reader.py +++ b/custom_components/bluetti_bt/bluetti_bt_lib/bluetooth/device_reader.py @@ -23,6 +23,7 @@ class DeviceReader: persistent_conn: bool = False, polling_timeout: int = 45, max_retries: int = 5, + encrypted: bool = False, ) -> None: self.client = bleak_client self.bluetti_device = bluetti_device @@ -30,6 +31,7 @@ class DeviceReader: self.persistent_conn = persistent_conn self.polling_timeout = polling_timeout self.max_retries = max_retries + self.encrypted = encrypted self.has_notifier = False self.notify_future: asyncio.Future[Any] | None = None diff --git a/custom_components/bluetti_bt/config_flow.py b/custom_components/bluetti_bt/config_flow.py index a8f8a26..a2267d5 100644 --- a/custom_components/bluetti_bt/config_flow.py +++ b/custom_components/bluetti_bt/config_flow.py @@ -22,6 +22,7 @@ from .bluetti_bt_lib.utils.device_builder import get_type_by_bt_name from .bluetti_bt_lib.bluetooth.device_recognizer import recognize_device from .const import ( + CONF_ENCRYPTION, CONF_MAX_RETRIES, CONF_PERSISTENT_CONN, CONF_POLLING_INTERVAL, @@ -160,6 +161,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow): CONF_POLLING_INTERVAL: user_input[CONF_POLLING_INTERVAL], CONF_POLLING_TIMEOUT: user_input[CONF_POLLING_TIMEOUT], CONF_MAX_RETRIES: user_input[CONF_MAX_RETRIES], + CONF_ENCRYPTION: user_input[CONF_ENCRYPTION], }, }, ) @@ -171,6 +173,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow): CONF_POLLING_INTERVAL: user_input[CONF_POLLING_INTERVAL], CONF_POLLING_TIMEOUT: user_input[CONF_POLLING_TIMEOUT], CONF_MAX_RETRIES: user_input[CONF_MAX_RETRIES], + CONF_ENCRYPTION: user_input[CONF_ENCRYPTION], }, ) @@ -198,6 +201,10 @@ class OptionsFlowHandler(config_entries.OptionsFlow): CONF_MAX_RETRIES, default=self.config_entry.data.get(CONF_MAX_RETRIES, 5), ): int, + vol.Required( + CONF_ENCRYPTION, + default=self.config_entry.data.get(CONF_ENCRYPTION, False), + ): selector.BooleanSelector(), } ), ) diff --git a/custom_components/bluetti_bt/const.py b/custom_components/bluetti_bt/const.py index aedc0d8..57d8eb2 100644 --- a/custom_components/bluetti_bt/const.py +++ b/custom_components/bluetti_bt/const.py @@ -9,6 +9,7 @@ CONF_PERSISTENT_CONN = "persistent_conn" CONF_POLLING_INTERVAL = "polling_interval" CONF_POLLING_TIMEOUT = "polling_timeout" CONF_MAX_RETRIES = "max_retries" +CONF_ENCRYPTION = "use_encryption" DATA_COORDINATOR = "coordinator" DATA_POLLING_RUNNING = "polling_running" diff --git a/custom_components/bluetti_bt/coordinator.py b/custom_components/bluetti_bt/coordinator.py index de8bd40..4f6d158 100644 --- a/custom_components/bluetti_bt/coordinator.py +++ b/custom_components/bluetti_bt/coordinator.py @@ -33,6 +33,7 @@ class PollingCoordinator(DataUpdateCoordinator): persistent_conn: bool, polling_timeout: int, max_retries: int, + encrypted: bool, ): """Initialize coordinator.""" super().__init__( @@ -60,6 +61,7 @@ class PollingCoordinator(DataUpdateCoordinator): persistent_conn=persistent_conn, polling_timeout=polling_timeout, max_retries=max_retries, + encrypted=encrypted, ) async def _async_update_data(self): diff --git a/custom_components/bluetti_bt/translations/de.json b/custom_components/bluetti_bt/translations/de.json index 9451cab..e03dcec 100644 --- a/custom_components/bluetti_bt/translations/de.json +++ b/custom_components/bluetti_bt/translations/de.json @@ -17,7 +17,8 @@ "persistent_conn": "Dauerhafte Verbindung (Neustart erforderlich)", "polling_interval": "Datenabruf-Intervall in Sekunden (Neustart erforderlich)", "polling_timeout": "Datenabruf-Timeout in Sekunden (Neustart erforderlich)", - "max_retries": "Maximale Verbindungsversuche (Neustart erforderlich)" + "max_retries": "Maximale Verbindungsversuche (Neustart erforderlich)", + "use_encryption": "Verschlüsselte Verbindung (erforderlich für neue Firmware-Versionen)" } } }, diff --git a/custom_components/bluetti_bt/translations/en.json b/custom_components/bluetti_bt/translations/en.json index c5b4610..93c4008 100644 --- a/custom_components/bluetti_bt/translations/en.json +++ b/custom_components/bluetti_bt/translations/en.json @@ -17,7 +17,8 @@ "persistent_conn": "Persistent connection (restart required)", "polling_interval": "Polling interval in seconds (restart required)", "polling_timeout": "Polling timeout in seconds (restart required)", - "max_retries": "Maximum amount of connection retries (restart required)" + "max_retries": "Maximum amount of connection retries (restart required)", + "use_encryption": "Encrypted connection (necessary for latest firmware versions)" } } }, diff --git a/deploy.sh b/deploy.sh index f9a37e3..9849af2 100755 --- a/deploy.sh +++ b/deploy.sh @@ -2,6 +2,7 @@ # This script is only for development purposes +sudo rm -rf /var/ha_config/custom_components/*/__pycache__ sudo cp -r ./custom_components/* /var/ha_config/custom_components/ docker restart homeassistant docker logs -f homeassistant