From 953d69db8edf43652d4080584f7ac8a16b9fad9d Mon Sep 17 00:00:00 2001 From: Matthieu Date: Sun, 27 Oct 2019 13:51:08 +0100 Subject: [PATCH] Add lock/unlock support --- custom_components/georide/__init__.py | 35 ++----- custom_components/georide/device_tracker.py | 42 +++----- custom_components/georide/manifest.json | 3 +- custom_components/georide/switch.py | 105 ++++++++++++++++++++ 4 files changed, 129 insertions(+), 56 deletions(-) create mode 100644 custom_components/georide/switch.py diff --git a/custom_components/georide/__init__.py b/custom_components/georide/__init__.py index 7743236..d7c3fcf 100644 --- a/custom_components/georide/__init__.py +++ b/custom_components/georide/__init__.py @@ -71,12 +71,17 @@ async def async_setup_entry(hass, entry): hass.data[DOMAIN]["context"] = context hass.async_create_task(hass.config_entries.async_forward_entry_setup(entry, "device_tracker")) + hass.async_create_task(hass.config_entries.async_forward_entry_setup(entry, "switch")) + + return True async def async_unload_entry(hass, entry): """Unload an Georide config entry.""" await hass.config_entries.async_forward_entry_unload(entry, "device_tracker") + await hass.config_entries.async_forward_entry_unload(entry, "switch") + hass.data[DOMAIN]["unsub"]() return True @@ -117,30 +122,10 @@ class GeorideContext: def georide_trackers(self): """ georide tracker list """ return self._georide_trackers - + + @callback - def async_see_beacons(self, hass, dev_id, kwargs_param): - """Set active beacons to the current location.""" - kwargs = kwargs_param.copy() - - # Mobile beacons should always be set to the location of the - # tracking device. I get the device state and make the necessary - # changes to kwargs. - device_tracker_state = hass.states.get(f"device_tracker.{dev_id}") - - if device_tracker_state is not None: - lat = device_tracker_state.attributes.get("latitude") - lon = device_tracker_state.attributes.get("longitude") - - if lat is not None and lon is not None: - kwargs["gps"] = (lat, lon) - else: - kwargs["gps"] = None - - for tracker in self.georide_trackers[dev_id]: - kwargs["dev_id"] = f"{TRACKER_ID}_{tracker}" - kwargs["host_name"] = tracker - - - + def async_get_token(self): + """ here we return the current valid tocken, TODO: add here token expiration control""" + return self._token diff --git a/custom_components/georide/device_tracker.py b/custom_components/georide/device_tracker.py index 8651b1e..a95c806 100644 --- a/custom_components/georide/device_tracker.py +++ b/custom_components/georide/device_tracker.py @@ -3,17 +3,11 @@ import logging from homeassistant.core import callback -from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE from homeassistant.components.device_tracker.const import ENTITY_ID_FORMAT, SOURCE_TYPE_GPS -from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.components.device_tracker.config_entry import TrackerEntity import georideapilib.api as GeorideApi -from .const import ( - CONF_TOKEN -) - from . import DOMAIN as GEORIDE_DOMAIN @@ -27,11 +21,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: d if georide_context.token is None: return False - _LOGGER.info('Current georide token: %s', georide_context.token) + _LOGGER.info('Current georide token: %s', georide_context.async_get_token()) - """TODO: add here token expiration control""" - trackers = GeorideApi.get_trackers(georide_context.token) + trackers = GeorideApi.get_trackers(georide_context.async_get_token()) tracker_entities = [] @@ -45,7 +38,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): # pylint: d return True -class GeorideTrackerEntity(TrackerEntity, RestoreEntity): +class GeorideTrackerEntity(TrackerEntity): """Represent a tracked device.""" def __init__(self, tracker_id, name, data=None): @@ -84,31 +77,22 @@ class GeorideTrackerEntity(TrackerEntity, RestoreEntity): def source_type(self): """Return the source type, eg gps or router, of the device.""" return SOURCE_TYPE_GPS + + @property + def location_accuracy(self): + """ return the gps accuracy of georide (could not be aquired, then 10) """ + return 10 @property def device_info(self): """Return the device info.""" - return {"name": self.name, "identifiers": {(GEORIDE_DOMAIN, self._tracker_id)}} - - async def async_added_to_hass(self): - """Call when entity about to be added to Home Assistant.""" - await super().async_added_to_hass() - - # Don't restore if we got set up with data. - if self._data: - return - - state = await self.async_get_last_state() - - if state is None: - return - - attr = state.attributes - self._data = { - "host_name": state.name, - "gps": (attr.get(ATTR_LATITUDE), attr.get(ATTR_LONGITUDE)), + return { + "name": self.name, + "identifiers": {(GEORIDE_DOMAIN, self._tracker_id)}, + "manufacturer": "GeoRide" } + @callback def update_data(self, data): """Mark the device as seen.""" diff --git a/custom_components/georide/manifest.json b/custom_components/georide/manifest.json index c4e74da..e0fb5e8 100644 --- a/custom_components/georide/manifest.json +++ b/custom_components/georide/manifest.json @@ -4,8 +4,7 @@ "config_flow": true, "documentation": "https://git.tontontux.fr/mduval/GeorideHA", "requirements": [ - "georideapilib>=0.2.0", - "urllib3>=1.25.6" + "georideapilib>=0.2.0" ], "dependencies": [], "codeowners": ["@ptimatth"] diff --git a/custom_components/georide/switch.py b/custom_components/georide/switch.py new file mode 100644 index 0000000..883ab05 --- /dev/null +++ b/custom_components/georide/switch.py @@ -0,0 +1,105 @@ +""" device tracker for Georide object """ + +import logging + +from homeassistant.components.switch import SwitchDevice +from homeassistant.components.switch import ENTITY_ID_FORMAT + +import georideapilib.api as GeorideApi + +from . import DOMAIN as 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"] + + if georide_context.token is None: + return False + + _LOGGER.info('Current georide token: %s', georide_context.async_get_token()) + + trackers = GeorideApi.get_trackers(georide_context.async_get_token()) + + + lock_switch_entities = [] + for tracker in trackers: + entity = GeorideLockSwitchEntity(tracker.tracker_id, tracker.tracker_name, + georide_context.async_get_token, data=tracker) + hass.data[GEORIDE_DOMAIN]["devices"][tracker.tracker_id] = entity + lock_switch_entities.append(entity) + + async_add_entities(lock_switch_entities) + + return True + + +class GeorideLockSwitchEntity(SwitchDevice): + """Represent a tracked device.""" + + def __init__(self, tracker_id, name, token_callback, data): + """Set up Georide entity.""" + self._tracker_id = tracker_id + self._name = name + self._data = data or {} + self._token_callback = token_callback + self._is_on = data.is_locked + self.entity_id = ENTITY_ID_FORMAT.format("lock."+str(tracker_id)) + + + async def async_turn_on(self, **kwargs): + """ lock the georide tracker """ + _LOGGER.info('async_turn_on %s', kwargs) + success = GeorideApi.lock_tracker(self.token_callback(), self._tracker_id) + if success: + self._is_on = True + + async def async_turn_off(self, **kwargs): + """ unlock the georide tracker """ + _LOGGER.info('async_turn_off %s', kwargs) + success = GeorideApi.unlock_tracker(self.token_callback(), self._tracker_id) + if success: + self._is_on = False + + async def async_toggle(self, **kwargs): + """ toggle lock the georide tracker """ + _LOGGER.info('async_toggle %s', kwargs) + self._is_on = GeorideApi.toogle_lock_tracker(self.token_callback(), self._tracker_id) + + async def async_update(self): + """ update the current tracker""" + _LOGGER.info('async_update ') + + + @property + def unique_id(self): + """Return the unique ID.""" + return self._tracker_id + + @property + def name(self): + """ Georide switch name """ + return self._name + + @property + def is_on(self): + """ Georide switch status """ + return self._is_on + + @property + def token_callback(self): + """ Georide switch token callback method """ + return self._token_callback + + + @property + def device_info(self): + """Return the device info.""" + return { + "name": self.name, + "identifiers": {(GEORIDE_DOMAIN, self._tracker_id)}, + "manufacturer": "GeoRide" + }