From 65f2fe9c011af7657591c432b073eef54e0c28cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Klomp?= Date: Thu, 27 May 2021 12:53:14 +0200 Subject: [PATCH] Bump pysma version to 0.5.0 (#51098) * Use new get_sensors method * Update pysma requirement * Update primary codeowner * Update device_info handling * Fix LEGACY_MAP * Updated tests * Fix pysma references * Fix pylint raise-missing-from * Better import of Sensors * Remove software version related changes * Revert codeowners change --- homeassistant/components/sma/__init__.py | 35 ++++++++++++---------- homeassistant/components/sma/manifest.json | 2 +- homeassistant/components/sma/sensor.py | 6 ++-- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/sma/conftest.py | 7 ++++- tests/components/sma/test_sensor.py | 2 +- 7 files changed, 33 insertions(+), 23 deletions(-) diff --git a/homeassistant/components/sma/__init__.py b/homeassistant/components/sma/__init__.py index ef948440a17..d8fcbbf8099 100644 --- a/homeassistant/components/sma/__init__.py +++ b/homeassistant/components/sma/__init__.py @@ -40,7 +40,9 @@ from .const import ( _LOGGER = logging.getLogger(__name__) -def _parse_legacy_options(entry: ConfigEntry, sensor_def: pysma.Sensors) -> list[str]: +def _parse_legacy_options( + entry: ConfigEntry, sensor_def: pysma.sensor.Sensors +) -> list[str]: """Parse legacy configuration options. This will parse the legacy CONF_SENSORS and CONF_CUSTOM configuration options @@ -50,7 +52,9 @@ def _parse_legacy_options(entry: ConfigEntry, sensor_def: pysma.Sensors) -> list # Add sensors from the custom config sensor_def.add( [ - pysma.Sensor(o[CONF_KEY], n, o[CONF_UNIT], o[CONF_FACTOR], o.get(CONF_PATH)) + pysma.sensor.Sensor( + o[CONF_KEY], n, o[CONF_UNIT], o[CONF_FACTOR], o.get(CONF_PATH) + ) for n, o in entry.data.get(CONF_CUSTOM).items() ] ) @@ -74,9 +78,9 @@ def _parse_legacy_options(entry: ConfigEntry, sensor_def: pysma.Sensors) -> list # Find and replace sensors removed from pysma # This only alters the config, the actual sensor migration takes place in _migrate_old_unique_ids for sensor in config_sensors.copy(): - if sensor in pysma.LEGACY_MAP: + if sensor in pysma.const.LEGACY_MAP: config_sensors.remove(sensor) - config_sensors.append(pysma.LEGACY_MAP[sensor]["new_sensor"]) + config_sensors.append(pysma.const.LEGACY_MAP[sensor]["new_sensor"]) # Only sensors from config should be enabled for sensor in sensor_def: @@ -88,7 +92,7 @@ def _parse_legacy_options(entry: ConfigEntry, sensor_def: pysma.Sensors) -> list def _migrate_old_unique_ids( hass: HomeAssistant, entry: ConfigEntry, - sensor_def: pysma.Sensors, + sensor_def: pysma.sensor.Sensors, config_sensors: list[str], ) -> None: """Migrate legacy sensor entity_id format to new format.""" @@ -96,16 +100,16 @@ def _migrate_old_unique_ids( # Create list of all possible sensor names possible_sensors = set( - config_sensors + [s.name for s in sensor_def] + list(pysma.LEGACY_MAP) + config_sensors + [s.name for s in sensor_def] + list(pysma.const.LEGACY_MAP) ) for sensor in possible_sensors: if sensor in sensor_def: pysma_sensor = sensor_def[sensor] original_key = pysma_sensor.key - elif sensor in pysma.LEGACY_MAP: + elif sensor in pysma.const.LEGACY_MAP: # If sensor was removed from pysma we will remap it to the new sensor - legacy_sensor = pysma.LEGACY_MAP[sensor] + legacy_sensor = pysma.const.LEGACY_MAP[sensor] pysma_sensor = sensor_def[legacy_sensor["new_sensor"]] original_key = legacy_sensor["old_key"] else: @@ -127,13 +131,6 @@ def _migrate_old_unique_ids( async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up sma from a config entry.""" - # Init all default sensors - sensor_def = pysma.Sensors() - - if entry.source == SOURCE_IMPORT: - config_sensors = _parse_legacy_options(entry, sensor_def) - _migrate_old_unique_ids(hass, entry, sensor_def, config_sensors) - # Init the SMA interface protocol = "https" if entry.data[CONF_SSL] else "http" url = f"{protocol}://{entry.data[CONF_HOST]}" @@ -144,6 +141,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: session = async_get_clientsession(hass, verify_ssl=verify_ssl) sma = pysma.SMA(session, url, password, group) + # Get all device sensors + sensor_def = await sma.get_sensors() + + # Parse legacy options if initial setup was done from yaml + if entry.source == SOURCE_IMPORT: + config_sensors = _parse_legacy_options(entry, sensor_def) + _migrate_old_unique_ids(hass, entry, sensor_def, config_sensors) + # Define the coordinator async def async_update_data(): """Update the used SMA sensors.""" diff --git a/homeassistant/components/sma/manifest.json b/homeassistant/components/sma/manifest.json index 8add6f830e8..66b845ac39f 100644 --- a/homeassistant/components/sma/manifest.json +++ b/homeassistant/components/sma/manifest.json @@ -3,7 +3,7 @@ "name": "SMA Solar", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/sma", - "requirements": ["pysma==0.4.3"], + "requirements": ["pysma==0.5.0"], "codeowners": ["@kellerza", "@rklomp"], "iot_class": "local_polling" } diff --git a/homeassistant/components/sma/sensor.py b/homeassistant/components/sma/sensor.py index 04bfb7644a3..2ef999a6579 100644 --- a/homeassistant/components/sma/sensor.py +++ b/homeassistant/components/sma/sensor.py @@ -46,8 +46,8 @@ _LOGGER = logging.getLogger(__name__) def _check_sensor_schema(conf: dict[str, Any]) -> dict[str, Any]: """Check sensors and attributes are valid.""" try: - valid = [s.name for s in pysma.Sensors()] - valid += pysma.LEGACY_MAP.keys() + valid = [s.name for s in pysma.sensor.Sensors()] + valid += pysma.const.LEGACY_MAP.keys() except (ImportError, AttributeError): return conf @@ -147,7 +147,7 @@ class SMAsensor(CoordinatorEntity, SensorEntity): coordinator: DataUpdateCoordinator, config_entry_unique_id: str, device_info: dict[str, Any], - pysma_sensor: pysma.Sensor, + pysma_sensor: pysma.sensor.Sensor, ) -> None: """Initialize the sensor.""" super().__init__(coordinator) diff --git a/requirements_all.txt b/requirements_all.txt index 29a490cfc43..989829b0e61 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1732,7 +1732,7 @@ pysignalclirestapi==0.3.4 pyskyqhub==0.1.3 # homeassistant.components.sma -pysma==0.4.3 +pysma==0.5.0 # homeassistant.components.smappee pysmappee==0.2.25 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 1caa6ba7b8e..551de00ccc3 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -968,7 +968,7 @@ pysiaalarm==3.0.0 pysignalclirestapi==0.3.4 # homeassistant.components.sma -pysma==0.4.3 +pysma==0.5.0 # homeassistant.components.smappee pysmappee==0.2.25 diff --git a/tests/components/sma/conftest.py b/tests/components/sma/conftest.py index 9ec9e1f5a11..80d9b38e28b 100644 --- a/tests/components/sma/conftest.py +++ b/tests/components/sma/conftest.py @@ -1,6 +1,9 @@ """Fixtures for sma tests.""" from unittest.mock import patch +from pysma.const import DEVCLASS_INVERTER +from pysma.definitions import sensor_map +from pysma.sensor import Sensors import pytest from homeassistant import config_entries @@ -28,7 +31,9 @@ async def init_integration(hass, mock_config_entry): """Create a fake SMA Config Entry.""" mock_config_entry.add_to_hass(hass) - with patch("pysma.SMA.read"): + with patch("pysma.SMA.read"), patch( + "pysma.SMA.get_sensors", return_value=Sensors(sensor_map[DEVCLASS_INVERTER]) + ): await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() return mock_config_entry diff --git a/tests/components/sma/test_sensor.py b/tests/components/sma/test_sensor.py index b86533a11df..129af154924 100644 --- a/tests/components/sma/test_sensor.py +++ b/tests/components/sma/test_sensor.py @@ -10,7 +10,7 @@ from . import MOCK_CUSTOM_SENSOR async def test_sensors(hass, init_integration): """Test states of the sensors.""" - state = hass.states.get("sensor.current_consumption") + state = hass.states.get("sensor.grid_power") assert state assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == POWER_WATT