Skip to content

Commit

Permalink
Update README with info about polling policy
Browse files Browse the repository at this point in the history
  • Loading branch information
Olen committed Jan 17, 2022
2 parents 62bf77c + 84282cc commit b1237c6
Show file tree
Hide file tree
Showing 12 changed files with 326 additions and 199 deletions.
16 changes: 8 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ repos:
rev: 5.7.0
hooks:
- id: isort
- repo: local
hooks:
- id: pytest-check
name: pytest-check
entry: pytest
language: system
pass_filenames: false
always_run: true
# - repo: local
# hooks:
# - id: pytest-check
# name: pytest-check
# entry: pytest
# language: system
# pass_filenames: false
# always_run: true
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

<!--next-version-placeholder-->

## v1.5.0 (2022-01-15)
### Feature
* Add set polling policy in configuration ([#127](https://github.com/alandtse/tesla/issues/127)) ([`2814149`](https://github.com/alandtse/tesla/commit/28141491eb8c5c3e53792ea900f91a1fc77c087c))
* Add polling interval service ([#128](https://github.com/alandtse/tesla/issues/128)) ([`3b2d8bc`](https://github.com/alandtse/tesla/commit/3b2d8bc4be6ba6d00e15356f94eed4c2d4dde9e1))

### Documentation
* Add chromium-tesla-token-generator to app list ([#123](https://github.com/alandtse/tesla/issues/123)) ([`33663fb`](https://github.com/alandtse/tesla/commit/33663fb9942d7d6f0ef4a119446132527a090e10))

## v1.4.0 (2021-12-11)
### Feature
* Add horn and flash lights buttons ([#114](https://github.com/alandtse/tesla/issues/114)) ([`1c39e63`](https://github.com/alandtse/tesla/commit/1c39e63b458fc70298ad7c16521a7612fcb8dd29))
Expand Down
26 changes: 16 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ A fork of the [official Tesla integration](https://www.home-assistant.io/integra
This is the successor to the core app which was removed due to Tesla login issues. Do not report issues to Home Assistant.

To use the component, you will need an application to generate a Tesla refresh token:
- Android: [Tesla Tokens](https://play.google.com/store/apps/details?id=net.leveugle.teslatokens)
- iOS: [Auth App for Tesla](https://apps.apple.com/us/app/auth-app-for-tesla/id1552058613)
- TeslaFi: [Tesla v3 API Tokens](https://support.teslafi.com/en/communities/1/topics/16979-tesla-v3-api-tokens)
- Chromium/Edge: [Chromium Tesla Token Generator](https://github.com/DoctorMcKay/chromium-tesla-token-generator)

- Android: [Tesla Tokens](https://play.google.com/store/apps/details?id=net.leveugle.teslatokens)
- iOS: [Auth App for Tesla](https://apps.apple.com/us/app/auth-app-for-tesla/id1552058613)
- TeslaFi: [Tesla v3 API Tokens](https://support.teslafi.com/en/communities/1/topics/16979-tesla-v3-api-tokens)
- Chromium/Edge: [Chromium Tesla Token Generator](https://github.com/DoctorMcKay/chromium-tesla-token-generator)

## Installation

1. Use [HACS](https://hacs.xyz/docs/setup/download), in `HACS > Integrations > Explore & Add Repositories` search for "Tesla". After adding this `https://github.com/alandtse/tesla` as a custom repository. Skip to 7.
1. Use [HACS](https://hacs.xyz/docs/setup/download), in `HACS > Integrations > Explore & Add Repositories` search for "Tesla". After adding this `https://github.com/alandtse/tesla` as a custom repository. Skip to 7.
2. If no HACS, use the tool of choice to open the directory (folder) for your HA configuration (where you find `configuration.yaml`).
3. If you do not have a `custom_components` directory (folder) there, you need to create it.
4. In the `custom_components` directory (folder) create a new folder called `tesla_custom`.
Expand All @@ -35,9 +37,10 @@ To use the component, you will need an application to generate a Tesla refresh t
8. [![Add Integration][add-integration-badge]][add-integration] or in the HA UI go to "Configuration" -> "Integrations" click "+" and search for "Tesla Custom Integration".

<!---->

## Usage
The `Tesla` integration offers integration with the [Tesla](https://auth.tesla.com/login) cloud service and provides presence detection as well as sensors such as charger state and temperature.

The `Tesla` integration offers integration with the [Tesla](https://auth.tesla.com/login) cloud service and provides presence detection as well as sensors such as charger state and temperature.

This integration provides the following platforms:

Expand All @@ -48,22 +51,25 @@ This integration provides the following platforms:
- Climate - HVAC control. Allow you to control (turn on/off, set target temperature) your Tesla's HVAC system. Also enables preset modes to enable or disable max defrost mode `defrost` or `normal` operation mode.
- Switches - Charger and max range switch allow you to start/stop charging and set max range charging. Polling switch allows you to disable polling of vehicles to conserve battery. Sentry mode switch enables or disable Sentry mode.
- Buttons - Horn and Flash lights

## Options

Tesla options are set via **Configuration** -> **Integrations** -> **Tesla** -> **Options**.

* Seconds between polling - referred to below as the `polling_interval`.
- Seconds between polling - referred to below as the `polling_interval`.

- Wake cars on start - Whether to wake sleeping cars on Home Assistant startup. This allows a user to choose whether cars should continue to sleep (and not update information) or to wake up the cars potentially interrupting long term hibernation and increasing vampire drain.

* Wake cars on start - Whether to wake sleeping cars on Home Assistant startup. This allows a user to choose whether cars should continue to sleep (and not update information) or to wake up the cars potentially interrupting long term hibernation and increasing vampire drain.
- Polling policy - When do we actively poll the car to get updates, and when do we try to allow the car to sleep. See [the Wiki](https://github.com/alandtse/tesla/wiki/Polling-policy) for more information.

## Potential Battery impacts

Here are some things to consider and understand when implementing the Tesla component and its potential effect on your car's battery.

- The `polling_interval` determines when to check if the car is awake and new information is available, but the Tesla integration will not wake up a sleeping car during this polling. By default, the polling will occur every 660 seconds. Polling a car too frequently can keep the car awake and drain the battery. Different firmware versions and measurements of Tesla cars can take from 11 to 15 minutes for sleep mode to occur. There is no official information on sleep mode timings so your mileage may vary and you should experiment with different polling times for an optimal experience.
- The `polling_interval` determines when to check if the car is awake and new information is available, but the Tesla integration will not wake up a sleeping car during this polling. By default, the polling will occur every 660 seconds. Polling a car too frequently can keep the car awake and drain the battery. Different firmware versions and measurements of Tesla cars can take from 11 to 15 minutes for sleep mode to occur. There is no official information on sleep mode timings so your mileage may vary and you should experiment with different polling times for an optimal experience.
- The car will, however, be woken up when a command is actively sent to the car, such as door unlock or turning on the HVAC. It will then also fetch updated information while the car is awake based on the `polling_interval`.
- The car can intentionally be woken up to fetch recent information by sending a harmless command, for example, a lock command. This can be used in an automation to, for example, ensure that updated information is available every morning. (Note that the command must be valid for that specific car model. So locking the frunk of a Model 3 will not wake up that car).
- You can also toggle the `polling switch` on/off to disable polling of the vehicle completely via automations or the Lovelace UI.
- You can also toggle the `polling switch` on/off to disable polling of the vehicle completely via automations or the Lovelace UI.

## Contributions are welcome!

Expand Down
7 changes: 7 additions & 0 deletions custom_components/tesla_custom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
from .config_flow import CannotConnect, InvalidAuth, validate_input
from .const import (
CONF_EXPIRATION,
CONF_POLLING_POLICY,
CONF_WAKE_ON_START,
DATA_LISTENER,
DEFAULT_POLLING_POLICY,
DEFAULT_SCAN_INTERVAL,
DEFAULT_WAKE_ON_START,
DOMAIN,
Expand Down Expand Up @@ -71,6 +73,7 @@ def _update_entry(email, data=None, options=None):
options = options or {
CONF_SCAN_INTERVAL: DEFAULT_SCAN_INTERVAL,
CONF_WAKE_ON_START: DEFAULT_WAKE_ON_START,
CONF_POLLING_POLICY: DEFAULT_POLLING_POLICY,
}
for entry in hass.config_entries.async_entries(DOMAIN):
if email != entry.title:
Expand Down Expand Up @@ -138,6 +141,9 @@ async def async_setup_entry(hass, config_entry):
update_interval=config_entry.options.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
),
polling_policy=config_entry.options.get(
CONF_POLLING_POLICY, DEFAULT_POLLING_POLICY
),
)
result = await controller.connect(
wake_if_asleep=config_entry.options.get(
Expand Down Expand Up @@ -274,6 +280,7 @@ async def _async_update_data(self):
# Note: asyncio.TimeoutError and aiohttp.ClientError are already
# handled by the data update coordinator.
async with async_timeout.timeout(30):
_LOGGER.debug("Running controller.update()")
return await self.controller.update()
except IncompleteCredentials:
await self.hass.config_entries.async_reload(self.config_entry.entry_id)
Expand Down
18 changes: 18 additions & 0 deletions custom_components/tesla_custom/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@
import voluptuous as vol

from .const import (
ATTR_POLLING_POLICY_ALWAYS,
ATTR_POLLING_POLICY_CONNECTED,
ATTR_POLLING_POLICY_NORMAL,
CONF_EXPIRATION,
CONF_POLLING_POLICY,
CONF_WAKE_ON_START,
DEFAULT_POLLING_POLICY,
DEFAULT_SCAN_INTERVAL,
DEFAULT_WAKE_ON_START,
MIN_SCAN_INTERVAL,
Expand Down Expand Up @@ -138,6 +143,18 @@ async def async_step_init(self, user_input=None):
CONF_WAKE_ON_START, DEFAULT_WAKE_ON_START
),
): bool,
vol.Required(
CONF_POLLING_POLICY,
default=self.config_entry.options.get(
CONF_POLLING_POLICY, DEFAULT_POLLING_POLICY
),
): vol.In(
[
ATTR_POLLING_POLICY_NORMAL,
ATTR_POLLING_POLICY_CONNECTED,
ATTR_POLLING_POLICY_ALWAYS,
]
),
}
)
return self.async_show_form(step_id="init", data_schema=data_schema)
Expand All @@ -160,6 +177,7 @@ async def validate_input(hass: core.HomeAssistant, data):
update_interval=DEFAULT_SCAN_INTERVAL,
expiration=data.get(CONF_EXPIRATION, 0),
auth_domain=data.get(CONF_DOMAIN, AUTH_DOMAIN),
polling_policy=data.get(CONF_POLLING_POLICY, DEFAULT_POLLING_POLICY),
)
result = await controller.connect(test_login=True)
config[CONF_TOKEN] = result["refresh_token"]
Expand Down
8 changes: 7 additions & 1 deletion custom_components/tesla_custom/const.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Const file for Tesla cars."""
VERSION = "1.4.0"
VERSION = "1.5.0"
CONF_WAKE_ON_START = "enable_wake_on_start"
CONF_EXPIRATION = "expiration"
CONF_POLLING_POLICY = "polling_policy"
DOMAIN = "tesla_custom"
DATA_LISTENER = "listener"
DEFAULT_SCAN_INTERVAL = 660
Expand Down Expand Up @@ -43,4 +44,9 @@

ATTR_PARAMETERS = "parameters"
ATTR_PATH_VARS = "path_vars"
ATTR_POLLING_POLICY_NORMAL = "normal"
ATTR_POLLING_POLICY_CONNECTED = "connected"
ATTR_POLLING_POLICY_ALWAYS = "always"
DEFAULT_POLLING_POLICY = ATTR_POLLING_POLICY_NORMAL
SERVICE_API = "api"
SERVICE_SCAN_INTERVAL = "polling_interval"
4 changes: 2 additions & 2 deletions custom_components/tesla_custom/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"config_flow": true,
"documentation": "https://github.com/alandtse/tesla",
"issue_tracker": "https://github.com/alandtse/tesla/issues",
"requirements": ["teslajsonpy==1.4.1"],
"requirements": ["teslajsonpy==1.5.0"],
"codeowners": ["@alandtse"],
"dependencies": ["http"],
"dhcp": [
Expand All @@ -22,5 +22,5 @@
}
],
"iot_class": "cloud_polling",
"version": "1.4.0"
"version": "1.5.0"
}
68 changes: 67 additions & 1 deletion custom_components/tesla_custom/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@
from homeassistant.helpers import config_validation as cv
import voluptuous as vol

from homeassistant.const import ATTR_COMMAND
from homeassistant.const import (
ATTR_COMMAND,
CONF_SCAN_INTERVAL,
)
from .const import (
ATTR_PARAMETERS,
ATTR_PATH_VARS,
DOMAIN,
SERVICE_API,
SERVICE_SCAN_INTERVAL,
DEFAULT_SCAN_INTERVAL,
)

_LOGGER = logging.getLogger(__name__)
Expand All @@ -30,6 +35,12 @@
}
)

SCAN_INTERVAL_SCHEMA = vol.Schema(
{
vol.Optional(CONF_EMAIL): vol.All(cv.string, vol.Length(min=1)),
vol.Required(CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL): vol.All(vol.Coerce(int), vol.Range(min=0, max=3600)),
}
)

@callback
def async_setup_services(hass) -> None:
Expand All @@ -42,13 +53,23 @@ async def async_call_tesla_service(service_call) -> None:
if service == SERVICE_API:
await api(service_call)

if service == SERVICE_SCAN_INTERVAL:
await set_update_interval(service_call)

hass.services.async_register(
DOMAIN,
SERVICE_API,
async_call_tesla_service,
schema=API_SCHEMA,
)

hass.services.async_register(
DOMAIN,
SERVICE_SCAN_INTERVAL,
async_call_tesla_service,
schema=SCAN_INTERVAL_SCHEMA,
)

async def api(call):
"""Handle api service request.
Expand Down Expand Up @@ -88,8 +109,53 @@ async def api(call):
path_vars = parameters.pop(ATTR_PATH_VARS)
return await controller.api(name=command, path_vars=path_vars, **parameters)

async def set_update_interval(call):
"""Handle api service request.
Arguments:
call.CONF_EMAIL {str: ""} -- email, optional
call.CONF_SCAN_INTERVAL {int: 660} -- New scan interval
Returns:
bool -- True if new interval is set
"""
_LOGGER.debug("call %s", call)
service_data = call.data
email = service_data.get(CONF_EMAIL, "")

if len(hass.config_entries.async_entries(DOMAIN)) > 1 and not email:
raise ValueError("Email address missing")
controller: Controller = None
for entry in hass.config_entries.async_entries(DOMAIN):
if (
len(hass.config_entries.async_entries(DOMAIN)) > 1
and entry.title != email
):
continue
controller = hass.data[DOMAIN].get(entry.entry_id)["coordinator"].controller
if controller is None:
raise ValueError(f"No Tesla controllers found for email {email}")

update_interval = service_data.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
_LOGGER.debug(
"Service %s called with email: %s interval %s",
SERVICE_SCAN_INTERVAL,
email,
update_interval,
)
old_update_interval = controller.update_interval
controller.update_interval = update_interval
if old_update_interval != controller.update_interval:
_LOGGER.debug(
"Changing update_interval from %s to %s",
old_update_interval,
controller.update_interval,
)
return True

@callback
def async_unload_services(hass) -> None:
"""Unload Tesla services."""
hass.services.async_remove(DOMAIN, SERVICE_API)
hass.services.async_remove(DOMAIN, SERVICE_SCAN_INTERVAL)
15 changes: 15 additions & 0 deletions custom_components/tesla_custom/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,18 @@ api:
required: true
selector:
object:

polling_interval:
description: Set polling interval for updating fresh data from an awake car
fields:
scan_interval:
description: Number of seconds between each poll. See https://github.com/alandtse/tesla/wiki/Polling-policy more information.
example: 660
required: true
default: 660
selector:
number:
min: 0
max: 3600
step: 30
unit_of_measurement: "s"
Loading

0 comments on commit b1237c6

Please sign in to comment.