coordinator reporting results back to sensor

This commit is contained in:
Patrick762 committed 2023-07-31 14:46:23 +02:00
1 parent cf149067d8
commit e435514db5
3 files changed
+44 -6

No files matched your search

+18
View File
@@ -1,2 +1,20 @@
# hassio-bluetti-bt # hassio-bluetti-bt
[![hacs_badge](https://img.shields.io/badge/HACS-Custom-41BDF5.svg)](https://github.com/hacs/integration)
[![Validate with hassfest](https://github.com/Patrick762/hassio-bluetti-bt/actions/workflows/hassfest_validation.yml/badge.svg)](https://github.com/Patrick762/hassio-bluetti-bt/actions/workflows/hassfest_validation.yml)
[![HACS Action](https://github.com/Patrick762/hassio-bluetti-bt/actions/workflows/HACS.yml/badge.svg)](https://github.com/Patrick762/hassio-bluetti-bt/actions/workflows/HACS.yml)
Bluetti Integration for Home Assistant Bluetti Integration for Home Assistant
Based on [bluetti_mqtt](https://github.com/warhammerkid/bluetti_mqtt).
Supported devices (based on supported devices of bluetti_mqtt):
- AC60
- AC200M
- AC300
- AC500
- EB3A
- EP500
- EP500P
- EP600 (tested)
+2
View File
@@ -2,3 +2,5 @@
DOMAIN = "bluetti_bt" DOMAIN = "bluetti_bt"
MANUFACTURER = "Bluetti" MANUFACTURER = "Bluetti"
API_RESPONSE_BATTERY = "total_battery_percent"
+24 -6
View File
@@ -6,6 +6,8 @@ import asyncio
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import cast from typing import cast
import async_timeout
from bleak import BleakClient, BleakError from bleak import BleakClient, BleakError
from homeassistant.components import bluetooth from homeassistant.components import bluetooth
@@ -29,6 +31,7 @@ from bluetti_mqtt.bluetooth import (
) )
from . import device_info as dev_info, get_unique_id from . import device_info as dev_info, get_unique_id
from .const import API_RESPONSE_BATTERY
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@@ -81,16 +84,18 @@ class PollingCoordinator(DataUpdateCoordinator):
device = bluetooth.async_ble_device_from_address(self.hass, self._address) device = bluetooth.async_ble_device_from_address(self.hass, self._address)
if device is None: if device is None:
self.logger.error("Device not available") self.logger.error("Device not available")
return return None
if self.bluetti_device is None: if self.bluetti_device is None:
self.logger.error("Device type not found") self.logger.error("Device type not found")
return return None
# Polling # Polling
client = BleakClient(device) client = BleakClient(device)
parsed_data: dict = {}
try: try:
async with async_timeout.timeout(15):
await client.connect() await client.connect()
await client.start_notify( await client.start_notify(
@@ -116,13 +121,15 @@ class PollingCoordinator(DataUpdateCoordinator):
) )
# Process data # Process data
self.logger.error("Got %s bytes", len(res)) self.logger.debug("Got %s bytes", len(res))
response = cast(bytes, res) response = cast(bytes, res)
body = command.parse_response(response) body = command.parse_response(response)
parsed = self.bluetti_device.parse(command.starting_address, body) parsed = self.bluetti_device.parse(
command.starting_address, body
)
self.logger.info("Parsed data: %s", parsed) self.logger.info("Parsed data: %s", parsed)
# Pass data back to sensors parsed_data.update(parsed)
except TimeoutError: except TimeoutError:
self.logger.error("Polling timed out") self.logger.error("Polling timed out")
@@ -136,11 +143,18 @@ class PollingCoordinator(DataUpdateCoordinator):
) )
except (BadConnectionError, BleakError) as err: except (BadConnectionError, BleakError) as err:
self.logger.debug("Needed to disconnect due to error: %s", err) self.logger.debug("Needed to disconnect due to error: %s", err)
except TimeoutError:
self.logger.error("Polling timed out")
return None
except BleakError as err: except BleakError as err:
self.logger.error("Bleak error: %s", err) self.logger.error("Bleak error: %s", err)
return None
finally: finally:
await client.disconnect() await client.disconnect()
# Pass data back to sensors
return parsed_data
def _notification_handler(self, _sender: int, data: bytearray): def _notification_handler(self, _sender: int, data: bytearray):
"""Handle bt data.""" """Handle bt data."""
@@ -179,7 +193,7 @@ class Battery(CoordinatorEntity, SensorEntity):
self._attr_device_info = device_info self._attr_device_info = device_info
self._attr_name = f"{device_info.get('name')} Battery level" self._attr_name = f"{device_info.get('name')} Battery level"
self._attr_unique_id = get_unique_id(f"{device_info.get('name')} Battery level") self._attr_unique_id = get_unique_id(f"{device_info.get('name')} Battery level")
self._attr_unit_of_measurement = "%" self._attr_native_unit_of_measurement = "%"
self._attr_device_class = "battery" self._attr_device_class = "battery"
self._address = address self._address = address
@@ -193,4 +207,8 @@ class Battery(CoordinatorEntity, SensorEntity):
def _handle_coordinator_update(self) -> None: def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator.""" """Handle updated data from the coordinator."""
_LOGGER.debug("Updating state of %s", self._attr_unique_id) _LOGGER.debug("Updating state of %s", self._attr_unique_id)
if not isinstance(self.coordinator.data, dict):
_LOGGER.error("Invalid data from coordinator")
return
self._attr_native_value = self.coordinator.data[API_RESPONSE_BATTERY]
self.async_write_ha_state() self.async_write_ha_state()