Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ See [HACS](https://github.com/custom-components/hacs).
Alternatively, place a copy of:

[`__init__.py`](custom_components/composite/__init__.py) at `<config>/custom_components/composite/__init__.py`
[`const.py`](custom_components/composite/const.py) at `<config>/custom_components/composite/const.py`
[`device_tracker.py`](custom_components/composite/device_tracker.py) at `<config>/custom_components/composite/device_tracker.py`
[`manifest.json`](custom_components/composite/manifest.json) at `<config>/custom_components/composite/manifest.json`

Expand All @@ -37,13 +38,21 @@ where `<config>` is your Home Assistant configuration directory.

### numpy on Raspberry Pi

To determine time zone from GPS coordinates (see `time_as` configuration variable below) the package [timezonefinderL](https://pypi.org/project/timezonefinderL/) is used. That package requires the package [numpy](https://pypi.org/project/numpy/). These will both be installed automatically by HA. Note, however, that numpy on Pi _usually_ requires libatlas to be installed. (See [this web page](https://www.raspberrypi.org/forums/viewtopic.php?t=207058) for more details.) It can be installed using this command:
To determine time zone from GPS coordinates (see `time_as` configuration variable below) the package [timezonefinderL](https://pypi.org/project/timezonefinderL/) (by default) is used. That package requires the package [numpy](https://pypi.org/project/numpy/). These will both be installed automatically by HA. Note, however, that numpy on Pi _usually_ requires libatlas to be installed. (See [this web page](https://www.raspberrypi.org/forums/viewtopic.php?t=207058) for more details.) It can be installed using this command:
```
sudo apt install libatlas3-base
```
>Note: This is the same step that would be required if using a standard HA component that uses numpy (such as the [Trend Binary Sensor](https://www.home-assistant.io/components/binary_sensor.trend/)), and is only required if you use `device_or_utc` or `device_or_local` for `time_as`.

## Configuration variables
### `composite` integration

- **tz_finder** (*Optional*): Specifies which `timezonefinder` package, and possibly version, to install. Must be formatted as required by `pip`. Default is `timezonefinderL==4.0.2`. Other common values:

`timezonefinderL==2.0.1`
`timezonefinder`
`timezonefinder==4.2.0`
### `device_tracker` platform

- **entity_id**: Entity IDs of watched device tracker devices. Can be a single entity ID, a list of entity IDs, or a string containing multiple entity IDs separated by commas.
- **name**: Object ID (i.e., part of entity ID after the dot) of composite device. For example, `NAME` would result in an entity ID of `device_tracker.NAME`.
Expand Down Expand Up @@ -84,6 +93,20 @@ source_type | Source of current location information: `binary_sensor`, `bluetoot
time_zone | The name of the time zone in which the device is located, or `unknown` if it cannot be determined. Only exists if `device_or_utc` or `device_or_local` is chosen for `time_as`.

## Examples
### Example Full Config
```yaml
composite:
tz_finder: timezonefinderL==2.0.1
device_tracker:
- platform: composite
name: me
time_as: device_or_local
require_movement: true
entity_id:
- device_tracker.platform1_me
- device_tracker.platform2_me
```

### Time zone examples

This example assumes `time_as` is set to `device_or_utc` or `device_or_local`. It determines the difference between the time zone in which the device is located and the `time_zone` in HA's configuration. A positive value means the device's time zone is ahead of (or later than, or east of) the local time zone.
Expand Down
52 changes: 52 additions & 0 deletions custom_components/composite/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,53 @@
"""Composite Device Tracker."""
import asyncio
import logging

import voluptuous as vol

from homeassistant.requirements import (
async_process_requirements, RequirementsNotFound)
from homeassistant.components.device_tracker import DOMAIN as DT_DOMAIN
from homeassistant.const import CONF_PLATFORM
import homeassistant.helpers.config_validation as cv

from .const import CONF_TIME_AS, DOMAIN, TZ_DEVICE_LOCAL, TZ_DEVICE_UTC

__version__ = '2.0.0'

CONF_TZ_FINDER = 'tz_finder'
DEFAULT_TZ_FINDER = 'timezonefinderL==4.0.2'

CONFIG_SCHEMA = vol.Schema({
vol.Optional(DOMAIN, default=dict): vol.Schema({
vol.Optional(CONF_TZ_FINDER, default=DEFAULT_TZ_FINDER):
cv.string,
}),
}, extra=vol.ALLOW_EXTRA)

_LOGGER = logging.getLogger(__name__)


def setup(hass, config):
if (any(conf[CONF_TIME_AS] in (TZ_DEVICE_UTC, TZ_DEVICE_LOCAL)
for conf in (config.get(DT_DOMAIN) or [])
if conf[CONF_PLATFORM] == DOMAIN)):
pkg = config[DOMAIN][CONF_TZ_FINDER]
try:
asyncio.run_coroutine_threadsafe(
async_process_requirements(
hass, '{}.{}'.format(DOMAIN, DT_DOMAIN), [pkg]),
hass.loop
).result()
except RequirementsNotFound:
_LOGGER.debug('Process requirements failed: %s', pkg)
return False
else:
_LOGGER.debug('Process requirements suceeded: %s', pkg)

if pkg.split('==')[0].strip().endswith('L'):
from timezonefinderL import TimezoneFinder
else:
from timezonefinder import TimezoneFinder
hass.data[DOMAIN] = TimezoneFinder()

return True
12 changes: 12 additions & 0 deletions custom_components/composite/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""Constants for Composite Integration."""
DOMAIN = 'composite'

CONF_REQ_MOVEMENT = 'require_movement'
CONF_TIME_AS = 'time_as'

TZ_UTC = 'utc'
TZ_LOCAL = 'local'
TZ_DEVICE_UTC = 'device_or_utc'
TZ_DEVICE_LOCAL = 'device_or_local'
# First item in list is default.
TIME_AS_OPTS = [TZ_UTC, TZ_LOCAL, TZ_DEVICE_UTC, TZ_DEVICE_LOCAL]
19 changes: 5 additions & 14 deletions custom_components/composite/device_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,11 @@
import homeassistant.util.dt as dt_util
from homeassistant.util.location import distance

_LOGGER = logging.getLogger(__name__)

__version__ = '1.11.2'
from .const import (
CONF_REQ_MOVEMENT, CONF_TIME_AS, DOMAIN, TIME_AS_OPTS, TZ_DEVICE_LOCAL,
TZ_DEVICE_UTC, TZ_LOCAL, TZ_UTC)

CONF_TIME_AS = 'time_as'
CONF_REQ_MOVEMENT = 'require_movement'

TZ_UTC = 'utc'
TZ_LOCAL = 'local'
TZ_DEVICE_UTC = 'device_or_utc'
TZ_DEVICE_LOCAL = 'device_or_local'
# First item in list is default.
TIME_AS_OPTS = [TZ_UTC, TZ_LOCAL, TZ_DEVICE_UTC, TZ_DEVICE_LOCAL]
_LOGGER = logging.getLogger(__name__)

ATTR_CHARGING = 'charging'
ATTR_LAST_SEEN = 'last_seen'
Expand Down Expand Up @@ -95,8 +87,7 @@ def __init__(self, hass, config, see):
self._entity_id = ENTITY_ID_FORMAT.format(self._dev_id)
self._time_as = config[CONF_TIME_AS]
if self._time_as in [TZ_DEVICE_UTC, TZ_DEVICE_LOCAL]:
from timezonefinderL import TimezoneFinder
self._tf = TimezoneFinder()
self._tf = hass.data[DOMAIN]
self._req_movement = config[CONF_REQ_MOVEMENT]
self._lock = threading.Lock()
self._prev_seen = None
Expand Down
8 changes: 2 additions & 6 deletions custom_components/composite/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
"domain": "composite",
"name": "Composite",
"documentation": "https://github.com/pnbruckner/homeassistant-config/blob/master/docs/composite.md",
"requirements": [
"timezonefinderL==4.0.2"
],
"requirements": [],
"dependencies": [],
"codeowners": [
"@pnbruckner"
]
"codeowners": ["@pnbruckner"]
}