Skip to content

Commit

Permalink
Device tracker add gps (#120)
Browse files Browse the repository at this point in the history
* Add GPS to device tracker.

* Add GPS to device tracker.

* Add GPS to device tracker.

* Add GPS to device tracker.
  • Loading branch information
twrecked committed Aug 15, 2024
1 parent 50dfaac commit d3abf40
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 11 deletions.
1 change: 1 addition & 0 deletions changelog
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
0.9.0b12:
Fix fan support.
Fix cover service calls.
Add GPS to device tracker
0.9.0b11:
Fix up light support.
Fix race condition in meta data write
Expand Down
60 changes: 52 additions & 8 deletions custom_components/virtual/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@
SourceType,
TrackerEntity,
)
from homeassistant.components.zone import ATTR_RADIUS
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_LATITUDE,
ATTR_LONGITUDE
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA

Expand All @@ -28,6 +33,7 @@
DEPENDENCIES = [COMPONENT_DOMAIN]

CONF_LOCATION = 'location'
CONF_GPS = 'gps'
DEFAULT_DEVICE_TRACKER_VALUE = 'home'

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(virtual_schema(DEFAULT_DEVICE_TRACKER_VALUE, {
Expand All @@ -38,7 +44,12 @@
SERVICE_MOVE = "move"
SERVICE_SCHEMA = vol.Schema({
vol.Required(ATTR_ENTITY_ID): cv.comp_entity_ids,
vol.Required(CONF_LOCATION): cv.string,
vol.Optional(CONF_LOCATION): cv.string,
vol.Optional(CONF_GPS): {
vol.Required(ATTR_LATITUDE): cv.latitude,
vol.Required(ATTR_LONGITUDE): cv.longitude,
vol.Optional(ATTR_RADIUS): cv.string,
},
})


Expand Down Expand Up @@ -84,6 +95,7 @@ def __init__(self, config):
super().__init__(config, PLATFORM_DOMAIN)

self._location = None
self._coords = {}

_LOGGER.debug(f"{self._attr_name}, available={self._attr_available}")
_LOGGER.debug(f"{self._attr_name}, entity={self.entity_id}")
Expand All @@ -96,12 +108,23 @@ def _create_state(self, config):
def _restore_state(self, state, config):
_LOGGER.debug(f"device_tracker-restore=state={state.state}")
_LOGGER.debug(f"device_tracker-restore=attrs={state.attributes}")

if ATTR_AVAILABLE not in state.attributes:
_LOGGER.debug("looks wrong, from upgrade? creating instead...")
self._create_state(config)
return

super()._restore_state(state, config)
if ATTR_LONGITUDE in state.attributes and ATTR_LATITUDE in state.attributes:
self._location = None
self._coords = {
ATTR_LONGITUDE: state.attributes[ATTR_LONGITUDE],
ATTR_LATITUDE: state.attributes[ATTR_LATITUDE],
ATTR_RADIUS: 0
}
else:
super()._restore_state(state, config)
self._location = state.state
self._coords = {}

@property
def location_name(self) -> str | None:
Expand All @@ -115,20 +138,41 @@ def source_type(self) -> SourceType | str:
@property
def latitude(self) -> float | None:
"""Return latitude value of the device."""
return None
return self._coords.get(ATTR_LATITUDE, None)

@property
def longitude(self) -> float | None:
"""Return longitude value of the device."""
return None
return self._coords.get(ATTR_LONGITUDE, None)

def move(self, new_location):
def move_to_location(self, new_location):
_LOGGER.debug(f"{self._attr_name} moving to {new_location}")
self._location = new_location
self._coords = {}
self.async_schedule_update_ha_state()

def move_to_coords(self, new_coords):
_LOGGER.debug(f"{self._attr_name} moving via GPS to {new_coords}")
self._location = None
self._coords = new_coords
self.async_schedule_update_ha_state()


async def async_virtual_move_service(hass, call):
for entity_id in call.data['entity_id']:
_LOGGER.debug(f"moving {entity_id}")
get_entity_from_domain(hass, PLATFORM_DOMAIN, entity_id).move(call.data[CONF_LOCATION])
_LOGGER.debug(f"moving {entity_id} --> {call.data}")

entity = get_entity_from_domain(hass, PLATFORM_DOMAIN, entity_id)
if entity is None:
_LOGGER.debug(f"can't find {entity_id}")
return

location = call.data.get(CONF_LOCATION, None)
coords = call.data.get(CONF_GPS, None)
if location is not None:
entity.move_to_location(location)
elif coords is not None:
entity.move_to_coords(coords)
else:
_LOGGER.debug(f"not moving {entity_id}")

10 changes: 8 additions & 2 deletions custom_components/virtual/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,15 @@ move:
domain: device_tracker
fields:
location:
name: Location
name: Named Location
description: Where to move the device tracker to.
required: true
example: 'home'
selector:
text:
gps:
name: GPS Location
description: Which coordinates to move the device tracker to.
example: '{"latitude": -27.9699373, "longitude": 153.4081865}'
selector:
location:
radius: false
6 changes: 5 additions & 1 deletion custom_components/virtual/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@
"fields": {
"location": {
"name": "Location",
"description": "Where to move the device tracker to."
"description": "A named location to move the device tracker to."
},
"gps": {
"name": "GPS",
"description": "Which coordinates to move the device tracker to."
}
}
}
Expand Down

0 comments on commit d3abf40

Please sign in to comment.