diff --git a/custom_components/georide/__init__.py b/custom_components/georide/__init__.py index 9c09610..77cac20 100644 --- a/custom_components/georide/__init__.py +++ b/custom_components/georide/__init__.py @@ -44,11 +44,8 @@ from .const import ( SIREN_ACTIVATION_DELAY ) - - _LOGGER = logging.getLogger(__name__) - CONFIG_SCHEMA = vol.Schema( { vol.Required(DOMAIN, default={}): { @@ -59,7 +56,6 @@ CONFIG_SCHEMA = vol.Schema( extra=vol.ALLOW_EXTRA, ) - async def async_setup(hass, config): """Setup GeoRide component.""" hass.data[DOMAIN] = {"config": config[DOMAIN], "devices": {}, "unsub": None} @@ -76,7 +72,6 @@ async def async_setup(hass, config): # Return boolean to indicate that initialization was successful. return True - async def async_setup_entry(hass, entry): """Set up GeoRide entry.""" config = hass.data[DOMAIN]["config"] @@ -120,10 +115,13 @@ async def async_unload_entry(hass, entry): await hass.config_entries.async_forward_entry_unload(entry, "binary_sensor") await hass.config_entries.async_forward_entry_unload(entry, "siren") - context = hass.data[DOMAIN]["context"] - context.socket.disconnect() + context.socket.disconnect() # Disconnect only if all devices is disabled + + return True +async def async_remove_config_entry_device(hass, config_entry, device_entry) -> bool: + """Remove an GeoRide device entry.""" return True @@ -308,7 +306,7 @@ class GeoRideContext: "tracker_device": Device(tracker), "coordinator": coordinator } - if tracker.version > 2: + if tracker.has_beacon: tracker_beacons = await self.get_tracker_beacons_by_tracker_id(tracker.tracker_id) for tracker_beacon in tracker_beacons: beacon_coordinator = DataUpdateCoordinator[Mapping[str, Any]]( diff --git a/custom_components/georide/binary_sensor.py b/custom_components/georide/binary_sensor.py index da6660d..911d1e5 100644 --- a/custom_components/georide/binary_sensor.py +++ b/custom_components/georide/binary_sensor.py @@ -6,8 +6,7 @@ from typing import Any, Mapping from homeassistant.core import callback from homeassistant.helpers.entity import DeviceInfo, EntityCategory -from homeassistant.components.binary_sensor import BinarySensorEntity -from homeassistant.components.binary_sensor import ENTITY_ID_FORMAT +from homeassistant.components.binary_sensor import BinarySensorEntity, BinarySensorDeviceClass, ENTITY_ID_FORMAT from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator @@ -33,6 +32,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: d entities.append(GeoRideActiveSubscriptionBinarySensorEntity(coordinator, tracker_device)) entities.append(GeoRideNetworkBinarySensorEntity(coordinator, tracker_device)) entities.append(GeoRideMovingBinarySensorEntity(coordinator, tracker_device)) + entities.append(GeoRideUpdatedBinarySensorEntity(coordinator, tracker_device)) hass.data[GEORIDE_DOMAIN]["devices"][tracker_device.tracker.tracker_id] = coordinator @@ -102,7 +102,7 @@ class GeoRideStolenBinarySensorEntity(GeoRideBinarySensorEntity): @property def device_class(self): """Return the device class.""" - return "problem" + return BinarySensorDeviceClass.PROBLEM @property def is_on(self): @@ -132,7 +132,7 @@ class GeoRideCrashedBinarySensorEntity(GeoRideBinarySensorEntity): @property def device_class(self): """Return the device class.""" - return "problem" + return BinarySensorDeviceClass.PROBLEM @property def is_on(self): @@ -236,6 +236,11 @@ class GeoRideNetworkBinarySensorEntity(GeoRideBinarySensorEntity): return True return False + @property + def device_class(self) -> str: + """device class""" + return BinarySensorDeviceClass.CONNECTIVITY + @property def name(self): """ GeoRide name """ @@ -268,12 +273,49 @@ class GeoRideMovingBinarySensorEntity(GeoRideBinarySensorEntity): def is_on(self): """state value property""" return self._tracker_device.tracker.moving + + @property + def device_class(self) -> str: + """device class""" + return BinarySensorDeviceClass.MOVING @property def name(self): """ GeoRide name """ return f"{self._name} is moving" +class GeoRideUpdatedBinarySensorEntity(GeoRideBinarySensorEntity): + """Represent a tracked device.""" + @property + def entity_category(self): + return EntityCategory.DIAGNOSTIC + + def __init__(self, coordinator: DataUpdateCoordinator[Mapping[str, Any]], + tracker_device: Device): + """Set up Georide entity.""" + super().__init__(coordinator, tracker_device) + self.entity_id = f"{ENTITY_ID_FORMAT.format('update')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301 + + @property + def unique_id(self): + """Return the unique ID.""" + return f"update_{self._tracker_device.tracker.tracker_id}" + + @property + def is_on(self): + """state value property""" + return not self._tracker_device.tracker.is_up_to_date + + @property + def device_class(self) -> str: + """device class""" + return BinarySensorDeviceClass.UPDATE + + @property + def name(self): + """ GeoRide name """ + return f"{self._name} have an update" + class GeoRideBeaconUpdatedBinarySensorEntity(GeoRideBeaconBinarySensorEntity): """Represent a tracked device.""" @property @@ -291,15 +333,15 @@ class GeoRideBeaconUpdatedBinarySensorEntity(GeoRideBeaconBinarySensorEntity): """Return the unique ID.""" return f"update_{self._tracker_device_beacon.beacon.beacon_id}" - @property - def device_class(self): - """Return the device class.""" - return "update" - @property def is_on(self): """state value property""" return not self._tracker_device_beacon.beacon.is_updated + + @property + def device_class(self) -> str: + """device class""" + return BinarySensorDeviceClass.UPDATE @property def name(self): diff --git a/custom_components/georide/config_flow.py b/custom_components/georide/config_flow.py index b8d5cc5..5e324ca 100644 --- a/custom_components/georide/config_flow.py +++ b/custom_components/georide/config_flow.py @@ -12,7 +12,7 @@ from .const import CONF_EMAIL, CONF_PASSWORD, CONF_TOKEN, DOMAIN _LOGGER = logging.getLogger(__name__) -@config_entries.HANDLERS.register("georide") +@config_entries.HANDLERS.register(DOMAIN) class GeoRideConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """GeoRide config flow """ @@ -37,8 +37,6 @@ class GeoRideConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): vol.Required(CONF_PASSWORD): vol.All(str) })) - - async def async_step_georide_login(self, user_input): """ try to seupt GeoRide Account """ diff --git a/custom_components/georide/device.py b/custom_components/georide/device.py index a7276c4..65fe47a 100644 --- a/custom_components/georide/device.py +++ b/custom_components/georide/device.py @@ -9,6 +9,7 @@ class Device: def __init__(self, tracker): """Initialize GeoRideTracker device.""" self._tracker: GeoRideTracker = tracker + @property def tracker(self): @@ -20,11 +21,26 @@ class Device: """Get the name.""" return self._tracker.tracker_name + @property + def default_manufacturer(self) -> str: + """Get the default_manufacturer.""" + return "GeoRide" + @property def manufacturer(self) -> str: """Get the manufacturer.""" return "GeoRide" + + @property + def default_model(self) -> str: + """Get the default model.""" + return "GeoRide 1" + @property + def suggested_area(self) -> str: + """Get the suggested_area.""" + return "Garage" + @property def model_name(self) -> str: """Get the model name.""" @@ -34,10 +50,28 @@ class Device: elif self._tracker.version == 2: name = "GeoRide 2" elif self._tracker.version == 3: - name = "GeoRide 3" + if self._tracker.model == 'georide-3': + name = "GeoRide 3" + else: + name = "GeoRide Mini" else: name = "Prototype / Unknown" return name + + @property + def sw_version(self) -> str: + """Get the software version.""" + return str(self._tracker.software_version) + + @property + def hw_version(self) -> str: + """Get the hardware version.""" + return str(self._tracker.version) + + @property + def unique_id(self) -> str: + """Get the unique id.""" + return {(GEORIDE_DOMAIN, self._tracker.tracker_id)} @property def device_info(self): @@ -45,17 +79,13 @@ class Device: return { "name": self.name, "identifiers": self.unique_id, - "manufacturer": "GeoRide", + "manufacturer": self.manufacturer, "model": self.model_name, - "suggested_area": "Garage" + "suggested_area": self.suggested_area, + "sw_version" : self.sw_version, + "hw_version": self.hw_version } - - @property - def unique_id(self) -> str: - """Get the unique id.""" - return {(GEORIDE_DOMAIN, self._tracker.tracker_id)} - def __str__(self) -> str: """Get string representation.""" return f"GeoRide Device: {self.name}::{self.model_name}::{self.unique_id}" @@ -77,10 +107,25 @@ class DeviceBeacon: """Get the name.""" return self._beacon.name + @property + def default_manufacturer(self) -> str: + """Get the default_manufacturer.""" + return "GeoRide" + @property def manufacturer(self) -> str: """Get the manufacturer.""" return "GeoRide" + + @property + def default_model(self) -> str: + """Get the default model.""" + return "GeoRide Beacon" + + @property + def suggested_area(self) -> str: + """Get the suggested_area.""" + return "Garage" @property def model_name(self) -> str: @@ -88,23 +133,28 @@ class DeviceBeacon: name = "GeoRide Beacon" return name + @property + def unique_id(self) -> str: + """Get the unique id.""" + return {(GEORIDE_DOMAIN, self._beacon.beacon_id)} + + @property + def via_device(self) -> str: + """Get the unique id.""" + return (GEORIDE_DOMAIN, self._beacon.linked_tracker_id ) + @property def device_info(self): """Return the device info.""" return { "name": self.name, "identifiers": self.unique_id, - "manufacturer": "GeoRide", + "manufacturer": self.manufacturer, "model": self.model_name, - "suggested_area": "Garage" + "suggested_area": self.suggested_area, + "via_device": self.via_device } - @property - def unique_id(self) -> str: - """Get the unique id.""" - - return {(GEORIDE_DOMAIN, self._beacon.beacon_id)} - def __str__(self) -> str: """Get string representation.""" return f"GeoRide Device: {self.name}::{self.model_name}::{self.unique_id}" \ No newline at end of file diff --git a/custom_components/georide/manifest.json b/custom_components/georide/manifest.json index f04ebf7..67eab13 100644 --- a/custom_components/georide/manifest.json +++ b/custom_components/georide/manifest.json @@ -6,10 +6,10 @@ "issue_tracker": "https://github.com/ptimatth/GeorideHA/issues", "iot_class": "cloud_polling", "requirements": [ - "georideapilib>=0.8.4", + "georideapilib>=0.9.4", "pyjwt>=2.2.0" ], "dependencies": [], "codeowners": ["ptimatth"], - "version": "0.9.0" + "version": "1.0.0" } \ No newline at end of file diff --git a/custom_components/georide/sensor.py b/custom_components/georide/sensor.py index 1ad10a8..62423bb 100644 --- a/custom_components/georide/sensor.py +++ b/custom_components/georide/sensor.py @@ -5,8 +5,7 @@ from typing import Any, Mapping from homeassistant.core import callback from homeassistant.helpers.entity import DeviceInfo, EntityCategory -from homeassistant.components.sensor import SensorEntity -from homeassistant.components.sensor import ENTITY_ID_FORMAT +from homeassistant.components.sensor import SensorEntity, SensorDeviceClass, ENTITY_ID_FORMAT from homeassistant.helpers.update_coordinator import ( CoordinatorEntity, DataUpdateCoordinator, @@ -245,6 +244,11 @@ class GeoRideInternalBatterySensorEntity(CoordinatorEntity, SensorEntity): """icon getter""" return "mdi:battery" + @property + def device_class(self) -> str: + """device class""" + return SensorDeviceClass.VOLTAGE + @property def device_info(self) -> DeviceInfo: """Return the device info.""" @@ -302,6 +306,11 @@ class GeoRideExternalBatterySensorEntity(CoordinatorEntity, SensorEntity): """icon getter""" return "mdi:battery" + @property + def device_class(self) -> str: + """device class""" + return SensorDeviceClass.VOLTAGE + @property def device_info(self) -> DeviceInfo: """Return the device info.""" @@ -391,6 +400,11 @@ class GeoRideBeaconBatterySensorEntity(CoordinatorEntity, SensorEntity): """icon getter""" return "mdi:battery" + @property + def device_class(self) -> str: + """device class""" + return SensorDeviceClass.BATTERY + @property def device_info(self) -> DeviceInfo: """Return the device info.""" diff --git a/hacs.json b/hacs.json index d8e4f24..8c67814 100644 --- a/hacs.json +++ b/hacs.json @@ -4,5 +4,5 @@ "render_readme": true, "domains": ["devices_tracker", "sensor"], "country": ["FR"], - "homeassistant": "2022.2.0" + "homeassistant": "2023.2.0" } \ No newline at end of file