diff --git a/homeassistant/components/goalzero/__init__.py b/homeassistant/components/goalzero/__init__.py index 308934819cd6d71546e79e54bf2a208ec5e488ff..379a56512c654a177fdb37d29d903d0650c6d71c 100644 --- a/homeassistant/components/goalzero/__init__.py +++ b/homeassistant/components/goalzero/__init__.py @@ -43,7 +43,7 @@ _LOGGER = logging.getLogger(__name__) PLATFORMS = [DOMAIN_BINARY_SENSOR, DOMAIN_SENSOR, DOMAIN_SWITCH] -async def async_setup_entry(hass, entry): +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Goal Zero Yeti from a config entry.""" name = entry.data[CONF_NAME] host = entry.data[CONF_HOST] @@ -81,7 +81,7 @@ async def async_setup_entry(hass, entry): return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): +async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) if unload_ok: @@ -94,7 +94,13 @@ class YetiEntity(CoordinatorEntity): _attr_extra_state_attributes = {ATTR_ATTRIBUTION: ATTRIBUTION} - def __init__(self, api, coordinator, name, server_unique_id): + def __init__( + self, + api: Yeti, + coordinator: DataUpdateCoordinator, + name: str, + server_unique_id: str, + ) -> None: """Initialize a Goal Zero Yeti entity.""" super().__init__(coordinator) self.api = api @@ -104,15 +110,10 @@ class YetiEntity(CoordinatorEntity): @property def device_info(self) -> DeviceInfo: """Return the device information of the entity.""" - model = sw_version = None - if self.api.sysdata: - model = self.api.sysdata[ATTR_MODEL] - if self.api.data: - sw_version = self.api.data["firmwareVersion"] return { ATTR_IDENTIFIERS: {(DOMAIN, self._server_unique_id)}, ATTR_MANUFACTURER: "Goal Zero", ATTR_NAME: self._name, - ATTR_MODEL: str(model), - ATTR_SW_VERSION: str(sw_version), + ATTR_MODEL: self.api.sysdata.get(ATTR_MODEL), + ATTR_SW_VERSION: self.api.data.get("firmwareVersion"), } diff --git a/homeassistant/components/goalzero/binary_sensor.py b/homeassistant/components/goalzero/binary_sensor.py index f9a110eff5556f3c96350d0369185b81a8dd3e11..21eecc678ade1f93da8c01966adc177f4aff718b 100644 --- a/homeassistant/components/goalzero/binary_sensor.py +++ b/homeassistant/components/goalzero/binary_sensor.py @@ -1,14 +1,51 @@ """Support for Goal Zero Yeti Sensors.""" -from homeassistant.components.binary_sensor import BinarySensorEntity -from homeassistant.const import ATTR_DEVICE_CLASS, ATTR_ICON, ATTR_NAME, CONF_NAME +from __future__ import annotations -from . import YetiEntity -from .const import BINARY_SENSOR_DICT, DATA_KEY_API, DATA_KEY_COORDINATOR, DOMAIN +from homeassistant.components.binary_sensor import ( + DEVICE_CLASS_BATTERY_CHARGING, + DEVICE_CLASS_CONNECTIVITY, + DEVICE_CLASS_POWER, + BinarySensorEntity, + BinarySensorEntityDescription, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_NAME +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator + +from . import Yeti, YetiEntity +from .const import DATA_KEY_API, DATA_KEY_COORDINATOR, DOMAIN PARALLEL_UPDATES = 0 +BINARY_SENSOR_TYPES: tuple[BinarySensorEntityDescription, ...] = ( + BinarySensorEntityDescription( + key="backlight", + name="Backlight", + icon="mdi:clock-digital", + ), + BinarySensorEntityDescription( + key="app_online", + name="App Online", + device_class=DEVICE_CLASS_CONNECTIVITY, + ), + BinarySensorEntityDescription( + key="isCharging", + name="Charging", + device_class=DEVICE_CLASS_BATTERY_CHARGING, + ), + BinarySensorEntityDescription( + key="inputDetected", + name="Input Detected", + device_class=DEVICE_CLASS_POWER, + ), +) + -async def async_setup_entry(hass, entry, async_add_entities): +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: """Set up the Goal Zero Yeti sensor.""" name = entry.data[CONF_NAME] goalzero_data = hass.data[DOMAIN][entry.entry_id] @@ -17,10 +54,10 @@ async def async_setup_entry(hass, entry, async_add_entities): goalzero_data[DATA_KEY_API], goalzero_data[DATA_KEY_COORDINATOR], name, - sensor_name, + description, entry.entry_id, ) - for sensor_name in BINARY_SENSOR_DICT + for description in BINARY_SENSOR_TYPES ) @@ -29,26 +66,19 @@ class YetiBinarySensor(YetiEntity, BinarySensorEntity): def __init__( self, - api, - coordinator, - name, - sensor_name, - server_unique_id, - ): + api: Yeti, + coordinator: DataUpdateCoordinator, + name: str, + description: BinarySensorEntityDescription, + server_unique_id: str, + ) -> None: """Initialize a Goal Zero Yeti sensor.""" super().__init__(api, coordinator, name, server_unique_id) - - self._condition = sensor_name - self._attr_device_class = BINARY_SENSOR_DICT[sensor_name].get(ATTR_DEVICE_CLASS) - self._attr_icon = BINARY_SENSOR_DICT[sensor_name].get(ATTR_ICON) - self._attr_name = f"{name} {BINARY_SENSOR_DICT[sensor_name].get(ATTR_NAME)}" - self._attr_unique_id = ( - f"{server_unique_id}/{BINARY_SENSOR_DICT[sensor_name].get(ATTR_NAME)}" - ) + self.entity_description = description + self._attr_name = f"{name} {description.name}" + self._attr_unique_id = f"{server_unique_id}/{description.key}" @property def is_on(self) -> bool: """Return if the service is on.""" - if self.api.data: - return self.api.data[self._condition] == 1 - return False + return self.api.data.get(self.entity_description.key) == 1 diff --git a/homeassistant/components/goalzero/config_flow.py b/homeassistant/components/goalzero/config_flow.py index 4c525de9c7d7ba4c61372f9b4f6dc15f3a58989d..cc2c4a9874fb544d27be961ce3dd417c6b792a92 100644 --- a/homeassistant/components/goalzero/config_flow.py +++ b/homeassistant/components/goalzero/config_flow.py @@ -13,6 +13,7 @@ from homeassistant.const import CONF_HOST, CONF_NAME from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.device_registry import format_mac +from homeassistant.helpers.typing import DiscoveryInfoType from .const import DEFAULT_NAME, DOMAIN @@ -24,11 +25,11 @@ class GoalZeroFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 - def __init__(self): + def __init__(self) -> None: """Initialize a Goal Zero Yeti flow.""" self.ip_address = None - async def async_step_dhcp(self, discovery_info): + async def async_step_dhcp(self, discovery_info: DiscoveryInfoType) -> FlowResult: """Handle dhcp discovery.""" self.ip_address = discovery_info[IP_ADDRESS] @@ -36,7 +37,7 @@ class GoalZeroFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): self._abort_if_unique_id_configured(updates={CONF_HOST: self.ip_address}) self._async_abort_entries_match({CONF_HOST: self.ip_address}) - _, error = await self._async_try_connect(self.ip_address) + _, error = await self._async_try_connect(str(self.ip_address)) if error is None: return await self.async_step_confirm_discovery() return self.async_abort(reason=error) @@ -63,7 +64,9 @@ class GoalZeroFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): }, ) - async def async_step_user(self, user_input=None) -> FlowResult: + async def async_step_user( + self, user_input: dict[str, Any] | None = None + ) -> FlowResult: """Handle a flow initiated by the user.""" errors = {} if user_input is not None: @@ -74,7 +77,7 @@ class GoalZeroFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): mac_address, error = await self._async_try_connect(host) if error is None: - await self.async_set_unique_id(format_mac(mac_address)) + await self.async_set_unique_id(format_mac(str(mac_address))) self._abort_if_unique_id_configured(updates={CONF_HOST: host}) return self.async_create_entry( title=name, @@ -98,7 +101,7 @@ class GoalZeroFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): errors=errors, ) - async def _async_try_connect(self, host) -> tuple: + async def _async_try_connect(self, host: str) -> tuple[str | None, str | None]: """Try connecting to Goal Zero Yeti.""" try: session = async_get_clientsession(self.hass) diff --git a/homeassistant/components/goalzero/const.py b/homeassistant/components/goalzero/const.py index e9fed7dc52bfedb8cbdd0caf0a624117544ad07f..d99cacb253eddc70649b2d1d70c306594d7143be 100644 --- a/homeassistant/components/goalzero/const.py +++ b/homeassistant/components/goalzero/const.py @@ -1,37 +1,6 @@ """Constants for the Goal Zero Yeti integration.""" from datetime import timedelta -from homeassistant.components.binary_sensor import ( - DEVICE_CLASS_BATTERY_CHARGING, - DEVICE_CLASS_CONNECTIVITY, - DEVICE_CLASS_POWER, -) -from homeassistant.components.sensor import ( - ATTR_STATE_CLASS, - DEVICE_CLASS_BATTERY, - DEVICE_CLASS_CURRENT, - DEVICE_CLASS_ENERGY, - DEVICE_CLASS_SIGNAL_STRENGTH, - DEVICE_CLASS_TEMPERATURE, - DEVICE_CLASS_VOLTAGE, - STATE_CLASS_MEASUREMENT, -) -from homeassistant.const import ( - ATTR_DEVICE_CLASS, - ATTR_ICON, - ATTR_NAME, - ATTR_UNIT_OF_MEASUREMENT, - ELECTRIC_CURRENT_AMPERE, - ELECTRIC_POTENTIAL_VOLT, - ENERGY_WATT_HOUR, - PERCENTAGE, - POWER_WATT, - SIGNAL_STRENGTH_DECIBELS, - TEMP_CELSIUS, - TIME_MINUTES, - TIME_SECONDS, -) - ATTRIBUTION = "Data provided by Goal Zero" ATTR_DEFAULT_ENABLED = "default_enabled" @@ -41,113 +10,3 @@ DEFAULT_NAME = "Yeti" DATA_KEY_API = "api" MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) - -BINARY_SENSOR_DICT = { - "backlight": {ATTR_NAME: "Backlight", ATTR_ICON: "mdi:clock-digital"}, - "app_online": { - ATTR_NAME: "App Online", - ATTR_DEVICE_CLASS: DEVICE_CLASS_CONNECTIVITY, - }, - "isCharging": { - ATTR_NAME: "Charging", - ATTR_DEVICE_CLASS: DEVICE_CLASS_BATTERY_CHARGING, - }, - "inputDetected": { - ATTR_NAME: "Input Detected", - ATTR_DEVICE_CLASS: DEVICE_CLASS_POWER, - }, -} - -SENSOR_DICT = { - "wattsIn": { - ATTR_NAME: "Watts In", - ATTR_DEVICE_CLASS: DEVICE_CLASS_POWER, - ATTR_UNIT_OF_MEASUREMENT: POWER_WATT, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - ATTR_DEFAULT_ENABLED: True, - }, - "ampsIn": { - ATTR_NAME: "Amps In", - ATTR_DEVICE_CLASS: DEVICE_CLASS_CURRENT, - ATTR_UNIT_OF_MEASUREMENT: ELECTRIC_CURRENT_AMPERE, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - ATTR_DEFAULT_ENABLED: False, - }, - "wattsOut": { - ATTR_NAME: "Watts Out", - ATTR_DEVICE_CLASS: DEVICE_CLASS_POWER, - ATTR_UNIT_OF_MEASUREMENT: POWER_WATT, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - ATTR_DEFAULT_ENABLED: True, - }, - "ampsOut": { - ATTR_NAME: "Amps Out", - ATTR_DEVICE_CLASS: DEVICE_CLASS_CURRENT, - ATTR_UNIT_OF_MEASUREMENT: ELECTRIC_CURRENT_AMPERE, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - ATTR_DEFAULT_ENABLED: False, - }, - "whOut": { - ATTR_NAME: "WH Out", - ATTR_DEVICE_CLASS: DEVICE_CLASS_ENERGY, - ATTR_UNIT_OF_MEASUREMENT: ENERGY_WATT_HOUR, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - ATTR_DEFAULT_ENABLED: False, - }, - "whStored": { - ATTR_NAME: "WH Stored", - ATTR_DEVICE_CLASS: DEVICE_CLASS_ENERGY, - ATTR_UNIT_OF_MEASUREMENT: ENERGY_WATT_HOUR, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - ATTR_DEFAULT_ENABLED: True, - }, - "volts": { - ATTR_NAME: "Volts", - ATTR_DEVICE_CLASS: DEVICE_CLASS_VOLTAGE, - ATTR_UNIT_OF_MEASUREMENT: ELECTRIC_POTENTIAL_VOLT, - ATTR_DEFAULT_ENABLED: False, - }, - "socPercent": { - ATTR_NAME: "State of Charge Percent", - ATTR_DEVICE_CLASS: DEVICE_CLASS_BATTERY, - ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE, - ATTR_DEFAULT_ENABLED: True, - }, - "timeToEmptyFull": { - ATTR_NAME: "Time to Empty/Full", - ATTR_DEVICE_CLASS: TIME_MINUTES, - ATTR_UNIT_OF_MEASUREMENT: TIME_MINUTES, - ATTR_DEFAULT_ENABLED: True, - }, - "temperature": { - ATTR_NAME: "Temperature", - ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, - ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS, - ATTR_DEFAULT_ENABLED: True, - }, - "wifiStrength": { - ATTR_NAME: "Wifi Strength", - ATTR_DEVICE_CLASS: DEVICE_CLASS_SIGNAL_STRENGTH, - ATTR_UNIT_OF_MEASUREMENT: SIGNAL_STRENGTH_DECIBELS, - ATTR_DEFAULT_ENABLED: True, - }, - "timestamp": { - ATTR_NAME: "Total Run Time", - ATTR_UNIT_OF_MEASUREMENT: TIME_SECONDS, - ATTR_DEFAULT_ENABLED: False, - }, - "ssid": { - ATTR_NAME: "Wi-Fi SSID", - ATTR_DEFAULT_ENABLED: False, - }, - "ipAddr": { - ATTR_NAME: "IP Address", - ATTR_DEFAULT_ENABLED: False, - }, -} - -SWITCH_DICT = { - "v12PortStatus": "12V Port Status", - "usbPortStatus": "USB Port Status", - "acPortStatus": "AC Port Status", -} diff --git a/homeassistant/components/goalzero/sensor.py b/homeassistant/components/goalzero/sensor.py index dbb85aa2d480059917ae74ec187eeee157e74ff9..8890c7db69c8f30cc7e519785ebe44c6620c70ea 100644 --- a/homeassistant/components/goalzero/sensor.py +++ b/homeassistant/components/goalzero/sensor.py @@ -2,28 +2,137 @@ from __future__ import annotations from homeassistant.components.sensor import ( - ATTR_LAST_RESET, - ATTR_STATE_CLASS, + STATE_CLASS_MEASUREMENT, + STATE_CLASS_TOTAL_INCREASING, SensorEntity, + SensorEntityDescription, ) +from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( - ATTR_DEVICE_CLASS, - ATTR_NAME, - ATTR_UNIT_OF_MEASUREMENT, CONF_NAME, + DEVICE_CLASS_BATTERY, + DEVICE_CLASS_CURRENT, + DEVICE_CLASS_ENERGY, + DEVICE_CLASS_POWER, + DEVICE_CLASS_SIGNAL_STRENGTH, + DEVICE_CLASS_TEMPERATURE, + DEVICE_CLASS_VOLTAGE, + ELECTRIC_CURRENT_AMPERE, + ELECTRIC_POTENTIAL_VOLT, + ENERGY_WATT_HOUR, + PERCENTAGE, + POWER_WATT, + SIGNAL_STRENGTH_DECIBELS, + TEMP_CELSIUS, + TIME_MINUTES, + TIME_SECONDS, ) +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator -from . import YetiEntity -from .const import ( - ATTR_DEFAULT_ENABLED, - DATA_KEY_API, - DATA_KEY_COORDINATOR, - DOMAIN, - SENSOR_DICT, +from . import Yeti, YetiEntity +from .const import DATA_KEY_API, DATA_KEY_COORDINATOR, DOMAIN + +SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( + SensorEntityDescription( + key="wattsIn", + name="Watts In", + device_class=DEVICE_CLASS_POWER, + unit_of_measurement=POWER_WATT, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key="ampsIn", + name="Amps In", + device_class=DEVICE_CLASS_CURRENT, + unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + state_class=STATE_CLASS_MEASUREMENT, + entity_registry_enabled_default=False, + ), + SensorEntityDescription( + key="wattsOut", + name="Watts Out", + device_class=DEVICE_CLASS_POWER, + unit_of_measurement=POWER_WATT, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key="ampsOut", + name="Amps Out", + device_class=DEVICE_CLASS_CURRENT, + unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + state_class=STATE_CLASS_MEASUREMENT, + entity_registry_enabled_default=False, + ), + SensorEntityDescription( + key="whOut", + name="WH Out", + device_class=DEVICE_CLASS_ENERGY, + unit_of_measurement=ENERGY_WATT_HOUR, + state_class=STATE_CLASS_TOTAL_INCREASING, + entity_registry_enabled_default=False, + ), + SensorEntityDescription( + key="whStored", + name="WH Stored", + device_class=DEVICE_CLASS_ENERGY, + unit_of_measurement=ENERGY_WATT_HOUR, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key="volts", + name="Volts", + device_class=DEVICE_CLASS_VOLTAGE, + unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + entity_registry_enabled_default=False, + ), + SensorEntityDescription( + key="socPercent", + name="State of Charge Percent", + device_class=DEVICE_CLASS_BATTERY, + unit_of_measurement=PERCENTAGE, + ), + SensorEntityDescription( + key="timeToEmptyFull", + name="Time to Empty/Full", + device_class=TIME_MINUTES, + unit_of_measurement=TIME_MINUTES, + ), + SensorEntityDescription( + key="temperature", + name="Temperature", + device_class=DEVICE_CLASS_TEMPERATURE, + unit_of_measurement=TEMP_CELSIUS, + ), + SensorEntityDescription( + key="wifiStrength", + name="Wifi Strength", + device_class=DEVICE_CLASS_SIGNAL_STRENGTH, + unit_of_measurement=SIGNAL_STRENGTH_DECIBELS, + ), + SensorEntityDescription( + key="timestamp", + name="Total Run Time", + unit_of_measurement=TIME_SECONDS, + entity_registry_enabled_default=False, + ), + SensorEntityDescription( + key="ssid", + name="Wi-Fi SSID", + entity_registry_enabled_default=False, + ), + SensorEntityDescription( + key="ipAddr", + name="IP Address", + entity_registry_enabled_default=False, + ), ) -async def async_setup_entry(hass, entry, async_add_entities): +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: """Set up the Goal Zero Yeti sensor.""" name = entry.data[CONF_NAME] goalzero_data = hass.data[DOMAIN][entry.entry_id] @@ -32,10 +141,10 @@ async def async_setup_entry(hass, entry, async_add_entities): goalzero_data[DATA_KEY_API], goalzero_data[DATA_KEY_COORDINATOR], name, - sensor_name, + description, entry.entry_id, ) - for sensor_name in SENSOR_DICT + for description in SENSOR_TYPES ] async_add_entities(sensors, True) @@ -43,22 +152,21 @@ async def async_setup_entry(hass, entry, async_add_entities): class YetiSensor(YetiEntity, SensorEntity): """Representation of a Goal Zero Yeti sensor.""" - def __init__(self, api, coordinator, name, sensor_name, server_unique_id): + def __init__( + self, + api: Yeti, + coordinator: DataUpdateCoordinator, + name: str, + description: SensorEntityDescription, + server_unique_id: str, + ) -> None: """Initialize a Goal Zero Yeti sensor.""" super().__init__(api, coordinator, name, server_unique_id) - self._condition = sensor_name - sensor = SENSOR_DICT[sensor_name] - self._attr_device_class = sensor.get(ATTR_DEVICE_CLASS) - self._attr_entity_registry_enabled_default = sensor.get(ATTR_DEFAULT_ENABLED) - self._attr_last_reset = sensor.get(ATTR_LAST_RESET) - self._attr_name = f"{name} {sensor.get(ATTR_NAME)}" - self._attr_native_unit_of_measurement = sensor.get(ATTR_UNIT_OF_MEASUREMENT) - self._attr_state_class = sensor.get(ATTR_STATE_CLASS) - self._attr_unique_id = f"{server_unique_id}/{sensor_name}" + self._attr_name = f"{name} {description.name}" + self.entity_description = description + self._attr_unique_id = f"{server_unique_id}/{description.key}" @property - def native_value(self) -> str | None: + def native_value(self) -> str: """Return the state.""" - if self.api.data: - return self.api.data.get(self._condition) - return None + return self.api.data.get(self.entity_description.key) diff --git a/homeassistant/components/goalzero/switch.py b/homeassistant/components/goalzero/switch.py index 9d37bcb0b7b36caffe923b91f7aa45a6295e4e63..767c728e62b3d2000a12377dc0b7d75e344074df 100644 --- a/homeassistant/components/goalzero/switch.py +++ b/homeassistant/components/goalzero/switch.py @@ -1,14 +1,35 @@ """Support for Goal Zero Yeti Switches.""" from __future__ import annotations -from homeassistant.components.switch import SwitchEntity +from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription +from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_NAME +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator -from . import YetiEntity -from .const import DATA_KEY_API, DATA_KEY_COORDINATOR, DOMAIN, SWITCH_DICT +from . import Yeti, YetiEntity +from .const import DATA_KEY_API, DATA_KEY_COORDINATOR, DOMAIN +SWITCH_TYPES: tuple[SwitchEntityDescription, ...] = ( + SwitchEntityDescription( + key="v12PortStatus", + name="12V Port Status", + ), + SwitchEntityDescription( + key="usbPortStatus", + name="USB Port Status", + ), + SwitchEntityDescription( + key="acPortStatus", + name="AC Port Status", + ), +) -async def async_setup_entry(hass, entry, async_add_entities): + +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: """Set up the Goal Zero Yeti switch.""" name = entry.data[CONF_NAME] goalzero_data = hass.data[DOMAIN][entry.entry_id] @@ -17,10 +38,10 @@ async def async_setup_entry(hass, entry, async_add_entities): goalzero_data[DATA_KEY_API], goalzero_data[DATA_KEY_COORDINATOR], name, - switch_name, + description, entry.entry_id, ) - for switch_name in SWITCH_DICT + for description in SWITCH_TYPES ) @@ -29,33 +50,31 @@ class YetiSwitch(YetiEntity, SwitchEntity): def __init__( self, - api, - coordinator, - name, - switch_name, - server_unique_id, - ): + api: Yeti, + coordinator: DataUpdateCoordinator, + name: str, + description: SwitchEntityDescription, + server_unique_id: str, + ) -> None: """Initialize a Goal Zero Yeti switch.""" super().__init__(api, coordinator, name, server_unique_id) - self._condition = switch_name - self._attr_name = f"{name} {SWITCH_DICT[switch_name]}" - self._attr_unique_id = f"{server_unique_id}/{switch_name}" + self.entity_description = description + self._attr_name = f"{name} {description.name}" + self._attr_unique_id = f"{server_unique_id}/{description.key}" @property def is_on(self) -> bool: """Return state of the switch.""" - if self.api.data: - return self.api.data[self._condition] - return False + return self.api.data.get(self.entity_description.key) - async def async_turn_off(self, **kwargs): + async def async_turn_off(self, **kwargs) -> None: """Turn off the switch.""" - payload = {self._condition: 0} + payload = {self.entity_description.key: 0} await self.api.post_state(payload=payload) self.coordinator.async_set_updated_data(data=payload) - async def async_turn_on(self, **kwargs): + async def async_turn_on(self, **kwargs) -> None: """Turn on the switch.""" - payload = {self._condition: 1} + payload = {self.entity_description.key: 1} await self.api.post_state(payload=payload) self.coordinator.async_set_updated_data(data=payload)