Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add diagnostics to Renault integration (#64531)
* Add diagnostics to Renault * Add diagnostic tests * Add device diagnostics * Include vehicle information in main diag Co-authored-by: epenet <epenet@users.noreply.github.com>
- Loading branch information
Showing
2 changed files
with
245 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
"""Diagnostics support for Renault.""" | ||
from __future__ import annotations | ||
|
||
from types import MappingProxyType | ||
from typing import Any | ||
|
||
from homeassistant.components.diagnostics import REDACTED | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME | ||
from homeassistant.core import HomeAssistant, callback | ||
from homeassistant.helpers.device_registry import DeviceEntry | ||
|
||
from . import RenaultHub | ||
from .const import CONF_KAMEREON_ACCOUNT_ID, DOMAIN | ||
|
||
TO_REDACT = ( | ||
CONF_KAMEREON_ACCOUNT_ID, | ||
CONF_PASSWORD, | ||
CONF_USERNAME, | ||
"radioCode", | ||
"registrationNumber", | ||
"vin", | ||
) | ||
|
||
|
||
@callback | ||
def _async_redact_data(data: MappingProxyType | dict) -> dict[str, Any]: | ||
"""Redact sensitive data in a dict.""" | ||
redacted = {**data} | ||
|
||
for key, value in redacted.items(): | ||
if key in TO_REDACT: | ||
redacted[key] = REDACTED | ||
elif isinstance(value, dict): | ||
redacted[key] = _async_redact_data(value) | ||
elif isinstance(value, list): | ||
redacted[key] = [_async_redact_data(item) for item in value] | ||
|
||
return redacted | ||
|
||
|
||
async def async_get_config_entry_diagnostics( | ||
hass: HomeAssistant, entry: ConfigEntry | ||
) -> dict[str, Any]: | ||
"""Return diagnostics for a config entry.""" | ||
renault_hub: RenaultHub = hass.data[DOMAIN][entry.entry_id] | ||
|
||
return { | ||
"entry": { | ||
"title": entry.title, | ||
"data": _async_redact_data(entry.data), | ||
}, | ||
"vehicles": [ | ||
_async_redact_data(vehicle.details.raw_data) | ||
for vehicle in renault_hub.vehicles.values() | ||
], | ||
} | ||
|
||
|
||
async def async_get_device_diagnostics( | ||
hass: HomeAssistant, entry: ConfigEntry, device: DeviceEntry | ||
) -> dict: | ||
"""Return diagnostics for a device.""" | ||
renault_hub: RenaultHub = hass.data[DOMAIN][entry.entry_id] | ||
vin = next(iter(device.identifiers))[1] | ||
|
||
return { | ||
"details": _async_redact_data(renault_hub.vehicles[vin].details.raw_data), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
"""Test Renault diagnostics.""" | ||
import pytest | ||
|
||
from homeassistant.components.renault import DOMAIN | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.core import HomeAssistant | ||
|
||
from tests.common import mock_device_registry | ||
from tests.components.diagnostics import ( | ||
get_diagnostics_for_config_entry, | ||
get_diagnostics_for_device, | ||
) | ||
|
||
pytestmark = pytest.mark.usefixtures("patch_renault_account", "patch_get_vehicles") | ||
|
||
VEHICLE_DETAILS = { | ||
"vin": "**REDACTED**", | ||
"registrationDate": "2017-08-01", | ||
"firstRegistrationDate": "2017-08-01", | ||
"engineType": "5AQ", | ||
"engineRatio": "601", | ||
"modelSCR": "ZOE", | ||
"deliveryCountry": {"code": "FR", "label": "FRANCE"}, | ||
"family": {"code": "X10", "label": "FAMILLE X10", "group": "007"}, | ||
"tcu": { | ||
"code": "TCU0G2", | ||
"label": "TCU VER 0 GEN 2", | ||
"group": "E70", | ||
}, | ||
"navigationAssistanceLevel": { | ||
"code": "NAV3G5", | ||
"label": "LEVEL 3 TYPE 5 NAVIGATION", | ||
"group": "408", | ||
}, | ||
"battery": { | ||
"code": "BT4AR1", | ||
"label": "BATTERIE BT4AR1", | ||
"group": "968", | ||
}, | ||
"radioType": { | ||
"code": "RAD37A", | ||
"label": "RADIO 37A", | ||
"group": "425", | ||
}, | ||
"registrationCountry": {"code": "FR"}, | ||
"brand": {"label": "RENAULT"}, | ||
"model": {"code": "X101VE", "label": "ZOE", "group": "971"}, | ||
"gearbox": { | ||
"code": "BVEL", | ||
"label": "BOITE A VARIATEUR ELECTRIQUE", | ||
"group": "427", | ||
}, | ||
"version": {"code": "INT MB 10R"}, | ||
"energy": {"code": "ELEC", "label": "ELECTRIQUE", "group": "019"}, | ||
"registrationNumber": "**REDACTED**", | ||
"vcd": "SYTINC/SKTPOU/SAND41/FDIU1/SSESM/MAPSUP/SSCALL/SAND88/SAND90/SQKDRO/SDIFPA/FACBA2/PRLEX1/SSRCAR/CABDO2/TCU0G2/SWALBO/EVTEC1/STANDA/X10/B10/EA2/MB/ELEC/DG/TEMP/TR4X2/RV/ABS/CAREG/LAC/VT003/CPE/RET03/SPROJA/RALU16/CEAVRH/AIRBA1/SERIE/DRA/DRAP08/HARM02/ATAR/TERQG/SFBANA/KM/DPRPN/AVREPL/SSDECA/ASRESP/RDAR02/ALEVA/CACBL2/SOP02C/CTHAB2/TRNOR/LVAVIP/LVAREL/SASURV/KTGREP/SGSCHA/APL03/ALOUCC/CMAR3P/NAV3G5/RAD37A/BVEL/AUTAUG/RNORM/ISOFIX/EQPEUR/HRGM01/SDPCLV/TLFRAN/SPRODI/SAN613/SSAPEX/GENEV1/ELC1/SANCML/PE2012/PHAS1/SAN913/045KWH/BT4AR1/VEC153/X101VE/NBT017/5AQ", | ||
"assets": [ | ||
{ | ||
"assetType": "PICTURE", | ||
"renditions": [ | ||
{ | ||
"resolutionType": "ONE_MYRENAULT_LARGE", | ||
"url": "https://3dv2.renault.com/ImageFromBookmark?configuration=SKTPOU%2FPRLEX1%2FSTANDA%2FB10%2FEA2%2FDG%2FVT003%2FRET03%2FRALU16%2FDRAP08%2FHARM02%2FTERQG%2FRDAR02%2FALEVA%2FSOP02C%2FTRNOR%2FLVAVIP%2FLVAREL%2FNAV3G5%2FRAD37A%2FSDPCLV%2FTLFRAN%2FGENEV1%2FSAN913%2FBT4AR1%2FNBT017&databaseId=1d514feb-93a6-4b45-8785-e11d2a6f1864&bookmarkSet=RSITE&bookmark=EXT_34_DESSUS&profile=HELIOS_OWNERSERVICES_LARGE", | ||
}, | ||
{ | ||
"resolutionType": "ONE_MYRENAULT_SMALL", | ||
"url": "https://3dv2.renault.com/ImageFromBookmark?configuration=SKTPOU%2FPRLEX1%2FSTANDA%2FB10%2FEA2%2FDG%2FVT003%2FRET03%2FRALU16%2FDRAP08%2FHARM02%2FTERQG%2FRDAR02%2FALEVA%2FSOP02C%2FTRNOR%2FLVAVIP%2FLVAREL%2FNAV3G5%2FRAD37A%2FSDPCLV%2FTLFRAN%2FGENEV1%2FSAN913%2FBT4AR1%2FNBT017&databaseId=1d514feb-93a6-4b45-8785-e11d2a6f1864&bookmarkSet=RSITE&bookmark=EXT_34_DESSUS&profile=HELIOS_OWNERSERVICES_SMALL_V2", | ||
}, | ||
], | ||
}, | ||
{ | ||
"assetType": "PDF", | ||
"assetRole": "GUIDE", | ||
"title": "PDF Guide", | ||
"description": "", | ||
"renditions": [ | ||
{ | ||
"url": "https://cdn.group.renault.com/ren/gb/myr/assets/x101ve/manual.pdf.asset.pdf/1558704861676.pdf" | ||
} | ||
], | ||
}, | ||
{ | ||
"assetType": "URL", | ||
"assetRole": "GUIDE", | ||
"title": "e-guide", | ||
"description": "", | ||
"renditions": [{"url": "http://gb.e-guide.renault.com/eng/Zoe"}], | ||
}, | ||
{ | ||
"assetType": "VIDEO", | ||
"assetRole": "CAR", | ||
"title": "10 Fundamentals about getting the best out of your electric vehicle", | ||
"description": "", | ||
"renditions": [{"url": "39r6QEKcOM4"}], | ||
}, | ||
{ | ||
"assetType": "VIDEO", | ||
"assetRole": "CAR", | ||
"title": "Automatic Climate Control", | ||
"description": "", | ||
"renditions": [{"url": "Va2FnZFo_GE"}], | ||
}, | ||
{ | ||
"assetType": "URL", | ||
"assetRole": "CAR", | ||
"title": "More videos", | ||
"description": "", | ||
"renditions": [{"url": "https://www.youtube.com/watch?v=wfpCMkK1rKI"}], | ||
}, | ||
{ | ||
"assetType": "VIDEO", | ||
"assetRole": "CAR", | ||
"title": "Charging the battery", | ||
"description": "", | ||
"renditions": [{"url": "RaEad8DjUJs"}], | ||
}, | ||
{ | ||
"assetType": "VIDEO", | ||
"assetRole": "CAR", | ||
"title": "Charging the battery at a station with a flap", | ||
"description": "", | ||
"renditions": [{"url": "zJfd7fJWtr0"}], | ||
}, | ||
], | ||
"yearsOfMaintenance": 12, | ||
"connectivityTechnology": "RLINK1", | ||
"easyConnectStore": False, | ||
"electrical": True, | ||
"rlinkStore": False, | ||
"deliveryDate": "2017-08-11", | ||
"retrievedFromDhs": False, | ||
"engineEnergyType": "ELEC", | ||
"radioCode": "**REDACTED**", | ||
} | ||
|
||
|
||
@pytest.mark.usefixtures("fixtures_with_data") | ||
@pytest.mark.parametrize("vehicle_type", ["zoe_40"], indirect=True) | ||
async def test_entry_diagnostics( | ||
hass: HomeAssistant, config_entry: ConfigEntry, hass_client | ||
): | ||
"""Test config entry diagnostics.""" | ||
await hass.config_entries.async_setup(config_entry.entry_id) | ||
await hass.async_block_till_done() | ||
|
||
assert await get_diagnostics_for_config_entry(hass, hass_client, config_entry) == { | ||
"entry": { | ||
"data": { | ||
"kamereon_account_id": "**REDACTED**", | ||
"locale": "fr_FR", | ||
"password": "**REDACTED**", | ||
"username": "**REDACTED**", | ||
}, | ||
"title": "Mock Title", | ||
}, | ||
"vehicles": [VEHICLE_DETAILS], | ||
} | ||
|
||
|
||
@pytest.mark.usefixtures("fixtures_with_data") | ||
@pytest.mark.parametrize("vehicle_type", ["zoe_40"], indirect=True) | ||
async def test_device_diagnostics( | ||
hass: HomeAssistant, config_entry: ConfigEntry, hass_client | ||
): | ||
"""Test config entry diagnostics.""" | ||
device_registry = mock_device_registry(hass) | ||
|
||
await hass.config_entries.async_setup(config_entry.entry_id) | ||
await hass.async_block_till_done() | ||
|
||
device = device_registry.async_get_device({(DOMAIN, "VF1AAAAA555777999")}) | ||
assert device is not None | ||
|
||
assert await get_diagnostics_for_device( | ||
hass, hass_client, config_entry, device | ||
) == {"details": VEHICLE_DETAILS} |