Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple vehicle support and config flow updates #70

Merged
merged 6 commits into from
Nov 6, 2024
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
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ If you find any bugs or would like to request a feature, please open an issue.

## Tested Vehicles
This integration has been tested with the following vehicles:
* Nissan Leaf (2022) - UK [@dan-r]
* Nissan Qashqai (2021) - EU
* Nissan Ariya - EU
* Nissan Leaf (2022) [@dan-r]
* Nissan Qashqai (2021)
* Nissan Ariya
* Nissan X-Trail (2024)
* Nissan Juke (2021)

## Supported Regions
* Europe

Currently only Nissan vehicles within Europe are supported.

### North America
The API used in North America is completely separate to Europe and it appears that Nissan USA are [a lot more hostile](https://tobis.dk/blog/the-farce-of-nissanconnect-north-america/) towards third-party access. Any future US support would rely on library support (such as [dartnissanconnectna](https://gitlab.com/tobiaswkjeldsen/dartnissanconnectna)) or someone in North America maintaining that side of things. If you're interested, get in touch!
Expand Down
3 changes: 2 additions & 1 deletion custom_components/nissan_connect/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ async def async_setup_entry(hass, entry):
config = dict(entry.data)

kamereon_session = NCISession(
region=config["region"]
region=config["region"],
unique_id=entry.unique_id
)

data = hass.data[DOMAIN] = {
Expand Down
4 changes: 4 additions & 0 deletions custom_components/nissan_connect/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ def _vehicle_name(self):
@property
def unique_id(self):
"""Return unique ID of the entity."""
# New unique ID format for multiple cars and multiple accounts
if self.vehicle.session.unique_id:
return f"{self.vehicle.session.unique_id}_{self.vehicle.vin}_{self._attr_translation_key}"

return f"{self._vehicle_name}_{self._attr_translation_key}"

@property
Expand Down
54 changes: 32 additions & 22 deletions custom_components/nissan_connect/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,31 @@
from .const import DOMAIN, CONFIG_VERSION, DEFAULT_INTERVAL_POLL, DEFAULT_INTERVAL_CHARGING, DEFAULT_INTERVAL_STATISTICS, DEFAULT_INTERVAL_FETCH, DEFAULT_REGION, REGIONS
from .kamereon import NCISession
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers import selector

USER_SCHEMA = vol.Schema({
vol.Required("email"): cv.string,
vol.Required("password"): cv.string,
# vol.Required(
# "interval", default=DEFAULT_INTERVAL_POLL
# ): int,
# vol.Required(
# "interval_charging", default=DEFAULT_INTERVAL_CHARGING
# ): int,
# vol.Required(
# "interval_fetch", default=DEFAULT_INTERVAL_FETCH
# ): int,
# vol.Required(
# "interval_statistics", default=DEFAULT_INTERVAL_STATISTICS
# ): int,
vol.Required(
"interval", default=DEFAULT_INTERVAL_POLL
): int,
vol.Required(
"interval_charging", default=DEFAULT_INTERVAL_CHARGING
): int,
vol.Required(
"interval_fetch", default=DEFAULT_INTERVAL_FETCH
): int,
vol.Required(
"interval_statistics", default=DEFAULT_INTERVAL_STATISTICS
): int,
vol.Required(
"region", default=DEFAULT_REGION): cv.string,
"region", default=DEFAULT_REGION.lower()): selector.SelectSelector(
selector.SelectSelectorConfig(
options=[el.lower() for el in REGIONS], # Translation keys must be lowercase
mode=selector.SelectSelectorMode.DROPDOWN,
translation_key="region"
),
),
vol.Required(
"imperial_distance", default=False): bool
})
Expand All @@ -32,9 +39,12 @@ class NissanConfigFlow(ConfigFlow, domain=DOMAIN):

async def async_step_user(self, info):
errors = {}
if info is not None and info["region"] not in REGIONS:
errors["base"] = "region_error"
elif info is not None:
if info is not None:
info["region"] = info["region"].upper()

await self.async_set_unique_id(info["email"])
self._abort_if_unique_id_configured()

# Validate credentials
kamereon_session = NCISession(
region=info["region"]
Expand All @@ -50,7 +60,7 @@ async def async_step_user(self, info):

if len(errors) == 0:
return self.async_create_entry(
title="NissanConnect Account",
title=info["email"],
data=info
)

Expand Down Expand Up @@ -80,9 +90,9 @@ async def async_step_init(self, options):
if "password" in options:
try:
await self.hass.async_add_executor_job(kamereon_session.login,
options["email"],
options["password"]
)
self._config_entry.data.get("email"),
options["password"]
)
except:
errors["base"] = "auth_error"

Expand All @@ -92,7 +102,7 @@ async def async_step_init(self, options):
if not "password" in options:
options.pop('email', None)
options.pop('password', None)

# Update data
data.update(options)
self.hass.config_entries.async_update_entry(
Expand All @@ -107,7 +117,7 @@ async def async_step_init(self, options):

return self.async_show_form(
step_id="init", data_schema=vol.Schema({
vol.Required("email", default=self._config_entry.data.get("email", "")): cv.string,
# vol.Required("email", default=self._config_entry.data.get("email", "")): cv.string,
vol.Optional("password"): cv.string,
vol.Required(
"interval", default=self._config_entry.data.get("interval", DEFAULT_INTERVAL_POLL)
Expand Down
2 changes: 1 addition & 1 deletion custom_components/nissan_connect/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
DEFAULT_INTERVAL_FETCH = 10

DEFAULT_REGION = "EU"
REGIONS = ["EU", "US"]
REGIONS = ["EU"]
4 changes: 3 additions & 1 deletion custom_components/nissan_connect/kamereon.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,13 +605,15 @@ class KamereonSession:

tenant = None
copy_realm = None
unique_id = None

def __init__(self, region):
def __init__(self, region, unique_id=None):
self.settings = settings_map[self.tenant][region]
session = requests.session()
self.session = session
self._oauth = None
self._user_id = None
self.unique_id = unique_id
# ugly hack
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

Expand Down
9 changes: 8 additions & 1 deletion custom_components/nissan_connect/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"interval_charging": "Polling-Intervall während des Ladevorgangs (Minuten)",
"interval_statistics": "Update-Intervall für Statistiken (Minuten)",
"interval_fetch": "Update-Intervall (Minuten)",
"region": "Region (EU, US)",
"region": "Region",
"imperial_distance": "Imperiale (amerikanische) Einheiten verwenden"
},
"data_description": {
Expand Down Expand Up @@ -135,5 +135,12 @@
"name": "Anzahl Fahrten (akt. Monat)"
}
}
},
"selector": {
"region": {
"options": {
"eu": "Europa"
}
}
}
}
9 changes: 8 additions & 1 deletion custom_components/nissan_connect/translations/dk.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"interval_charging": "Opdateringsfrekvens under ladning(minutter)",
"interval_statistics": "Opdateringsfrekvens for daglige/månedlige statistikker (minutter)",
"interval_fetch": "Opdateringsfrekvens for hentning (minutter)",
"region": "Region (EU, US)",
"region": "Region",
"imperial_distance": "Brug Engelske afstands enheder"
},
"data_description": {
Expand Down Expand Up @@ -135,5 +135,12 @@
"name": "Månedlig ture"
}
}
},
"selector": {
"region": {
"options": {
"eu": "Europa"
}
}
}
}
9 changes: 8 additions & 1 deletion custom_components/nissan_connect/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"interval_charging": "Polling interval while charging (minutes)",
"interval_statistics": "Update interval for daily/monthly statistics (minutes)",
"interval_fetch": "Update interval (minutes)",
"region": "Region (EU, US)",
"region": "Region",
"imperial_distance": "Use imperial distance units (miles)"
},
"data_description": {
Expand Down Expand Up @@ -135,5 +135,12 @@
"name": "Monthly Trips"
}
}
},
"selector": {
"region": {
"options": {
"eu": "Europe"
}
}
}
}
9 changes: 8 additions & 1 deletion custom_components/nissan_connect/translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"interval_charging": "Intervalo de sondeo durante la carga (minutos)",
"interval_statistics": "Intervalo de actualización de estadísticas diarias/mensuales (minutos)",
"interval_fetch": "Intervalo de actualización (minutos)",
"region": "Región (UE, EE. UU.)",
"region": "Región",
"imperial_distance": "Usar unidades de distancia imperiales"
},
"data_description": {
Expand Down Expand Up @@ -135,5 +135,12 @@
"name": "Viajes Mensuales"
}
}
},
"selector": {
"region": {
"options": {
"eu": "Europa"
}
}
}
}
9 changes: 8 additions & 1 deletion custom_components/nissan_connect/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"interval_charging": "Intervalle de sondage pendant la charge (minutes)",
"interval_statistics": "Intervalle de mise à jour des statistiques quotidiennes/mensuelles (minutes)",
"interval_fetch": "Intervalle de mise à jour (minutes)",
"region": "Région (EU, US)",
"region": "Région",
"imperial_distance": "Utiliser les unités de distance impériales"
},
"data_description": {
Expand Down Expand Up @@ -135,5 +135,12 @@
"name": "Trajets mensuels"
}
}
},
"selector": {
"region": {
"options": {
"eu": "Europe"
}
}
}
}
9 changes: 8 additions & 1 deletion custom_components/nissan_connect/translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"interval_charging": "Intervallo di polling durante la ricarica (minuti)",
"interval_statistics": "Intervallo di aggiornamento per le statistiche giornaliere/mensili (minuti)",
"interval_fetch": "Intervallo di aggiornamento (minuti)",
"region": "Regione (EU, US)",
"region": "Regione",
"imperial_distance": "Utilizza unità di misura imperiali per la distanza"
},
"data_description": {
Expand Down Expand Up @@ -135,5 +135,12 @@
"name": "Viaggi mensili"
}
}
},
"selector": {
"region": {
"options": {
"eu": "Europa"
}
}
}
}
9 changes: 8 additions & 1 deletion custom_components/nissan_connect/translations/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"interval_charging": "Polling interval tijdens laden (Minuten)",
"interval_statistics": "Update-interval voor dagelijkse/maandelijkse statistieken (Minuten)",
"interval_fetch": "Update interval (Minuten)",
"region": "Regio (EU, US)",
"region": "Regio",
"imperial_distance": "Gebruik imperiale afstandseenheden"
},
"data_description": {
Expand Down Expand Up @@ -135,5 +135,12 @@
"name": "Maandelijkse ritafstand"
}
}
},
"selector": {
"region": {
"options": {
"eu": "Europa"
}
}
}
}
9 changes: 8 additions & 1 deletion custom_components/nissan_connect/translations/no.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"interval_charging": "Oppdateringsfrekvens under lading for henting av data (i minutter)",
"interval_statistics": "Oppdateringsfrekvens for daglig / månedlig statistikk (i minutter)",
"interval_fetch": "Oppdateringsfrekvens for henting av data (i minutter)",
"region": "Region (EU, US)",
"region": "Region",
"imperial_distance": "Bruk Britiske/Amerikanske (Imperial) måleenheter"
},
"data_description": {
Expand Down Expand Up @@ -135,5 +135,12 @@
"name": "Månedlige turer"
}
}
},
"selector": {
"region": {
"options": {
"eu": "Europa"
}
}
}
}
9 changes: 8 additions & 1 deletion custom_components/nissan_connect/translations/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"interval_charging": "Interwał odpytywania podczas ładowania (minuty)",
"interval_statistics": "Interwał aktualizacji dziennych/miesięcznych statystyk (minuty)",
"interval_fetch": "Interwał aktualizacji (minuty)",
"region": "Region (EU, US)",
"region": "Region",
"imperial_distance": "Używaj jednostek imperialnych"
},
"data_description": {
Expand Down Expand Up @@ -135,5 +135,12 @@
"name": "Miesięczne Trasy"
}
}
},
"selector": {
"region": {
"options": {
"eu": "Europa"
}
}
}
}
9 changes: 8 additions & 1 deletion custom_components/nissan_connect/translations/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"interval_charging": "Intervalo de consulta durante o carregamento (minutos)",
"interval_statistics": "Intervalo de atualização para estatísticas diárias/mensais (minutos)",
"interval_fetch": "Intervalo de atualização (minutos)",
"region": "Região (EU, US)",
"region": "Região",
"imperial_distance": "Usar unidades de distância imperiais"
},
"data_description": {
Expand Down Expand Up @@ -135,5 +135,12 @@
"name": "Viagens mensais"
}
}
},
"selector": {
"region": {
"options": {
"eu": "Europa"
}
}
}
}
Loading
Loading