Compare commits

...

18 Commits

Author SHA1 Message Date
aa6cf7b515 Add beacon verification from the parametter has_beacon unsted of hw version 2023-02-28 19:34:56 +01:00
fa0f67e6ec Update to latest georidelib 2023-02-28 19:23:10 +01:00
bdaccea1e1 Add devices class to better categorisation in HA 2023-02-27 21:49:14 +01:00
Matthieu DUVAL
7ea6c96331 Update to to latest georideapilib 2023-02-27 18:02:27 +01:00
b8c8bcba14 Update pyjwt to match with the latest version 2022-04-06 17:24:18 +02:00
d270517025 Update to georideapilib 0.8.4 2022-03-20 14:05:24 +01:00
6eebbebdfa Update to georideapilib 0.8.3 2022-03-19 21:45:17 +01:00
cb5f069aff Fix tracker asign to tracker_device 2022-03-07 12:12:03 +01:00
4384526fae Fix call on position_event 2022-03-06 19:38:51 +01:00
2bc41f43c5 Fix sensor declaration 2022-03-06 13:44:19 +01:00
118911c361 Fix tracker position, add mesuremnt for longtherme statistics 2022-03-06 13:16:44 +01:00
9719f26631 Fix update beacon, Add speedometer, Add update on tracker properties change 2022-03-06 12:46:50 +01:00
0ee5a9ad12 Fix tracker device not exti 2022-03-04 19:46:09 +01:00
e9da051fc1 Fix attribute missing _tracker_device_beacon 2022-03-04 19:43:05 +01:00
1b2776f646 Fix update method on coordinator coma 2022-03-04 19:37:06 +01:00
112cf68542 Fix update method on coordinator 2022-03-04 19:34:00 +01:00
9f70dc220f Fix 'Device' object has no attribute 'beacon' 2022-03-04 19:24:47 +01:00
7a8702d57c Fix 'DeviceBeacon' object has no attribute 'tracker_beacon' 2022-03-04 19:21:59 +01:00
7 changed files with 257 additions and 54 deletions

View File

@@ -44,11 +44,8 @@ from .const import (
SIREN_ACTIVATION_DELAY SIREN_ACTIVATION_DELAY
) )
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = vol.Schema( CONFIG_SCHEMA = vol.Schema(
{ {
vol.Required(DOMAIN, default={}): { vol.Required(DOMAIN, default={}): {
@@ -59,7 +56,6 @@ CONFIG_SCHEMA = vol.Schema(
extra=vol.ALLOW_EXTRA, extra=vol.ALLOW_EXTRA,
) )
async def async_setup(hass, config): async def async_setup(hass, config):
"""Setup GeoRide component.""" """Setup GeoRide component."""
hass.data[DOMAIN] = {"config": config[DOMAIN], "devices": {}, "unsub": None} 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 boolean to indicate that initialization was successful.
return True return True
async def async_setup_entry(hass, entry): async def async_setup_entry(hass, entry):
"""Set up GeoRide entry.""" """Set up GeoRide entry."""
config = hass.data[DOMAIN]["config"] config = hass.data[DOMAIN]["config"]
@@ -120,12 +115,15 @@ 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, "binary_sensor")
await hass.config_entries.async_forward_entry_unload(entry, "siren") await hass.config_entries.async_forward_entry_unload(entry, "siren")
context = hass.data[DOMAIN]["context"] context = hass.data[DOMAIN]["context"]
context.socket.disconnect() context.socket.disconnect() # Disconnect only if all devices is disabled
return True return True
async def async_remove_config_entry_device(hass, config_entry, device_entry) -> bool:
"""Remove an GeoRide device entry."""
return True
class GeoRideContext: class GeoRideContext:
@@ -182,6 +180,7 @@ class GeoRideContext:
socket.subscribe_device(self.on_device_callback) socket.subscribe_device(self.on_device_callback)
socket.subscribe_position(self.on_position_callback) socket.subscribe_position(self.on_position_callback)
socket.subscribe_alarm(self.on_alarm_callback) socket.subscribe_alarm(self.on_alarm_callback)
socket.subscribe_refresh_tracker(self.on_refresh_tracker_callback)
self._socket = socket self._socket = socket
socket.init() socket.init()
@@ -240,6 +239,10 @@ class GeoRideContext:
if time.time() - SIREN_ACTIVATION_DELAY > tracker.siren_last_on_date: if time.time() - SIREN_ACTIVATION_DELAY > tracker.siren_last_on_date:
tracker.is_siren_on = False tracker.is_siren_on = False
async def refresh_trackers_beacon(self):
""" here we return last tracker by id"""
_LOGGER.debug("Do nothing, updated by another way")
async def force_refresh_trackers(self): async def force_refresh_trackers(self):
"""Used to refresh the tracker list""" """Used to refresh the tracker list"""
_LOGGER.info("Tracker list refresh") _LOGGER.info("Tracker list refresh")
@@ -271,7 +274,7 @@ class GeoRideContext:
for new_georide_tracker_beacon in new_georide_tracker_beacons: for new_georide_tracker_beacon in new_georide_tracker_beacons:
found = False found = False
for tracker_beacon in self._georide_trackers_beacon: for tracker_beacon in self._georide_trackers_beacon:
if tracker_beacon.tracker_id == new_georide_tracker_beacon.beacon_id: if tracker_beacon.beacon_id == new_georide_tracker_beacon.beacon_id:
tracker_beacon.update_all_data(new_georide_tracker_beacon) tracker_beacon.update_all_data(new_georide_tracker_beacon)
found = True found = True
if not found: if not found:
@@ -282,6 +285,8 @@ class GeoRideContext:
self._thread_started = True self._thread_started = True
await self.connect_socket() await self.connect_socket()
async def init_context(self, hass): async def init_context(self, hass):
"""Used to refresh the tracker list""" """Used to refresh the tracker list"""
_LOGGER.info("Init_context") _LOGGER.info("Init_context")
@@ -301,13 +306,15 @@ class GeoRideContext:
"tracker_device": Device(tracker), "tracker_device": Device(tracker),
"coordinator": coordinator "coordinator": coordinator
} }
if tracker.version > 2: if tracker.has_beacon:
tracker_beacons = await self.get_tracker_beacons_by_tracker_id(tracker.tracker_id) tracker_beacons = await self.get_tracker_beacons_by_tracker_id(tracker.tracker_id)
for tracker_beacon in tracker_beacons: for tracker_beacon in tracker_beacons:
beacon_coordinator = DataUpdateCoordinator[Mapping[str, Any]]( beacon_coordinator = DataUpdateCoordinator[Mapping[str, Any]](
hass, hass,
_LOGGER, _LOGGER,
name= tracker_beacon.name name=tracker_beacon.name,
update_method=self.refresh_trackers_beacon,
update_interval=update_interval
) )
coordoned_beacon = { coordoned_beacon = {
"tracker_beacon": DeviceBeacon(tracker_beacon), "tracker_beacon": DeviceBeacon(tracker_beacon),
@@ -382,6 +389,25 @@ class GeoRideContext:
coordinator.async_request_refresh(), self._hass.loop coordinator.async_request_refresh(), self._hass.loop
).result() ).result()
break break
@callback
def on_refresh_tracker_callback(self):
"""on device callback"""
_LOGGER.info("On refresh tracker received")
self._previous_refresh = math.floor(time.time()/60)
self.force_refresh_trackers()
for coordoned_tracker in self._georide_trackers_coordoned:
tracker_device = coordoned_tracker['tracker_device']
tracker = tracker_device.tracker
coordinator = coordoned_tracker['coordinator']
event_data = {
"device_id": tracker_device.unique_id,
"device_name": tracker_device.name,
}
self._hass.bus.async_fire(f"{DOMAIN}_refresh_tracker_event", event_data)
asyncio.run_coroutine_threadsafe(
coordinator.async_request_refresh(), self._hass.loop
).result()
@callback @callback
def on_alarm_callback(self, data): def on_alarm_callback(self, data):
@@ -439,7 +465,8 @@ class GeoRideContext:
"""on position callback""" """on position callback"""
_LOGGER.info("On position received") _LOGGER.info("On position received")
for coordoned_tracker in self._georide_trackers_coordoned: for coordoned_tracker in self._georide_trackers_coordoned:
tracker = coordoned_tracker['tracker_device'].tracker tracker_device = coordoned_tracker['tracker_device']
tracker = tracker_device.tracker
coordinator = coordoned_tracker['coordinator'] coordinator = coordoned_tracker['coordinator']
if tracker.tracker_id == data['trackerId']: if tracker.tracker_id == data['trackerId']:
tracker.latitude = data['latitude'] tracker.latitude = data['latitude']

View File

@@ -6,8 +6,7 @@ from typing import Any, Mapping
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.entity import DeviceInfo, EntityCategory from homeassistant.helpers.entity import DeviceInfo, EntityCategory
from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.components.binary_sensor import BinarySensorEntity, BinarySensorDeviceClass, ENTITY_ID_FORMAT
from homeassistant.components.binary_sensor import ENTITY_ID_FORMAT
from homeassistant.helpers.update_coordinator import ( from homeassistant.helpers.update_coordinator import (
CoordinatorEntity, CoordinatorEntity,
DataUpdateCoordinator 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(GeoRideActiveSubscriptionBinarySensorEntity(coordinator, tracker_device))
entities.append(GeoRideNetworkBinarySensorEntity(coordinator, tracker_device)) entities.append(GeoRideNetworkBinarySensorEntity(coordinator, tracker_device))
entities.append(GeoRideMovingBinarySensorEntity(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 hass.data[GEORIDE_DOMAIN]["devices"][tracker_device.tracker.tracker_id] = coordinator
@@ -41,7 +41,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: d
tracker_beacon = coordoned_beacon['tracker_beacon'] tracker_beacon = coordoned_beacon['tracker_beacon']
coordinator = coordoned_beacon['coordinator'] coordinator = coordoned_beacon['coordinator']
entities.append(GeoRideBeaconUpdatedBinarySensorEntity(coordinator, tracker_beacon)) entities.append(GeoRideBeaconUpdatedBinarySensorEntity(coordinator, tracker_beacon))
hass.data[GEORIDE_DOMAIN]["devices"][tracker_device.beacon.beacon_id] = coordinator hass.data[GEORIDE_DOMAIN]["devices"][tracker_beacon.beacon.beacon_id] = coordinator
async_add_entities(entities, True) async_add_entities(entities, True)
@@ -84,7 +84,7 @@ class GeoRideBeaconBinarySensorEntity(CoordinatorEntity, BinarySensorEntity):
@property @property
def device_info(self): def device_info(self):
"""Return the device info.""" """Return the device info."""
return self._tracker_device.device_info return self._tracker_device_beacon.device_info
class GeoRideStolenBinarySensorEntity(GeoRideBinarySensorEntity): class GeoRideStolenBinarySensorEntity(GeoRideBinarySensorEntity):
"""Represent a tracked device.""" """Represent a tracked device."""
@@ -102,7 +102,7 @@ class GeoRideStolenBinarySensorEntity(GeoRideBinarySensorEntity):
@property @property
def device_class(self): def device_class(self):
"""Return the device class.""" """Return the device class."""
return "problem" return BinarySensorDeviceClass.PROBLEM
@property @property
def is_on(self): def is_on(self):
@@ -132,7 +132,7 @@ class GeoRideCrashedBinarySensorEntity(GeoRideBinarySensorEntity):
@property @property
def device_class(self): def device_class(self):
"""Return the device class.""" """Return the device class."""
return "problem" return BinarySensorDeviceClass.PROBLEM
@property @property
def is_on(self): def is_on(self):
@@ -236,6 +236,11 @@ class GeoRideNetworkBinarySensorEntity(GeoRideBinarySensorEntity):
return True return True
return False return False
@property
def device_class(self) -> str:
"""device class"""
return BinarySensorDeviceClass.CONNECTIVITY
@property @property
def name(self): def name(self):
""" GeoRide name """ """ GeoRide name """
@@ -250,6 +255,10 @@ class GeoRideMovingBinarySensorEntity(GeoRideBinarySensorEntity):
super().__init__(coordinator, tracker_device) super().__init__(coordinator, tracker_device)
self.entity_id = f"{ENTITY_ID_FORMAT.format('moving')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301 self.entity_id = f"{ENTITY_ID_FORMAT.format('moving')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
@property
def entity_category(self):
return EntityCategory.DIAGNOSTIC
@property @property
def unique_id(self): def unique_id(self):
"""Return the unique ID.""" """Return the unique ID."""
@@ -265,11 +274,48 @@ class GeoRideMovingBinarySensorEntity(GeoRideBinarySensorEntity):
"""state value property""" """state value property"""
return self._tracker_device.tracker.moving return self._tracker_device.tracker.moving
@property
def device_class(self) -> str:
"""device class"""
return BinarySensorDeviceClass.MOVING
@property @property
def name(self): def name(self):
""" GeoRide name """ """ GeoRide name """
return f"{self._name} is moving" 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): class GeoRideBeaconUpdatedBinarySensorEntity(GeoRideBeaconBinarySensorEntity):
"""Represent a tracked device.""" """Represent a tracked device."""
@property @property
@@ -280,22 +326,22 @@ class GeoRideBeaconUpdatedBinarySensorEntity(GeoRideBeaconBinarySensorEntity):
tracker_beacon_device: DeviceBeacon): tracker_beacon_device: DeviceBeacon):
"""Set up Georide entity.""" """Set up Georide entity."""
super().__init__(coordinator, tracker_beacon_device) super().__init__(coordinator, tracker_beacon_device)
self.entity_id = f"{ENTITY_ID_FORMAT.format('update')}.{tracker_beacon_device.tracker_beacon.beacon_id}"# pylint: disable=C0301 self.entity_id = f"{ENTITY_ID_FORMAT.format('update')}.{tracker_beacon_device.beacon.beacon_id}"# pylint: disable=C0301
@property @property
def unique_id(self): def unique_id(self):
"""Return the unique ID.""" """Return the unique ID."""
return f"update_{self._tracker_beacon_device.beacon.beacon_id}" return f"update_{self._tracker_device_beacon.beacon.beacon_id}"
@property
def device_class(self):
"""Return the device class."""
return "update"
@property @property
def is_on(self): def is_on(self):
"""state value property""" """state value property"""
return not self._tracker_beacon_device.beacon.is_updated return not self._tracker_device_beacon.beacon.is_updated
@property
def device_class(self) -> str:
"""device class"""
return BinarySensorDeviceClass.UPDATE
@property @property
def name(self): def name(self):

View File

@@ -12,7 +12,7 @@ from .const import CONF_EMAIL, CONF_PASSWORD, CONF_TOKEN, DOMAIN
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@config_entries.HANDLERS.register("georide") @config_entries.HANDLERS.register(DOMAIN)
class GeoRideConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): class GeoRideConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""GeoRide config flow """ """GeoRide config flow """
@@ -37,8 +37,6 @@ class GeoRideConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
vol.Required(CONF_PASSWORD): vol.All(str) vol.Required(CONF_PASSWORD): vol.All(str)
})) }))
async def async_step_georide_login(self, user_input): async def async_step_georide_login(self, user_input):
""" try to seupt GeoRide Account """ """ try to seupt GeoRide Account """

View File

@@ -10,6 +10,7 @@ class Device:
"""Initialize GeoRideTracker device.""" """Initialize GeoRideTracker device."""
self._tracker: GeoRideTracker = tracker self._tracker: GeoRideTracker = tracker
@property @property
def tracker(self): def tracker(self):
"""return the tracker""" """return the tracker"""
@@ -20,11 +21,26 @@ class Device:
"""Get the name.""" """Get the name."""
return self._tracker.tracker_name return self._tracker.tracker_name
@property
def default_manufacturer(self) -> str:
"""Get the default_manufacturer."""
return "GeoRide"
@property @property
def manufacturer(self) -> str: def manufacturer(self) -> str:
"""Get the manufacturer.""" """Get the manufacturer."""
return "GeoRide" 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 @property
def model_name(self) -> str: def model_name(self) -> str:
"""Get the model name.""" """Get the model name."""
@@ -34,28 +50,42 @@ class Device:
elif self._tracker.version == 2: elif self._tracker.version == 2:
name = "GeoRide 2" name = "GeoRide 2"
elif self._tracker.version == 3: elif self._tracker.version == 3:
if self._tracker.model == 'georide-3':
name = "GeoRide 3" name = "GeoRide 3"
else:
name = "GeoRide Mini"
else: else:
name = "Prototype / Unknown" name = "Prototype / Unknown"
return name 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 @property
def device_info(self): def device_info(self):
"""Return the device info.""" """Return the device info."""
return { return {
"name": self.name, "name": self.name,
"identifiers": self.unique_id, "identifiers": self.unique_id,
"manufacturer": "GeoRide", "manufacturer": self.manufacturer,
"model": self.model_name, "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: def __str__(self) -> str:
"""Get string representation.""" """Get string representation."""
return f"GeoRide Device: {self.name}::{self.model_name}::{self.unique_id}" return f"GeoRide Device: {self.name}::{self.model_name}::{self.unique_id}"
@@ -77,34 +107,54 @@ class DeviceBeacon:
"""Get the name.""" """Get the name."""
return self._beacon.name return self._beacon.name
@property
def default_manufacturer(self) -> str:
"""Get the default_manufacturer."""
return "GeoRide"
@property @property
def manufacturer(self) -> str: def manufacturer(self) -> str:
"""Get the manufacturer.""" """Get the manufacturer."""
return "GeoRide" 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 @property
def model_name(self) -> str: def model_name(self) -> str:
"""Get the model name.""" """Get the model name."""
name = "GeoRide Beacon" name = "GeoRide Beacon"
return name 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 @property
def device_info(self): def device_info(self):
"""Return the device info.""" """Return the device info."""
return { return {
"name": self.name, "name": self.name,
"identifiers": self.unique_id, "identifiers": self.unique_id,
"manufacturer": "GeoRide", "manufacturer": self.manufacturer,
"model": self.model_name, "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: def __str__(self) -> str:
"""Get string representation.""" """Get string representation."""
return f"GeoRide Device: {self.name}::{self.model_name}::{self.unique_id}" return f"GeoRide Device: {self.name}::{self.model_name}::{self.unique_id}"

View File

@@ -6,10 +6,10 @@
"issue_tracker": "https://github.com/ptimatth/GeorideHA/issues", "issue_tracker": "https://github.com/ptimatth/GeorideHA/issues",
"iot_class": "cloud_polling", "iot_class": "cloud_polling",
"requirements": [ "requirements": [
"georideapilib>=0.8.2", "georideapilib>=0.9.4",
"pyjwt==2.1.0" "pyjwt>=2.2.0"
], ],
"dependencies": [], "dependencies": [],
"codeowners": ["ptimatth"], "codeowners": ["ptimatth"],
"version": "0.9.0" "version": "1.0.0"
} }

View File

@@ -5,8 +5,7 @@ from typing import Any, Mapping
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.entity import DeviceInfo, EntityCategory from homeassistant.helpers.entity import DeviceInfo, EntityCategory
from homeassistant.components.sensor import SensorEntity from homeassistant.components.sensor import SensorEntity, SensorDeviceClass, ENTITY_ID_FORMAT
from homeassistant.components.sensor import ENTITY_ID_FORMAT
from homeassistant.helpers.update_coordinator import ( from homeassistant.helpers.update_coordinator import (
CoordinatorEntity, CoordinatorEntity,
DataUpdateCoordinator, DataUpdateCoordinator,
@@ -31,6 +30,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: d
hass.data[GEORIDE_DOMAIN]["devices"][tracker_device.tracker.tracker_id] = coordinator hass.data[GEORIDE_DOMAIN]["devices"][tracker_device.tracker.tracker_id] = coordinator
entities.append(GeoRideOdometerSensorEntity(coordinator, tracker_device, hass)) entities.append(GeoRideOdometerSensorEntity(coordinator, tracker_device, hass))
entities.append(GeoRideOdometerKmSensorEntity(coordinator, tracker_device, hass)) entities.append(GeoRideOdometerKmSensorEntity(coordinator, tracker_device, hass))
entities.append(GeoRideSpeedSensorEntity(coordinator, tracker_device,hass))
entities.append(GeoRideFixtimeSensorEntity(coordinator, tracker_device)) entities.append(GeoRideFixtimeSensorEntity(coordinator, tracker_device))
if tracker_device.tracker.version > 2: if tracker_device.tracker.version > 2:
entities.append(GeoRideInternalBatterySensorEntity(coordinator, tracker_device)) entities.append(GeoRideInternalBatterySensorEntity(coordinator, tracker_device))
@@ -41,7 +41,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: d
tracker_beacon = coordoned_beacon['tracker_beacon'] tracker_beacon = coordoned_beacon['tracker_beacon']
coordinator = coordoned_beacon['coordinator'] coordinator = coordoned_beacon['coordinator']
entities.append(GeoRideBeaconBatterySensorEntity(coordinator, tracker_beacon)) entities.append(GeoRideBeaconBatterySensorEntity(coordinator, tracker_beacon))
hass.data[GEORIDE_DOMAIN]["devices"][tracker_device.beacon.beacon_id] = coordinator hass.data[GEORIDE_DOMAIN]["devices"][tracker_beacon.beacon.beacon_id] = coordinator
async_add_entities(entities) async_add_entities(entities)
@@ -142,6 +142,55 @@ class GeoRideOdometerKmSensorEntity(CoordinatorEntity, SensorEntity):
"""Return the device info.""" """Return the device info."""
return self._tracker_device.device_info return self._tracker_device.device_info
class GeoRideSpeedSensorEntity(CoordinatorEntity, SensorEntity):
"""Represent a tracked device."""
def __init__(self, coordinator: DataUpdateCoordinator[Mapping[str, Any]],
tracker_device:Device, hass):
"""Set up GeoRide entity."""
super().__init__(coordinator)
self._tracker_device = tracker_device
self._name = tracker_device.tracker.tracker_name
self._unit_of_measurement = "km/h"
self.entity_id = f"{ENTITY_ID_FORMAT.format('speed')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
self._state = 0
self._hass = hass
self._state_class = "measurement"
@property
def unique_id(self):
"""Return the unique ID."""
return f"speed_{self._tracker_device.tracker.tracker_id}"
@property
def state(self):
"""state property"""
return self._tracker_device.tracker.speed
@property
def state_class(self):
return self._state_class
@property
def unit_of_measurement(self):
"""unit of mesurment property"""
return self._unit_of_measurement
@property
def name(self):
""" GeoRide odometer name """
return f"{self._name} speed"
@property
def icon(self):
"""icon getter"""
return "mdi:speedometer"
@property
def device_info(self) -> DeviceInfo:
"""Return the device info."""
return self._tracker_device.device_info
class GeoRideInternalBatterySensorEntity(CoordinatorEntity, SensorEntity): class GeoRideInternalBatterySensorEntity(CoordinatorEntity, SensorEntity):
"""Represent a tracked device.""" """Represent a tracked device."""
entity_category = EntityCategory.DIAGNOSTIC entity_category = EntityCategory.DIAGNOSTIC
@@ -154,8 +203,17 @@ class GeoRideInternalBatterySensorEntity(CoordinatorEntity, SensorEntity):
self._name = tracker_device.tracker.tracker_name self._name = tracker_device.tracker.tracker_name
self._unit_of_measurement = "V" self._unit_of_measurement = "V"
self.entity_id = f"{ENTITY_ID_FORMAT.format('internal_battery_voltage')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301 self.entity_id = f"{ENTITY_ID_FORMAT.format('internal_battery_voltage')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
self._state = 0 self._state = 0
self._state_class = "measurement"
self._device_class = "voltage"
@property
def state_class(self):
return self._state_class
@property
def device_class(self):
return self._device_class
@property @property
def entity_category(self): def entity_category(self):
@@ -186,6 +244,11 @@ class GeoRideInternalBatterySensorEntity(CoordinatorEntity, SensorEntity):
"""icon getter""" """icon getter"""
return "mdi:battery" return "mdi:battery"
@property
def device_class(self) -> str:
"""device class"""
return SensorDeviceClass.VOLTAGE
@property @property
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo:
"""Return the device info.""" """Return the device info."""
@@ -203,6 +266,16 @@ class GeoRideExternalBatterySensorEntity(CoordinatorEntity, SensorEntity):
self._unit_of_measurement = "V" self._unit_of_measurement = "V"
self.entity_id = f"{ENTITY_ID_FORMAT.format('external_battery_voltage')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301 self.entity_id = f"{ENTITY_ID_FORMAT.format('external_battery_voltage')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
self._state = 0 self._state = 0
self._state_class = "measurement"
self._device_class = "voltage"
@property
def state_class(self):
return self._state_class
@property
def device_class(self):
return self._device_class
@property @property
def entity_category(self): def entity_category(self):
@@ -233,6 +306,11 @@ class GeoRideExternalBatterySensorEntity(CoordinatorEntity, SensorEntity):
"""icon getter""" """icon getter"""
return "mdi:battery" return "mdi:battery"
@property
def device_class(self) -> str:
"""device class"""
return SensorDeviceClass.VOLTAGE
@property @property
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo:
"""Return the device info.""" """Return the device info."""
@@ -248,7 +326,6 @@ class GeoRideFixtimeSensorEntity(CoordinatorEntity, SensorEntity):
self._tracker_device = tracker_device self._tracker_device = tracker_device
self._name = tracker_device.tracker.tracker_name self._name = tracker_device.tracker.tracker_name
self.entity_id = f"{ENTITY_ID_FORMAT.format('fixtime')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301 self.entity_id = f"{ENTITY_ID_FORMAT.format('fixtime')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
self._state = 0 self._state = 0
self._device_class = "timestamp" self._device_class = "timestamp"
@@ -323,6 +400,11 @@ class GeoRideBeaconBatterySensorEntity(CoordinatorEntity, SensorEntity):
"""icon getter""" """icon getter"""
return "mdi:battery" return "mdi:battery"
@property
def device_class(self) -> str:
"""device class"""
return SensorDeviceClass.BATTERY
@property @property
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo:
"""Return the device info.""" """Return the device info."""

View File

@@ -4,5 +4,5 @@
"render_readme": true, "render_readme": true,
"domains": ["devices_tracker", "sensor"], "domains": ["devices_tracker", "sensor"],
"country": ["FR"], "country": ["FR"],
"homeassistant": "2022.2.0" "homeassistant": "2023.2.0"
} }