Compare commits

..

11 Commits
0.7.0 ... 0.8.2

Author SHA1 Message Date
7d809c2105 Shipping v0.8.2 2022-03-03 20:40:02 +01:00
af12cd70e4 Add cloud and issue info 2022-03-03 20:30:24 +01:00
e59c8cb195 Shipping v0.8.1 2021-10-10 13:09:57 +02:00
b17f38ee66 Fix #4 jwt decode afater update of hA to pyjwt 2.1.0 2021-10-10 13:06:26 +02:00
5af8e7dc5d Shipping v0.8.0, thx to @Inervo 2021-08-30 20:14:56 +02:00
fe073cff55 Merge PR #3 2021-08-30 20:09:10 +02:00
9053f95bc1 Shipping v0.7.2 2021-07-13 20:37:32 +02:00
a3c5d2db6e Fix data.name unsted of data['name'] 2021-07-13 20:36:19 +02:00
fc383ff373 Shipping v0.7.1 2021-07-05 18:42:57 +02:00
c295c8848c Change version 2021-07-05 18:41:22 +02:00
29f42a75c9 Fix alarm event trigger 2021-07-05 18:39:07 +02:00
6 changed files with 281 additions and 30 deletions

View File

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

View File

@@ -184,7 +184,7 @@ class GeoRideContext:
async def get_token(self): async def get_token(self):
""" here we return the current valid tocken """ """ here we return the current valid tocken """
jwt_data = jwt.decode(self._token, verify=False) jwt_data = jwt.decode(self._token, options={"verify_signature": False})
exp_timestamp = jwt_data['exp'] exp_timestamp = jwt_data['exp']
epoch = math.ceil(time.time()) epoch = math.ceil(time.time())
@@ -329,41 +329,41 @@ class GeoRideContext:
tracker = coordoned_tracker['tracker_device'].tracker tracker = coordoned_tracker['tracker_device'].tracker
coordinator = coordoned_tracker['coordinator'] coordinator = coordoned_tracker['coordinator']
if tracker.tracker_id == data['trackerId']: if tracker.tracker_id == data['trackerId']:
if data.name == 'vibration': if data['name'] == 'vibration':
_LOGGER.info("Vibration detected") _LOGGER.info("Vibration detected")
elif data.name == 'exitZone': elif data['name'] == 'exitZone':
_LOGGER.info("Exit zone detected") _LOGGER.info("Exit zone detected")
elif data.name == 'crash': elif data['name'] == 'crash':
_LOGGER.info("Crash detected") _LOGGER.info("Crash detected")
elif data.name == 'crashParking': elif data['name'] == 'crashParking':
_LOGGER.info("Crash parking detected") _LOGGER.info("Crash parking detected")
elif data.name == 'deviceOffline': elif data['name'] == 'deviceOffline':
_LOGGER.info("Device offline detected") _LOGGER.info("Device offline detected")
elif data.name == 'deviceOnline': elif data['name'] == 'deviceOnline':
_LOGGER.info("Device online detected") _LOGGER.info("Device online detected")
elif data.name == 'powerCut': elif data['name'] == 'powerCut':
_LOGGER.info("powerCut detected") _LOGGER.info("powerCut detected")
elif data.name == 'powerUncut': elif data['name'] == 'powerUncut':
_LOGGER.info("powerUncut detected") _LOGGER.info("powerUncut detected")
elif data.name == 'batteryWarning': elif data['name'] == 'batteryWarning':
_LOGGER.info("batteryWarning detected") _LOGGER.info("batteryWarning detected")
elif data.name == 'temperatureWarning': elif data['name'] == 'temperatureWarning':
_LOGGER.info("temperatureWarning detected") _LOGGER.info("temperatureWarning detected")
elif data.name == 'magnetOn': elif data['name'] == 'magnetOn':
_LOGGER.info("magnetOn detected") _LOGGER.info("magnetOn detected")
elif data.name == 'magnetOff': elif data['name'] == 'magnetOff':
_LOGGER.info("magnetOff detected") _LOGGER.info("magnetOff detected")
elif data.name == 'sonorAlarmOn': elif data['name'] == 'sonorAlarmOn':
_LOGGER.info("sonorAlarmOn detected") _LOGGER.info("sonorAlarmOn detected")
else: else:
_LOGGER.warning("Unmanaged alarm: %s", data.name) _LOGGER.warning("Unmanaged alarm: %s", data["name"])
event_data = { event_data = {
"device_id": tracker.tracker_id, "device_id": tracker.tracker_id,
"device_name": tracker.tracker_name, "device_name": tracker.tracker_name,
"type": f"alarm_{data.name}" "type": f"alarm_{data['name']}"
} }
self._hass.bus.fire(f"{DOMAIN}_alarm_event", event_data) self._hass.bus.async_fire(f"{DOMAIN}_alarm_event", event_data)
asyncio.run_coroutine_threadsafe( asyncio.run_coroutine_threadsafe(
coordinator.async_request_refresh(), self._hass.loop coordinator.async_request_refresh(), self._hass.loop
).result() ).result()

View File

@@ -30,6 +30,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: d
entities.append(GeoRideCrashedBinarySensorEntity(coordinator, tracker_device)) entities.append(GeoRideCrashedBinarySensorEntity(coordinator, tracker_device))
entities.append(GeoRideOwnerBinarySensorEntity(coordinator, tracker_device)) entities.append(GeoRideOwnerBinarySensorEntity(coordinator, tracker_device))
entities.append(GeoRideActiveSubscriptionBinarySensorEntity(coordinator, tracker_device)) entities.append(GeoRideActiveSubscriptionBinarySensorEntity(coordinator, tracker_device))
entities.append(GeoRideNetworkBinarySensorEntity(coordinator, tracker_device))
entities.append(GeoRideMovingBinarySensorEntity(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
@@ -68,6 +70,11 @@ class GeoRideStolenBinarySensorEntity(GeoRideBinarySensorEntity):
"""Return the unique ID.""" """Return the unique ID."""
return f"is_stolen_{self._tracker_device.tracker.tracker_id}" return f"is_stolen_{self._tracker_device.tracker.tracker_id}"
@property
def device_class(self):
"""Return the device class."""
return "problem"
@property @property
def is_on(self): def is_on(self):
"""state value property""" """state value property"""
@@ -93,6 +100,11 @@ class GeoRideCrashedBinarySensorEntity(GeoRideBinarySensorEntity):
"""Return the unique ID.""" """Return the unique ID."""
return f"is_crashed_{self._tracker_device.tracker.tracker_id}" return f"is_crashed_{self._tracker_device.tracker.tracker_id}"
@property
def device_class(self):
"""Return the device class."""
return "problem"
@property @property
def is_on(self): def is_on(self):
"""state value property""" """state value property"""
@@ -154,4 +166,63 @@ class GeoRideOwnerBinarySensorEntity(GeoRideBinarySensorEntity):
def name(self): def name(self):
""" GeoRide odometer name """ """ GeoRide odometer name """
return f"{self._name} is own tracker" 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 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 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 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 name(self):
""" GeoRide name """
return f"{self._name} is moving"

View File

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

View File

@@ -27,9 +27,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: d
for coordoned_tracker in coordoned_trackers: for coordoned_tracker in coordoned_trackers:
tracker_device = coordoned_tracker['tracker_device'] tracker_device = coordoned_tracker['tracker_device']
coordinator = coordoned_tracker['coordinator'] coordinator = coordoned_tracker['coordinator']
entity = GeoRideOdometerSensorEntity(coordinator, tracker_device, hass)
hass.data[GEORIDE_DOMAIN]["devices"][tracker_device.tracker.tracker_id] = coordinator hass.data[GEORIDE_DOMAIN]["devices"][tracker_device.tracker.tracker_id] = coordinator
entities.append(entity) entities.append(GeoRideOdometerSensorEntity(coordinator, tracker_device, hass))
entities.append(GeoRideOdometerKmSensorEntity(coordinator, tracker_device, hass))
entities.append(GeoRideInternalBatterySensorEntity(coordinator, tracker_device))
entities.append(GeoRideExternalBatterySensorEntity(coordinator, tracker_device))
entities.append(GeoRideFixtimeSensorEntity(coordinator, tracker_device))
async_add_entities(entities) async_add_entities(entities)
@@ -58,7 +61,8 @@ class GeoRideOdometerSensorEntity(CoordinatorEntity, SensorEntity):
@property @property
def state(self): def state(self):
"""state property""" """state property"""
return self._tracker_device.tracker.odometer odometer = self._tracker_device.tracker.odometer
return odometer
@property @property
def unit_of_measurement(self): def unit_of_measurement(self):
@@ -79,3 +83,176 @@ class GeoRideOdometerSensorEntity(CoordinatorEntity, SensorEntity):
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.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):
"""Return the device info."""
return self._tracker_device.device_info
class GeoRideInternalBatterySensorEntity(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('internal_battery_voltage')}.{tracker_device.tracker.tracker_id}"# pylint: disable=C0301
self._state = 0
@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_info(self):
"""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
@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_info(self):
"""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 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):
"""Return the device info."""
return self._tracker_device.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": "2021.6.0" "homeassistant": "2022.2.0"
} }