Add Binary Sensor platform to Tessie (#105421)

This commit is contained in:
Brett Adams 2023-12-16 14:56:38 +10:00 committed by GitHub
parent 59630460c6
commit 887f9a21e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 237 additions and 5 deletions

View File

@ -14,7 +14,7 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DOMAIN
from .coordinator import TessieDataUpdateCoordinator
PLATFORMS = [Platform.SENSOR]
PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
_LOGGER = logging.getLogger(__name__)

View File

@ -0,0 +1,142 @@
"""Binary Sensor platform for Tessie integration."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .coordinator import TessieDataUpdateCoordinator
from .entity import TessieEntity
@dataclass
class TessieBinarySensorEntityDescription(BinarySensorEntityDescription):
"""Describes Tessie binary sensor entity."""
is_on: Callable[..., bool] = lambda x: x
DESCRIPTIONS: tuple[TessieBinarySensorEntityDescription, ...] = (
TessieBinarySensorEntityDescription(
key="charge_state_battery_heater_on",
device_class=BinarySensorDeviceClass.HEAT,
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="charge_state_charging_state",
device_class=BinarySensorDeviceClass.BATTERY_CHARGING,
is_on=lambda x: x == "Charging",
),
TessieBinarySensorEntityDescription(
key="charge_state_preconditioning_enabled",
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="charge_state_scheduled_charging_pending",
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="charge_state_trip_charging",
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="climate_state_auto_seat_climate_left",
device_class=BinarySensorDeviceClass.HEAT,
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="climate_state_auto_seat_climate_right",
device_class=BinarySensorDeviceClass.HEAT,
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="climate_state_auto_steering_wheel_heat",
device_class=BinarySensorDeviceClass.HEAT,
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="climate_state_cabin_overheat_protection",
device_class=BinarySensorDeviceClass.RUNNING,
is_on=lambda x: x == "On",
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="climate_state_cabin_overheat_protection_actively_cooling",
device_class=BinarySensorDeviceClass.HEAT,
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="vehicle_state_dashcam_state",
device_class=BinarySensorDeviceClass.RUNNING,
is_on=lambda x: x == "Recording",
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="vehicle_state_is_user_present",
device_class=BinarySensorDeviceClass.PRESENCE,
),
TessieBinarySensorEntityDescription(
key="vehicle_state_tpms_soft_warning_fl",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="vehicle_state_tpms_soft_warning_fr",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="vehicle_state_tpms_soft_warning_rl",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
),
TessieBinarySensorEntityDescription(
key="vehicle_state_tpms_soft_warning_rr",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
),
)
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up the Tessie binary sensor platform from a config entry."""
coordinators = hass.data[DOMAIN][entry.entry_id]
async_add_entities(
TessieBinarySensorEntity(coordinator, description)
for coordinator in coordinators
for description in DESCRIPTIONS
if description.key in coordinator.data
)
class TessieBinarySensorEntity(TessieEntity, BinarySensorEntity):
"""Base class for Tessie binary sensors."""
entity_description: TessieBinarySensorEntityDescription
def __init__(
self,
coordinator: TessieDataUpdateCoordinator,
description: TessieBinarySensorEntityDescription,
) -> None:
"""Initialize the sensor."""
super().__init__(coordinator, description.key)
self.entity_description = description
@property
def is_on(self) -> bool:
"""Return the state of the binary sensor."""
return self.entity_description.is_on(self._value)

View File

@ -71,16 +71,16 @@
"name": "Odometer"
},
"vehicle_state_tpms_pressure_fl": {
"name": "Tyre pressure front left"
"name": "Tire pressure front left"
},
"vehicle_state_tpms_pressure_fr": {
"name": "Tyre pressure front right"
"name": "Tire pressure front right"
},
"vehicle_state_tpms_pressure_rl": {
"name": "Tyre pressure rear left"
"name": "Tire pressure rear left"
},
"vehicle_state_tpms_pressure_rr": {
"name": "Tyre pressure rear right"
"name": "Tire pressure rear right"
},
"climate_state_inside_temp": {
"name": "Inside temperature"
@ -94,6 +94,62 @@
"climate_state_passenger_temp_setting": {
"name": "Passenger temperature setting"
}
},
"binary_sensor": {
"charge_state_battery_heater_on": {
"name": "Battery heater"
},
"charge_state_charge_enable_request": {
"name": "Charge enable request"
},
"charge_state_charge_port_door_open": {
"name": "Charge port door"
},
"charge_state_charging_state": {
"name": "Charging"
},
"charge_state_preconditioning_enabled": {
"name": "Preconditioning enabled"
},
"charge_state_scheduled_charging_pending": {
"name": "Scheduled charging pending"
},
"charge_state_trip_charging": {
"name": "Trip charging"
},
"climate_state_auto_seat_climate_left": {
"name": "Auto seat climate left"
},
"climate_state_auto_seat_climate_right": {
"name": "Auto seat climate right"
},
"climate_state_auto_steering_wheel_heater": {
"name": "Auto steering wheel heater"
},
"climate_state_cabin_overheat_protection": {
"name": "Cabin overheat protection"
},
"climate_state_cabin_overheat_protection_actively_cooling": {
"name": "Cabin overheat protection actively cooling"
},
"vehicle_state_dashcam_state": {
"name": "Dashcam"
},
"vehicle_state_is_user_present": {
"name": "User present"
},
"vehicle_state_tpms_soft_warning_fl": {
"name": "Tire pressure warning front left"
},
"vehicle_state_tpms_soft_warning_fr": {
"name": "Tire pressure warning front right"
},
"vehicle_state_tpms_soft_warning_rl": {
"name": "Tire pressure warning rear left"
},
"vehicle_state_tpms_soft_warning_rr": {
"name": "Tire pressure warning rear right"
}
}
}
}

View File

@ -15,6 +15,7 @@ from tests.common import MockConfigEntry, load_json_object_fixture
TEST_STATE_OF_ALL_VEHICLES = load_json_object_fixture("vehicles.json", DOMAIN)
TEST_VEHICLE_STATE_ONLINE = load_json_object_fixture("online.json", DOMAIN)
TEST_VEHICLE_STATE_ASLEEP = load_json_object_fixture("asleep.json", DOMAIN)
TEST_RESPONSE = {"result": True}
TEST_CONFIG = {CONF_ACCESS_TOKEN: "1234567890"}
TESSIE_URL = "https://api.tessie.com/"

View File

@ -0,0 +1,33 @@
"""Test the Tessie binary sensor platform."""
from homeassistant.components.tessie.binary_sensor import DESCRIPTIONS
from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.core import HomeAssistant
from .common import TEST_VEHICLE_STATE_ONLINE, setup_platform
OFFON = [STATE_OFF, STATE_ON]
async def test_binary_sensors(hass: HomeAssistant) -> None:
"""Tests that the sensors are correct."""
assert len(hass.states.async_all("binary_sensor")) == 0
await setup_platform(hass)
assert len(hass.states.async_all("binary_sensor")) == len(DESCRIPTIONS)
state = hass.states.get("binary_sensor.test_battery_heater").state
is_on = state == STATE_ON
assert is_on == TEST_VEHICLE_STATE_ONLINE["charge_state"]["battery_heater_on"]
state = hass.states.get("binary_sensor.test_charging").state
is_on = state == STATE_ON
assert is_on == (
TEST_VEHICLE_STATE_ONLINE["charge_state"]["charging_state"] == "Charging"
)
state = hass.states.get("binary_sensor.test_auto_seat_climate_left").state
is_on = state == STATE_ON
assert is_on == TEST_VEHICLE_STATE_ONLINE["climate_state"]["auto_seat_climate_left"]