diff --git a/README.md b/README.md index 0395a0c..deaf4bb 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ I have added a service to poll the car for updates, due to the battery drain I h ### Click on options and choose imperial or metric to display in km/miles. Takes effect on next restart of home assistant. Default is Metric +### Clear Tokens +If you are experiencing any sign in issues, please trying clearing your tokens using the "clear_tokens" service call. + ## Currently Working @@ -40,6 +43,7 @@ Click on options and choose imperial or metric to display in km/miles. Takes eff - Last Car Refresh status - Car Tracker - Supports Multiple Regions +- Electric Vehicle Support ## Coming Soon diff --git a/custom_components/fordpass/__init__.py b/custom_components/fordpass/__init__.py index 0232852..731057e 100644 --- a/custom_components/fordpass/__init__.py +++ b/custom_components/fordpass/__init__.py @@ -69,11 +69,22 @@ async def async_refresh_status_service(service_call): refresh_status, hass, service_call, coordinator ) + async def async_clear_tokens_service(service_call): + await hass.async_add_executor_job(clear_tokens, hass, service_call, coordinator) + + async def async_clear_tokens_service(service_call): + await hass.async_add_executor_job(clear_tokens, hass, service_call, coordinator) + hass.services.async_register( DOMAIN, "refresh_status", async_refresh_status_service, ) + hass.services.async_register( + DOMAIN, + "clear_tokens", + async_clear_tokens_service, + ) return True @@ -88,6 +99,16 @@ def refresh_status(service, hass, coordinator): coordinator.vehicle.requestUpdate() +def clear_tokens(service, hass, coordinator): + _LOGGER.debug("Clearing Tokens") + coordinator.vehicle.clearToken() + + +def clear_tokens(service, hass, coordinator): + _LOGGER.debug("Clearing Tokens") + coordinator.vehicle.clearToken() + + async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): """Unload a config entry.""" unload_ok = all( diff --git a/custom_components/fordpass/const.py b/custom_components/fordpass/const.py index 63c0fd6..da281c8 100644 --- a/custom_components/fordpass/const.py +++ b/custom_components/fordpass/const.py @@ -17,3 +17,18 @@ REGION = "region" REGION_OPTIONS = ["UK&Europe", "Australia", "North America & Canada"] + +SENSORS = { + "odometer": {"icon": "mdi:counter"}, + "fuel": {"icon": "mdi:gas-station"}, + "battery": {"icon": "mdi:car-battery"}, + "oil": {"icon": "mdi:oil"}, + "tirePressure": {"icon": "mdi:car-tire-alert"}, + "gps": {"icon": "mdi:radar"}, + "alarm": {"icon": "mdi:bell"}, + "ignitionStatus": {"icon": "hass:power"}, + "doorStatus": {"icon": "mdi:car-door"}, + "windowPosition": {"icon": "mdi:car-door"}, + "lastRefresh": {"icon": "mdi:clock"}, + "elVeh": {"icon": "mdi:ev-station"}, +} diff --git a/custom_components/fordpass/device_tracker.py b/custom_components/fordpass/device_tracker.py index f45fd5a..16ca5a8 100644 --- a/custom_components/fordpass/device_tracker.py +++ b/custom_components/fordpass/device_tracker.py @@ -46,3 +46,7 @@ def device_id(self): @property def device_state_attributes(self): return self.coordinator.data[self.sensor].items() + + @property + def icon(self): + return "mdi:radar" diff --git a/custom_components/fordpass/fordpass_new.py b/custom_components/fordpass/fordpass_new.py index 9ebb59a..a7b1b89 100644 --- a/custom_components/fordpass/fordpass_new.py +++ b/custom_components/fordpass/fordpass_new.py @@ -1,6 +1,6 @@ import json import logging -import os.path +import os import time import requests @@ -144,6 +144,12 @@ def readToken(self): with open("/tmp/fordpass_token.txt") as token_file: return json.load(token_file) + def clearToken(self): + if os.path.isfile("/tmp/fordpass_token.txt"): + os.remove("/tmp/fordpass_token.txt") + if os.path.isfile("/tmp/token.txt"): + os.remove("/tmp/token.txt") + def status(self): # Get the status of the vehicle @@ -214,10 +220,10 @@ def __makeRequest(self, method, url, data, params): """ headers = { - **apiHeaders, + **apiHeaders, "auth-token": self.token, - "Application-Id": self.region - } + "Application-Id": self.region, + } return getattr(requests, method.lower())( url, headers=headers, data=data, params=params diff --git a/custom_components/fordpass/lock.py b/custom_components/fordpass/lock.py index eff6e46..084ca17 100644 --- a/custom_components/fordpass/lock.py +++ b/custom_components/fordpass/lock.py @@ -50,3 +50,7 @@ def is_locked(self): if self.coordinator.data is None or self.coordinator.data["lockStatus"] is None: return None return self.coordinator.data["lockStatus"]["value"] == "LOCKED" + + @property + def icon(self): + return "mdi:car-door-lock" diff --git a/custom_components/fordpass/sensor.py b/custom_components/fordpass/sensor.py index 3763531..591994f 100644 --- a/custom_components/fordpass/sensor.py +++ b/custom_components/fordpass/sensor.py @@ -5,7 +5,7 @@ from homeassistant.util import Throttle from . import FordPassEntity -from .const import CONF_UNIT, DOMAIN +from .const import CONF_UNIT, DOMAIN, SENSORS _LOGGER = logging.getLogger(__name__) @@ -13,22 +13,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities): """Add the Entities from the config.""" entry = hass.data[DOMAIN][config_entry.entry_id] - snrarray = [ - "odometer", - "fuel", - "battery", - "oil", - "tirePressure", - "gps", - "alarm", - "ignitionStatus", - "doorStatus", - "windowPosition", - "lastRefresh", - ] sensors = [] - for snr in snrarray: - async_add_entities([CarSensor(entry, snr, config_entry.options)], True) + for key, value in SENSORS.items(): + async_add_entities([CarSensor(entry, key, config_entry.options)], True) class CarSensor( @@ -68,7 +55,7 @@ def get_value(self, ftype): return self.coordinator.data[self.sensor]["value"] elif self.sensor == "doorStatus": for key, value in self.coordinator.data[self.sensor].items(): - if value["value"] != "Closed": + if (value["value"] != "Closed") or (value["value"] != "Invalid"): return "Open" return "Closed" elif self.sensor == "windowPosition": @@ -80,6 +67,11 @@ def get_value(self, ftype): return "Closed" elif self.sensor == "lastRefresh": return self.coordinator.data[self.sensor] + elif self.sensor == "elVeh": + if self.coordinator.data["elVehDTE"] != None: + return self.coordinator.data["chargingStatus"]["value"] + else: + return "Unsupported" elif ftype == "measurement": if self.sensor == "odometer": if self.options[CONF_UNIT] == "imperial": @@ -112,7 +104,11 @@ def get_value(self, ftype): elif self.sensor == "fuel": return self.coordinator.data[self.sensor].items() elif self.sensor == "battery": - return None + return { + "Battery Voltage": self.coordinator.data[self.sensor][ + "batteryStatusActual" + ]["value"] + } elif self.sensor == "oil": return self.coordinator.data[self.sensor].items() elif self.sensor == "tirePressure": @@ -137,6 +133,25 @@ def get_value(self, ftype): return windows elif self.sensor == "lastRefresh": return None + elif self.sensor == "elVeh": + if self.coordinator.data["elVehDTE"] != None: + return { + "Plug Status": self.coordinator.data["plugStatus"]["value"], + "Charge Start Time": self.coordinator.data["chargeStartTime"][ + "value" + ], + "Charge End Time": self.coordinator.data["chargeEndTime"][ + "value" + ], + "Battery Fill Level": self.coordinator.data["batteryFillLevel"][ + "value" + ], + "Charger Power Type": self.coordinator.data["chargerPowertype"][ + "value" + ], + } + else: + return None @property def name(self): @@ -157,3 +172,7 @@ def device_state_attributes(self): @property def unit_of_measurement(self): return self.get_value("measurement") + + @property + def icon(self): + return SENSORS[self.sensor]["icon"] diff --git a/custom_components/fordpass/services.yaml b/custom_components/fordpass/services.yaml index 66a0086..53b6729 100644 --- a/custom_components/fordpass/services.yaml +++ b/custom_components/fordpass/services.yaml @@ -1,2 +1,4 @@ refresh_status: description: "Poll car for latest status (Takes up to 5mins to update once this function has been run!)" +clear_tokens: + description: "Clear the cached tokens" diff --git a/custom_components/fordpass/switch.py b/custom_components/fordpass/switch.py index 323b9db..1b19acf 100644 --- a/custom_components/fordpass/switch.py +++ b/custom_components/fordpass/switch.py @@ -47,3 +47,7 @@ def is_on(self): ): return None return self.coordinator.data["remoteStartStatus"]["value"] + + @property + def icon(self): + return "mdi:key-star" diff --git a/info.md b/info.md index a02a687..d684136 100644 --- a/info.md +++ b/info.md @@ -1,5 +1,11 @@ # **Changelog** +### Version 1.08 +- Added Icons for each entity +- Added "clear_tokens" service call +- Added Electric Vehicle features +- Fixed "Invalid" lock status + ### Version 1.07 - Support for multiple regions (Fixes unavaliable bug) - Token renamed to fordpass_token