Compare commits

..

1 Commits

Author SHA1 Message Date
abmantis
9823e31206 Add Ubisys virtual integration 2026-02-27 10:58:27 +00:00
50 changed files with 7056 additions and 29252 deletions

View File

@@ -325,7 +325,6 @@ homeassistant.components.ld2410_ble.*
homeassistant.components.led_ble.*
homeassistant.components.lektrico.*
homeassistant.components.letpot.*
homeassistant.components.lg_infrared.*
homeassistant.components.libre_hardware_monitor.*
homeassistant.components.lidarr.*
homeassistant.components.lifx.*

4
CODEOWNERS generated
View File

@@ -1901,8 +1901,8 @@ build.json @home-assistant/supervisor
/tests/components/withings/ @joostlek
/homeassistant/components/wiz/ @sbidy @arturpragacz
/tests/components/wiz/ @sbidy @arturpragacz
/homeassistant/components/wled/ @frenck @mik-laj
/tests/components/wled/ @frenck @mik-laj
/homeassistant/components/wled/ @frenck
/tests/components/wled/ @frenck
/homeassistant/components/wmspro/ @mback2k
/tests/components/wmspro/ @mback2k
/homeassistant/components/wolflink/ @adamkrol93 @mtielen

View File

@@ -0,0 +1,5 @@
{
"domain": "ubisys",
"name": "Ubisys",
"iot_standards": ["zigbee"]
}

View File

@@ -64,8 +64,6 @@ SENSOR_TYPES: tuple[BSBLanSensorEntityDescription, ...] = (
device_class=SensorDeviceClass.ENERGY,
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
state_class=SensorStateClass.TOTAL_INCREASING,
suggested_display_precision=0,
entity_registry_enabled_default=False,
value_fn=lambda data: (
data.sensor.total_energy.value
if data.sensor.total_energy is not None

View File

@@ -33,8 +33,6 @@ DUNEHD_PLAYER_SUPPORT: Final[MediaPlayerEntityFeature] = (
| MediaPlayerEntityFeature.PLAY
| MediaPlayerEntityFeature.PLAY_MEDIA
| MediaPlayerEntityFeature.BROWSE_MEDIA
| MediaPlayerEntityFeature.VOLUME_STEP
| MediaPlayerEntityFeature.VOLUME_MUTE
)

View File

@@ -405,13 +405,8 @@ CT_SENSORS = (
)
for cttype, key in (
(CtType.NET_CONSUMPTION, "lifetime_net_consumption"),
(CtType.PRODUCTION, "production_ct_energy_delivered"),
# Production CT energy_delivered is not used
(CtType.STORAGE, "lifetime_battery_discharged"),
(CtType.TOTAL_CONSUMPTION, "total_consumption_ct_energy_delivered"),
(CtType.BACKFEED, "backfeed_ct_energy_delivered"),
(CtType.LOAD, "load_ct_energy_delivered"),
(CtType.EVSE, "evse_ct_energy_delivered"),
(CtType.PV3P, "pv3p_ct_energy_delivered"),
)
]
+ [
@@ -428,13 +423,8 @@ CT_SENSORS = (
)
for cttype, key in (
(CtType.NET_CONSUMPTION, "lifetime_net_production"),
(CtType.PRODUCTION, "production_ct_energy_received"),
# Production CT energy_received is not used
(CtType.STORAGE, "lifetime_battery_charged"),
(CtType.TOTAL_CONSUMPTION, "total_consumption_ct_energy_received"),
(CtType.BACKFEED, "backfeed_ct_energy_received"),
(CtType.LOAD, "load_ct_energy_received"),
(CtType.EVSE, "evse_ct_energy_received"),
(CtType.PV3P, "pv3p_ct_energy_received"),
)
]
+ [
@@ -451,13 +441,8 @@ CT_SENSORS = (
)
for cttype, key in (
(CtType.NET_CONSUMPTION, "net_consumption"),
(CtType.PRODUCTION, "production_ct_power"),
# Production CT active_power is not used
(CtType.STORAGE, "battery_discharge"),
(CtType.TOTAL_CONSUMPTION, "total_consumption_ct_power"),
(CtType.BACKFEED, "backfeed_ct_power"),
(CtType.LOAD, "load_ct_power"),
(CtType.EVSE, "evse_ct_power"),
(CtType.PV3P, "pv3p_ct_power"),
)
]
+ [
@@ -476,11 +461,6 @@ CT_SENSORS = (
(CtType.NET_CONSUMPTION, "frequency", "net_ct_frequency"),
(CtType.PRODUCTION, "production_ct_frequency", ""),
(CtType.STORAGE, "storage_ct_frequency", ""),
(CtType.TOTAL_CONSUMPTION, "total_consumption_ct_frequency", ""),
(CtType.BACKFEED, "backfeed_ct_frequency", ""),
(CtType.LOAD, "load_ct_frequency", ""),
(CtType.EVSE, "evse_ct_frequency", ""),
(CtType.PV3P, "pv3p_ct_frequency", ""),
)
]
+ [
@@ -500,11 +480,6 @@ CT_SENSORS = (
(CtType.NET_CONSUMPTION, "voltage", "net_ct_voltage"),
(CtType.PRODUCTION, "production_ct_voltage", ""),
(CtType.STORAGE, "storage_voltage", "storage_ct_voltage"),
(CtType.TOTAL_CONSUMPTION, "total_consumption_ct_voltage", ""),
(CtType.BACKFEED, "backfeed_ct_voltage", ""),
(CtType.LOAD, "load_ct_voltage", ""),
(CtType.EVSE, "evse_ct_voltage", ""),
(CtType.PV3P, "pv3p_ct_voltage", ""),
)
]
+ [
@@ -524,11 +499,6 @@ CT_SENSORS = (
(CtType.NET_CONSUMPTION, "net_ct_current"),
(CtType.PRODUCTION, "production_ct_current"),
(CtType.STORAGE, "storage_ct_current"),
(CtType.TOTAL_CONSUMPTION, "total_consumption_ct_current"),
(CtType.BACKFEED, "backfeed_ct_current"),
(CtType.LOAD, "load_ct_current"),
(CtType.EVSE, "evse_ct_current"),
(CtType.PV3P, "pv3p_ct_current"),
)
]
+ [
@@ -546,11 +516,6 @@ CT_SENSORS = (
(CtType.NET_CONSUMPTION, "net_ct_powerfactor"),
(CtType.PRODUCTION, "production_ct_powerfactor"),
(CtType.STORAGE, "storage_ct_powerfactor"),
(CtType.TOTAL_CONSUMPTION, "total_consumption_ct_powerfactor"),
(CtType.BACKFEED, "backfeed_ct_powerfactor"),
(CtType.LOAD, "load_ct_powerfactor"),
(CtType.EVSE, "evse_ct_powerfactor"),
(CtType.PV3P, "pv3p_ct_powerfactor"),
)
]
+ [
@@ -572,11 +537,6 @@ CT_SENSORS = (
),
(CtType.PRODUCTION, "production_ct_metering_status", ""),
(CtType.STORAGE, "storage_ct_metering_status", ""),
(CtType.TOTAL_CONSUMPTION, "total_consumption_ct_metering_status", ""),
(CtType.BACKFEED, "backfeed_ct_metering_status", ""),
(CtType.LOAD, "load_ct_metering_status", ""),
(CtType.EVSE, "evse_ct_metering_status", ""),
(CtType.PV3P, "pv3p_ct_metering_status", ""),
)
]
+ [
@@ -597,11 +557,6 @@ CT_SENSORS = (
),
(CtType.PRODUCTION, "production_ct_status_flags", ""),
(CtType.STORAGE, "storage_ct_status_flags", ""),
(CtType.TOTAL_CONSUMPTION, "total_consumption_ct_status_flags", ""),
(CtType.BACKFEED, "backfeed_ct_status_flags", ""),
(CtType.LOAD, "load_ct_status_flags", ""),
(CtType.EVSE, "evse_ct_status_flags", ""),
(CtType.PV3P, "pv3p_ct_status_flags", ""),
)
]
)

View File

@@ -160,60 +160,6 @@
"available_energy": {
"name": "Available battery energy"
},
"backfeed_ct_current": {
"name": "Backfeed CT current"
},
"backfeed_ct_current_phase": {
"name": "Backfeed CT current {phase_name}"
},
"backfeed_ct_energy_delivered": {
"name": "Backfeed CT energy delivered"
},
"backfeed_ct_energy_delivered_phase": {
"name": "Backfeed CT energy delivered {phase_name}"
},
"backfeed_ct_energy_received": {
"name": "Backfeed CT energy received"
},
"backfeed_ct_energy_received_phase": {
"name": "Backfeed CT energy received {phase_name}"
},
"backfeed_ct_frequency": {
"name": "Frequency backfeed CT"
},
"backfeed_ct_frequency_phase": {
"name": "Frequency backfeed CT {phase_name}"
},
"backfeed_ct_metering_status": {
"name": "Metering status backfeed CT"
},
"backfeed_ct_metering_status_phase": {
"name": "Metering status backfeed CT {phase_name}"
},
"backfeed_ct_power": {
"name": "Backfeed CT power"
},
"backfeed_ct_power_phase": {
"name": "Backfeed CT power {phase_name}"
},
"backfeed_ct_powerfactor": {
"name": "Power factor backfeed CT"
},
"backfeed_ct_powerfactor_phase": {
"name": "Power factor backfeed CT {phase_name}"
},
"backfeed_ct_status_flags": {
"name": "Meter status flags active backfeed CT"
},
"backfeed_ct_status_flags_phase": {
"name": "Meter status flags active backfeed CT {phase_name}"
},
"backfeed_ct_voltage": {
"name": "Voltage backfeed CT"
},
"backfeed_ct_voltage_phase": {
"name": "Voltage backfeed CT {phase_name}"
},
"balanced_net_consumption": {
"name": "Balanced net power consumption"
},
@@ -265,60 +211,6 @@
"energy_today": {
"name": "[%key:component::enphase_envoy::entity::sensor::daily_production::name%]"
},
"evse_ct_current": {
"name": "EVSE CT current"
},
"evse_ct_current_phase": {
"name": "EVSE CT current {phase_name}"
},
"evse_ct_energy_delivered": {
"name": "EVSE CT energy delivered"
},
"evse_ct_energy_delivered_phase": {
"name": "EVSE CT energy delivered {phase_name}"
},
"evse_ct_energy_received": {
"name": "EVSE CT energy received"
},
"evse_ct_energy_received_phase": {
"name": "EVSE CT energy received {phase_name}"
},
"evse_ct_frequency": {
"name": "Frequency EVSE CT"
},
"evse_ct_frequency_phase": {
"name": "Frequency EVSE CT {phase_name}"
},
"evse_ct_metering_status": {
"name": "Metering status EVSE CT"
},
"evse_ct_metering_status_phase": {
"name": "Metering status EVSE CT {phase_name}"
},
"evse_ct_power": {
"name": "EVSE CT power"
},
"evse_ct_power_phase": {
"name": "EVSE CT power {phase_name}"
},
"evse_ct_powerfactor": {
"name": "Power factor EVSE CT"
},
"evse_ct_powerfactor_phase": {
"name": "Power factor EVSE CT {phase_name}"
},
"evse_ct_status_flags": {
"name": "Meter status flags active EVSE CT"
},
"evse_ct_status_flags_phase": {
"name": "Meter status flags active EVSE CT {phase_name}"
},
"evse_ct_voltage": {
"name": "Voltage EVSE CT"
},
"evse_ct_voltage_phase": {
"name": "Voltage EVSE CT {phase_name}"
},
"grid_status": {
"name": "[%key:component::enphase_envoy::entity::binary_sensor::grid_status::name%]",
"state": {
@@ -378,60 +270,6 @@
"lifetime_production_phase": {
"name": "Lifetime energy production {phase_name}"
},
"load_ct_current": {
"name": "Load CT current"
},
"load_ct_current_phase": {
"name": "Load CT current {phase_name}"
},
"load_ct_energy_delivered": {
"name": "Load CT energy delivered"
},
"load_ct_energy_delivered_phase": {
"name": "Load CT energy delivered {phase_name}"
},
"load_ct_energy_received": {
"name": "Load CT energy received"
},
"load_ct_energy_received_phase": {
"name": "Load CT energy received {phase_name}"
},
"load_ct_frequency": {
"name": "Frequency load CT"
},
"load_ct_frequency_phase": {
"name": "Frequency load CT {phase_name}"
},
"load_ct_metering_status": {
"name": "Metering status load CT"
},
"load_ct_metering_status_phase": {
"name": "Metering status load CT {phase_name}"
},
"load_ct_power": {
"name": "Load CT power"
},
"load_ct_power_phase": {
"name": "Load CT power {phase_name}"
},
"load_ct_powerfactor": {
"name": "Power factor load CT"
},
"load_ct_powerfactor_phase": {
"name": "Power factor load CT {phase_name}"
},
"load_ct_status_flags": {
"name": "Meter status flags active load CT"
},
"load_ct_status_flags_phase": {
"name": "Meter status flags active load CT {phase_name}"
},
"load_ct_voltage": {
"name": "Voltage load CT"
},
"load_ct_voltage_phase": {
"name": "Voltage load CT {phase_name}"
},
"max_capacity": {
"name": "Battery capacity"
},
@@ -493,18 +331,6 @@
"production_ct_current_phase": {
"name": "Production CT current {phase_name}"
},
"production_ct_energy_delivered": {
"name": "Production CT energy delivered"
},
"production_ct_energy_delivered_phase": {
"name": "Production CT energy delivered {phase_name}"
},
"production_ct_energy_received": {
"name": "Production CT energy received"
},
"production_ct_energy_received_phase": {
"name": "Production CT energy received {phase_name}"
},
"production_ct_frequency": {
"name": "Frequency production CT"
},
@@ -517,12 +343,6 @@
"production_ct_metering_status_phase": {
"name": "Metering status production CT {phase_name}"
},
"production_ct_power": {
"name": "Production CT power"
},
"production_ct_power_phase": {
"name": "Production CT power {phase_name}"
},
"production_ct_powerfactor": {
"name": "Power factor production CT"
},
@@ -541,60 +361,6 @@
"production_ct_voltage_phase": {
"name": "Voltage production CT {phase_name}"
},
"pv3p_ct_current": {
"name": "PV3P CT current"
},
"pv3p_ct_current_phase": {
"name": "PV3P CT current {phase_name}"
},
"pv3p_ct_energy_delivered": {
"name": "PV3P CT energy delivered"
},
"pv3p_ct_energy_delivered_phase": {
"name": "PV3P CT energy delivered {phase_name}"
},
"pv3p_ct_energy_received": {
"name": "PV3P CT energy received"
},
"pv3p_ct_energy_received_phase": {
"name": "PV3P CT energy received {phase_name}"
},
"pv3p_ct_frequency": {
"name": "Frequency PV3P CT"
},
"pv3p_ct_frequency_phase": {
"name": "Frequency PV3P CT {phase_name}"
},
"pv3p_ct_metering_status": {
"name": "Metering status PV3P CT"
},
"pv3p_ct_metering_status_phase": {
"name": "Metering status PV3P CT {phase_name}"
},
"pv3p_ct_power": {
"name": "PV3P CT power"
},
"pv3p_ct_power_phase": {
"name": "PV3P CT power {phase_name}"
},
"pv3p_ct_powerfactor": {
"name": "Power factor PV3P CT"
},
"pv3p_ct_powerfactor_phase": {
"name": "Power factor PV3P CT {phase_name}"
},
"pv3p_ct_status_flags": {
"name": "Meter status flags active PV3P CT"
},
"pv3p_ct_status_flags_phase": {
"name": "Meter status flags active PV3P CT {phase_name}"
},
"pv3p_ct_voltage": {
"name": "Voltage PV3P CT"
},
"pv3p_ct_voltage_phase": {
"name": "Voltage PV3P CT {phase_name}"
},
"reserve_energy": {
"name": "Reserve battery energy"
},
@@ -648,60 +414,6 @@
},
"storage_ct_voltage_phase": {
"name": "Voltage storage CT {phase_name}"
},
"total_consumption_ct_current": {
"name": "Total consumption CT current"
},
"total_consumption_ct_current_phase": {
"name": "Total consumption CT current {phase_name}"
},
"total_consumption_ct_energy_delivered": {
"name": "Total consumption CT energy delivered"
},
"total_consumption_ct_energy_delivered_phase": {
"name": "Total consumption CT energy delivered {phase_name}"
},
"total_consumption_ct_energy_received": {
"name": "Total consumption CT energy received"
},
"total_consumption_ct_energy_received_phase": {
"name": "Total consumption CT energy received {phase_name}"
},
"total_consumption_ct_frequency": {
"name": "Frequency total consumption CT"
},
"total_consumption_ct_frequency_phase": {
"name": "Frequency total consumption CT {phase_name}"
},
"total_consumption_ct_metering_status": {
"name": "Metering status total consumption CT"
},
"total_consumption_ct_metering_status_phase": {
"name": "Metering status total consumption CT {phase_name}"
},
"total_consumption_ct_power": {
"name": "Total consumption CT power"
},
"total_consumption_ct_power_phase": {
"name": "Total consumption CT power {phase_name}"
},
"total_consumption_ct_powerfactor": {
"name": "Power factor total consumption CT"
},
"total_consumption_ct_powerfactor_phase": {
"name": "Power factor total consumption CT {phase_name}"
},
"total_consumption_ct_status_flags": {
"name": "Meter status flags active total consumption CT"
},
"total_consumption_ct_status_flags_phase": {
"name": "Meter status flags active total consumption CT {phase_name}"
},
"total_consumption_ct_voltage": {
"name": "Voltage total consumption CT"
},
"total_consumption_ct_voltage_phase": {
"name": "Voltage total consumption CT {phase_name}"
}
},
"switch": {

View File

@@ -29,7 +29,6 @@ from aioesphomeapi import (
Event,
EventInfo,
FanInfo,
InfraredInfo,
LightInfo,
LockInfo,
MediaPlayerInfo,
@@ -86,7 +85,6 @@ INFO_TYPE_TO_PLATFORM: dict[type[EntityInfo], Platform] = {
DateTimeInfo: Platform.DATETIME,
EventInfo: Platform.EVENT,
FanInfo: Platform.FAN,
InfraredInfo: Platform.INFRARED,
LightInfo: Platform.LIGHT,
LockInfo: Platform.LOCK,
MediaPlayerInfo: Platform.MEDIA_PLAYER,

View File

@@ -1,106 +0,0 @@
"""Infrared platform for ESPHome."""
from __future__ import annotations
import logging
from aioesphomeapi import (
APIConnectionError,
EntityInfo,
EntityState,
InfraredCapability,
InfraredInfo,
)
from homeassistant.components.infrared import InfraredCommand, InfraredEntity
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_platform
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import DOMAIN
from .entity import EsphomeEntity, async_static_info_updated
from .entry_data import ESPHomeConfigEntry
_LOGGER = logging.getLogger(__name__)
PARALLEL_UPDATES = 0
class EsphomeInfraredEntity(EsphomeEntity[InfraredInfo, EntityState], InfraredEntity):
"""ESPHome infrared entity using native API."""
_attr_has_entity_name = True
_attr_name = "Infrared Transmitter"
@callback
def _on_device_update(self) -> None:
"""Call when device updates or entry data changes."""
super()._on_device_update()
if self._entry_data.available:
# Infrared entities should go available as soon as the device comes online
self.async_write_ha_state()
async def async_send_command(self, command: InfraredCommand) -> None:
"""Send an IR command.
Raises:
HomeAssistantError: If transmission fails.
"""
timings = [
interval
for timing in command.get_raw_timings()
for interval in (timing.high_us, -timing.low_us)
]
_LOGGER.debug("Sending command: %s", timings)
try:
self._client.infrared_rf_transmit_raw_timings(
self._static_info.key,
carrier_frequency=command.modulation,
timings=timings,
)
except APIConnectionError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="error_sending_ir_command",
translation_placeholders={
"device_name": self._device_info.name,
"error": str(err),
},
) from err
async def async_setup_entry(
hass: HomeAssistant,
entry: ESPHomeConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up ESPHome infrared entities, filtering out receiver-only devices."""
entry_data = entry.runtime_data
entry_data.info[InfraredInfo] = {}
platform = entity_platform.async_get_current_platform()
def filtered_static_info_update(infos: list[EntityInfo]) -> None:
transmitter_infos: list[EntityInfo] = [
info
for info in infos
if isinstance(info, InfraredInfo)
and info.capabilities & InfraredCapability.TRANSMITTER
]
async_static_info_updated(
hass,
entry_data,
platform,
async_add_entities,
InfraredInfo,
EsphomeInfraredEntity,
EntityState,
transmitter_infos,
)
entry_data.cleanup_callbacks.append(
entry_data.async_register_static_info_callback(
InfraredInfo, filtered_static_info_update
)
)

View File

@@ -137,9 +137,6 @@
"error_compiling": {
"message": "Error compiling {configuration}. Try again in ESPHome dashboard for more information."
},
"error_sending_ir_command": {
"message": "Error sending IR command to {device_name}: {error}"
},
"error_uploading": {
"message": "Error during OTA (Over-The-Air) update of {configuration}. Try again in ESPHome dashboard for more information."
},

View File

@@ -1,7 +1,7 @@
{
"exceptions": {
"zone_only_service": {
"message": "Only zones support the `{service}` action"
"message": "Only zones support the `{service}` service"
}
},
"services": {

View File

@@ -45,10 +45,6 @@ async def async_user_store(hass: HomeAssistant, user_id: str) -> UserStore:
except BaseException as ex:
del stores[user_id]
future.set_exception(ex)
# Ensure the future is marked as retrieved
# since if there is no concurrent call it
# will otherwise never be retrieved.
future.exception()
raise
future.set_result(store)

View File

@@ -57,8 +57,8 @@
"battery_charge_discharge_state": {
"name": "Battery charge/discharge state",
"state": {
"charging": "[%key:common::state::charging%]",
"discharging": "[%key:common::state::discharging%]",
"charging": "Charging",
"discharging": "Discharging",
"static": "Static"
}
},

View File

@@ -1,20 +0,0 @@
"""LG IR Remote integration for Home Assistant."""
from __future__ import annotations
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
PLATFORMS = [Platform.BUTTON, Platform.MEDIA_PLAYER]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up LG IR from a config entry."""
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a LG IR config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

View File

@@ -1,260 +0,0 @@
"""Button platform for LG IR integration."""
from __future__ import annotations
from dataclasses import dataclass
from infrared_protocols import NECCommand
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.components.infrared import async_send_command
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.event import async_track_state_change_event
from .const import (
CONF_DEVICE_TYPE,
CONF_INFRARED_ENTITY_ID,
DOMAIN,
LG_ADDRESS,
MODULATION,
LGDeviceType,
LGTVCommand,
)
@dataclass(frozen=True, kw_only=True)
class LgIrButtonEntityDescription(ButtonEntityDescription):
"""Describes LG IR button entity."""
command_code: int
TV_BUTTON_DESCRIPTIONS: tuple[LgIrButtonEntityDescription, ...] = (
LgIrButtonEntityDescription(
key="power_on",
translation_key="power_on",
command_code=LGTVCommand.POWER_ON,
),
LgIrButtonEntityDescription(
key="power_off",
translation_key="power_off",
command_code=LGTVCommand.POWER_OFF,
),
LgIrButtonEntityDescription(
key="hdmi_1",
translation_key="hdmi_1",
command_code=LGTVCommand.HDMI_1,
),
LgIrButtonEntityDescription(
key="hdmi_2",
translation_key="hdmi_2",
command_code=LGTVCommand.HDMI_2,
),
LgIrButtonEntityDescription(
key="hdmi_3",
translation_key="hdmi_3",
command_code=LGTVCommand.HDMI_3,
),
LgIrButtonEntityDescription(
key="hdmi_4",
translation_key="hdmi_4",
command_code=LGTVCommand.HDMI_4,
),
LgIrButtonEntityDescription(
key="exit",
translation_key="exit",
command_code=LGTVCommand.EXIT,
),
LgIrButtonEntityDescription(
key="info",
translation_key="info",
command_code=LGTVCommand.INFO,
),
LgIrButtonEntityDescription(
key="guide",
translation_key="guide",
command_code=LGTVCommand.GUIDE,
),
LgIrButtonEntityDescription(
key="up",
translation_key="up",
command_code=LGTVCommand.NAV_UP,
),
LgIrButtonEntityDescription(
key="down",
translation_key="down",
command_code=LGTVCommand.NAV_DOWN,
),
LgIrButtonEntityDescription(
key="left",
translation_key="left",
command_code=LGTVCommand.NAV_LEFT,
),
LgIrButtonEntityDescription(
key="right",
translation_key="right",
command_code=LGTVCommand.NAV_RIGHT,
),
LgIrButtonEntityDescription(
key="ok",
translation_key="ok",
command_code=LGTVCommand.OK,
),
LgIrButtonEntityDescription(
key="back",
translation_key="back",
command_code=LGTVCommand.BACK,
),
LgIrButtonEntityDescription(
key="home",
translation_key="home",
command_code=LGTVCommand.HOME,
),
LgIrButtonEntityDescription(
key="menu",
translation_key="menu",
command_code=LGTVCommand.MENU,
),
LgIrButtonEntityDescription(
key="input",
translation_key="input",
command_code=LGTVCommand.INPUT,
),
LgIrButtonEntityDescription(
key="num_0",
translation_key="num_0",
command_code=LGTVCommand.NUM_0,
),
LgIrButtonEntityDescription(
key="num_1",
translation_key="num_1",
command_code=LGTVCommand.NUM_1,
),
LgIrButtonEntityDescription(
key="num_2",
translation_key="num_2",
command_code=LGTVCommand.NUM_2,
),
LgIrButtonEntityDescription(
key="num_3",
translation_key="num_3",
command_code=LGTVCommand.NUM_3,
),
LgIrButtonEntityDescription(
key="num_4",
translation_key="num_4",
command_code=LGTVCommand.NUM_4,
),
LgIrButtonEntityDescription(
key="num_5",
translation_key="num_5",
command_code=LGTVCommand.NUM_5,
),
LgIrButtonEntityDescription(
key="num_6",
translation_key="num_6",
command_code=LGTVCommand.NUM_6,
),
LgIrButtonEntityDescription(
key="num_7",
translation_key="num_7",
command_code=LGTVCommand.NUM_7,
),
LgIrButtonEntityDescription(
key="num_8",
translation_key="num_8",
command_code=LGTVCommand.NUM_8,
),
LgIrButtonEntityDescription(
key="num_9",
translation_key="num_9",
command_code=LGTVCommand.NUM_9,
),
)
HIFI_BUTTON_DESCRIPTIONS: tuple[LgIrButtonEntityDescription, ...] = (
LgIrButtonEntityDescription(
key="power_on",
translation_key="power_on",
command_code=LGTVCommand.POWER_ON,
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up LG IR buttons from config entry."""
infrared_entity_id = entry.data[CONF_INFRARED_ENTITY_ID]
device_type = entry.data.get(CONF_DEVICE_TYPE, LGDeviceType.TV)
if device_type == LGDeviceType.TV:
async_add_entities(
LgIrButton(entry, infrared_entity_id, description)
for description in TV_BUTTON_DESCRIPTIONS
)
class LgIrButton(ButtonEntity):
"""LG IR button entity."""
_attr_has_entity_name = True
_description: LgIrButtonEntityDescription
def __init__(
self,
entry: ConfigEntry,
infrared_entity_id: str,
description: LgIrButtonEntityDescription,
) -> None:
"""Initialize LG IR button."""
self._entry = entry
self._infrared_entity_id = infrared_entity_id
self._description = description
self.entity_description = description
self._attr_unique_id = f"{entry.entry_id}_{description.key}"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, entry.entry_id)}, name="LG TV", manufacturer="LG"
)
async def async_added_to_hass(self) -> None:
"""Subscribe to infrared entity state changes."""
await super().async_added_to_hass()
@callback
def _async_ir_state_changed(event: Event[EventStateChangedData]) -> None:
"""Handle infrared entity state changes."""
new_state = event.data["new_state"]
self._attr_available = (
new_state is not None and new_state.state != STATE_UNAVAILABLE
)
self.async_write_ha_state()
self.async_on_remove(
async_track_state_change_event(
self.hass, [self._infrared_entity_id], _async_ir_state_changed
)
)
# Set initial availability based on current infrared entity state
ir_state = self.hass.states.get(self._infrared_entity_id)
self._attr_available = (
ir_state is not None and ir_state.state != STATE_UNAVAILABLE
)
async def async_press(self) -> None:
"""Press the button."""
command = NECCommand(
address=LG_ADDRESS,
command=self._description.command_code,
modulation=MODULATION,
repeat_count=1,
)
await async_send_command(
self.hass, self._infrared_entity_id, command, context=self._context
)

View File

@@ -1,82 +0,0 @@
"""Config flow for LG IR integration."""
from typing import Any
import voluptuous as vol
from homeassistant.components.infrared import (
DOMAIN as INFRARED_DOMAIN,
async_get_emitters,
)
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.helpers.selector import (
EntitySelector,
EntitySelectorConfig,
SelectSelector,
SelectSelectorConfig,
SelectSelectorMode,
)
from .const import CONF_DEVICE_TYPE, CONF_INFRARED_ENTITY_ID, DOMAIN, LGDeviceType
DEVICE_TYPE_NAMES: dict[LGDeviceType, str] = {
LGDeviceType.TV: "TV",
}
class LgIrConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle config flow for LG IR."""
VERSION = 1
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial step."""
entities = async_get_emitters(self.hass)
if not entities:
return self.async_abort(reason="no_emitters")
valid_entity_ids = [entity.entity_id for entity in entities]
if user_input is not None:
entity_id = user_input[CONF_INFRARED_ENTITY_ID]
device_type = user_input[CONF_DEVICE_TYPE]
await self.async_set_unique_id(f"lg_ir_{device_type}_{entity_id}")
self._abort_if_unique_id_configured()
# Get entity name for the title
entity_name = next(
(
entity.name or entity.entity_id
for entity in entities
if entity.entity_id == entity_id
),
entity_id,
)
device_type_name = DEVICE_TYPE_NAMES[LGDeviceType(device_type)]
title = f"LG {device_type_name} via {entity_name}"
return self.async_create_entry(title=title, data=user_input)
return self.async_show_form(
step_id="user",
data_schema=vol.Schema(
{
vol.Required(CONF_DEVICE_TYPE): SelectSelector(
SelectSelectorConfig(
options=[device_type.value for device_type in LGDeviceType],
translation_key=CONF_DEVICE_TYPE,
mode=SelectSelectorMode.DROPDOWN,
)
),
vol.Required(CONF_INFRARED_ENTITY_ID): EntitySelector(
EntitySelectorConfig(
domain=INFRARED_DOMAIN,
include_entities=valid_entity_ids,
)
),
}
),
)

View File

@@ -1,60 +0,0 @@
"""Constants for the LG IR integration."""
from enum import StrEnum
DOMAIN = "lg_infrared"
CONF_INFRARED_ENTITY_ID = "infrared_entity_id"
CONF_DEVICE_TYPE = "device_type"
MODULATION = 38000
LG_ADDRESS = 0xFB04
class LGDeviceType(StrEnum):
"""LG device types."""
TV = "tv"
class LGTVCommand:
"""LG TV IR command codes."""
BACK = 0xD728
CHANNEL_DOWN = 0xFE01
CHANNEL_UP = 0xFF00
EXIT = 0xA45B
FAST_FORWARD = 0x718E
GUIDE = 0x56A9
HDMI_1 = 0x31CE
HDMI_2 = 0x33CC
HDMI_3 = 0x16E9
HDMI_4 = 0x25DA
HOME = 0x837C
INFO = 0x55AA
INPUT = 0xF40B
MENU = 0xBC43
MUTE = 0xF609
NAV_DOWN = 0xBE41
NAV_LEFT = 0xF807
NAV_RIGHT = 0xF906
NAV_UP = 0xBF40
NUM_0 = 0xEF10
NUM_1 = 0xEE11
NUM_2 = 0xED12
NUM_3 = 0xEC13
NUM_4 = 0xEB14
NUM_5 = 0xEA15
NUM_6 = 0xE916
NUM_7 = 0xE817
NUM_8 = 0xE718
NUM_9 = 0xE619
OK = 0xBB44
PAUSE = 0x45BA
PLAY = 0x4FB0
POWER = 0xF708
POWER_ON = 0x3BC4
POWER_OFF = 0x3AC5
REWIND = 0x708F
STOP = 0x4EB1
VOLUME_DOWN = 0xFC03
VOLUME_UP = 0xFD02

View File

@@ -1,11 +0,0 @@
{
"domain": "lg_infrared",
"name": "LG Infrared",
"codeowners": [],
"config_flow": true,
"dependencies": ["infrared"],
"documentation": "https://www.home-assistant.io/integrations/lg_infrared",
"integration_type": "device",
"iot_class": "local_push",
"quality_scale": "bronze"
}

View File

@@ -1,148 +0,0 @@
"""Media player platform for LG IR integration."""
from __future__ import annotations
from infrared_protocols import NECCommand
from homeassistant.components.infrared import async_send_command
from homeassistant.components.media_player import (
MediaPlayerDeviceClass,
MediaPlayerEntity,
MediaPlayerEntityFeature,
MediaPlayerState,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.event import async_track_state_change_event
from .const import (
CONF_DEVICE_TYPE,
CONF_INFRARED_ENTITY_ID,
DOMAIN,
LG_ADDRESS,
MODULATION,
LGDeviceType,
LGTVCommand,
)
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up LG IR media player from config entry."""
infrared_entity_id = entry.data[CONF_INFRARED_ENTITY_ID]
device_type = entry.data.get(CONF_DEVICE_TYPE, LGDeviceType.TV)
if device_type == LGDeviceType.TV:
async_add_entities([LgIrTvMediaPlayer(entry, infrared_entity_id)])
class LgIrTvMediaPlayer(MediaPlayerEntity):
"""LG IR media player entity."""
_attr_has_entity_name = True
_attr_name = None
_attr_assumed_state = True
_attr_device_class = MediaPlayerDeviceClass.TV
_attr_supported_features = (
MediaPlayerEntityFeature.TURN_ON
| MediaPlayerEntityFeature.TURN_OFF
| MediaPlayerEntityFeature.VOLUME_STEP
| MediaPlayerEntityFeature.VOLUME_MUTE
| MediaPlayerEntityFeature.NEXT_TRACK
| MediaPlayerEntityFeature.PREVIOUS_TRACK
| MediaPlayerEntityFeature.PLAY
| MediaPlayerEntityFeature.PAUSE
| MediaPlayerEntityFeature.STOP
)
def __init__(self, entry: ConfigEntry, infrared_entity_id: str) -> None:
"""Initialize LG IR media player."""
self._entry = entry
self._infrared_entity_id = infrared_entity_id
self._attr_unique_id = f"{entry.entry_id}_media_player"
self._attr_state = MediaPlayerState.ON
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, entry.entry_id)}, name="LG TV", manufacturer="LG"
)
async def async_added_to_hass(self) -> None:
"""Subscribe to infrared entity state changes."""
await super().async_added_to_hass()
@callback
def _async_ir_state_changed(event: Event[EventStateChangedData]) -> None:
"""Handle infrared entity state changes."""
new_state = event.data["new_state"]
self._attr_available = (
new_state is not None and new_state.state != STATE_UNAVAILABLE
)
self.async_write_ha_state()
self.async_on_remove(
async_track_state_change_event(
self.hass, [self._infrared_entity_id], _async_ir_state_changed
)
)
# Set initial availability based on current infrared entity state
ir_state = self.hass.states.get(self._infrared_entity_id)
self._attr_available = (
ir_state is not None and ir_state.state != STATE_UNAVAILABLE
)
async def _send_command(self, command_code: int, repeat_count: int = 1) -> None:
"""Send an IR command using the LG protocol."""
command = NECCommand(
address=LG_ADDRESS,
command=command_code,
modulation=MODULATION,
repeat_count=repeat_count,
)
await async_send_command(
self.hass, self._infrared_entity_id, command, context=self._context
)
async def async_turn_on(self) -> None:
"""Turn on the TV."""
await self._send_command(LGTVCommand.POWER)
async def async_turn_off(self) -> None:
"""Turn off the TV."""
await self._send_command(LGTVCommand.POWER)
async def async_volume_up(self) -> None:
"""Send volume up command."""
await self._send_command(LGTVCommand.VOLUME_UP)
async def async_volume_down(self) -> None:
"""Send volume down command."""
await self._send_command(LGTVCommand.VOLUME_DOWN)
async def async_mute_volume(self, mute: bool) -> None:
"""Send mute command."""
await self._send_command(LGTVCommand.MUTE)
async def async_media_next_track(self) -> None:
"""Send channel up command."""
await self._send_command(LGTVCommand.CHANNEL_UP)
async def async_media_previous_track(self) -> None:
"""Send channel down command."""
await self._send_command(LGTVCommand.CHANNEL_DOWN)
async def async_media_play(self) -> None:
"""Send play command."""
await self._send_command(LGTVCommand.PLAY)
async def async_media_pause(self) -> None:
"""Send pause command."""
await self._send_command(LGTVCommand.PAUSE)
async def async_media_stop(self) -> None:
"""Send stop command."""
await self._send_command(LGTVCommand.STOP)

View File

@@ -1,127 +0,0 @@
rules:
# Bronze
action-setup:
status: exempt
comment: |
This integration does not provide additional actions.
appropriate-polling:
status: exempt
comment: |
This integration does not poll.
brands:
status: exempt
comment: |
This is a proof of concept integration, brand assets will be added later.
common-modules:
status: exempt
comment: |
This integration is simple and does not share patterns with others.
config-flow-test-coverage:
status: exempt
comment: |
This is a proof of concept integration, config flow tests will be added later.
config-flow: done
dependency-transparency: done
docs-actions:
status: exempt
comment: |
This integration does not provide additional actions.
docs-high-level-description:
status: exempt
comment: |
This is a proof of concept integration, documentation will be added later.
docs-installation-instructions:
status: exempt
comment: |
This is a proof of concept integration, documentation will be added later.
docs-removal-instructions:
status: exempt
comment: |
This is a proof of concept integration, documentation will be added later.
entity-event-setup:
status: exempt
comment: |
This integration does not subscribe to events.
entity-unique-id: done
has-entity-name: done
runtime-data:
status: exempt
comment: |
This integration does not store runtime data.
test-before-configure: done
test-before-setup:
status: exempt
comment: |
Setup validation is handled by checking emitter existence in remote.py.
unique-config-entry: done
# Silver
action-exceptions: todo
config-entry-unloading: done
docs-configuration-parameters: todo
docs-installation-parameters: todo
entity-unavailable: done
integration-owner: todo
log-when-unavailable: todo
parallel-updates: todo
reauthentication-flow:
status: exempt
comment: |
This integration does not require authentication.
test-coverage: todo
# Gold
devices: done
diagnostics: todo
discovery-update-info:
status: exempt
comment: |
This integration does not support discovery.
discovery:
status: exempt
comment: |
This integration is configured manually via config flow.
docs-data-update: todo
docs-examples: todo
docs-known-limitations: todo
docs-supported-devices: todo
docs-supported-functions: todo
docs-troubleshooting: todo
docs-use-cases: todo
dynamic-devices:
status: exempt
comment: |
Each config entry creates a single device.
entity-category:
status: exempt
comment: |
The remote entity is the primary entity and does not need a category.
entity-device-class:
status: exempt
comment: |
Remote entities do not have a device class.
entity-disabled-by-default:
status: exempt
comment: |
The remote entity is the primary entity and should be enabled by default.
entity-translations: todo
exception-translations: todo
icon-translations: todo
reconfiguration-flow: todo
repair-issues:
status: exempt
comment: |
This integration does not have repairable issues.
stale-devices:
status: exempt
comment: |
Each config entry manages exactly one device.
# Platinum
async-dependency:
status: exempt
comment: |
This integration only depends on ir_proxy which is part of Home Assistant.
inject-websession:
status: exempt
comment: |
This integration does not make HTTP requests.
strict-typing: todo

View File

@@ -1,114 +0,0 @@
{
"config": {
"abort": {
"already_configured": "This LG device has already been configured with this transmitter.",
"no_emitters": "No infrared transmitter entities found. Please set up an infrared device first."
},
"step": {
"user": {
"data": {
"device_type": "Device type",
"infrared_entity_id": "Infrared transmitter"
},
"description": "Select the device type and the infrared transmitter entity to use for controlling your LG device.",
"title": "Set up LG IR Remote"
}
}
},
"entity": {
"button": {
"back": {
"name": "Back"
},
"down": {
"name": "Down"
},
"exit": {
"name": "Exit"
},
"guide": {
"name": "Guide"
},
"hdmi_1": {
"name": "HDMI 1"
},
"hdmi_2": {
"name": "HDMI 2"
},
"hdmi_3": {
"name": "HDMI 3"
},
"hdmi_4": {
"name": "HDMI 4"
},
"home": {
"name": "Home"
},
"info": {
"name": "Info"
},
"input": {
"name": "Input"
},
"left": {
"name": "Left"
},
"menu": {
"name": "Menu"
},
"num_0": {
"name": "0"
},
"num_1": {
"name": "1"
},
"num_2": {
"name": "2"
},
"num_3": {
"name": "3"
},
"num_4": {
"name": "4"
},
"num_5": {
"name": "5"
},
"num_6": {
"name": "6"
},
"num_7": {
"name": "7"
},
"num_8": {
"name": "8"
},
"num_9": {
"name": "9"
},
"ok": {
"name": "OK"
},
"power_off": {
"name": "Power off"
},
"power_on": {
"name": "Power on"
},
"right": {
"name": "Right"
},
"up": {
"name": "Up"
}
}
},
"selector": {
"device_type": {
"options": {
"hifi": "Hi-Fi",
"tv": "TV"
}
}
}
}

View File

@@ -5,13 +5,13 @@ from __future__ import annotations
from typing import Any
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_API_TOKEN, CONF_URL
from homeassistant.const import CONF_API_TOKEN
from homeassistant.core import HomeAssistant
from . import PortainerConfigEntry
from .coordinator import PortainerCoordinator
TO_REDACT = [CONF_API_TOKEN, CONF_URL]
TO_REDACT = [CONF_API_TOKEN]
def _serialize_coordinator(coordinator: PortainerCoordinator) -> dict[str, Any]:

View File

@@ -38,12 +38,6 @@
"ssl": "[%key:common::config_flow::data::ssl%]",
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
},
"data_description": {
"group": "[%key:component::sma::config::step::user::data_description::group%]",
"host": "[%key:component::sma::config::step::user::data_description::host%]",
"ssl": "[%key:component::sma::config::step::user::data_description::ssl%]",
"verify_ssl": "[%key:component::sma::config::step::user::data_description::verify_ssl%]"
},
"description": "Use the following form to reconfigure your SMA device.",
"title": "Reconfigure SMA Solar Integration"
},
@@ -56,11 +50,7 @@
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
},
"data_description": {
"group": "The group of your SMA device, where the Modbus connection is configured",
"host": "The hostname or IP address of your SMA device",
"password": "The password for your SMA device",
"ssl": "Whether to use SSL to connect to your SMA device. This is required for newer SMA devices, but older devices do not support SSL",
"verify_ssl": "Whether to verify SSL certificates. Disable only if you have a self-signed certificate"
"host": "The hostname or IP address of your SMA device."
},
"description": "Enter your SMA device information.",
"title": "Set up SMA Solar"

View File

@@ -95,7 +95,6 @@ ROBOT_CLEANER_TURBO_MODE_STATE_MAP = {
ROBOT_CLEANER_MOVEMENT_MAP = {
"powerOff": "off",
"washingMop": "washing_mop",
}
OVEN_MODE = {
@@ -881,7 +880,6 @@ CAPABILITY_TO_SENSORS: dict[
"after",
"cleaning",
"pause",
"washing_mop",
],
device_class=SensorDeviceClass.ENUM,
value_fn=lambda value: ROBOT_CLEANER_MOVEMENT_MAP.get(value, value),

View File

@@ -718,8 +718,7 @@
"off": "[%key:common::state::off%]",
"pause": "[%key:common::state::paused%]",
"point": "Point",
"reserve": "Reserve",
"washing_mop": "Washing mop"
"reserve": "Reserve"
}
},
"robot_cleaner_turbo_mode": {

View File

@@ -42,5 +42,5 @@
"iot_class": "local_push",
"loggers": ["switchbot"],
"quality_scale": "gold",
"requirements": ["PySwitchbot==1.1.0"]
"requirements": ["PySwitchbot==1.0.0"]
}

View File

@@ -1,7 +1,7 @@
{
"domain": "wled",
"name": "WLED",
"codeowners": ["@frenck", "@mik-laj"],
"codeowners": ["@frenck"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/wled",
"integration_type": "device",

View File

@@ -382,7 +382,6 @@ FLOWS = {
"led_ble",
"lektrico",
"letpot",
"lg_infrared",
"lg_netcast",
"lg_soundbar",
"lg_thinq",

View File

@@ -3665,12 +3665,6 @@
}
}
},
"lg_infrared": {
"name": "LG Infrared",
"integration_type": "device",
"config_flow": true,
"iot_class": "local_push"
},
"libre_hardware_monitor": {
"name": "Libre Hardware Monitor",
"integration_type": "device",
@@ -7350,6 +7344,12 @@
}
}
},
"ubisys": {
"name": "Ubisys",
"iot_standards": [
"zigbee"
]
},
"ubiwizz": {
"name": "Ubiwizz",
"integration_type": "virtual",

10
mypy.ini generated
View File

@@ -3006,16 +3006,6 @@ disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.lg_infrared.*]
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_decorators = true
disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.libre_hardware_monitor.*]
check_untyped_defs = true
disallow_incomplete_defs = true

2
requirements_all.txt generated
View File

@@ -83,7 +83,7 @@ PyRMVtransport==0.3.3
PySrDaliGateway==0.19.3
# homeassistant.components.switchbot
PySwitchbot==1.1.0
PySwitchbot==1.0.0
# homeassistant.components.switchmate
PySwitchmate==0.5.1

View File

@@ -83,7 +83,7 @@ PyRMVtransport==0.3.3
PySrDaliGateway==0.19.3
# homeassistant.components.switchbot
PySwitchbot==1.1.0
PySwitchbot==1.0.0
# homeassistant.components.syncthru
PySyncThru==0.8.0

View File

@@ -213,7 +213,6 @@ async def test_reauth_flow_scenario(
ap_fixture: AirOSData,
mock_airos_client: AsyncMock,
mock_config_entry: MockConfigEntry,
mock_setup_entry: AsyncMock,
) -> None:
"""Test successful reauthentication."""
mock_config_entry.add_to_hass(hass)
@@ -221,15 +220,11 @@ async def test_reauth_flow_scenario(
mock_airos_client.login.side_effect = AirOSConnectionAuthenticationError
await hass.config_entries.async_setup(mock_config_entry.entry_id)
with patch(
"homeassistant.components.airos.config_flow.async_get_firmware_data",
side_effect=AirOSConnectionAuthenticationError,
):
flow = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_REAUTH, "entry_id": mock_config_entry.entry_id},
data=mock_config_entry.data,
)
flow = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_REAUTH, "entry_id": mock_config_entry.entry_id},
data=mock_config_entry.data,
)
assert flow["type"] == FlowResultType.FORM
assert flow["step_id"] == REAUTH_STEP
@@ -241,22 +236,20 @@ async def test_reauth_flow_scenario(
hostname=ap_fixture.host.hostname,
)
mock_firmware = AsyncMock(return_value=valid_data)
with (
patch(
"homeassistant.components.airos.config_flow.async_get_firmware_data",
new=mock_firmware,
new=AsyncMock(return_value=valid_data),
),
patch(
"homeassistant.components.airos.async_get_firmware_data",
new=mock_firmware,
new=AsyncMock(return_value=valid_data),
),
):
result = await hass.config_entries.flow.async_configure(
flow["flow_id"],
user_input={CONF_PASSWORD: NEW_PASSWORD},
)
await hass.async_block_till_done(wait_background_tasks=True)
# Always test resolution
assert result["type"] is FlowResultType.ABORT

View File

@@ -139,7 +139,7 @@
'object_id_base': 'Total energy',
'options': dict({
'sensor': dict({
'suggested_display_precision': 0,
'suggested_display_precision': 2,
}),
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,

View File

@@ -3,7 +3,6 @@
from unittest.mock import AsyncMock
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.const import Platform
@@ -19,7 +18,6 @@ ENTITY_OUTSIDE_TEMP = "sensor.bsb_lan_outside_temperature"
ENTITY_TOTAL_ENERGY = "sensor.bsb_lan_total_energy"
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_sensor_entity_properties(
hass: HomeAssistant,
mock_bsblan: AsyncMock,

View File

@@ -196,66 +196,6 @@
"measurement_type": "storage",
"metering_status": "normal",
"status_flags": []
},
"backfeed": {
"eid": "100000040",
"timestamp": 1708006120,
"energy_delivered": 41234,
"energy_received": 42345,
"active_power": 104,
"power_factor": 0.24,
"voltage": 114,
"current": 0.5,
"frequency": 50.4,
"state": "enabled",
"measurement_type": "backfeed",
"metering_status": "normal",
"status_flags": []
},
"load": {
"eid": "100000050",
"timestamp": 1708006120,
"energy_delivered": 51234,
"energy_received": 52345,
"active_power": 105,
"power_factor": 0.25,
"voltage": 115,
"current": 0.6,
"frequency": 50.6,
"state": "enabled",
"measurement_type": "load",
"metering_status": "normal",
"status_flags": []
},
"evse": {
"eid": "100000060",
"timestamp": 1708006120,
"energy_delivered": 61234,
"energy_received": 62345,
"active_power": 106,
"power_factor": 0.26,
"voltage": 116,
"current": 0.7,
"frequency": 50.7,
"state": "enabled",
"measurement_type": "evse",
"metering_status": "normal",
"status_flags": []
},
"pv3p": {
"eid": "100000070",
"timestamp": 1708006120,
"energy_delivered": 71234,
"energy_received": 72345,
"active_power": 107,
"power_factor": 0.27,
"voltage": 117,
"current": 0.8,
"frequency": 50.8,
"state": "enabled",
"measurement_type": "pv3p",
"metering_status": "normal",
"status_flags": []
}
},
"ctmeters_phases": {
@@ -399,194 +339,6 @@
"metering_status": "normal",
"status_flags": []
}
},
"backfeed": {
"L1": {
"eid": "100000041",
"timestamp": 1708006121,
"energy_delivered": 412341,
"energy_received": 423451,
"active_power": 114,
"power_factor": 0.24,
"voltage": 114,
"current": 4.1,
"frequency": 50.4,
"state": "enabled",
"measurement_type": "backfeed",
"metering_status": "normal",
"status_flags": []
},
"L2": {
"eid": "100000042",
"timestamp": 1708006122,
"energy_delivered": 412342,
"energy_received": 423452,
"active_power": 124,
"power_factor": 0.24,
"voltage": 114,
"current": 4.2,
"frequency": 50.4,
"state": "enabled",
"measurement_type": "backfeed",
"metering_status": "normal",
"status_flags": []
},
"L3": {
"eid": "100000042",
"timestamp": 1708006123,
"energy_delivered": 412343,
"energy_received": 423453,
"active_power": 134,
"power_factor": 0.24,
"voltage": 114,
"current": 4.3,
"frequency": 50.4,
"state": "enabled",
"measurement_type": "backfeed",
"metering_status": "normal",
"status_flags": []
}
},
"load": {
"L1": {
"eid": "100000051",
"timestamp": 1708006121,
"energy_delivered": 512341,
"energy_received": 523451,
"active_power": 115,
"power_factor": 0.25,
"voltage": 115,
"current": 5.1,
"frequency": 50.6,
"state": "enabled",
"measurement_type": "load",
"metering_status": "normal",
"status_flags": []
},
"L2": {
"eid": "100000052",
"timestamp": 1708006122,
"energy_delivered": 512342,
"energy_received": 523452,
"active_power": 125,
"power_factor": 0.25,
"voltage": 115,
"current": 5.2,
"frequency": 50.6,
"state": "enabled",
"measurement_type": "load",
"metering_status": "normal",
"status_flags": []
},
"L3": {
"eid": "100000052",
"timestamp": 1708006123,
"energy_delivered": 512343,
"energy_received": 523453,
"active_power": 135,
"power_factor": 0.25,
"voltage": 115,
"current": 5.3,
"frequency": 50.6,
"state": "enabled",
"measurement_type": "load",
"metering_status": "normal",
"status_flags": []
}
},
"evse": {
"L1": {
"eid": "100000061",
"timestamp": 1708006121,
"energy_delivered": 612341,
"energy_received": 623451,
"active_power": 116,
"power_factor": 0.26,
"voltage": 116,
"current": 6.1,
"frequency": 50.6,
"state": "enabled",
"measurement_type": "evse",
"metering_status": "normal",
"status_flags": []
},
"L2": {
"eid": "100000062",
"timestamp": 1708006122,
"energy_delivered": 612342,
"energy_received": 623452,
"active_power": 126,
"power_factor": 0.26,
"voltage": 116,
"current": 6.2,
"frequency": 50.6,
"state": "enabled",
"measurement_type": "evse",
"metering_status": "normal",
"status_flags": []
},
"L3": {
"eid": "100000063",
"timestamp": 1708006123,
"energy_delivered": 612343,
"energy_received": 623453,
"active_power": 136,
"power_factor": 0.26,
"voltage": 116,
"current": 6.3,
"frequency": 50.6,
"state": "enabled",
"measurement_type": "evse",
"metering_status": "normal",
"status_flags": []
}
},
"pv3p": {
"L1": {
"eid": "100000071",
"timestamp": 1708006127,
"energy_delivered": 712341,
"energy_received": 723451,
"active_power": 117,
"power_factor": 0.27,
"voltage": 117,
"current": 7.1,
"frequency": 50.7,
"state": "enabled",
"measurement_type": "pv3p",
"metering_status": "normal",
"status_flags": []
},
"L2": {
"eid": "100000072",
"timestamp": 1708006122,
"energy_delivered": 712342,
"energy_received": 723452,
"active_power": 127,
"power_factor": 0.27,
"voltage": 117,
"current": 7.2,
"frequency": 50.7,
"state": "enabled",
"measurement_type": "pv3p",
"metering_status": "normal",
"status_flags": []
},
"L3": {
"eid": "100000073",
"timestamp": 1708006123,
"energy_delivered": 712343,
"energy_received": 723453,
"active_power": 137,
"power_factor": 0.27,
"voltage": 117,
"current": 7.3,
"frequency": 50.7,
"state": "enabled",
"measurement_type": "pv3p",
"metering_status": "normal",
"status_flags": []
}
}
},
"ctmeter_production": {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,6 @@ from unittest.mock import AsyncMock
from freezegun.api import FrozenDateTimeFactory
from pyenphase.exceptions import EnvoyError
from pyenphase.models.meters import CtType
import pytest
from syrupy.assertion import SnapshotAssertion
@@ -119,68 +118,6 @@ async def test_entry_diagnostics_with_interface_information(
async_fire_time_changed(hass)
await hass.async_block_till_done(wait_background_tasks=True)
# fix order of entities by device to avoid snapshot assertion
# failures due to changed id based order between test runs
diagnostics = await get_diagnostics_for_config_entry(
assert await get_diagnostics_for_config_entry(
hass, hass_client, config_entry
)
diagnostics["envoy_entities_by_device"] = [
{
"device": device_entities["device"],
"entities": sorted(
device_entities["entities"], key=lambda e: e["entity"]["entity_id"]
),
}
for device_entities in sorted(
diagnostics["envoy_entities_by_device"],
key=lambda e: e["device"]["identifiers"],
)
]
assert diagnostics == snapshot(exclude=limit_diagnostic_attrs)
@pytest.mark.parametrize(
("mock_envoy", "ctpresent"),
[
("envoy", ()),
("envoy_1p_metered", (CtType.PRODUCTION, CtType.NET_CONSUMPTION)),
("envoy_acb_batt", (CtType.PRODUCTION, CtType.NET_CONSUMPTION)),
("envoy_eu_batt", (CtType.PRODUCTION, CtType.NET_CONSUMPTION)),
(
"envoy_metered_batt_relay",
(
CtType.PRODUCTION,
CtType.NET_CONSUMPTION,
CtType.STORAGE,
CtType.BACKFEED,
CtType.LOAD,
CtType.EVSE,
CtType.PV3P,
),
),
("envoy_nobatt_metered_3p", (CtType.PRODUCTION, CtType.NET_CONSUMPTION)),
("envoy_tot_cons_metered", (CtType.PRODUCTION, CtType.TOTAL_CONSUMPTION)),
],
indirect=["mock_envoy"],
)
async def test_entry_diagnostics_ct_presence(
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
mock_envoy: AsyncMock,
ctpresent: tuple[CtType, ...],
) -> None:
"""Test config entry diagnostics including interface data."""
await setup_integration(hass, config_entry)
diagnostics = await get_diagnostics_for_config_entry(
hass, hass_client, config_entry
)
# are expected ct in diagnostic report
for ct in ctpresent:
assert diagnostics["envoy_model_data"]["ctmeters"][ct]
# are no more ct in diagnostic report as in ctpresent
for ct in diagnostics["envoy_model_data"]["ctmeters"]:
assert ct in ctpresent
) == snapshot(exclude=limit_diagnostic_attrs)

View File

@@ -680,186 +680,6 @@ async def test_sensor_storage_ct_phase_data(
assert entity_state.state == target
CT_NAMES_FLOAT = (
"<cttype>_ct_energy_delivered",
"<cttype>_ct_energy_received",
"<cttype>_ct_power",
"frequency_<cttype>_ct",
"voltage_<cttype>_ct",
"<cttype>_ct_current",
"power_factor_<cttype>_ct",
"meter_status_flags_active_<cttype>_ct",
)
CT_NAMES_STR = ("metering_status_<cttype>_ct",)
@pytest.mark.parametrize(
("cttype", "mock_envoy"),
[
(CtType.PRODUCTION, "envoy_metered_batt_relay"),
(CtType.TOTAL_CONSUMPTION, "envoy_tot_cons_metered"),
(CtType.BACKFEED, "envoy_metered_batt_relay"),
(CtType.LOAD, "envoy_metered_batt_relay"),
(CtType.EVSE, "envoy_metered_batt_relay"),
(CtType.PV3P, "envoy_metered_batt_relay"),
],
indirect=["mock_envoy"],
)
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_sensor_ct_data(
hass: HomeAssistant,
mock_envoy: AsyncMock,
config_entry: MockConfigEntry,
cttype: CtType,
) -> None:
"""Test ct entities values."""
with patch("homeassistant.components.enphase_envoy.PLATFORMS", [Platform.SENSOR]):
await setup_integration(hass, config_entry)
sn = mock_envoy.serial_number
ENTITY_BASE: str = f"{Platform.SENSOR}.envoy_{sn}"
data = mock_envoy.data.ctmeters[cttype]
CT_TARGETS_FLOAT = (
data.energy_delivered / 1000000.0,
data.energy_received / 1000000.0,
data.active_power / 1000.0,
data.frequency,
data.voltage,
data.current,
data.power_factor,
len(data.status_flags),
)
count_names: int = 0
for name, target in list(
zip(
[
entity.replace("<cttype>", cttype).replace("-", "_")
for entity in CT_NAMES_FLOAT
],
CT_TARGETS_FLOAT,
strict=False,
)
):
assert (entity_state := hass.states.get(f"{ENTITY_BASE}_{name}"))
assert float(entity_state.state) == target
count_names += 1
CT_TARGETS_STR = (data.metering_status,)
for name, target in list(
zip(
[
entity.replace("<cttype>", cttype).replace("-", "_")
for entity in CT_NAMES_STR
],
CT_TARGETS_STR,
strict=False,
)
):
assert (entity_state := hass.states.get(f"{ENTITY_BASE}_{name}"))
assert entity_state.state == target
count_names += 1
# verify we're testing them all
assert len(CT_NAMES_FLOAT) + len(CT_NAMES_STR) == count_names
CT_NAMES_FLOAT_PHASE = [
f"{name}_{phase.lower()}" for phase in PHASENAMES for name in (CT_NAMES_FLOAT)
]
CT_NAMES_STR_PHASE = [
f"{name}_{phase.lower()}" for phase in PHASENAMES for name in (CT_NAMES_STR)
]
@pytest.mark.parametrize(
"cttype",
[
CtType.PRODUCTION,
CtType.BACKFEED,
CtType.LOAD,
CtType.EVSE,
CtType.PV3P,
],
)
@pytest.mark.parametrize(
("mock_envoy"),
[
"envoy_metered_batt_relay",
],
indirect=["mock_envoy"],
)
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_sensor_ct_phase_data(
hass: HomeAssistant,
mock_envoy: AsyncMock,
config_entry: MockConfigEntry,
cttype: CtType,
) -> None:
"""Test ct phase entities values."""
with patch("homeassistant.components.enphase_envoy.PLATFORMS", [Platform.SENSOR]):
await setup_integration(hass, config_entry)
sn = mock_envoy.serial_number
ENTITY_BASE: str = f"{Platform.SENSOR}.envoy_{sn}"
CT_NAMES_FLOAT_PHASE_TARGET = chain(
*[
(
phase_data.energy_delivered / 1000000.0,
phase_data.energy_received / 1000000.0,
phase_data.active_power / 1000.0,
phase_data.frequency,
phase_data.voltage,
phase_data.current,
phase_data.power_factor,
len(phase_data.status_flags),
)
for phase_data in mock_envoy.data.ctmeters_phases[cttype].values()
]
)
count_names: int = 0
for name, target in list(
zip(
[
entity.replace("<cttype>", cttype).replace("-", "_")
for entity in CT_NAMES_FLOAT_PHASE
],
CT_NAMES_FLOAT_PHASE_TARGET,
strict=False,
)
):
assert (entity_state := hass.states.get(f"{ENTITY_BASE}_{name}"))
assert float(entity_state.state) == target
count_names += 1
CT_NAMES_STR_PHASE_TARGET = [
phase_data.metering_status
for phase_data in mock_envoy.data.ctmeters_phases[cttype].values()
]
for name, target in list(
zip(
[
entity.replace("<cttype>", cttype).replace("-", "_")
for entity in CT_NAMES_STR_PHASE
],
CT_NAMES_STR_PHASE_TARGET,
strict=False,
)
):
assert (entity_state := hass.states.get(f"{ENTITY_BASE}_{name}"))
assert entity_state.state == target
count_names += 1
# verify we're testing them all
assert len(CT_NAMES_FLOAT_PHASE) + len(CT_NAMES_STR_PHASE) == count_names
@pytest.mark.parametrize(
("mock_envoy"),
[

View File

@@ -1,172 +0,0 @@
"""Test ESPHome infrared platform."""
from aioesphomeapi import (
APIClient,
APIConnectionError,
InfraredCapability,
InfraredInfo,
)
from infrared_protocols import NECCommand
import pytest
from homeassistant.components import infrared
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from .conftest import MockESPHomeDeviceType
ENTITY_ID = "infrared.test_ir"
async def _mock_ir_device(
mock_esphome_device: MockESPHomeDeviceType,
mock_client: APIClient,
capabilities: InfraredCapability = InfraredCapability.TRANSMITTER,
) -> MockESPHomeDeviceType:
entity_info = [
InfraredInfo(object_id="ir", key=1, name="IR", capabilities=capabilities)
]
return await mock_esphome_device(
mock_client=mock_client, entity_info=entity_info, states=[]
)
@pytest.mark.parametrize(
("capabilities", "entity_created"),
[
(InfraredCapability.TRANSMITTER, True),
(InfraredCapability.RECEIVER, False),
(InfraredCapability.TRANSMITTER | InfraredCapability.RECEIVER, True),
(0, False),
],
)
async def test_infrared_entity_transmitter(
hass: HomeAssistant,
mock_client: APIClient,
mock_esphome_device: MockESPHomeDeviceType,
capabilities: InfraredCapability,
entity_created: bool,
) -> None:
"""Test infrared entity with transmitter capability is created."""
await _mock_ir_device(mock_esphome_device, mock_client, capabilities)
state = hass.states.get(ENTITY_ID)
assert (state is not None) == entity_created
emitters = infrared.async_get_emitters(hass)
assert (len(emitters) == 1) == entity_created
async def test_infrared_multiple_entities_mixed_capabilities(
hass: HomeAssistant,
mock_client: APIClient,
mock_esphome_device: MockESPHomeDeviceType,
) -> None:
"""Test multiple infrared entities with mixed capabilities."""
entity_info = [
InfraredInfo(
object_id="ir_transmitter",
key=1,
name="IR Transmitter",
capabilities=InfraredCapability.TRANSMITTER,
),
InfraredInfo(
object_id="ir_receiver",
key=2,
name="IR Receiver",
capabilities=InfraredCapability.RECEIVER,
),
InfraredInfo(
object_id="ir_transceiver",
key=3,
name="IR Transceiver",
capabilities=InfraredCapability.TRANSMITTER | InfraredCapability.RECEIVER,
),
]
await mock_esphome_device(
mock_client=mock_client,
entity_info=entity_info,
states=[],
)
# Only transmitter and transceiver should be created
assert hass.states.get("infrared.test_ir_transmitter") is not None
assert hass.states.get("infrared.test_ir_receiver") is None
assert hass.states.get("infrared.test_ir_transceiver") is not None
emitters = infrared.async_get_emitters(hass)
assert len(emitters) == 2
async def test_infrared_send_command_success(
hass: HomeAssistant,
mock_client: APIClient,
mock_esphome_device: MockESPHomeDeviceType,
) -> None:
"""Test sending IR command successfully."""
await _mock_ir_device(mock_esphome_device, mock_client)
command = NECCommand(address=0x04, command=0x08, modulation=38000)
await infrared.async_send_command(hass, ENTITY_ID, command)
# Verify the command was sent to the ESPHome client
mock_client.infrared_rf_transmit_raw_timings.assert_called_once()
call_args = mock_client.infrared_rf_transmit_raw_timings.call_args
assert call_args[0][0] == 1 # key
assert call_args[1]["carrier_frequency"] == 38000
# Verify timings (alternating positive/negative values)
timings = call_args[1]["timings"]
assert len(timings) > 0
for i in range(0, len(timings), 2):
assert timings[i] >= 0
for i in range(1, len(timings), 2):
assert timings[i] <= 0
async def test_infrared_send_command_failure(
hass: HomeAssistant,
mock_client: APIClient,
mock_esphome_device: MockESPHomeDeviceType,
) -> None:
"""Test sending IR command with APIConnectionError raises HomeAssistantError."""
await _mock_ir_device(mock_esphome_device, mock_client)
mock_client.infrared_rf_transmit_raw_timings.side_effect = APIConnectionError(
"Connection lost"
)
command = NECCommand(address=0x04, command=0x08, modulation=38000)
with pytest.raises(HomeAssistantError) as exc_info:
await infrared.async_send_command(hass, ENTITY_ID, command)
assert exc_info.value.translation_domain == "esphome"
assert exc_info.value.translation_key == "error_sending_ir_command"
async def test_infrared_entity_availability(
hass: HomeAssistant,
mock_client: APIClient,
mock_esphome_device: MockESPHomeDeviceType,
) -> None:
"""Test infrared entity becomes available after device reconnects."""
mock_device = await _mock_ir_device(mock_esphome_device, mock_client)
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state != STATE_UNAVAILABLE
await mock_device.mock_disconnect(False)
await hass.async_block_till_done()
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == STATE_UNAVAILABLE
await mock_device.mock_connect()
await hass.async_block_till_done()
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state != STATE_UNAVAILABLE

View File

@@ -4,7 +4,7 @@
'config_entry': dict({
'data': dict({
'api_token': '**REDACTED**',
'url': '**REDACTED**',
'url': 'https://127.0.0.1:9000/',
'verify_ssl': True,
}),
'disabled_by': None,

View File

@@ -62,12 +62,4 @@ MOCK_VEHICLES = {
"pressure": "pressure.1.json",
},
},
"megane_e_tech": {
"endpoints": {
"battery_status": "battery_status_charging.json",
"cockpit": "cockpit_ev.json",
"hvac_status": "hvac_status.1.json",
"location": "location.json",
},
},
}

View File

@@ -1,219 +0,0 @@
{
"accountId": "account-id-1",
"country": "FR",
"vehicleLinks": [
{
"brand": "RENAULT",
"vin": "VF1MEGANEETECHVIN",
"status": "ACTIVE",
"linkType": "OWNER",
"garageBrand": "renault",
"startDate": "2024-01-16",
"createdDate": "2024-01-16T13:31:27.089634Z",
"lastModifiedDate": "2024-01-17T18:15:38.607328Z",
"ownershipStartDate": "2024-01-16",
"connectedDriver": {
"role": "MAIN_DRIVER",
"createdDate": "2024-01-17T18:15:38.607044265Z",
"lastModifiedDate": "2024-01-17T18:15:38.607044265Z"
},
"vehicleDetails": {
"vin": "VF1MEGANEETECHVIN",
"registrationDate": "2024-01-16",
"firstRegistrationDate": "2024-01-16",
"engineType": "6AM",
"engineRatio": "402",
"modelSCR": "ZO1",
"passToSalesDate": "2023-04-04",
"deliveryCountry": {
"code": "FR",
"label": "FRANCE"
},
"family": {
"code": "XCB",
"label": "XCB FAMILY",
"group": "007"
},
"tcu": {
"code": "AIVCT",
"label": "WITH AIVC CONNECTION UNIT",
"group": "E70"
},
"battery": {
"code": "BTBAE",
"label": "BTBAE BATTERY",
"group": "968"
},
"radioType": {
"code": "NA448",
"label": "IVI2 FULL PREM DAB",
"group": "425"
},
"registrationCountry": {
"code": "FR"
},
"brand": {
"label": "RENAULT"
},
"model": {
"code": "XCB1VE",
"label": "MEGANE E-TECH",
"group": "971"
},
"gearbox": {
"code": "1EVGB",
"label": "REDUCER FOR ELECTRIC MOTOR",
"group": "427"
},
"version": {
"code": "ICO2M J1 L"
},
"energy": {
"code": "ELECX",
"label": "ELECTRICITY",
"group": "019"
},
"bodyType": {
"code": "BCB",
"label": "BERLINE FOR XCB",
"group": "008"
},
"steeringSide": {
"code": "LHDG",
"label": "LEFT-HAND DRIVE",
"group": "027"
},
"additionalEngineType": {
"code": "NOATY",
"label": "WITHOUT ADDITIONAL ENGINE TYPE",
"group": "948"
},
"hybridation": {
"code": "NOHYB",
"label": "NO HYBRIDISATION LEVEL",
"group": "956"
},
"registrationNumber": "REG-MEG-0",
"vcd": "PAVEH/XCB/BCB/EA4/J1/ELECX/LHDG/TEMP/2WDRV/BEMBK/ACC02/00ABS/ACD03/STDRF/HTRWI/WFURP/CLK00/RVX07/1RVLG/FFGL2/SDLGT/RAL20/FSBAJ/SPADP/FAB02/NOCNV/LRSCO/LRS02/HAR04/RHR03/FSE06/RSE00/BIXPA/NTIBC/KMETR/TPRM2/SDSGL/NOSTK/SABG5/LEDCO/ESCHS/PALAW/SPBDA/M3CA3/PRROP/DB4C0/NOAGR/LRSW0/OSEWA/RVICM/TRSV0/NBRVX/FWL1T/RWL1T/NOOSW/REPKT/HTS02/00NLD/BRA03/AJSW2/HSTPL/SBR05/RMSB3/NA448/1EVGB/ASOC2/EVAU2/RIM09/TYSUM/ISOFI/EPER0/HR11M/SLCCA/NOATD/CPTC0/CHGS4/TL01A/BDPRO/NOADT/AIRBDE/PRUPTA/ELC1/NOETC/NOLSV/NOFEX/M2021/PHAS1/NOLTD/NOATY/NOHYB/60K0B/BTBAE/VEC151/XCB1VE/NB003/6AM/SFANT/ADR00/LKA05/PSFT0/BIHT0/NODUP/NOWAP/NOCCH/AMLT0/DRL02/RCALL/NOART/TBI00/MET05/BSD02/ECMD0/NRCAR/NOM2C/AIVCT/GSI00/TPNNP/TSGNE/2BCOL/ITP14/MDMOD/PXA00/NOPXB/PIG02/HTSW0/DAALT/WICH0/EV1GA1/SMOSP/NOWMC/FCOWA/C1AHS/NOPRA/VSPTA/1234Y/NOLIE/NOLII/NOWFI/AEB09/WOSRE/PRAHL/SPMIR/AVCAM/RAEB2/DTRNI",
"manufacturingDate": "2023-04-04",
"assets": [
{
"assetType": "PICTURE",
"viewpoint": "mybrand_2",
"renditions": [
{
"resolutionType": "ONE_MYRENAULT_SMALL",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=RSITE&bookmark=EXT_34_DESSUS&profile=HELIOS_OWNERSERVICES_SMALL_V2"
},
{
"resolutionType": "ONE_MYRENAULT_LARGE",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=RSITE&bookmark=EXT_34_DESSUS&profile=HELIOS_OWNERSERVICES_LARGE"
}
],
"viewPointInLowerCase": "mybrand_2"
},
{
"assetType": "PICTURE",
"viewpoint": "mybrand_5",
"renditions": [
{
"resolutionType": "ONE_MYRENAULT_SMALL",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=RSITE&bookmark=EXT_34_AV&profile=HELIOS_OWNERSERVICES_SMALL_V2"
},
{
"resolutionType": "ONE_MYRENAULT_LARGE",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=RSITE&bookmark=EXT_34_AV&profile=HELIOS_OWNERSERVICES_LARGE"
}
],
"viewPointInLowerCase": "mybrand_5"
},
{
"assetType": "PICTURE",
"viewpoint": "myb_car_selector",
"renditions": [
{
"resolutionType": "ONE_MYRENAULT_SMALL",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=RSITE&bookmark=EXT_34_AV&profile=HELIOS_OWNERSERVICES_SMALL_V2"
},
{
"resolutionType": "ONE_MYRENAULT_LARGE",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=RSITE&bookmark=EXT_34_AV&profile=HELIOS_OWNERSERVICES_LARGE"
}
],
"viewPointInLowerCase": "myb_car_selector"
},
{
"assetType": "PICTURE",
"viewpoint": "myb_car_page_dashboard",
"renditions": [
{
"resolutionType": "ONE_MYRENAULT_SMALL",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=CARPICKER&bookmark=EXT_LEFT_SIDE&profile=HELIOS_OWNERSERVICES_SMALL_V2"
},
{
"resolutionType": "ONE_MYRENAULT_LARGE",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=CARPICKER&bookmark=EXT_LEFT_SIDE&profile=HELIOS_OWNERSERVICES_LARGE"
}
],
"viewPointInLowerCase": "myb_car_page_dashboard"
},
{
"assetType": "PICTURE",
"viewpoint": "myb_program_settings_page",
"renditions": [
{
"resolutionType": "ONE_MYRENAULT_SMALL",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=CARPICKER&bookmark=EXT_LEFT_SIDE&profile=HELIOS_OWNERSERVICES_SMALL_V2"
},
{
"resolutionType": "ONE_MYRENAULT_LARGE",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=CARPICKER&bookmark=EXT_LEFT_SIDE&profile=HELIOS_OWNERSERVICES_LARGE"
}
],
"viewPointInLowerCase": "myb_program_settings_page"
},
{
"assetType": "PICTURE",
"viewpoint": "myb_plug_and_charge_activation",
"renditions": [
{
"resolutionType": "ONE_MYRENAULT_SMALL",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=CARPICKER&bookmark=EXT_RIGHT_SIDE&profile=HELIOS_OWNERSERVICES_SMALL_V2"
},
{
"resolutionType": "ONE_MYRENAULT_LARGE",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=CARPICKER&bookmark=EXT_RIGHT_SIDE&profile=HELIOS_OWNERSERVICES_LARGE"
}
],
"viewPointInLowerCase": "myb_plug_and_charge_activation"
},
{
"assetType": "PICTURE",
"viewpoint": "myb_plug_and_charge_my_car",
"renditions": [
{
"resolutionType": "ONE_MYRENAULT_SMALL",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=CARPICKER&bookmark=EXT_LEFT_SIDE&profile=HELIOS_OWNERSERVICES_SMALL_V2"
},
{
"resolutionType": "ONE_MYRENAULT_LARGE",
"url": "https://3dv.renault.com/ImageFromBookmark?configuration=BCB%2FEA4%2FLHDG%2FACD03%2FSTDRF%2FWFURP%2FRVX07%2FRAL20%2FLRS02%2FFSE06%2FBIXPA%2FLEDCO%2FPALAW%2FSPBDA%2FLRSW0%2FRVICM%2FTRSV0%2FAJSW2%2FNA448%2FASOC2%2FRIM09%2FSLCCA%2FNOATD%2FCPTC0%2FBDPRO%2FAIRBDE%2FPRUPTA%2FNOETC%2FM2021%2FNB003%2FSFANT%2FPSFT0%2FNODUP%2FNOWAP%2FRCALL%2FBSD02%2F2BCOL%2FITP14%2FMDMOD%2FPXA00%2FNOPXB%2FPIG02%2FNOLII%2FAVCAM%2FDTRNI&databaseId=a7cc2a21-d3fe-43bf-8643-14d3b8f9b2fa&bookmarkSet=CARPICKER&bookmark=EXT_LEFT_SIDE&profile=HELIOS_OWNERSERVICES_LARGE"
}
],
"viewPointInLowerCase": "myb_plug_and_charge_my_car"
}
],
"yearsOfMaintenance": 12,
"connectivityTechnology": "OPENRLINK",
"easyConnectStore": true,
"electrical": true,
"deliveryDate": "2024-01-16",
"retrievedFromDhs": false,
"engineEnergyType": "ELEC",
"radioCode": "",
"premiumSubscribed": false,
"batteryType": "NMC"
}
}
]
}

View File

@@ -495,155 +495,6 @@
'state': 'on',
})
# ---
# name: test_binary_sensors[megane_e_tech][binary_sensor.reg_meg_0_charging-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.reg_meg_0_charging',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Charging',
'options': dict({
}),
'original_device_class': <BinarySensorDeviceClass.BATTERY_CHARGING: 'battery_charging'>,
'original_icon': None,
'original_name': 'Charging',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'vf1meganeetechvin_charging',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensors[megane_e_tech][binary_sensor.reg_meg_0_charging-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'battery_charging',
'friendly_name': 'REG-MEG-0 Charging',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.reg_meg_0_charging',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_binary_sensors[megane_e_tech][binary_sensor.reg_meg_0_hvac-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.reg_meg_0_hvac',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'HVAC',
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'HVAC',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'hvac_status',
'unique_id': 'vf1meganeetechvin_hvac_status',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensors[megane_e_tech][binary_sensor.reg_meg_0_hvac-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'REG-MEG-0 HVAC',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.reg_meg_0_hvac',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_binary_sensors[megane_e_tech][binary_sensor.reg_meg_0_plug-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.reg_meg_0_plug',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Plug',
'options': dict({
}),
'original_device_class': <BinarySensorDeviceClass.PLUG: 'plug'>,
'original_icon': None,
'original_name': 'Plug',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'vf1meganeetechvin_plugged_in',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensors[megane_e_tech][binary_sensor.reg_meg_0_plug-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'plug',
'friendly_name': 'REG-MEG-0 Plug',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.reg_meg_0_plug',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_binary_sensors[twingo_3_electric][binary_sensor.reg_twingo_iii_charging-entry]
EntityRegistryEntrySnapshot({
'aliases': set({

View File

@@ -1371,202 +1371,6 @@
'state': 'unknown',
})
# ---
# name: test_buttons[megane_e_tech][button.reg_meg_0_flash_lights-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.reg_meg_0_flash_lights',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Flash lights',
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Flash lights',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'flash_lights',
'unique_id': 'vf1meganeetechvin_flash_lights',
'unit_of_measurement': None,
})
# ---
# name: test_buttons[megane_e_tech][button.reg_meg_0_flash_lights-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'REG-MEG-0 Flash lights',
}),
'context': <ANY>,
'entity_id': 'button.reg_meg_0_flash_lights',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_buttons[megane_e_tech][button.reg_meg_0_sound_horn-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.reg_meg_0_sound_horn',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Sound horn',
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Sound horn',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'sound_horn',
'unique_id': 'vf1meganeetechvin_sound_horn',
'unit_of_measurement': None,
})
# ---
# name: test_buttons[megane_e_tech][button.reg_meg_0_sound_horn-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'REG-MEG-0 Sound horn',
}),
'context': <ANY>,
'entity_id': 'button.reg_meg_0_sound_horn',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_buttons[megane_e_tech][button.reg_meg_0_start_air_conditioner-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.reg_meg_0_start_air_conditioner',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Start air conditioner',
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Start air conditioner',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'start_air_conditioner',
'unique_id': 'vf1meganeetechvin_start_air_conditioner',
'unit_of_measurement': None,
})
# ---
# name: test_buttons[megane_e_tech][button.reg_meg_0_start_air_conditioner-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'REG-MEG-0 Start air conditioner',
}),
'context': <ANY>,
'entity_id': 'button.reg_meg_0_start_air_conditioner',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_buttons[megane_e_tech][button.reg_meg_0_start_charge-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.reg_meg_0_start_charge',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Start charge',
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Start charge',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'start_charge',
'unique_id': 'vf1meganeetechvin_start_charge',
'unit_of_measurement': None,
})
# ---
# name: test_buttons[megane_e_tech][button.reg_meg_0_start_charge-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'REG-MEG-0 Start charge',
}),
'context': <ANY>,
'entity_id': 'button.reg_meg_0_start_charge',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_buttons[twingo_3_electric][button.reg_twingo_iii_flash_lights-entry]
EntityRegistryEntrySnapshot({
'aliases': set({

View File

@@ -204,59 +204,6 @@
'state': 'not_home',
})
# ---
# name: test_device_trackers[megane_e_tech][device_tracker.reg_meg_0_location-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'device_tracker',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'device_tracker.reg_meg_0_location',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Location',
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Location',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'location',
'unique_id': 'vf1meganeetechvin_location',
'unit_of_measurement': None,
})
# ---
# name: test_device_trackers[megane_e_tech][device_tracker.reg_meg_0_location-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'REG-MEG-0 Location',
'gps_accuracy': 0,
'latitude': 48.1234567,
'longitude': 11.1234567,
'source_type': <SourceType.GPS: 'gps'>,
}),
'context': <ANY>,
'entity_id': 'device_tracker.reg_meg_0_location',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'not_home',
})
# ---
# name: test_device_trackers[twingo_3_electric][device_tracker.reg_twingo_iii_location-entry]
EntityRegistryEntrySnapshot({
'aliases': set({

View File

@@ -65,39 +65,6 @@
}),
])
# ---
# name: test_device_registry[megane_e_tech]
list([
DeviceRegistryEntrySnapshot({
'area_id': None,
'config_entries': <ANY>,
'config_entries_subentries': <ANY>,
'configuration_url': None,
'connections': set({
}),
'disabled_by': None,
'entry_type': None,
'hw_version': None,
'id': <ANY>,
'identifiers': set({
tuple(
'renault',
'VF1MEGANEETECHVIN',
),
}),
'labels': set({
}),
'manufacturer': 'Renault',
'model': 'Megane e-tech',
'model_id': 'XCB1VE',
'name': 'REG-MEG-0',
'name_by_user': None,
'primary_config_entry': <ANY>,
'serial_number': None,
'sw_version': None,
'via_device_id': None,
}),
])
# ---
# name: test_device_registry[twingo_3_electric]
list([
DeviceRegistryEntrySnapshot({

View File

@@ -2758,795 +2758,6 @@
'state': 'plugged',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_admissible_charging_power-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_admissible_charging_power',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Admissible charging power',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
}),
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
'original_icon': None,
'original_name': 'Admissible charging power',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'admissible_charging_power',
'unique_id': 'vf1meganeetechvin_charging_power',
'unit_of_measurement': <UnitOfPower.KILO_WATT: 'kW'>,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_admissible_charging_power-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'power',
'friendly_name': 'REG-MEG-0 Admissible charging power',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfPower.KILO_WATT: 'kW'>,
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_admissible_charging_power',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '27.0',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_battery-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_battery',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Battery',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
'original_icon': None,
'original_name': 'Battery',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'vf1meganeetechvin_battery_level',
'unit_of_measurement': '%',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_battery-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'battery',
'friendly_name': 'REG-MEG-0 Battery',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_battery',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '60',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_battery_autonomy-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_battery_autonomy',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Battery autonomy',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
}),
'original_device_class': <SensorDeviceClass.DISTANCE: 'distance'>,
'original_icon': None,
'original_name': 'Battery autonomy',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'battery_autonomy',
'unique_id': 'vf1meganeetechvin_battery_autonomy',
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_battery_autonomy-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'distance',
'friendly_name': 'REG-MEG-0 Battery autonomy',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_battery_autonomy',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '141',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_battery_available_energy-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL: 'total'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_battery_available_energy',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Battery available energy',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
}),
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
'original_icon': None,
'original_name': 'Battery available energy',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'battery_available_energy',
'unique_id': 'vf1meganeetechvin_battery_available_energy',
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_battery_available_energy-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'energy',
'friendly_name': 'REG-MEG-0 Battery available energy',
'state_class': <SensorStateClass.TOTAL: 'total'>,
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_battery_available_energy',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '31',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_battery_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_battery_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Battery temperature',
'options': dict({
'sensor': dict({
'suggested_display_precision': 1,
}),
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Battery temperature',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'battery_temperature',
'unique_id': 'vf1meganeetechvin_battery_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_battery_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'REG-MEG-0 Battery temperature',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_battery_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '20',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_charge_state-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'not_in_charge',
'waiting_for_a_planned_charge',
'charge_ended',
'waiting_for_current_charge',
'energy_flap_opened',
'charge_in_progress',
'charge_error',
'unavailable',
]),
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_charge_state',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Charge state',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Charge state',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'charge_state',
'unique_id': 'vf1meganeetechvin_charge_state',
'unit_of_measurement': None,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_charge_state-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'REG-MEG-0 Charge state',
'options': list([
'not_in_charge',
'waiting_for_a_planned_charge',
'charge_ended',
'waiting_for_current_charge',
'energy_flap_opened',
'charge_in_progress',
'charge_error',
'unavailable',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_charge_state',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'charge_in_progress',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_charging_remaining_time-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_charging_remaining_time',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Charging remaining time',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_icon': None,
'original_name': 'Charging remaining time',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'charging_remaining_time',
'unique_id': 'vf1meganeetechvin_charging_remaining_time',
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_charging_remaining_time-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'friendly_name': 'REG-MEG-0 Charging remaining time',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_charging_remaining_time',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '145',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_hvac_soc_threshold-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_hvac_soc_threshold',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'HVAC SoC threshold',
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'HVAC SoC threshold',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'hvac_soc_threshold',
'unique_id': 'vf1meganeetechvin_hvac_soc_threshold',
'unit_of_measurement': '%',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_hvac_soc_threshold-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'REG-MEG-0 HVAC SoC threshold',
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_hvac_soc_threshold',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_last_battery_activity-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_last_battery_activity',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Last battery activity',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Last battery activity',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'battery_last_activity',
'unique_id': 'vf1meganeetechvin_battery_last_activity',
'unit_of_measurement': None,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_last_battery_activity-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'friendly_name': 'REG-MEG-0 Last battery activity',
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_last_battery_activity',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2020-01-12T21:40:16+00:00',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_last_hvac_activity-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_last_hvac_activity',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Last HVAC activity',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Last HVAC activity',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'hvac_last_activity',
'unique_id': 'vf1meganeetechvin_hvac_last_activity',
'unit_of_measurement': None,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_last_hvac_activity-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'friendly_name': 'REG-MEG-0 Last HVAC activity',
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_last_hvac_activity',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_last_location_activity-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_last_location_activity',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Last location activity',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Last location activity',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'location_last_activity',
'unique_id': 'vf1meganeetechvin_location_last_activity',
'unit_of_measurement': None,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_last_location_activity-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'friendly_name': 'REG-MEG-0 Last location activity',
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_last_location_activity',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2020-02-18T16:58:38+00:00',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_mileage-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_mileage',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Mileage',
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
}),
'original_device_class': <SensorDeviceClass.DISTANCE: 'distance'>,
'original_icon': None,
'original_name': 'Mileage',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'mileage',
'unique_id': 'vf1meganeetechvin_mileage',
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_mileage-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'distance',
'friendly_name': 'REG-MEG-0 Mileage',
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_mileage',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '49114',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_outside_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_outside_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Outside temperature',
'options': dict({
'sensor': dict({
'suggested_display_precision': 1,
}),
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Outside temperature',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'outside_temperature',
'unique_id': 'vf1meganeetechvin_outside_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_outside_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'REG-MEG-0 Outside temperature',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_outside_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '8.0',
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_plug_state-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'unplugged',
'plugged',
'plugged_waiting_for_charge',
'plug_error',
'plug_unknown',
]),
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.reg_meg_0_plug_state',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Plug state',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Plug state',
'platform': 'renault',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'plug_state',
'unique_id': 'vf1meganeetechvin_plug_state',
'unit_of_measurement': None,
})
# ---
# name: test_sensors[megane_e_tech][sensor.reg_meg_0_plug_state-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'REG-MEG-0 Plug state',
'options': list([
'unplugged',
'plugged',
'plugged_waiting_for_charge',
'plug_error',
'plug_unknown',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.reg_meg_0_plug_state',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'plugged',
})
# ---
# name: test_sensors[twingo_3_electric][sensor.reg_twingo_iii_admissible_charging_power-entry]
EntityRegistryEntrySnapshot({
'aliases': set({

View File

@@ -10780,7 +10780,6 @@
'after',
'cleaning',
'pause',
'washing_mop',
]),
}),
'config_entry_id': <ANY>,
@@ -10829,7 +10828,6 @@
'after',
'cleaning',
'pause',
'washing_mop',
]),
}),
'context': <ANY>,
@@ -11154,7 +11152,6 @@
'after',
'cleaning',
'pause',
'washing_mop',
]),
}),
'config_entry_id': <ANY>,
@@ -11203,7 +11200,6 @@
'after',
'cleaning',
'pause',
'washing_mop',
]),
}),
'context': <ANY>,