Skip to content
This repository has been archived by the owner on Jan 5, 2023. It is now read-only.

Commit

Permalink
Add checks for endpoint support and contract requirements (#113)
Browse files Browse the repository at this point in the history
* Add checks for endpoint support

* Add checks for endpoint contract requirements

* Add indication to open an issue on renault-api

* Use INFO for endpoint_available
  • Loading branch information
epenet committed Jan 31, 2021
1 parent bdd6ee2 commit 04db8fc
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 35 deletions.
2 changes: 2 additions & 0 deletions custom_components/renault/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@
DEVICE_CLASS_PLUG_STATE = "renault__plug_state"
DEVICE_CLASS_CHARGE_STATE = "renault__charge_state"
DEVICE_CLASS_CHARGE_MODE = "renault__charge_mode"

RENAULT_API_URL = "https://github.com/hacf-fr/renault-api/issues"
112 changes: 77 additions & 35 deletions custom_components/renault/renault_vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from homeassistant.helpers.typing import HomeAssistantType

from .const import DOMAIN
from .const import DOMAIN, RENAULT_API_URL
from .renault_coordinator import RenaultDataUpdateCoordinator

LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -60,60 +60,102 @@ def distances_in_miles(self) -> bool:

async def async_initialise(self) -> None:
"""Load available sensors."""
self.coordinators["cockpit"] = RenaultDataUpdateCoordinator(
self.hass,
LOGGER,
# Name of the data. For logging purposes.
name=f"{self.details.vin} cockpit",
update_method=self.get_cockpit,
# Polling interval. Will only be polled if there are subscribers.
update_interval=self._scan_interval,
)
self.coordinators["hvac_status"] = RenaultDataUpdateCoordinator(
self.hass,
LOGGER,
# Name of the data. For logging purposes.
name=f"{self.details.vin} hvac_status",
update_method=self.get_hvac_status,
# Polling interval. Will only be polled if there are subscribers.
update_interval=self._scan_interval,
)
if self.details.uses_electricity():
self.coordinators["battery"] = RenaultDataUpdateCoordinator(
if await self.endpoint_available("cockpit"):
self.coordinators["cockpit"] = RenaultDataUpdateCoordinator(
self.hass,
LOGGER,
# Name of the data. For logging purposes.
name=f"{self.details.vin} battery",
update_method=self.get_battery_status,
name=f"{self.details.vin} cockpit",
update_method=self.get_cockpit,
# Polling interval. Will only be polled if there are subscribers.
update_interval=self._scan_interval,
)
self.coordinators["charge_mode"] = RenaultDataUpdateCoordinator(
if await self.endpoint_available("hvac-status"):
self.coordinators["hvac_status"] = RenaultDataUpdateCoordinator(
self.hass,
LOGGER,
# Name of the data. For logging purposes.
name=f"{self.details.vin} charge_mode",
update_method=self.get_charge_mode,
name=f"{self.details.vin} hvac_status",
update_method=self.get_hvac_status,
# Polling interval. Will only be polled if there are subscribers.
update_interval=self._scan_interval,
)
if self.details.uses_electricity():
if await self.endpoint_available("battery-status"):
self.coordinators["battery"] = RenaultDataUpdateCoordinator(
self.hass,
LOGGER,
# Name of the data. For logging purposes.
name=f"{self.details.vin} battery",
update_method=self.get_battery_status,
# Polling interval. Will only be polled if there are subscribers.
update_interval=self._scan_interval,
)
if await self.endpoint_available("charge-mode"):
self.coordinators["charge_mode"] = RenaultDataUpdateCoordinator(
self.hass,
LOGGER,
# Name of the data. For logging purposes.
name=f"{self.details.vin} charge_mode",
update_method=self.get_charge_mode,
# Polling interval. Will only be polled if there are subscribers.
update_interval=self._scan_interval,
)
if await self.endpoint_available("location"):
self.coordinators["location"] = RenaultDataUpdateCoordinator(
self.hass,
LOGGER,
# Name of the data. For logging purposes.
name=f"{self.details.vin} location",
update_method=self.get_location,
# Polling interval. Will only be polled if there are subscribers.
update_interval=self._scan_interval,
)
self.coordinators["location"] = RenaultDataUpdateCoordinator(
self.hass,
LOGGER,
# Name of the data. For logging purposes.
name=f"{self.details.vin} location",
update_method=self.get_location,
# Polling interval. Will only be polled if there are subscribers.
update_interval=self._scan_interval,
)
for key in list(self.coordinators.keys()):
await self.coordinators[key].async_refresh()
if self.coordinators[key].not_supported:
# Remove endpoint if it is not supported for this vehicle.
del self.coordinators[key]
LOGGER.warning(
"`Not Supported` on HA coordinator %s was not caught"
" by `endpoint_available` method. It may be useful"
" to open an issue on %s",
key,
RENAULT_API_URL,
)

elif self.coordinators[key].access_denied:
# Remove endpoint if it is denied for this vehicle.
del self.coordinators[key]
LOGGER.warning(
"`Access Denied` on HA coordinator %s was not caught"
" by `endpoint_available` method. It may be useful"
" to open an issue on %s",
key,
RENAULT_API_URL,
)

async def endpoint_available(self, endpoint: str) -> bool:
"""Ensure the endpoint is available to avoid unnecessary queries."""
if not await self._vehicle.supports_endpoint(endpoint):
LOGGER.info(
"Vehicle model %s does not appear to support endpoint '%s'."
" If you think this is a mistake, please open an issue on %s",
self.details.get_model_code(),
endpoint,
RENAULT_API_URL,
)
return False
if not await self._vehicle.has_contract_for_endpoint(endpoint):
LOGGER.info(
"Vehicle %s does not appear to have a valid contract for endpoint '%s'."
" If you think this is a mistake, please open an issue on %s",
self.details.vin(),
endpoint,
RENAULT_API_URL,
)
return False
return True

async def get_battery_status(self) -> models.KamereonVehicleBatteryStatusData:
"""Get battery status information from vehicle."""
Expand Down

0 comments on commit 04db8fc

Please sign in to comment.