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

Added default values for missing info and a new sensor for raw JSON response #38

Merged
merged 10 commits into from
Oct 2, 2023
21 changes: 20 additions & 1 deletion custom_components/bouncie/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from homeassistant.const import CONF_SCAN_INTERVAL, Platform
from homeassistant.core import Config, HomeAssistant

from .const import DOMAIN, LOGGER
from .const import DOMAIN, LOGGER, VEHICLE_MODEL_KEY
from .coordinator import BouncieDataUpdateCoordinator

PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.DEVICE_TRACKER]
Expand Down Expand Up @@ -50,4 +50,23 @@ def patch_missing_data(vehicle_info):
"status": "Not available",
"lastUpdated": "Not available",
}
if "mil" not in vehicle_info["stats"]:
vehicle_info["stats"]["mil"] = {
"milOn": "Not available",
"lastUpdated": "Not available",
}
if "location" not in vehicle_info["stats"]:
vehicle_info["stats"]["location"] = {
"address": "Not available",
}
if "fuelLevel" not in vehicle_info["stats"]:
vehicle_info["stats"]["fuelLevel"] = -1
if "nickName" not in vehicle_info:
vehicle_info["nickName"] = (
str(vehicle_info[VEHICLE_MODEL_KEY]["year"])
+ " "
+ str(vehicle_info[VEHICLE_MODEL_KEY]["make"])
+ " "
+ str(vehicle_info[VEHICLE_MODEL_KEY]["name"])
)
return vehicle_info
2 changes: 2 additions & 0 deletions custom_components/bouncie/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
ATTR_VEHICLE_VIN_KEY = "vin"
ATTR_VEHICLE_IMEI_KEY = "imei"

ATTR_VEHICLE_STATS_LAST_UPDATE_JSON_KEY = "stats_last_update_json"

ATTR_VEHICLE_STATS_LAST_UPDATED_KEY = "stats_last_updated"
ATTR_VEHICLE_STATS_ODOMETER_KEY = "stats_odometer"
ATTR_VEHICLE_STATS_LOCATION_LAT_KEY = "stats_location_lat"
Expand Down
11 changes: 11 additions & 0 deletions custom_components/bouncie/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

from . import BouncieDataUpdateCoordinator, const, patch_missing_data

import json

ATTRIBUTION = "Data provided by Bouncie"
PARALLEL_UPDATES = 1

Expand Down Expand Up @@ -54,6 +56,15 @@ def update_car_info_attributes(vehicle_info):


SENSORS: tuple[BouncieSensorEntityDescription, ...] = (
BouncieSensorEntityDescription(
key="car-last-update",
icon="mdi:code-json",
name="Last Update",
value_fn=lambda vehicle_info: vehicle_info["stats"]["lastUpdated"],
extra_attrs_fn=lambda vehicle_info: {
const.ATTR_VEHICLE_STATS_LAST_UPDATE_JSON_KEY: json.dumps(vehicle_info)
}
),
BouncieSensorEntityDescription(
key="car-info",
icon="mdi:car",
Expand Down
56 changes: 56 additions & 0 deletions tests/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,59 @@ async def test_battery_info_missing(
assert entry is not None
state = hass.states.get("sensor.my_prius_car_battery")
assert state.state == "Not available"


async def test_stats_mil_missing(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test battery info missing from bouncie server."""
updated_response = list(const.MOCK_VEHICLES_RESPONSE)
del updated_response[0]["stats"]["mil"]
await setup_platform(hass, SENSOR_DOMAIN, updated_response)
entity_registry = er.async_get(hass)
entry = entity_registry.async_get("sensor.my_prius_car_mil")
assert entry is not None
state = hass.states.get("sensor.my_prius_car_mil")
assert state.state == "Not available"


async def test_stats_location_missing(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test battery info missing from bouncie server."""
updated_response = list(const.MOCK_VEHICLES_RESPONSE)
del updated_response[0]["stats"]["location"]
await setup_platform(hass, SENSOR_DOMAIN, updated_response)
entity_registry = er.async_get(hass)
entry = entity_registry.async_get("sensor.my_prius_car_address")
assert entry is not None
state = hass.states.get("sensor.my_prius_car_address")
assert state.state == "Not available"


async def test_stats_fuel_missing(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test battery info missing from bouncie server."""
updated_response = list(const.MOCK_VEHICLES_RESPONSE)
del updated_response[0]["stats"]["fuelLevel"]
await setup_platform(hass, SENSOR_DOMAIN, updated_response)
entity_registry = er.async_get(hass)
entry = entity_registry.async_get("sensor.my_prius_car_fuel")
assert entry is not None
state = hass.states.get("sensor.my_prius_car_fuel")
assert state.state == "-1"


async def test_nickname_missing(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test battery info missing from bouncie server."""
updated_response = list(const.MOCK_VEHICLES_RESPONSE)
del updated_response[0]["nickName"]
await setup_platform(hass, SENSOR_DOMAIN, updated_response)
entity_registry = er.async_get(hass)
entry = entity_registry.async_get("sensor.2007_toyota_prius_car_info")
assert entry is not None
entry = entity_registry.async_get("sensor.my_prious_car_info")
assert entry is None