Compare commits

..

6 Commits

Author SHA1 Message Date
57abb51b13 Shipping 0.7.0 2021-07-01 11:54:45 +02:00
24180c9345 Shipping v0.6.2 2021-05-05 22:56:38 +02:00
a83bae6d3e Shipping v0.6.1 2021-04-11 18:01:27 +02:00
b84a4cfd7f Shipping v0.6.0 2021-04-11 17:27:23 +02:00
02e1656aab Merge branch 'develop' 2020-12-01 19:24:26 +01:00
9b651f933e Shipping v0.5.0 2020-05-23 15:07:27 +02:00
12 changed files with 104 additions and 992 deletions

View File

@@ -15,15 +15,12 @@ This component add some sensor for GeoRide Tracker
Get GeoRide position
Get GeoRide lock status
Change GeoRide lock status
Add GeoRide from configuration.yml
Add GeoRide from interface
Get stollen status
Get crashed status
Get is owner status
Get subsription status
Get odomoter to km an m (2 entities)
Internal battery (of georide 3) (not work on GR1)
External battery (of the bike) (not work on GR1)
Fixtime (last registered positition of the georide)
### What's events are available:
you can filter by data.device_id == XX (XX is your tracker id)
@@ -56,7 +53,7 @@ here is the alarm type available: (listen the georide_alarm_event)
## Question:
### How to have the odometer in Km ? (Deprecated, now you have an entity - thx @Inervo)
### How to have the odometer in Km ?
Simply add a sensor like this in configuration.yaml
(Replace XX by your tracker id)
@@ -69,6 +66,8 @@ sensor:
friendly_name: "Odometter - Km"
value_template: "{{ states.sensor.odometer_XX.state | multiply(0.001) | round(3, 'flour') }}"
unit_of_measurement: 'Km'
```
### How to use the event:

View File

@@ -32,7 +32,7 @@ from homeassistant.helpers.update_coordinator import (
)
from .device import Device, DeviceBeacon
from .device import Device
from .const import (
CONF_EMAIL,
CONF_PASSWORD,
@@ -40,12 +40,14 @@ from .const import (
TRACKER_ID,
TOKEN_SAFE_DAY,
MIN_UNTIL_REFRESH,
DOMAIN,
SIREN_ACTIVATION_DELAY
DOMAIN
)
_LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = vol.Schema(
{
vol.Required(DOMAIN, default={}): {
@@ -56,6 +58,7 @@ 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}
@@ -72,6 +75,7 @@ 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"]
@@ -101,8 +105,6 @@ async def async_setup_entry(hass, entry):
hass.config_entries.async_forward_entry_setup(entry, "sensor"))
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, "binary_sensor"))
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, "siren"))
return True
@@ -113,17 +115,13 @@ async def async_unload_entry(hass, entry):
await hass.config_entries.async_forward_entry_unload(entry, "switch")
await hass.config_entries.async_forward_entry_unload(entry, "sensor")
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() # Disconnect only if all devices is disabled
context.socket.disconnect()
return True
async def async_remove_config_entry_device(hass, config_entry, device_entry) -> bool:
"""Remove an GeoRide device entry."""
return True
class GeoRideContext:
@@ -135,8 +133,6 @@ class GeoRideContext:
self._email = email
self._password = password
self._georide_trackers_coordoned = []
self._georide_trackers_beacon_coordoned = []
self._georide_trackers_beacon = []
self._georide_trackers = []
self._token = token
self._socket = None
@@ -180,7 +176,7 @@ class GeoRideContext:
socket.subscribe_device(self.on_device_callback)
socket.subscribe_position(self.on_position_callback)
socket.subscribe_alarm(self.on_alarm_callback)
socket.subscribe_refresh_tracker(self.on_refresh_tracker_callback)
self._socket = socket
socket.init()
@@ -188,7 +184,7 @@ class GeoRideContext:
async def get_token(self):
""" here we return the current valid tocken """
jwt_data = jwt.decode(self._token, options={"verify_signature": False})
jwt_data = jwt.decode(self._token, verify=False)
exp_timestamp = jwt_data['exp']
epoch = math.ceil(time.time())
@@ -212,36 +208,17 @@ class GeoRideContext:
return tracker
return {}
async def get_tracker_beacon(self, beacon_id):
""" here we return last tracker_beacon by id"""
for tracker_beacon in self._georide_trackers_beacon:
if tracker_beacon.beacon_id == beacon_id:
return tracker_beacon
return {}
async def get_tracker_beacons_by_tracker_id(self, tracker_id):
""" here we return last tracker_beacon by id"""
filtered_beacon = []
for tracker_beacon in self._georide_trackers_beacon:
if tracker_beacon.linked_tracker_id == tracker_id:
filtered_beacon.append(tracker_beacon)
return filtered_beacon
async def refresh_trackers(self):
""" here we return last tracker by id"""
_LOGGER.debug("Call refresh tracker")
epoch_min = math.floor(time.time()/60)
#if (epoch_min % MIN_UNTIL_REFRESH) == 0:
if epoch_min != self._previous_refresh:
self._previous_refresh = epoch_min
await self.force_refresh_trackers()
for tracker in self._georide_trackers:
if tracker.is_siren_on:
if time.time() - SIREN_ACTIVATION_DELAY > tracker.siren_last_on_date:
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")
#else:
# _LOGGER.debug("We wil dont refresh the tracker list")
async def force_refresh_trackers(self):
"""Used to refresh the tracker list"""
@@ -253,32 +230,9 @@ class GeoRideContext:
for tracker in self._georide_trackers:
if tracker.tracker_id == refreshed_tracker.tracker_id:
tracker.update_all_data(refreshed_tracker)
if tracker.version > 2:
await self.force_refresh_trackers_beacon(tracker.tracker_id)
found = True
if not found:
self._georide_trackers.append(refreshed_tracker)
if refreshed_tracker.version > 2:
await self.force_refresh_trackers_beacon(refreshed_tracker.tracker_id)
if not self._thread_started:
_LOGGER.info("Start the thread")
# We refresh the tracker list each hours
self._thread_started = True
await self.connect_socket()
async def force_refresh_trackers_beacon(self, tracker_id):
"""Used to refresh the tracker list"""
_LOGGER.info("Tracker beacon refresh")
new_georide_tracker_beacons = await self._hass.async_add_executor_job(GeoRideApi.get_tracker_beacons,
await self.get_token(), tracker_id)
for new_georide_tracker_beacon in new_georide_tracker_beacons:
found = False
for tracker_beacon in self._georide_trackers_beacon:
if tracker_beacon.beacon_id == new_georide_tracker_beacon.beacon_id:
tracker_beacon.update_all_data(new_georide_tracker_beacon)
found = True
if not found:
self._georide_trackers_beacon.append(new_georide_tracker_beacon)
if not self._thread_started:
_LOGGER.info("Start the thread")
# We refresh the tracker list each hours
@@ -301,41 +255,17 @@ class GeoRideContext:
update_method=self.refresh_trackers,
update_interval=update_interval
)
coordoned_tracker = {
"tracker_device": Device(tracker),
"coordinator": coordinator
}
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]](
hass,
_LOGGER,
name=tracker_beacon.name,
update_method=self.refresh_trackers_beacon,
update_interval=update_interval
)
coordoned_beacon = {
"tracker_beacon": DeviceBeacon(tracker_beacon),
"coordinator": beacon_coordinator
}
self._georide_trackers_beacon_coordoned.append(coordoned_beacon)
self._georide_trackers_coordoned.append(coordoned_tracker)
self._georide_trackers_coordoned.append({
"tracker_device": Device(tracker),
"coordinator": coordinator
})
@property
def georide_trackers_coordoned(self):
def get_coordoned_trackers(self):
"""Return coordoned trackers"""
return self._georide_trackers_coordoned
@property
def georide_trackers_beacon_coordoned(self):
"""Return coordoned trackers"""
return self._georide_trackers_beacon_coordoned
@property
def socket(self):
""" hold the GeoRide socket """
@@ -351,8 +281,7 @@ class GeoRideContext:
"""on lock callback"""
_LOGGER.info("On lock received")
for coordoned_tracker in self._georide_trackers_coordoned:
tracker_device = coordoned_tracker['tracker_device']
tracker = tracker_device.tracker
tracker = coordoned_tracker['tracker_device'].tracker
coordinator = coordoned_tracker['coordinator']
if tracker.tracker_id == data['trackerId']:
tracker.locked_latitude = data['lockedLatitude']
@@ -360,8 +289,8 @@ class GeoRideContext:
tracker.is_locked = data['isLocked']
event_data = {
"device_id": tracker_device.unique_id,
"device_name": tracker_device.name,
"device_id": tracker.tracker_id,
"device_name": tracker.tracker_name
}
self._hass.bus.async_fire(f"{DOMAIN}_lock_event", event_data)
@@ -370,91 +299,71 @@ class GeoRideContext:
).result()
break
@callback
def on_device_callback(self, data):
"""on device callback"""
_LOGGER.info("On device received")
for coordoned_tracker in self._georide_trackers_coordoned:
tracker_device = coordoned_tracker['tracker_device']
tracker = tracker_device.tracker
tracker = coordoned_tracker['tracker_device'].tracker
coordinator = coordoned_tracker['coordinator']
if tracker.tracker_id == data['trackerId']:
tracker.status = data['status']
event_data = {
"device_id": tracker_device.unique_id,
"device_name": tracker_device.name,
"device_id": tracker.tracker_id,
"device_name": tracker.tracker_name,
}
self._hass.bus.async_fire(f"{DOMAIN}_device_event", event_data)
asyncio.run_coroutine_threadsafe(
coordinator.async_request_refresh(), self._hass.loop
).result()
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
def on_alarm_callback(self, data):
"""on device callback"""
_LOGGER.info("On alarm received")
for coordoned_tracker in self._georide_trackers_coordoned:
tracker_device = coordoned_tracker['tracker_device']
tracker = tracker_device.tracker
tracker = coordoned_tracker['tracker_device'].tracker
coordinator = coordoned_tracker['coordinator']
if tracker.tracker_id == data['trackerId']:
if data['name'] == 'vibration':
if data.name == 'vibration':
_LOGGER.info("Vibration detected")
elif data['name'] == 'exitZone':
elif data.name == 'exitZone':
_LOGGER.info("Exit zone detected")
elif data['name'] == 'crash':
elif data.name == 'crash':
_LOGGER.info("Crash detected")
elif data['name'] == 'crashParking':
elif data.name == 'crashParking':
_LOGGER.info("Crash parking detected")
elif data['name'] == 'deviceOffline':
elif data.name == 'deviceOffline':
_LOGGER.info("Device offline detected")
elif data['name'] == 'deviceOnline':
elif data.name == 'deviceOnline':
_LOGGER.info("Device online detected")
elif data['name'] == 'powerCut':
elif data.name == 'powerCut':
_LOGGER.info("powerCut detected")
elif data['name'] == 'powerUncut':
elif data.name == 'powerUncut':
_LOGGER.info("powerUncut detected")
elif data['name'] == 'batteryWarning':
elif data.name == 'batteryWarning':
_LOGGER.info("batteryWarning detected")
elif data['name'] == 'temperatureWarning':
elif data.name == 'temperatureWarning':
_LOGGER.info("temperatureWarning detected")
elif data['name'] == 'magnetOn':
elif data.name == 'magnetOn':
_LOGGER.info("magnetOn detected")
elif data['name'] == 'magnetOff':
elif data.name == 'magnetOff':
_LOGGER.info("magnetOff detected")
elif data['name'] == 'sonorAlarmOn':
elif data.name == 'sonorAlarmOn':
_LOGGER.info("sonorAlarmOn detected")
tracker.is_siren_on = True
else:
_LOGGER.warning("Unmanaged alarm: %s", data["name"])
_LOGGER.warning("Unmanaged alarm: %s", data.name)
event_data = {
"device_id": tracker_device.unique_id,
"device_name": tracker_device.name,
"type": f"alarm_{data['name']}"
"device_id": tracker.tracker_id,
"device_name": tracker.tracker_name,
"type": f"alarm_{data.name}"
}
self._hass.bus.async_fire(f"{DOMAIN}_alarm_event", event_data)
self._hass.bus.fire(f"{DOMAIN}_alarm_event", event_data)
asyncio.run_coroutine_threadsafe(
coordinator.async_request_refresh(), self._hass.loop
).result()
@@ -465,8 +374,7 @@ class GeoRideContext:
"""on position callback"""
_LOGGER.info("On position received")
for coordoned_tracker in self._georide_trackers_coordoned:
tracker_device = coordoned_tracker['tracker_device']
tracker = tracker_device.tracker
tracker = coordoned_tracker['tracker_device'].tracker
coordinator = coordoned_tracker['coordinator']
if tracker.tracker_id == data['trackerId']:
tracker.latitude = data['latitude']
@@ -476,8 +384,8 @@ class GeoRideContext:
tracker.fixtime = data['fixtime']
event_data = {
"device_id": tracker_device.unique_id,
"device_name": tracker_device.name,
"device_id": tracker.tracker_id,
"device_name": tracker.tracker_name
}
self._hass.bus.async_fire(f"{DOMAIN}_position_event", event_data)
asyncio.run_coroutine_threadsafe(

View File

@@ -5,8 +5,8 @@ import logging
from typing import Any, Mapping
from homeassistant.core import callback
from homeassistant.helpers.entity import DeviceInfo, EntityCategory
from homeassistant.components.binary_sensor import BinarySensorEntity, BinarySensorDeviceClass, ENTITY_ID_FORMAT
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.components.binary_sensor import ENTITY_ID_FORMAT
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator
@@ -14,14 +14,14 @@ from homeassistant.helpers.update_coordinator import (
from .const import DOMAIN as GEORIDE_DOMAIN
from .device import Device, DeviceBeacon
from .device import Device
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: disable=W0613
"""Set up GeoRide tracker based off an entry."""
georide_context = hass.data[GEORIDE_DOMAIN]["context"]
entities = []
coordoned_trackers = georide_context.georide_trackers_coordoned
coordoned_trackers = georide_context.get_coordoned_trackers()
for coordoned_tracker in coordoned_trackers:
tracker_device = coordoned_tracker['tracker_device']
coordinator = coordoned_tracker['coordinator']
@@ -30,19 +30,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: d
entities.append(GeoRideCrashedBinarySensorEntity(coordinator, tracker_device))
entities.append(GeoRideOwnerBinarySensorEntity(coordinator, tracker_device))
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
coordoned_beacons = georide_context.georide_trackers_beacon_coordoned
for coordoned_beacon in coordoned_beacons:
tracker_beacon = coordoned_beacon['tracker_beacon']
coordinator = coordoned_beacon['coordinator']
entities.append(GeoRideBeaconUpdatedBinarySensorEntity(coordinator, tracker_beacon))
hass.data[GEORIDE_DOMAIN]["devices"][tracker_beacon.beacon.beacon_id] = coordinator
async_add_entities(entities, True)
@@ -66,26 +55,6 @@ class GeoRideBinarySensorEntity(CoordinatorEntity, BinarySensorEntity):
"""Return the device info."""
return self._tracker_device.device_info
class GeoRideBeaconBinarySensorEntity(CoordinatorEntity, BinarySensorEntity):
"""Represent a tracked device."""
def __init__(self, coordinator: DataUpdateCoordinator[Mapping[str, Any]],
tracker_device_beacon: DeviceBeacon):
"""Set up Georide entity."""
super().__init__(coordinator)
self._tracker_device_beacon = tracker_device_beacon
self._name = tracker_device_beacon.beacon.name
self.entity_id = f"{ENTITY_ID_FORMAT.format('binary_sensor')}.{tracker_device_beacon.beacon.beacon_id}"# pylint: disable=C0301
self._is_on = False
@property
def entity_category(self):
return None
@property
def device_info(self):
"""Return the device info."""
return self._tracker_device_beacon.device_info
class GeoRideStolenBinarySensorEntity(GeoRideBinarySensorEntity):
"""Represent a tracked device."""
def __init__(self, coordinator: DataUpdateCoordinator[Mapping[str, Any]],
@@ -99,11 +68,6 @@ class GeoRideStolenBinarySensorEntity(GeoRideBinarySensorEntity):
"""Return the unique ID."""
return f"is_stolen_{self._tracker_device.tracker.tracker_id}"
@property
def device_class(self):
"""Return the device class."""
return BinarySensorDeviceClass.PROBLEM
@property
def is_on(self):
"""state value property"""
@@ -112,7 +76,7 @@ class GeoRideStolenBinarySensorEntity(GeoRideBinarySensorEntity):
@property
def name(self):
""" GeoRide odometer name """
return f"{self._name} is not stolen"
return f"{self._name} is stolen"
class GeoRideCrashedBinarySensorEntity(GeoRideBinarySensorEntity):
@@ -129,11 +93,6 @@ class GeoRideCrashedBinarySensorEntity(GeoRideBinarySensorEntity):
"""Return the unique ID."""
return f"is_crashed_{self._tracker_device.tracker.tracker_id}"
@property
def device_class(self):
"""Return the device class."""
return BinarySensorDeviceClass.PROBLEM
@property
def is_on(self):
"""state value property"""
@@ -142,7 +101,7 @@ class GeoRideCrashedBinarySensorEntity(GeoRideBinarySensorEntity):
@property
def name(self):
""" GeoRide odometer name """
return f"{self._name} is not crashed"
return f"{self._name} is crashed"
class GeoRideActiveSubscriptionBinarySensorEntity(GeoRideBinarySensorEntity):
"""Represent a tracked device."""
@@ -153,10 +112,6 @@ class GeoRideActiveSubscriptionBinarySensorEntity(GeoRideBinarySensorEntity):
super().__init__(coordinator, tracker_device)
self.entity_id = f"{ENTITY_ID_FORMAT.format('is_active_subscription_')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
@property
def entity_category(self):
return EntityCategory.DIAGNOSTIC
@property
def unique_id(self):
"""Return the unique ID."""
@@ -165,15 +120,9 @@ class GeoRideActiveSubscriptionBinarySensorEntity(GeoRideBinarySensorEntity):
@property
def is_on(self):
"""state value property"""
tracker = self._tracker_device.tracker
if tracker.is_oldsubscription:
if tracker.subscription_id is not None:
return True
return False
else:
if tracker.subscription is not None and tracker.subscription.subscription_id is not None:
return True
return False
if self._tracker_device.tracker.subscription_id is not None:
return True
return False
@property
def name(self):
@@ -205,145 +154,4 @@ class GeoRideOwnerBinarySensorEntity(GeoRideBinarySensorEntity):
def name(self):
""" GeoRide odometer name """
return f"{self._name} is own tracker"
class GeoRideNetworkBinarySensorEntity(GeoRideBinarySensorEntity):
"""Represent a tracked device."""
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('have_network')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
@property
def entity_category(self):
return EntityCategory.DIAGNOSTIC
@property
def unique_id(self):
"""Return the unique ID."""
return f"have_network_{self._tracker_device.tracker.tracker_id}"
@property
def device_class(self):
"""Return the device class."""
return "connectivity"
@property
def is_on(self):
"""state value property"""
if self._tracker_device.tracker.status == "online":
return True
return False
@property
def device_class(self) -> str:
"""device class"""
return BinarySensorDeviceClass.CONNECTIVITY
@property
def name(self):
""" GeoRide name """
return f"{self._name} have network"
class GeoRideMovingBinarySensorEntity(GeoRideBinarySensorEntity):
"""Represent a tracked device."""
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('moving')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
@property
def entity_category(self):
return EntityCategory.DIAGNOSTIC
@property
def unique_id(self):
"""Return the unique ID."""
return f"moving_{self._tracker_device.tracker.tracker_id}"
@property
def device_class(self):
"""Return the device class."""
return "moving"
@property
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
def entity_category(self):
return EntityCategory.DIAGNOSTIC
def __init__(self, coordinator: DataUpdateCoordinator[Mapping[str, Any]],
tracker_beacon_device: DeviceBeacon):
"""Set up Georide entity."""
super().__init__(coordinator, tracker_beacon_device)
self.entity_id = f"{ENTITY_ID_FORMAT.format('update')}.{tracker_beacon_device.beacon.beacon_id}"# pylint: disable=C0301
@property
def unique_id(self):
"""Return the unique ID."""
return f"update_{self._tracker_device_beacon.beacon.beacon_id}"
@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):
""" GeoRide name """
return f"{self._name} have an update"

View File

@@ -12,7 +12,7 @@ from .const import CONF_EMAIL, CONF_PASSWORD, CONF_TOKEN, DOMAIN
_LOGGER = logging.getLogger(__name__)
@config_entries.HANDLERS.register(DOMAIN)
@config_entries.HANDLERS.register("georide")
class GeoRideConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""GeoRide config flow """
@@ -37,6 +37,8 @@ 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 """

View File

@@ -10,6 +10,4 @@ TRACKER_ID = "trackerId"
MIN_UNTIL_REFRESH = 10
SIREN_ACTIVATION_DELAY = 30
TOKEN_SAFE_DAY = 432000 # five days

View File

@@ -1,5 +1,5 @@
"""Home Assistant representation of an GeoRide Tracker device."""
from georideapilib.objects import GeoRideTracker, GeoRideTrackerBeacon
import georideapilib.objects as GeoRideTracker
from .const import DOMAIN as GEORIDE_DOMAIN
@@ -9,7 +9,6 @@ class Device:
def __init__(self, tracker):
"""Initialize GeoRideTracker device."""
self._tracker: GeoRideTracker = tracker
@property
def tracker(self):
@@ -21,140 +20,38 @@ 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."""
name = None
if self._tracker.version == 1:
name = "GeoRide 1"
elif self._tracker.version == 2:
name = "GeoRide 2"
elif self._tracker.version == 3:
if self._tracker.model == 'georide-3':
name = "GeoRide 3"
else:
name = "GeoRide Mini"
else:
name = "Prototype / Unknown"
name = "GeoRide 1"
if self._tracker.is_old_tracker:
name = "Prototype / GeoRide 1"
elif self._tracker.is_second_gen:
name = "GeoRide 2 / GeoRide 3"
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)
def device_info(self):
"""Return the device info."""
return {
"name": self.name,
"identifiers": {(GEORIDE_DOMAIN, self._tracker.tracker_id)},
"manufacturer": "GeoRide",
"model": self.model_name,
"suggested_area": "Garage"
}
@property
def unique_id(self) -> str:
"""Get the unique id."""
return {(GEORIDE_DOMAIN, self._tracker.tracker_id)}
@property
def device_info(self):
"""Return the device info."""
return {
"name": self.name,
"identifiers": self.unique_id,
"manufacturer": self.manufacturer,
"model": self.model_name,
"suggested_area": self.suggested_area,
"sw_version" : self.sw_version,
"hw_version": self.hw_version
}
def __str__(self) -> str:
"""Get string representation."""
return f"GeoRide Device: {self.name}::{self.model_name}::{self.unique_id}"
class DeviceBeacon:
"""Home Assistant representation of a GeoRide Tracker device."""
def __init__(self, beacon):
"""Initialize GeoRideTracker device."""
self._beacon: GeoRideTrackerBeacon = beacon
@property
def beacon(self):
"""return the tracker beacon"""
return self._beacon
@property
def name(self) -> str:
"""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:
"""Get the model name."""
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": self.manufacturer,
"model": self.model_name,
"suggested_area": self.suggested_area,
"via_device": self.via_device
}
def __str__(self) -> str:
"""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

@@ -20,7 +20,7 @@ _LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: disable=W0613
"""Set up Georide tracker based off an entry."""
georide_context = hass.data[GEORIDE_DOMAIN]["context"]
coordoned_trackers = georide_context.georide_trackers_coordoned
coordoned_trackers = georide_context.get_coordoned_trackers()
entities = []
for coordoned_tracker in coordoned_trackers:
@@ -47,10 +47,6 @@ class GeoRideTrackerEntity(CoordinatorEntity, TrackerEntity):
self.entity_id = DOMAIN + ".{}".format(tracker_device.tracker.tracker_id)
self._hass = hass
@property
def entity_category(self):
return None
@property
def unique_id(self):
"""Return the unique ID."""

View File

@@ -3,13 +3,11 @@
"name": "GeoRide",
"config_flow": true,
"documentation": "https://github.com/ptimatth/GeorideHA",
"issue_tracker": "https://github.com/ptimatth/GeorideHA/issues",
"iot_class": "cloud_polling",
"requirements": [
"georideapilib>=0.9.6",
"pyjwt>=2.2.0"
"georideapilib>=0.6.1",
"pyjwt>=1.7.1"
],
"dependencies": [],
"codeowners": ["ptimatth"],
"version": "1.0.0"
"version": "0.7.0"
}

View File

@@ -4,15 +4,15 @@ import logging
from typing import Any, Mapping
from homeassistant.core import callback
from homeassistant.helpers.entity import DeviceInfo, EntityCategory
from homeassistant.components.sensor import SensorEntity, SensorDeviceClass, ENTITY_ID_FORMAT
from homeassistant.components.sensor import SensorEntity
from homeassistant.components.sensor import ENTITY_ID_FORMAT
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
)
from .const import DOMAIN as GEORIDE_DOMAIN
from .device import Device, DeviceBeacon
from .device import Device
_LOGGER = logging.getLogger(__name__)
@@ -21,27 +21,15 @@ _LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: disable=W0613
"""Set up GeoRide tracker based off an entry."""
georide_context = hass.data[GEORIDE_DOMAIN]["context"]
coordoned_trackers = georide_context.georide_trackers_coordoned
coordoned_trackers = georide_context.get_coordoned_trackers()
entities = []
for coordoned_tracker in coordoned_trackers:
tracker_device = coordoned_tracker['tracker_device']
coordinator = coordoned_tracker['coordinator']
entity = GeoRideOdometerSensorEntity(coordinator, tracker_device, hass)
hass.data[GEORIDE_DOMAIN]["devices"][tracker_device.tracker.tracker_id] = coordinator
entities.append(GeoRideOdometerSensorEntity(coordinator, tracker_device, hass))
entities.append(GeoRideOdometerKmSensorEntity(coordinator, tracker_device, hass))
entities.append(GeoRideSpeedSensorEntity(coordinator, tracker_device,hass))
entities.append(GeoRideFixtimeSensorEntity(coordinator, tracker_device))
if tracker_device.tracker.version > 2:
entities.append(GeoRideInternalBatterySensorEntity(coordinator, tracker_device))
entities.append(GeoRideExternalBatterySensorEntity(coordinator, tracker_device))
coordoned_beacons = georide_context.georide_trackers_beacon_coordoned
for coordoned_beacon in coordoned_beacons:
tracker_beacon = coordoned_beacon['tracker_beacon']
coordinator = coordoned_beacon['coordinator']
entities.append(GeoRideBeaconBatterySensorEntity(coordinator, tracker_beacon))
hass.data[GEORIDE_DOMAIN]["devices"][tracker_beacon.beacon.beacon_id] = coordinator
entities.append(entity)
async_add_entities(entities)
@@ -62,10 +50,6 @@ class GeoRideOdometerSensorEntity(CoordinatorEntity, SensorEntity):
self._state = 0
self._hass = hass
@property
def entity_category(self):
return None
@property
def unique_id(self):
"""Return the unique ID."""
@@ -74,8 +58,7 @@ class GeoRideOdometerSensorEntity(CoordinatorEntity, SensorEntity):
@property
def state(self):
"""state property"""
odometer = self._tracker_device.tracker.odometer
return odometer
return self._tracker_device.tracker.odometer
@property
def unit_of_measurement(self):
@@ -93,319 +76,6 @@ class GeoRideOdometerSensorEntity(CoordinatorEntity, SensorEntity):
return "mdi:counter"
@property
def device_info(self) -> DeviceInfo:
def device_info(self):
"""Return the device info."""
return self._tracker_device.device_info
class GeoRideOdometerKmSensorEntity(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"
self.entity_id = f"{ENTITY_ID_FORMAT.format('odometer_km')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
self._state = 0
self._hass = hass
@property
def unique_id(self):
"""Return the unique ID."""
return f"odometer_km_{self._tracker_device.tracker.tracker_id}"
@property
def state(self):
"""state property"""
odometer = self._tracker_device.tracker.odometer // 1000
return odometer
@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} odometer km"
@property
def icon(self):
"""icon getter"""
return "mdi:counter"
@property
def device_info(self) -> DeviceInfo:
"""Return the 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):
"""Represent a tracked device."""
entity_category = EntityCategory.DIAGNOSTIC
def __init__(self, coordinator: DataUpdateCoordinator[Mapping[str, Any]],
tracker_device:Device):
"""Set up GeoRide entity."""
super().__init__(coordinator)
self._tracker_device = tracker_device
self._name = tracker_device.tracker.tracker_name
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._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
def entity_category(self):
return EntityCategory.DIAGNOSTIC
@property
def unique_id(self):
"""Return the unique ID."""
return f"internal_battery_voltage_{self._tracker_device.tracker.tracker_id}"
@property
def state(self):
"""state property"""
return self._tracker_device.tracker.internal_battery_voltage
@property
def unit_of_measurement(self):
"""unit of mesurment property"""
return self._unit_of_measurement
@property
def name(self):
""" GeoRide internal_battery_voltage name """
return f"{self._name} internal_battery_voltage"
@property
def icon(self):
"""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."""
return self._tracker_device.device_info
class GeoRideExternalBatterySensorEntity(CoordinatorEntity, SensorEntity):
"""Represent a tracked device."""
def __init__(self, coordinator: DataUpdateCoordinator[Mapping[str, Any]],
tracker_device:Device):
"""Set up GeoRide entity."""
super().__init__(coordinator)
self._tracker_device = tracker_device
self._name = tracker_device.tracker.tracker_name
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._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
def entity_category(self):
return EntityCategory.DIAGNOSTIC
@property
def unique_id(self):
"""Return the unique ID."""
return f"external_battery_voltage_{self._tracker_device.tracker.tracker_id}"
@property
def state(self):
"""state property"""
return self._tracker_device.tracker.external_battery_voltage
@property
def unit_of_measurement(self):
"""unit of mesurment property"""
return self._unit_of_measurement
@property
def name(self):
""" GeoRide internal_battery_voltage name """
return f"{self._name} external_battery_voltage"
@property
def icon(self):
"""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."""
return self._tracker_device.device_info
class GeoRideFixtimeSensorEntity(CoordinatorEntity, SensorEntity):
"""Represent a tracked device."""
def __init__(self, coordinator: DataUpdateCoordinator[Mapping[str, Any]],
tracker_device:Device):
"""Set up GeoRide entity."""
super().__init__(coordinator)
self._tracker_device = tracker_device
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._state = 0
self._device_class = "timestamp"
@property
def entity_category(self):
return EntityCategory.DIAGNOSTIC
@property
def unique_id(self):
"""Return the unique ID."""
return f"fixtime_{self._tracker_device.tracker.tracker_id}"
@property
def state(self):
"""state property"""
return self._tracker_device.tracker.fixtime
@property
def name(self):
""" GeoRide fixtime name """
return f"{self._name} last fixed position"
@property
def icon(self):
"""icon getter"""
return "mdi:map-clock"
@property
def device_info(self) -> DeviceInfo:
"""Return the device info."""
return self._tracker_device.device_info
class GeoRideBeaconBatterySensorEntity(CoordinatorEntity, SensorEntity):
"""Represent a tracked device."""
def __init__(self, coordinator: DataUpdateCoordinator[Mapping[str, Any]],
tracker_beacon: DeviceBeacon):
"""Set up GeoRide entity."""
super().__init__(coordinator)
self._tracker_device = tracker_beacon
self._name = tracker_beacon.beacon.name
self._unit_of_measurement = "%"
self.entity_id = f"{ENTITY_ID_FORMAT.format('battery_percent')}.{tracker_beacon.beacon.beacon_id}"# pylint: disable=C0301
self._state = 0
@property
def entity_category(self):
return EntityCategory.DIAGNOSTIC
@property
def unique_id(self):
"""Return the unique ID."""
return f"battery_percent_{self._tracker_device.beacon.beacon_id}"
@property
def state(self):
"""state property"""
return self._tracker_device.beacon.battery_level
@property
def unit_of_measurement(self):
"""unit of mesurment property"""
return self._unit_of_measurement
@property
def name(self):
""" GeoRide internal_battery_voltage name """
return f"{self._name} battery percent"
@property
def icon(self):
"""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."""
return self._tracker_device.device_info

View File

@@ -1,96 +0,0 @@
""" device tracker for GeoRide object """
import logging
from typing import Any, Mapping
from homeassistant.components.siren import SirenEntity
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
)
import georideapilib.api as GeoRideApi
from .const import DOMAIN as GEORIDE_DOMAIN
from .device import Device
ENTITY_ID_FORMAT = GEORIDE_DOMAIN + ".{}"
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: disable=W0613
"""Set up GeoRide tracker based off an entry."""
georide_context = hass.data[GEORIDE_DOMAIN]["context"]
coordoned_trackers = georide_context.georide_trackers_coordoned
entities = []
for coordoned_tracker in coordoned_trackers:
tracker_device = coordoned_tracker['tracker_device']
coordinator = coordoned_tracker['coordinator']
hass.data[GEORIDE_DOMAIN]["devices"][tracker_device.tracker.tracker_id] = coordinator
if tracker_device.tracker.version > 2:
entities.append(GeoRideSirenEntity(coordinator, tracker_device, hass))
async_add_entities(entities)
return True
class GeoRideSirenEntity(CoordinatorEntity, SirenEntity):
"""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.entity_id = f"{ENTITY_ID_FORMAT.format('eco_mode')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
self._hass = hass
@property
def entity_category(self):
return None
async def async_turn_on(self, **kwargs):
""" lock the GeoRide tracker """
_LOGGER.info('async_turn_on eco %s', kwargs)
georide_context = self._hass.data[GEORIDE_DOMAIN]["context"]
token = await georide_context.get_token()
success = await self._hass.async_add_executor_job(GeoRideApi.change_tracker_siren_state,
token, self._tracker_device.tracker.tracker_id, True)
if success:
self._tracker_device.tracker.is_siren_on = True
async def async_turn_off(self, **kwargs):
""" unlock the GeoRide tracker """
_LOGGER.info('async_turn_off eco %s', kwargs)
georide_context = self._hass.data[GEORIDE_DOMAIN]["context"]
token = await georide_context.get_token()
success = await self._hass.async_add_executor_job(GeoRideApi.change_tracker_siren_state,
token, self._tracker_device.tracker.tracker_id, False)
if success:
self._tracker_device.tracker.is_siren_on = False
@property
def unique_id(self):
"""Return the unique ID."""
return f"siren_{self._tracker_device.tracker.tracker_id}"
@property
def name(self):
""" GeoRide odometer name """
return f"{self._name} siren"
@property
def is_on(self):
""" GeoRide switch status """
return self._tracker_device.tracker.is_siren_on
@property
def device_info(self):
"""Return the device info."""
return self._tracker_device.device_info

View File

@@ -24,18 +24,17 @@ _LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: disable=W0613
"""Set up GeoRide tracker based off an entry."""
georide_context = hass.data[GEORIDE_DOMAIN]["context"]
coordoned_trackers = georide_context.georide_trackers_coordoned
coordoned_trackers = georide_context.get_coordoned_trackers()
entities = []
lock_switch_entities = []
for coordoned_tracker in coordoned_trackers:
tracker_device = coordoned_tracker['tracker_device']
coordinator = coordoned_tracker['coordinator']
entity = GeoRideLockSwitchEntity(coordinator, tracker_device, hass)
hass.data[GEORIDE_DOMAIN]["devices"][tracker_device.tracker.tracker_id] = coordinator
entities.append(GeoRideLockSwitchEntity(coordinator, tracker_device, hass))
if tracker_device.tracker.version > 2:
entities.append(GeoRideEcoModeSwitchEntity(coordinator, tracker_device, hass))
lock_switch_entities.append(entity)
async_add_entities(entities)
async_add_entities(lock_switch_entities)
return True
@@ -51,10 +50,6 @@ class GeoRideLockSwitchEntity(CoordinatorEntity, SwitchEntity):
self.entity_id = f"{ENTITY_ID_FORMAT.format('lock')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
self._hass = hass
@property
def entity_category(self):
return None
async def async_turn_on(self, **kwargs):
""" lock the GeoRide tracker """
_LOGGER.info('async_turn_on %s', kwargs)
@@ -110,66 +105,3 @@ class GeoRideLockSwitchEntity(CoordinatorEntity, SwitchEntity):
def device_info(self):
"""Return the device info."""
return self._tracker_device.device_info
class GeoRideEcoModeSwitchEntity(CoordinatorEntity, SwitchEntity):
"""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.entity_id = f"{ENTITY_ID_FORMAT.format('eco_mode')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
self._hass = hass
@property
def entity_category(self):
return None
async def async_turn_on(self, **kwargs):
""" lock the GeoRide tracker """
_LOGGER.info('async_turn_on eco %s', kwargs)
georide_context = self._hass.data[GEORIDE_DOMAIN]["context"]
token = await georide_context.get_token()
success = await self._hass.async_add_executor_job(GeoRideApi.change_tracker_eco_mode_state,
token, self._tracker_device.tracker.tracker_id, True)
if success:
self._tracker_device.tracker.is_in_eco = True
async def async_turn_off(self, **kwargs):
""" unlock the GeoRide tracker """
_LOGGER.info('async_turn_off eco %s', kwargs)
georide_context = self._hass.data[GEORIDE_DOMAIN]["context"]
token = await georide_context.get_token()
success = await self._hass.async_add_executor_job(GeoRideApi.change_tracker_eco_mode_state,
token, self._tracker_device.tracker.tracker_id, False)
if success:
self._tracker_device.tracker.is_in_eco = False
@property
def unique_id(self):
"""Return the unique ID."""
return f"eco_mode_{self._tracker_device.tracker.tracker_id}"
@property
def name(self):
""" GeoRide odometer name """
return f"{self._name} eco mode"
@property
def is_on(self):
""" GeoRide switch status """
return self._tracker_device.tracker.is_in_eco
@property
def icon(self):
"""return the entity icon"""
if self._tracker_device.tracker.is_in_eco:
return "mdi:battery-heart-variant"
return "mdi:battery"
@property
def device_info(self):
"""Return the device info."""
return self._tracker_device.device_info

View File

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