diff --git a/custom_components/ember_mug/__init__.py b/custom_components/ember_mug/__init__.py index 5338ba1..90985a2 100644 --- a/custom_components/ember_mug/__init__.py +++ b/custom_components/ember_mug/__init__.py @@ -34,7 +34,11 @@ def __init__(self, hass: HomeAssistant, config: ConfigEntry) -> None: ) self.mac_address = config.data[CONF_MAC] self.name = config.data.get(CONF_NAME, f"Ember Mug {self.mac_address}") - self.unit_of_measurement = config.data.get(CONF_TEMPERATURE_UNIT, TEMP_CELSIUS) + self.unit_of_measurement = ( + TEMP_FAHRENHEIT + if "F" in config.data.get(CONF_TEMPERATURE_UNIT) + else TEMP_CELSIUS + ) self.mug = EmberMug( self.mac_address, self.unit_of_measurement != TEMP_FAHRENHEIT @@ -48,7 +52,7 @@ def __init__(self, hass: HomeAssistant, config: ConfigEntry) -> None: "serial_number": None, "mug_id": None, "last_read_time": None, - "firmware_info": None, + "firmware_info": {}, "model": "Ember Mug", "mug_name": self.name, } @@ -98,7 +102,7 @@ def device_info(self) -> DeviceInfo: identifiers={(DOMAIN, unique_id)}, name=self.data["mug_name"], model=self.data["model"], - sw_version=self.data["firmware_info"], + sw_version=self.data["firmware_info"].get("version"), manufacturer="Ember", ) diff --git a/custom_components/ember_mug/const.py b/custom_components/ember_mug/const.py index 5f3866c..8ca485a 100644 --- a/custom_components/ember_mug/const.py +++ b/custom_components/ember_mug/const.py @@ -102,7 +102,7 @@ # To gather bytes from mug for stats (Notify) UUID_STATISTICS = UUID("fc540013-236c-4c94-8fa9-944a3e5353fa") -# RGBA Coloud of LED (Read/Write) +# RGBA Colour of LED (Read/Write) UUID_LED = UUID("fc540014-236c-4c94-8fa9-944a3e5353fa") # Date/Time (Read/Write) diff --git a/custom_components/ember_mug/mug.py b/custom_components/ember_mug/mug.py index cfa2143..c4c6833 100644 --- a/custom_components/ember_mug/mug.py +++ b/custom_components/ember_mug/mug.py @@ -48,12 +48,12 @@ def decode_byte_string(data: bytes | bytearray) -> str: return re.sub("(\\r|\\n)", "", base64.encodebytes(data + b"===").decode("utf8")) -def bytes_to_little_int(data: bytearray) -> int: +def bytes_to_little_int(data: bytearray | bytes) -> int: """Convert bytes to little int.""" return int.from_bytes(data, byteorder="little", signed=False) -def bytes_to_big_int(data: bytearray) -> int: +def bytes_to_big_int(data: bytearray | bytes) -> int: """Convert bytes to big int.""" return int.from_bytes(data, "big") @@ -146,8 +146,9 @@ async def set_led_colour(self, colour: tuple[int, int, int, int]) -> None: """Set new target temp for mug.""" _LOGGER.debug(f"Set led colour to {colour}") colour = bytearray(colour) # To RGBA bytearray - await self.client.pair() - await self.client.write_gatt_char(UUID_LED, colour, False) + with contextlib.suppress(BleakError): + await self.client.pair() + await self.client.write_gatt_char(UUID_LED, colour, True) async def update_target_temp(self) -> None: """Get target temp form mug gatt.""" @@ -162,7 +163,7 @@ async def set_target_temp(self, target_temp: float) -> None: _LOGGER.debug(f"Set target temp to {target_temp}") target = bytearray(int(target_temp / 0.01).to_bytes(2, "little")) await self.client.pair() - await self.client.write_gatt_char(UUID_TARGET_TEMPERATURE, target, False) + await self.client.write_gatt_char(UUID_TARGET_TEMPERATURE, target, True) async def update_current_temp(self) -> None: """Get current temp from mug gatt.""" @@ -208,6 +209,7 @@ async def update_dsk(self) -> None: async def update_temperature_unit(self) -> None: """Get mug temp unit.""" unit_bytes = await self.client.read_gatt_char(UUID_TEMPERATURE_UNIT) + _LOGGER.debug(f"Temperature unit from mug: {unit_bytes}") self.temperature_unit = ( TEMP_CELSIUS if bytes_to_little_int(unit_bytes) == 0 else TEMP_FAHRENHEIT ) @@ -217,7 +219,7 @@ async def update_battery_voltage(self) -> None: battery_voltage_bytes = await self.client.read_gatt_char( UUID_CONTROL_REGISTER_DATA ) - self.battery_voltage = str(battery_voltage_bytes) + self.battery_voltage = bytes_to_big_int(battery_voltage_bytes[:1]) async def update_date_time_zone(self) -> None: """Get date and time zone.""" @@ -227,10 +229,12 @@ async def update_date_time_zone(self) -> None: async def update_firmware_info(self) -> None: """Get firmware info.""" - # string getIntValue(18, 0) -> Firmware version - # string getIntValue(18, 2) -> Hardware - # string getIntValue(18, 4) -> Bootloader - self.firmware_info = str(await self.client.read_gatt_char(UUID_OTA)) + info = await self.client.read_gatt_char(UUID_OTA) + self.firmware_info = { + "version": bytes_to_little_int(info[:2]), + "hardware": bytes_to_little_int(info[2:4]), + "bootloader": bytes_to_little_int(info[4:]), + } async def connect(self) -> bool: """Try 10 times to connect and if we fail wait five minutes and try again. If connected also subscribe to state notifications.""" @@ -238,7 +242,8 @@ async def connect(self) -> bool: for i in range(1, 10 + 1): try: await self.client.connect() - await self.client.pair() + with contextlib.suppress(BleakError): + await self.client.pair() connected = True _LOGGER.info(f"Connected to {self.mac_address}") break diff --git a/custom_components/ember_mug/sensor.py b/custom_components/ember_mug/sensor.py index 50f4997..522ade5 100644 --- a/custom_components/ember_mug/sensor.py +++ b/custom_components/ember_mug/sensor.py @@ -3,30 +3,25 @@ from homeassistant.components.motion_blinds.sensor import ATTR_BATTERY_VOLTAGE from homeassistant.components.sensor import ( - PLATFORM_SCHEMA, SensorDeviceClass, SensorEntity, SensorStateClass, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( - CONF_MAC, - CONF_NAME, CONF_TEMPERATURE_UNIT, PERCENTAGE, TEMP_CELSIUS, TEMP_FAHRENHEIT, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers import config_validation as cv, entity_platform +from homeassistant.helpers import entity_platform from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -import voluptuous as vol from . import MugDataUpdateCoordinator from .const import ( DOMAIN, - MAC_ADDRESS_REGEX, SERVICE_SET_LED_COLOUR, SERVICE_SET_MUG_NAME, SERVICE_SET_TARGET_TEMP, @@ -40,15 +35,6 @@ set_target_temp, ) -# Schema -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( - { - vol.Required(CONF_MAC): cv.matches_regex(MAC_ADDRESS_REGEX), - vol.Optional(CONF_NAME): cv.string, - vol.Optional(CONF_TEMPERATURE_UNIT): cv.temperature_unit, - } -) - class EmberMugSensorBase(CoordinatorEntity): """Base Mug Sensor.""" diff --git a/custom_components/ember_mug/strings.json b/custom_components/ember_mug/strings.json index 8f82115..3e716fe 100644 --- a/custom_components/ember_mug/strings.json +++ b/custom_components/ember_mug/strings.json @@ -5,8 +5,8 @@ "user": { "title": "Add an Ember Mug", "data": { - "mug": "Mug", - "name": "Nickname (Optional)", + "mug": "Mug (MAC Address)", + "name": "Name", "temperature_unit": "Temperature Unit" } } @@ -18,7 +18,7 @@ }, "abort": { "unknown": "Unknown error occurred", - "not_found": "No Mugs were found. Please ensure they are in pairing mode and retry." + "not_found": "No Mugs were found. Please ensure it has been reset and is in pairing mode." } } } diff --git a/custom_components/ember_mug/translations/en.json b/custom_components/ember_mug/translations/en.json new file mode 100644 index 0000000..3e716fe --- /dev/null +++ b/custom_components/ember_mug/translations/en.json @@ -0,0 +1,24 @@ +{ + "title": "Ember Mug", + "config": { + "step": { + "user": { + "title": "Add an Ember Mug", + "data": { + "mug": "Mug (MAC Address)", + "name": "Name", + "temperature_unit": "Temperature Unit" + } + } + }, + "error": { + "invalid_mac": "MAC Address is invalid", + "connection_failed": "Failed to connect to the Mug", + "cannot_connect": "Unable to connect to the Mug" + }, + "abort": { + "unknown": "Unknown error occurred", + "not_found": "No Mugs were found. Please ensure it has been reset and is in pairing mode." + } + } +} diff --git a/custom_components/ember_mug/translations/fr.json b/custom_components/ember_mug/translations/fr.json new file mode 100644 index 0000000..384ef20 --- /dev/null +++ b/custom_components/ember_mug/translations/fr.json @@ -0,0 +1,24 @@ +{ + "title": "Tasse Ember", + "config": { + "step": { + "user": { + "title": "Ajouter une tasse Ember", + "data": { + "mug": "Tasse (adresse MAC)", + "name": "Nom", + "temperature_unit": "Unité de température" + } + } + }, + "error": { + "invalid_mac": "Adresse MAC invalide", + "connection_failed": "Un erreur est survenue lors du tentative de connexion à la tasse.", + "cannot_connect": "Impossible de se connecter à la tasse" + }, + "abort": { + "unknown": "Un erreur inconue est survenue", + "not_found": "Aucune tasse a été trouvé. Veuillez assurer qu'il à été réinitialisé et est en mode jumelage." + } + } +}