mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 01:37:08 +00:00
Migrate APCUPSD to has entity name (#112997)
* Properly set entity names for APCUPSD * Add test cases to prevent future regressions * Fix tests due to the updated entity IDs * Prettify code * Remove redundant translation key
This commit is contained in:
parent
b125a6b1bb
commit
db31afe019
@ -20,7 +20,6 @@ from .coordinator import APCUPSdCoordinator
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
_DESCRIPTION = BinarySensorEntityDescription(
|
_DESCRIPTION = BinarySensorEntityDescription(
|
||||||
key="statflag",
|
key="statflag",
|
||||||
name="UPS Online Status",
|
|
||||||
translation_key="online_status",
|
translation_key="online_status",
|
||||||
)
|
)
|
||||||
# The bit in STATFLAG that indicates the online status of the APC UPS.
|
# The bit in STATFLAG that indicates the online status of the APC UPS.
|
||||||
@ -46,6 +45,8 @@ async def async_setup_entry(
|
|||||||
class OnlineStatus(CoordinatorEntity[APCUPSdCoordinator], BinarySensorEntity):
|
class OnlineStatus(CoordinatorEntity[APCUPSdCoordinator], BinarySensorEntity):
|
||||||
"""Representation of a UPS online status."""
|
"""Representation of a UPS online status."""
|
||||||
|
|
||||||
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
coordinator: APCUPSdCoordinator,
|
coordinator: APCUPSdCoordinator,
|
||||||
|
@ -34,11 +34,10 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
"alarmdel": SensorEntityDescription(
|
"alarmdel": SensorEntityDescription(
|
||||||
key="alarmdel",
|
key="alarmdel",
|
||||||
translation_key="alarm_delay",
|
translation_key="alarm_delay",
|
||||||
name="UPS Alarm Delay",
|
|
||||||
),
|
),
|
||||||
"ambtemp": SensorEntityDescription(
|
"ambtemp": SensorEntityDescription(
|
||||||
key="ambtemp",
|
key="ambtemp",
|
||||||
name="UPS Ambient Temperature",
|
translation_key="ambient_temperature",
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
@ -46,40 +45,34 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
"apc": SensorEntityDescription(
|
"apc": SensorEntityDescription(
|
||||||
key="apc",
|
key="apc",
|
||||||
translation_key="apc_status",
|
translation_key="apc_status",
|
||||||
name="UPS Status Data",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"apcmodel": SensorEntityDescription(
|
"apcmodel": SensorEntityDescription(
|
||||||
key="apcmodel",
|
key="apcmodel",
|
||||||
translation_key="apc_model",
|
translation_key="apc_model",
|
||||||
name="UPS Model",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"badbatts": SensorEntityDescription(
|
"badbatts": SensorEntityDescription(
|
||||||
key="badbatts",
|
key="badbatts",
|
||||||
translation_key="bad_batteries",
|
translation_key="bad_batteries",
|
||||||
name="UPS Bad Batteries",
|
|
||||||
),
|
),
|
||||||
"battdate": SensorEntityDescription(
|
"battdate": SensorEntityDescription(
|
||||||
key="battdate",
|
key="battdate",
|
||||||
translation_key="battery_replacement_date",
|
translation_key="battery_replacement_date",
|
||||||
name="UPS Battery Replaced",
|
|
||||||
),
|
),
|
||||||
"battstat": SensorEntityDescription(
|
"battstat": SensorEntityDescription(
|
||||||
key="battstat",
|
key="battstat",
|
||||||
translation_key="battery_status",
|
translation_key="battery_status",
|
||||||
name="UPS Battery Status",
|
|
||||||
),
|
),
|
||||||
"battv": SensorEntityDescription(
|
"battv": SensorEntityDescription(
|
||||||
key="battv",
|
key="battv",
|
||||||
name="UPS Battery Voltage",
|
translation_key="battery_voltage",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"bcharge": SensorEntityDescription(
|
"bcharge": SensorEntityDescription(
|
||||||
key="bcharge",
|
key="bcharge",
|
||||||
name="UPS Battery",
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
device_class=SensorDeviceClass.BATTERY,
|
device_class=SensorDeviceClass.BATTERY,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
@ -87,86 +80,74 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
"cable": SensorEntityDescription(
|
"cable": SensorEntityDescription(
|
||||||
key="cable",
|
key="cable",
|
||||||
translation_key="cable_type",
|
translation_key="cable_type",
|
||||||
name="UPS Cable Type",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"cumonbatt": SensorEntityDescription(
|
"cumonbatt": SensorEntityDescription(
|
||||||
key="cumonbatt",
|
key="cumonbatt",
|
||||||
translation_key="total_time_on_battery",
|
translation_key="total_time_on_battery",
|
||||||
name="UPS Total Time on Battery",
|
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
"date": SensorEntityDescription(
|
"date": SensorEntityDescription(
|
||||||
key="date",
|
key="date",
|
||||||
translation_key="date",
|
translation_key="date",
|
||||||
name="UPS Status Date",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"dipsw": SensorEntityDescription(
|
"dipsw": SensorEntityDescription(
|
||||||
key="dipsw",
|
key="dipsw",
|
||||||
translation_key="dip_switch_settings",
|
translation_key="dip_switch_settings",
|
||||||
name="UPS Dip Switch Settings",
|
|
||||||
),
|
),
|
||||||
"dlowbatt": SensorEntityDescription(
|
"dlowbatt": SensorEntityDescription(
|
||||||
key="dlowbatt",
|
key="dlowbatt",
|
||||||
translation_key="low_battery_signal",
|
translation_key="low_battery_signal",
|
||||||
name="UPS Low Battery Signal",
|
|
||||||
),
|
),
|
||||||
"driver": SensorEntityDescription(
|
"driver": SensorEntityDescription(
|
||||||
key="driver",
|
key="driver",
|
||||||
translation_key="driver",
|
translation_key="driver",
|
||||||
name="UPS Driver",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"dshutd": SensorEntityDescription(
|
"dshutd": SensorEntityDescription(
|
||||||
key="dshutd",
|
key="dshutd",
|
||||||
translation_key="shutdown_delay",
|
translation_key="shutdown_delay",
|
||||||
name="UPS Shutdown Delay",
|
|
||||||
),
|
),
|
||||||
"dwake": SensorEntityDescription(
|
"dwake": SensorEntityDescription(
|
||||||
key="dwake",
|
key="dwake",
|
||||||
translation_key="wake_delay",
|
translation_key="wake_delay",
|
||||||
name="UPS Wake Delay",
|
|
||||||
),
|
),
|
||||||
"end apc": SensorEntityDescription(
|
"end apc": SensorEntityDescription(
|
||||||
key="end apc",
|
key="end apc",
|
||||||
translation_key="date_and_time",
|
translation_key="date_and_time",
|
||||||
name="UPS Date and Time",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"extbatts": SensorEntityDescription(
|
"extbatts": SensorEntityDescription(
|
||||||
key="extbatts",
|
key="extbatts",
|
||||||
translation_key="external_batteries",
|
translation_key="external_batteries",
|
||||||
name="UPS External Batteries",
|
|
||||||
),
|
),
|
||||||
"firmware": SensorEntityDescription(
|
"firmware": SensorEntityDescription(
|
||||||
key="firmware",
|
key="firmware",
|
||||||
translation_key="firmware_version",
|
translation_key="firmware_version",
|
||||||
name="UPS Firmware Version",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"hitrans": SensorEntityDescription(
|
"hitrans": SensorEntityDescription(
|
||||||
key="hitrans",
|
key="hitrans",
|
||||||
name="UPS Transfer High",
|
translation_key="transfer_high",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
),
|
),
|
||||||
"hostname": SensorEntityDescription(
|
"hostname": SensorEntityDescription(
|
||||||
key="hostname",
|
key="hostname",
|
||||||
translation_key="hostname",
|
translation_key="hostname",
|
||||||
name="UPS Hostname",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"humidity": SensorEntityDescription(
|
"humidity": SensorEntityDescription(
|
||||||
key="humidity",
|
key="humidity",
|
||||||
name="UPS Ambient Humidity",
|
translation_key="humidity",
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
device_class=SensorDeviceClass.HUMIDITY,
|
device_class=SensorDeviceClass.HUMIDITY,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"itemp": SensorEntityDescription(
|
"itemp": SensorEntityDescription(
|
||||||
key="itemp",
|
key="itemp",
|
||||||
name="UPS Internal Temperature",
|
translation_key="internal_temperature",
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
@ -174,29 +155,26 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
"laststest": SensorEntityDescription(
|
"laststest": SensorEntityDescription(
|
||||||
key="laststest",
|
key="laststest",
|
||||||
translation_key="last_self_test",
|
translation_key="last_self_test",
|
||||||
name="UPS Last Self Test",
|
|
||||||
),
|
),
|
||||||
"lastxfer": SensorEntityDescription(
|
"lastxfer": SensorEntityDescription(
|
||||||
key="lastxfer",
|
key="lastxfer",
|
||||||
translation_key="last_transfer",
|
translation_key="last_transfer",
|
||||||
name="UPS Last Transfer",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"linefail": SensorEntityDescription(
|
"linefail": SensorEntityDescription(
|
||||||
key="linefail",
|
key="linefail",
|
||||||
translation_key="line_failure",
|
translation_key="line_failure",
|
||||||
name="UPS Input Voltage Status",
|
|
||||||
),
|
),
|
||||||
"linefreq": SensorEntityDescription(
|
"linefreq": SensorEntityDescription(
|
||||||
key="linefreq",
|
key="linefreq",
|
||||||
name="UPS Line Frequency",
|
translation_key="line_frequency",
|
||||||
native_unit_of_measurement=UnitOfFrequency.HERTZ,
|
native_unit_of_measurement=UnitOfFrequency.HERTZ,
|
||||||
device_class=SensorDeviceClass.FREQUENCY,
|
device_class=SensorDeviceClass.FREQUENCY,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"linev": SensorEntityDescription(
|
"linev": SensorEntityDescription(
|
||||||
key="linev",
|
key="linev",
|
||||||
name="UPS Input Voltage",
|
translation_key="line_voltage",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
@ -204,113 +182,104 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
"loadpct": SensorEntityDescription(
|
"loadpct": SensorEntityDescription(
|
||||||
key="loadpct",
|
key="loadpct",
|
||||||
translation_key="load_capacity",
|
translation_key="load_capacity",
|
||||||
name="UPS Load",
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"loadapnt": SensorEntityDescription(
|
"loadapnt": SensorEntityDescription(
|
||||||
key="loadapnt",
|
key="loadapnt",
|
||||||
translation_key="apparent_power",
|
translation_key="apparent_power",
|
||||||
name="UPS Load Apparent Power",
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
),
|
),
|
||||||
"lotrans": SensorEntityDescription(
|
"lotrans": SensorEntityDescription(
|
||||||
key="lotrans",
|
key="lotrans",
|
||||||
name="UPS Transfer Low",
|
translation_key="transfer_low",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
),
|
),
|
||||||
"mandate": SensorEntityDescription(
|
"mandate": SensorEntityDescription(
|
||||||
key="mandate",
|
key="mandate",
|
||||||
translation_key="manufacture_date",
|
translation_key="manufacture_date",
|
||||||
name="UPS Manufacture Date",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"masterupd": SensorEntityDescription(
|
"masterupd": SensorEntityDescription(
|
||||||
key="masterupd",
|
key="masterupd",
|
||||||
translation_key="master_update",
|
translation_key="master_update",
|
||||||
name="UPS Master Update",
|
|
||||||
),
|
),
|
||||||
"maxlinev": SensorEntityDescription(
|
"maxlinev": SensorEntityDescription(
|
||||||
key="maxlinev",
|
key="maxlinev",
|
||||||
name="UPS Input Voltage High",
|
translation_key="input_voltage_high",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
),
|
),
|
||||||
"maxtime": SensorEntityDescription(
|
"maxtime": SensorEntityDescription(
|
||||||
key="maxtime",
|
key="maxtime",
|
||||||
translation_key="max_time",
|
translation_key="max_time",
|
||||||
name="UPS Battery Timeout",
|
|
||||||
),
|
),
|
||||||
"mbattchg": SensorEntityDescription(
|
"mbattchg": SensorEntityDescription(
|
||||||
key="mbattchg",
|
key="mbattchg",
|
||||||
translation_key="max_battery_charge",
|
translation_key="max_battery_charge",
|
||||||
name="UPS Battery Shutdown",
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
),
|
),
|
||||||
"minlinev": SensorEntityDescription(
|
"minlinev": SensorEntityDescription(
|
||||||
key="minlinev",
|
key="minlinev",
|
||||||
name="UPS Input Voltage Low",
|
translation_key="input_voltage_low",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
),
|
),
|
||||||
"mintimel": SensorEntityDescription(
|
"mintimel": SensorEntityDescription(
|
||||||
key="mintimel",
|
key="mintimel",
|
||||||
translation_key="min_time",
|
translation_key="min_time",
|
||||||
name="UPS Shutdown Time",
|
|
||||||
),
|
),
|
||||||
"model": SensorEntityDescription(
|
"model": SensorEntityDescription(
|
||||||
key="model",
|
key="model",
|
||||||
translation_key="model",
|
translation_key="model",
|
||||||
name="UPS Model",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"nombattv": SensorEntityDescription(
|
"nombattv": SensorEntityDescription(
|
||||||
key="nombattv",
|
key="nombattv",
|
||||||
name="UPS Battery Nominal Voltage",
|
translation_key="battery_nominal_voltage",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
),
|
),
|
||||||
"nominv": SensorEntityDescription(
|
"nominv": SensorEntityDescription(
|
||||||
key="nominv",
|
key="nominv",
|
||||||
name="UPS Nominal Input Voltage",
|
translation_key="nominal_input_voltage",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
),
|
),
|
||||||
"nomoutv": SensorEntityDescription(
|
"nomoutv": SensorEntityDescription(
|
||||||
key="nomoutv",
|
key="nomoutv",
|
||||||
name="UPS Nominal Output Voltage",
|
translation_key="nominal_output_voltage",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
),
|
),
|
||||||
"nompower": SensorEntityDescription(
|
"nompower": SensorEntityDescription(
|
||||||
key="nompower",
|
key="nompower",
|
||||||
name="UPS Nominal Output Power",
|
translation_key="nominal_output_power",
|
||||||
native_unit_of_measurement=UnitOfPower.WATT,
|
native_unit_of_measurement=UnitOfPower.WATT,
|
||||||
device_class=SensorDeviceClass.POWER,
|
device_class=SensorDeviceClass.POWER,
|
||||||
),
|
),
|
||||||
"nomapnt": SensorEntityDescription(
|
"nomapnt": SensorEntityDescription(
|
||||||
key="nomapnt",
|
key="nomapnt",
|
||||||
name="UPS Nominal Apparent Power",
|
translation_key="nominal_apparent_power",
|
||||||
native_unit_of_measurement=UnitOfApparentPower.VOLT_AMPERE,
|
native_unit_of_measurement=UnitOfApparentPower.VOLT_AMPERE,
|
||||||
device_class=SensorDeviceClass.APPARENT_POWER,
|
device_class=SensorDeviceClass.APPARENT_POWER,
|
||||||
),
|
),
|
||||||
"numxfers": SensorEntityDescription(
|
"numxfers": SensorEntityDescription(
|
||||||
key="numxfers",
|
key="numxfers",
|
||||||
translation_key="transfer_count",
|
translation_key="transfer_count",
|
||||||
name="UPS Transfer Count",
|
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
"outcurnt": SensorEntityDescription(
|
"outcurnt": SensorEntityDescription(
|
||||||
key="outcurnt",
|
key="outcurnt",
|
||||||
name="UPS Output Current",
|
translation_key="output_current",
|
||||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||||
device_class=SensorDeviceClass.CURRENT,
|
device_class=SensorDeviceClass.CURRENT,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"outputv": SensorEntityDescription(
|
"outputv": SensorEntityDescription(
|
||||||
key="outputv",
|
key="outputv",
|
||||||
name="UPS Output Voltage",
|
translation_key="output_voltage",
|
||||||
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
device_class=SensorDeviceClass.VOLTAGE,
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
@ -318,108 +287,89 @@ SENSORS: dict[str, SensorEntityDescription] = {
|
|||||||
"reg1": SensorEntityDescription(
|
"reg1": SensorEntityDescription(
|
||||||
key="reg1",
|
key="reg1",
|
||||||
translation_key="register_1_fault",
|
translation_key="register_1_fault",
|
||||||
name="UPS Register 1 Fault",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"reg2": SensorEntityDescription(
|
"reg2": SensorEntityDescription(
|
||||||
key="reg2",
|
key="reg2",
|
||||||
translation_key="register_2_fault",
|
translation_key="register_2_fault",
|
||||||
name="UPS Register 2 Fault",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"reg3": SensorEntityDescription(
|
"reg3": SensorEntityDescription(
|
||||||
key="reg3",
|
key="reg3",
|
||||||
translation_key="register_3_fault",
|
translation_key="register_3_fault",
|
||||||
name="UPS Register 3 Fault",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"retpct": SensorEntityDescription(
|
"retpct": SensorEntityDescription(
|
||||||
key="retpct",
|
key="retpct",
|
||||||
translation_key="restore_capacity",
|
translation_key="restore_capacity",
|
||||||
name="UPS Restore Requirement",
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
),
|
),
|
||||||
"selftest": SensorEntityDescription(
|
"selftest": SensorEntityDescription(
|
||||||
key="selftest",
|
key="selftest",
|
||||||
translation_key="self_test_result",
|
translation_key="self_test_result",
|
||||||
name="UPS Self Test result",
|
|
||||||
),
|
),
|
||||||
"sense": SensorEntityDescription(
|
"sense": SensorEntityDescription(
|
||||||
key="sense",
|
key="sense",
|
||||||
translation_key="sensitivity",
|
translation_key="sensitivity",
|
||||||
name="UPS Sensitivity",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"serialno": SensorEntityDescription(
|
"serialno": SensorEntityDescription(
|
||||||
key="serialno",
|
key="serialno",
|
||||||
translation_key="serial_number",
|
translation_key="serial_number",
|
||||||
name="UPS Serial Number",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"starttime": SensorEntityDescription(
|
"starttime": SensorEntityDescription(
|
||||||
key="starttime",
|
key="starttime",
|
||||||
translation_key="startup_time",
|
translation_key="startup_time",
|
||||||
name="UPS Startup Time",
|
|
||||||
),
|
),
|
||||||
"statflag": SensorEntityDescription(
|
"statflag": SensorEntityDescription(
|
||||||
key="statflag",
|
key="statflag",
|
||||||
translation_key="online_status",
|
translation_key="online_status",
|
||||||
name="UPS Status Flag",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"status": SensorEntityDescription(
|
"status": SensorEntityDescription(
|
||||||
key="status",
|
key="status",
|
||||||
translation_key="status",
|
translation_key="status",
|
||||||
name="UPS Status",
|
|
||||||
),
|
),
|
||||||
"stesti": SensorEntityDescription(
|
"stesti": SensorEntityDescription(
|
||||||
key="stesti",
|
key="stesti",
|
||||||
translation_key="self_test_interval",
|
translation_key="self_test_interval",
|
||||||
name="UPS Self Test Interval",
|
|
||||||
),
|
),
|
||||||
"timeleft": SensorEntityDescription(
|
"timeleft": SensorEntityDescription(
|
||||||
key="timeleft",
|
key="timeleft",
|
||||||
translation_key="time_left",
|
translation_key="time_left",
|
||||||
name="UPS Time Left",
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"tonbatt": SensorEntityDescription(
|
"tonbatt": SensorEntityDescription(
|
||||||
key="tonbatt",
|
key="tonbatt",
|
||||||
translation_key="time_on_battery",
|
translation_key="time_on_battery",
|
||||||
name="UPS Time on Battery",
|
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
"upsmode": SensorEntityDescription(
|
"upsmode": SensorEntityDescription(
|
||||||
key="upsmode",
|
key="upsmode",
|
||||||
translation_key="ups_mode",
|
translation_key="ups_mode",
|
||||||
name="UPS Mode",
|
|
||||||
),
|
),
|
||||||
"upsname": SensorEntityDescription(
|
"upsname": SensorEntityDescription(
|
||||||
key="upsname",
|
key="upsname",
|
||||||
translation_key="ups_name",
|
translation_key="ups_name",
|
||||||
name="UPS Name",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"version": SensorEntityDescription(
|
"version": SensorEntityDescription(
|
||||||
key="version",
|
key="version",
|
||||||
translation_key="version",
|
translation_key="version",
|
||||||
name="UPS Daemon Info",
|
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
),
|
),
|
||||||
"xoffbat": SensorEntityDescription(
|
"xoffbat": SensorEntityDescription(
|
||||||
key="xoffbat",
|
key="xoffbat",
|
||||||
translation_key="transfer_from_battery",
|
translation_key="transfer_from_battery",
|
||||||
name="UPS Transfer from Battery",
|
|
||||||
),
|
),
|
||||||
"xoffbatt": SensorEntityDescription(
|
"xoffbatt": SensorEntityDescription(
|
||||||
key="xoffbatt",
|
key="xoffbatt",
|
||||||
translation_key="transfer_from_battery",
|
translation_key="transfer_from_battery",
|
||||||
name="UPS Transfer from Battery",
|
|
||||||
),
|
),
|
||||||
"xonbatt": SensorEntityDescription(
|
"xonbatt": SensorEntityDescription(
|
||||||
key="xonbatt",
|
key="xonbatt",
|
||||||
translation_key="transfer_to_battery",
|
translation_key="transfer_to_battery",
|
||||||
name="UPS Transfer to Battery",
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,6 +436,8 @@ def infer_unit(value: str) -> tuple[str, str | None]:
|
|||||||
class APCUPSdSensor(CoordinatorEntity[APCUPSdCoordinator], SensorEntity):
|
class APCUPSdSensor(CoordinatorEntity[APCUPSdCoordinator], SensorEntity):
|
||||||
"""Representation of a sensor entity for APCUPSd status values."""
|
"""Representation of a sensor entity for APCUPSd status values."""
|
||||||
|
|
||||||
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
coordinator: APCUPSdCoordinator,
|
coordinator: APCUPSdCoordinator,
|
||||||
|
@ -16,5 +16,209 @@
|
|||||||
"description": "Enter the host and port on which the apcupsd NIS is being served."
|
"description": "Enter the host and port on which the apcupsd NIS is being served."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"binary_sensor": {
|
||||||
|
"online_status": {
|
||||||
|
"name": "Online status"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sensor": {
|
||||||
|
"alarm_delay": {
|
||||||
|
"name": "Alarm delay"
|
||||||
|
},
|
||||||
|
"ambient_temperature": {
|
||||||
|
"name": "Ambient temperature"
|
||||||
|
},
|
||||||
|
"apc_status": {
|
||||||
|
"name": "Status data"
|
||||||
|
},
|
||||||
|
"apc_model": {
|
||||||
|
"name": "Model"
|
||||||
|
},
|
||||||
|
"bad_batteries": {
|
||||||
|
"name": "Bad batteries"
|
||||||
|
},
|
||||||
|
"battery_replacement_date": {
|
||||||
|
"name": "Battery replaced"
|
||||||
|
},
|
||||||
|
"battery_status": {
|
||||||
|
"name": "Battery status"
|
||||||
|
},
|
||||||
|
"battery_voltage": {
|
||||||
|
"name": "Battery voltage"
|
||||||
|
},
|
||||||
|
"cable_type": {
|
||||||
|
"name": "Cable type"
|
||||||
|
},
|
||||||
|
"total_time_on_battery": {
|
||||||
|
"name": "Total time on battery"
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"name": "Status date"
|
||||||
|
},
|
||||||
|
"dip_switch_settings": {
|
||||||
|
"name": "Dip switch settings"
|
||||||
|
},
|
||||||
|
"low_battery_signal": {
|
||||||
|
"name": "Low battery signal"
|
||||||
|
},
|
||||||
|
"driver": {
|
||||||
|
"name": "Driver"
|
||||||
|
},
|
||||||
|
"shutdown_delay": {
|
||||||
|
"name": "Shutdown delay"
|
||||||
|
},
|
||||||
|
"wake_delay": {
|
||||||
|
"name": "Wake delay"
|
||||||
|
},
|
||||||
|
"date_and_time": {
|
||||||
|
"name": "Date and time"
|
||||||
|
},
|
||||||
|
"external_batteries": {
|
||||||
|
"name": "External batteries"
|
||||||
|
},
|
||||||
|
"firmware_version": {
|
||||||
|
"name": "Firmware version"
|
||||||
|
},
|
||||||
|
"transfer_high": {
|
||||||
|
"name": "Transfer high"
|
||||||
|
},
|
||||||
|
"hostname": {
|
||||||
|
"name": "Hostname"
|
||||||
|
},
|
||||||
|
"humidity": {
|
||||||
|
"name": "Ambient humidity"
|
||||||
|
},
|
||||||
|
"internal_temperature": {
|
||||||
|
"name": "Internal temperature"
|
||||||
|
},
|
||||||
|
"last_self_test": {
|
||||||
|
"name": "Last self test"
|
||||||
|
},
|
||||||
|
"last_transfer": {
|
||||||
|
"name": "Last transfer"
|
||||||
|
},
|
||||||
|
"line_failure": {
|
||||||
|
"name": "Input voltage status"
|
||||||
|
},
|
||||||
|
"line_frequency": {
|
||||||
|
"name": "Line frequency"
|
||||||
|
},
|
||||||
|
"line_voltage": {
|
||||||
|
"name": "Input voltage"
|
||||||
|
},
|
||||||
|
"load_capacity": {
|
||||||
|
"name": "Load"
|
||||||
|
},
|
||||||
|
"apparent_power": {
|
||||||
|
"name": "Load apparent power"
|
||||||
|
},
|
||||||
|
"transfer_low": {
|
||||||
|
"name": "Transfer low"
|
||||||
|
},
|
||||||
|
"manufacture_date": {
|
||||||
|
"name": "Manufacture date"
|
||||||
|
},
|
||||||
|
"master_update": {
|
||||||
|
"name": "Master update"
|
||||||
|
},
|
||||||
|
"input_voltage_high": {
|
||||||
|
"name": "Input voltage high"
|
||||||
|
},
|
||||||
|
"max_time": {
|
||||||
|
"name": "Battery timeout"
|
||||||
|
},
|
||||||
|
"max_battery_charge": {
|
||||||
|
"name": "Battery shutdown"
|
||||||
|
},
|
||||||
|
"input_voltage_low": {
|
||||||
|
"name": "Input voltage low"
|
||||||
|
},
|
||||||
|
"min_time": {
|
||||||
|
"name": "Shutdown time"
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "Model"
|
||||||
|
},
|
||||||
|
"battery_nominal_voltage": {
|
||||||
|
"name": "Battery nominal voltage"
|
||||||
|
},
|
||||||
|
"nominal_input_voltage": {
|
||||||
|
"name": "Nominal input voltage"
|
||||||
|
},
|
||||||
|
"nominal_output_voltage": {
|
||||||
|
"name": "Nominal output voltage"
|
||||||
|
},
|
||||||
|
"nominal_output_power": {
|
||||||
|
"name": "Nominal output power"
|
||||||
|
},
|
||||||
|
"nominal_apparent_power": {
|
||||||
|
"name": "Nominal apparent power"
|
||||||
|
},
|
||||||
|
"transfer_count": {
|
||||||
|
"name": "Transfer count"
|
||||||
|
},
|
||||||
|
"output_current": {
|
||||||
|
"name": "Output current"
|
||||||
|
},
|
||||||
|
"output_voltage": {
|
||||||
|
"name": "Output voltage"
|
||||||
|
},
|
||||||
|
"register_1_fault": {
|
||||||
|
"name": "Register 1 fault"
|
||||||
|
},
|
||||||
|
"register_2_fault": {
|
||||||
|
"name": "Register 2 fault"
|
||||||
|
},
|
||||||
|
"register_3_fault": {
|
||||||
|
"name": "Register 3 fault"
|
||||||
|
},
|
||||||
|
"restore_capacity": {
|
||||||
|
"name": "Restore requirement"
|
||||||
|
},
|
||||||
|
"self_test_result": {
|
||||||
|
"name": "Self test result"
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"name": "Sensitivity"
|
||||||
|
},
|
||||||
|
"serial_number": {
|
||||||
|
"name": "Serial number"
|
||||||
|
},
|
||||||
|
"startup_time": {
|
||||||
|
"name": "Startup time"
|
||||||
|
},
|
||||||
|
"online_status": {
|
||||||
|
"name": "Status flag"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"name": "Status"
|
||||||
|
},
|
||||||
|
"self_test_interval": {
|
||||||
|
"name": "Self test interval"
|
||||||
|
},
|
||||||
|
"time_left": {
|
||||||
|
"name": "Time left"
|
||||||
|
},
|
||||||
|
"time_on_battery": {
|
||||||
|
"name": "Time on battery"
|
||||||
|
},
|
||||||
|
"ups_mode": {
|
||||||
|
"name": "Mode"
|
||||||
|
},
|
||||||
|
"ups_name": {
|
||||||
|
"name": "Name"
|
||||||
|
},
|
||||||
|
"version": {
|
||||||
|
"name": "Daemon version"
|
||||||
|
},
|
||||||
|
"transfer_from_battery": {
|
||||||
|
"name": "Transfer from battery"
|
||||||
|
},
|
||||||
|
"transfer_to_battery": {
|
||||||
|
"name": "Transfer to battery"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
from homeassistant.util import slugify
|
||||||
|
|
||||||
from . import MOCK_STATUS, async_init_integration
|
from . import MOCK_STATUS, async_init_integration
|
||||||
|
|
||||||
@ -12,12 +13,13 @@ async def test_binary_sensor(
|
|||||||
"""Test states of binary sensor."""
|
"""Test states of binary sensor."""
|
||||||
await async_init_integration(hass, status=MOCK_STATUS)
|
await async_init_integration(hass, status=MOCK_STATUS)
|
||||||
|
|
||||||
state = hass.states.get("binary_sensor.ups_online_status")
|
device_slug, serialno = slugify(MOCK_STATUS["UPSNAME"]), MOCK_STATUS["SERIALNO"]
|
||||||
|
state = hass.states.get(f"binary_sensor.{device_slug}_online_status")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == "on"
|
assert state.state == "on"
|
||||||
entry = entity_registry.async_get("binary_sensor.ups_online_status")
|
entry = entity_registry.async_get(f"binary_sensor.{device_slug}_online_status")
|
||||||
assert entry
|
assert entry
|
||||||
assert entry.unique_id == "XXXXXXXXXXXX_statflag"
|
assert entry.unique_id == f"{serialno}_statflag"
|
||||||
|
|
||||||
|
|
||||||
async def test_no_binary_sensor(hass: HomeAssistant) -> None:
|
async def test_no_binary_sensor(hass: HomeAssistant) -> None:
|
||||||
@ -26,5 +28,6 @@ async def test_no_binary_sensor(hass: HomeAssistant) -> None:
|
|||||||
status.pop("STATFLAG")
|
status.pop("STATFLAG")
|
||||||
await async_init_integration(hass, status=status)
|
await async_init_integration(hass, status=status)
|
||||||
|
|
||||||
state = hass.states.get("binary_sensor.ups_online_status")
|
device_slug = slugify(MOCK_STATUS["UPSNAME"])
|
||||||
|
state = hass.states.get(f"binary_sensor.{device_slug}_online_status")
|
||||||
assert state is None
|
assert state is None
|
||||||
|
@ -12,23 +12,41 @@ from homeassistant.config_entries import SOURCE_USER, ConfigEntryState
|
|||||||
from homeassistant.const import STATE_UNAVAILABLE
|
from homeassistant.const import STATE_UNAVAILABLE
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import device_registry as dr
|
from homeassistant.helpers import device_registry as dr
|
||||||
from homeassistant.util import utcnow
|
from homeassistant.util import slugify, utcnow
|
||||||
|
|
||||||
from . import CONF_DATA, MOCK_MINIMAL_STATUS, MOCK_STATUS, async_init_integration
|
from . import CONF_DATA, MOCK_MINIMAL_STATUS, MOCK_STATUS, async_init_integration
|
||||||
|
|
||||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("status", (MOCK_STATUS, MOCK_MINIMAL_STATUS))
|
@pytest.mark.parametrize(
|
||||||
|
"status",
|
||||||
|
(
|
||||||
|
# Contains "SERIALNO" and "UPSNAME" fields.
|
||||||
|
# We should create devices for the entities and prefix their IDs with "MyUPS".
|
||||||
|
MOCK_STATUS,
|
||||||
|
# Contains "SERIALNO" but no "UPSNAME" field.
|
||||||
|
# We should create devices for the entities and prefix their IDs with default "APC UPS".
|
||||||
|
MOCK_MINIMAL_STATUS | {"SERIALNO": "XXXX"},
|
||||||
|
# Does not contain either "SERIALNO" field.
|
||||||
|
# We should _not_ create devices for the entities and their IDs will not have prefixes.
|
||||||
|
MOCK_MINIMAL_STATUS,
|
||||||
|
),
|
||||||
|
)
|
||||||
async def test_async_setup_entry(hass: HomeAssistant, status: OrderedDict) -> None:
|
async def test_async_setup_entry(hass: HomeAssistant, status: OrderedDict) -> None:
|
||||||
"""Test a successful setup entry."""
|
"""Test a successful setup entry."""
|
||||||
# Minimal status does not contain "SERIALNO" field, which is used to determine the
|
# Minimal status does not contain "SERIALNO" field, which is used to determine the
|
||||||
# unique ID of this integration. But, the integration should work fine without it.
|
# unique ID of this integration. But, the integration should work fine without it.
|
||||||
|
# In such a case, the device will not be added either
|
||||||
await async_init_integration(hass, status=status)
|
await async_init_integration(hass, status=status)
|
||||||
|
|
||||||
|
prefix = ""
|
||||||
|
if "SERIALNO" in status:
|
||||||
|
prefix = slugify(status.get("UPSNAME", "APC UPS")) + "_"
|
||||||
|
|
||||||
# Verify successful setup by querying the status sensor.
|
# Verify successful setup by querying the status sensor.
|
||||||
state = hass.states.get("binary_sensor.ups_online_status")
|
state = hass.states.get(f"binary_sensor.{prefix}online_status")
|
||||||
assert state is not None
|
assert state
|
||||||
assert state.state != STATE_UNAVAILABLE
|
assert state.state != STATE_UNAVAILABLE
|
||||||
assert state.state == "on"
|
assert state.state == "on"
|
||||||
|
|
||||||
@ -93,12 +111,32 @@ async def test_multiple_integrations(hass: HomeAssistant) -> None:
|
|||||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 2
|
assert len(hass.config_entries.async_entries(DOMAIN)) == 2
|
||||||
assert all(entry.state is ConfigEntryState.LOADED for entry in entries)
|
assert all(entry.state is ConfigEntryState.LOADED for entry in entries)
|
||||||
|
|
||||||
state1 = hass.states.get("sensor.ups_load")
|
# Since the two UPS device names are the same, we will have to add a "_2" suffix.
|
||||||
state2 = hass.states.get("sensor.ups_load_2")
|
device_slug = slugify(MOCK_STATUS["UPSNAME"])
|
||||||
|
state1 = hass.states.get(f"sensor.{device_slug}_load")
|
||||||
|
state2 = hass.states.get(f"sensor.{device_slug}_load_2")
|
||||||
assert state1 is not None and state2 is not None
|
assert state1 is not None and state2 is not None
|
||||||
assert state1.state != state2.state
|
assert state1.state != state2.state
|
||||||
|
|
||||||
|
|
||||||
|
async def test_multiple_integrations_different_devices(hass: HomeAssistant) -> None:
|
||||||
|
"""Test successful setup for multiple entries with different device names."""
|
||||||
|
status1 = MOCK_STATUS | {"SERIALNO": "XXXXX1", "UPSNAME": "MyUPS1"}
|
||||||
|
status2 = MOCK_STATUS | {"SERIALNO": "XXXXX2", "UPSNAME": "MyUPS2"}
|
||||||
|
entries = (
|
||||||
|
await async_init_integration(hass, host="test1", status=status1),
|
||||||
|
await async_init_integration(hass, host="test2", status=status2),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(hass.config_entries.async_entries(DOMAIN)) == 2
|
||||||
|
assert all(entry.state is ConfigEntryState.LOADED for entry in entries)
|
||||||
|
|
||||||
|
# The device names are different, so they are prefixed differently.
|
||||||
|
state1 = hass.states.get("sensor.myups1_load")
|
||||||
|
state2 = hass.states.get("sensor.myups2_load")
|
||||||
|
assert state1 is not None and state2 is not None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"error",
|
"error",
|
||||||
(OSError(), asyncio.IncompleteReadError(partial=b"", expected=0)),
|
(OSError(), asyncio.IncompleteReadError(partial=b"", expected=0)),
|
||||||
@ -154,7 +192,8 @@ async def test_availability(hass: HomeAssistant) -> None:
|
|||||||
"""Ensure that we mark the entity's availability properly when network is down / back up."""
|
"""Ensure that we mark the entity's availability properly when network is down / back up."""
|
||||||
await async_init_integration(hass)
|
await async_init_integration(hass)
|
||||||
|
|
||||||
state = hass.states.get("sensor.ups_load")
|
device_slug = slugify(MOCK_STATUS["UPSNAME"])
|
||||||
|
state = hass.states.get(f"sensor.{device_slug}_load")
|
||||||
assert state
|
assert state
|
||||||
assert state.state != STATE_UNAVAILABLE
|
assert state.state != STATE_UNAVAILABLE
|
||||||
assert pytest.approx(float(state.state)) == 14.0
|
assert pytest.approx(float(state.state)) == 14.0
|
||||||
@ -167,7 +206,7 @@ async def test_availability(hass: HomeAssistant) -> None:
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
# Sensors should be marked as unavailable.
|
# Sensors should be marked as unavailable.
|
||||||
state = hass.states.get("sensor.ups_load")
|
state = hass.states.get(f"sensor.{device_slug}_load")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == STATE_UNAVAILABLE
|
assert state.state == STATE_UNAVAILABLE
|
||||||
|
|
||||||
@ -179,7 +218,7 @@ async def test_availability(hass: HomeAssistant) -> None:
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
# Sensors should be online now with the new value.
|
# Sensors should be online now with the new value.
|
||||||
state = hass.states.get("sensor.ups_load")
|
state = hass.states.get(f"sensor.{device_slug}_load")
|
||||||
assert state
|
assert state
|
||||||
assert state.state != STATE_UNAVAILABLE
|
assert state.state != STATE_UNAVAILABLE
|
||||||
assert pytest.approx(float(state.state)) == 15.0
|
assert pytest.approx(float(state.state)) == 15.0
|
||||||
|
@ -22,6 +22,7 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
from homeassistant.util import slugify
|
||||||
from homeassistant.util.dt import utcnow
|
from homeassistant.util.dt import utcnow
|
||||||
|
|
||||||
from . import MOCK_STATUS, async_init_integration
|
from . import MOCK_STATUS, async_init_integration
|
||||||
@ -32,17 +33,18 @@ from tests.common import async_fire_time_changed
|
|||||||
async def test_sensor(hass: HomeAssistant, entity_registry: er.EntityRegistry) -> None:
|
async def test_sensor(hass: HomeAssistant, entity_registry: er.EntityRegistry) -> None:
|
||||||
"""Test states of sensor."""
|
"""Test states of sensor."""
|
||||||
await async_init_integration(hass, status=MOCK_STATUS)
|
await async_init_integration(hass, status=MOCK_STATUS)
|
||||||
|
device_slug, serialno = slugify(MOCK_STATUS["UPSNAME"]), MOCK_STATUS["SERIALNO"]
|
||||||
|
|
||||||
# Test a representative string sensor.
|
# Test a representative string sensor.
|
||||||
state = hass.states.get("sensor.ups_mode")
|
state = hass.states.get(f"sensor.{device_slug}_mode")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == "Stand Alone"
|
assert state.state == "Stand Alone"
|
||||||
entry = entity_registry.async_get("sensor.ups_mode")
|
entry = entity_registry.async_get(f"sensor.{device_slug}_mode")
|
||||||
assert entry
|
assert entry
|
||||||
assert entry.unique_id == "XXXXXXXXXXXX_upsmode"
|
assert entry.unique_id == f"{serialno}_upsmode"
|
||||||
|
|
||||||
# Test two representative voltage sensors.
|
# Test two representative voltage sensors.
|
||||||
state = hass.states.get("sensor.ups_input_voltage")
|
state = hass.states.get(f"sensor.{device_slug}_input_voltage")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == "124.0"
|
assert state.state == "124.0"
|
||||||
assert (
|
assert (
|
||||||
@ -50,11 +52,11 @@ async def test_sensor(hass: HomeAssistant, entity_registry: er.EntityRegistry) -
|
|||||||
)
|
)
|
||||||
assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT
|
assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT
|
||||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.VOLTAGE
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.VOLTAGE
|
||||||
entry = entity_registry.async_get("sensor.ups_input_voltage")
|
entry = entity_registry.async_get(f"sensor.{device_slug}_input_voltage")
|
||||||
assert entry
|
assert entry
|
||||||
assert entry.unique_id == "XXXXXXXXXXXX_linev"
|
assert entry.unique_id == f"{serialno}_linev"
|
||||||
|
|
||||||
state = hass.states.get("sensor.ups_battery_voltage")
|
state = hass.states.get(f"sensor.{device_slug}_battery_voltage")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == "13.7"
|
assert state.state == "13.7"
|
||||||
assert (
|
assert (
|
||||||
@ -62,38 +64,59 @@ async def test_sensor(hass: HomeAssistant, entity_registry: er.EntityRegistry) -
|
|||||||
)
|
)
|
||||||
assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT
|
assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT
|
||||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.VOLTAGE
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.VOLTAGE
|
||||||
entry = entity_registry.async_get("sensor.ups_battery_voltage")
|
entry = entity_registry.async_get(f"sensor.{device_slug}_battery_voltage")
|
||||||
assert entry
|
assert entry
|
||||||
assert entry.unique_id == "XXXXXXXXXXXX_battv"
|
assert entry.unique_id == f"{serialno}_battv"
|
||||||
|
|
||||||
# test a representative time sensor.
|
# Test a representative time sensor.
|
||||||
state = hass.states.get("sensor.ups_self_test_interval")
|
state = hass.states.get(f"sensor.{device_slug}_self_test_interval")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == "7"
|
assert state.state == "7"
|
||||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfTime.DAYS
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfTime.DAYS
|
||||||
entry = entity_registry.async_get("sensor.ups_self_test_interval")
|
entry = entity_registry.async_get(f"sensor.{device_slug}_self_test_interval")
|
||||||
assert entry
|
assert entry
|
||||||
assert entry.unique_id == "XXXXXXXXXXXX_stesti"
|
assert entry.unique_id == f"{serialno}_stesti"
|
||||||
|
|
||||||
# Test a representative percentage sensor.
|
# Test a representative percentage sensor.
|
||||||
state = hass.states.get("sensor.ups_load")
|
state = hass.states.get(f"sensor.{device_slug}_load")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == "14.0"
|
assert state.state == "14.0"
|
||||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE
|
||||||
assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT
|
assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT
|
||||||
entry = entity_registry.async_get("sensor.ups_load")
|
entry = entity_registry.async_get(f"sensor.{device_slug}_load")
|
||||||
assert entry
|
assert entry
|
||||||
assert entry.unique_id == "XXXXXXXXXXXX_loadpct"
|
assert entry.unique_id == f"{serialno}_loadpct"
|
||||||
|
|
||||||
# Test a representative wattage sensor.
|
# Test a representative wattage sensor.
|
||||||
state = hass.states.get("sensor.ups_nominal_output_power")
|
state = hass.states.get(f"sensor.{device_slug}_nominal_output_power")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == "330"
|
assert state.state == "330"
|
||||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfPower.WATT
|
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UnitOfPower.WATT
|
||||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.POWER
|
assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.POWER
|
||||||
entry = entity_registry.async_get("sensor.ups_nominal_output_power")
|
entry = entity_registry.async_get(f"sensor.{device_slug}_nominal_output_power")
|
||||||
assert entry
|
assert entry
|
||||||
assert entry.unique_id == "XXXXXXXXXXXX_nompower"
|
assert entry.unique_id == f"{serialno}_nompower"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensor_name(hass: HomeAssistant) -> None:
|
||||||
|
"""Test if sensor name follows the recommended entity naming scheme.
|
||||||
|
|
||||||
|
See https://developers.home-assistant.io/docs/core/entity/#entity-naming for more details.
|
||||||
|
"""
|
||||||
|
await async_init_integration(hass, status=MOCK_STATUS)
|
||||||
|
|
||||||
|
all_states = hass.states.async_all()
|
||||||
|
assert len(all_states) != 0
|
||||||
|
|
||||||
|
device_name = MOCK_STATUS["UPSNAME"]
|
||||||
|
for state in all_states:
|
||||||
|
# Friendly name must start with the device name.
|
||||||
|
friendly_name = state.name
|
||||||
|
assert friendly_name.startswith(device_name)
|
||||||
|
|
||||||
|
# Entity names should start with a capital letter, the rest of the words are lower case.
|
||||||
|
entity_name = friendly_name.removeprefix(device_name).strip()
|
||||||
|
assert entity_name == entity_name.capitalize()
|
||||||
|
|
||||||
|
|
||||||
async def test_sensor_disabled(
|
async def test_sensor_disabled(
|
||||||
@ -102,10 +125,11 @@ async def test_sensor_disabled(
|
|||||||
"""Test sensor disabled by default."""
|
"""Test sensor disabled by default."""
|
||||||
await async_init_integration(hass)
|
await async_init_integration(hass)
|
||||||
|
|
||||||
|
device_slug, serialno = slugify(MOCK_STATUS["UPSNAME"]), MOCK_STATUS["SERIALNO"]
|
||||||
# Test a representative integration-disabled sensor.
|
# Test a representative integration-disabled sensor.
|
||||||
entry = entity_registry.async_get("sensor.ups_model")
|
entry = entity_registry.async_get(f"sensor.{device_slug}_model")
|
||||||
assert entry.disabled
|
assert entry.disabled
|
||||||
assert entry.unique_id == "XXXXXXXXXXXX_model"
|
assert entry.unique_id == f"{serialno}_model"
|
||||||
assert entry.disabled_by is er.RegistryEntryDisabler.INTEGRATION
|
assert entry.disabled_by is er.RegistryEntryDisabler.INTEGRATION
|
||||||
|
|
||||||
# Test enabling entity.
|
# Test enabling entity.
|
||||||
@ -121,7 +145,8 @@ async def test_state_update(hass: HomeAssistant) -> None:
|
|||||||
"""Ensure the sensor state changes after updating the data."""
|
"""Ensure the sensor state changes after updating the data."""
|
||||||
await async_init_integration(hass)
|
await async_init_integration(hass)
|
||||||
|
|
||||||
state = hass.states.get("sensor.ups_load")
|
device_slug = slugify(MOCK_STATUS["UPSNAME"])
|
||||||
|
state = hass.states.get(f"sensor.{device_slug}_load")
|
||||||
assert state
|
assert state
|
||||||
assert state.state != STATE_UNAVAILABLE
|
assert state.state != STATE_UNAVAILABLE
|
||||||
assert state.state == "14.0"
|
assert state.state == "14.0"
|
||||||
@ -132,7 +157,7 @@ async def test_state_update(hass: HomeAssistant) -> None:
|
|||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass, future)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = hass.states.get("sensor.ups_load")
|
state = hass.states.get(f"sensor.{device_slug}_load")
|
||||||
assert state
|
assert state
|
||||||
assert state.state != STATE_UNAVAILABLE
|
assert state.state != STATE_UNAVAILABLE
|
||||||
assert state.state == "15.0"
|
assert state.state == "15.0"
|
||||||
@ -142,8 +167,9 @@ async def test_manual_update_entity(hass: HomeAssistant) -> None:
|
|||||||
"""Test manual update entity via service homeassistant/update_entity."""
|
"""Test manual update entity via service homeassistant/update_entity."""
|
||||||
await async_init_integration(hass)
|
await async_init_integration(hass)
|
||||||
|
|
||||||
|
device_slug = slugify(MOCK_STATUS["UPSNAME"])
|
||||||
# Assert the initial state of sensor.ups_load.
|
# Assert the initial state of sensor.ups_load.
|
||||||
state = hass.states.get("sensor.ups_load")
|
state = hass.states.get(f"sensor.{device_slug}_load")
|
||||||
assert state
|
assert state
|
||||||
assert state.state != STATE_UNAVAILABLE
|
assert state.state != STATE_UNAVAILABLE
|
||||||
assert state.state == "14.0"
|
assert state.state == "14.0"
|
||||||
@ -163,7 +189,12 @@ async def test_manual_update_entity(hass: HomeAssistant) -> None:
|
|||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
"homeassistant",
|
"homeassistant",
|
||||||
"update_entity",
|
"update_entity",
|
||||||
{ATTR_ENTITY_ID: ["sensor.ups_load", "sensor.ups_battery"]},
|
{
|
||||||
|
ATTR_ENTITY_ID: [
|
||||||
|
f"sensor.{device_slug}_load",
|
||||||
|
f"sensor.{device_slug}_battery",
|
||||||
|
]
|
||||||
|
},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
# Even if we requested updates for two entities, our integration should smartly
|
# Even if we requested updates for two entities, our integration should smartly
|
||||||
@ -171,7 +202,7 @@ async def test_manual_update_entity(hass: HomeAssistant) -> None:
|
|||||||
assert mock_request_status.call_count == 1
|
assert mock_request_status.call_count == 1
|
||||||
|
|
||||||
# The new state should be effective.
|
# The new state should be effective.
|
||||||
state = hass.states.get("sensor.ups_load")
|
state = hass.states.get(f"sensor.{device_slug}_load")
|
||||||
assert state
|
assert state
|
||||||
assert state.state != STATE_UNAVAILABLE
|
assert state.state != STATE_UNAVAILABLE
|
||||||
assert state.state == "15.0"
|
assert state.state == "15.0"
|
||||||
@ -184,6 +215,7 @@ async def test_multiple_manual_update_entity(hass: HomeAssistant) -> None:
|
|||||||
"""
|
"""
|
||||||
await async_init_integration(hass)
|
await async_init_integration(hass)
|
||||||
|
|
||||||
|
device_slug = slugify(MOCK_STATUS["UPSNAME"])
|
||||||
# Setup HASS for calling the update_entity service.
|
# Setup HASS for calling the update_entity service.
|
||||||
await async_setup_component(hass, "homeassistant", {})
|
await async_setup_component(hass, "homeassistant", {})
|
||||||
|
|
||||||
@ -196,7 +228,12 @@ async def test_multiple_manual_update_entity(hass: HomeAssistant) -> None:
|
|||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
"homeassistant",
|
"homeassistant",
|
||||||
"update_entity",
|
"update_entity",
|
||||||
{ATTR_ENTITY_ID: ["sensor.ups_load", "sensor.ups_input_voltage"]},
|
{
|
||||||
|
ATTR_ENTITY_ID: [
|
||||||
|
f"sensor.{device_slug}_load",
|
||||||
|
f"sensor.{device_slug}_input_voltage",
|
||||||
|
]
|
||||||
|
},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
assert mock_request_status.call_count == 1
|
assert mock_request_status.call_count == 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user