From 80c2efa9f2865982ea223bd488d4e3252bdbfc1d Mon Sep 17 00:00:00 2001 From: Robert Chmielowiec <robert+github@chmielowiec.net> Date: Wed, 27 Jan 2021 14:10:58 +0100 Subject: [PATCH] Add total energy, preheater and RMOT sensors to comfoconnect (#45373) --- .coveragerc | 2 +- .../components/comfoconnect/sensor.py | 48 ++++++++-- requirements_test_all.txt | 3 + tests/components/comfoconnect/__init__.py | 1 + tests/components/comfoconnect/test_sensor.py | 93 +++++++++++++++++++ 5 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 tests/components/comfoconnect/__init__.py create mode 100644 tests/components/comfoconnect/test_sensor.py diff --git a/.coveragerc b/.coveragerc index da6cfd2a3b9..4faf71102f8 100644 --- a/.coveragerc +++ b/.coveragerc @@ -144,7 +144,7 @@ omit = homeassistant/components/co2signal/* homeassistant/components/coinbase/* homeassistant/components/comed_hourly_pricing/sensor.py - homeassistant/components/comfoconnect/* + homeassistant/components/comfoconnect/fan.py homeassistant/components/concord232/alarm_control_panel.py homeassistant/components/concord232/binary_sensor.py homeassistant/components/control4/__init__.py diff --git a/homeassistant/components/comfoconnect/sensor.py b/homeassistant/components/comfoconnect/sensor.py index d1003d59229..53075beecaf 100644 --- a/homeassistant/components/comfoconnect/sensor.py +++ b/homeassistant/components/comfoconnect/sensor.py @@ -3,6 +3,7 @@ import logging from pycomfoconnect import ( SENSOR_BYPASS_STATE, + SENSOR_CURRENT_RMOT, SENSOR_DAYS_TO_REPLACE_FILTER, SENSOR_FAN_EXHAUST_DUTY, SENSOR_FAN_EXHAUST_FLOW, @@ -15,7 +16,9 @@ from pycomfoconnect import ( SENSOR_HUMIDITY_OUTDOOR, SENSOR_HUMIDITY_SUPPLY, SENSOR_POWER_CURRENT, + SENSOR_POWER_TOTAL, SENSOR_PREHEATER_POWER_CURRENT, + SENSOR_PREHEATER_POWER_TOTAL, SENSOR_TEMPERATURE_EXHAUST, SENSOR_TEMPERATURE_EXTRACT, SENSOR_TEMPERATURE_OUTDOOR, @@ -27,9 +30,11 @@ from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( ATTR_DEVICE_CLASS, CONF_RESOURCES, + DEVICE_CLASS_ENERGY, DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_POWER, DEVICE_CLASS_TEMPERATURE, + ENERGY_KILO_WATT_HOUR, PERCENTAGE, POWER_WATT, TEMP_CELSIUS, @@ -46,6 +51,7 @@ ATTR_AIR_FLOW_EXHAUST = "air_flow_exhaust" ATTR_AIR_FLOW_SUPPLY = "air_flow_supply" ATTR_BYPASS_STATE = "bypass_state" ATTR_CURRENT_HUMIDITY = "current_humidity" +ATTR_CURRENT_RMOT = "current_rmot" ATTR_CURRENT_TEMPERATURE = "current_temperature" ATTR_DAYS_TO_REPLACE_FILTER = "days_to_replace_filter" ATTR_EXHAUST_FAN_DUTY = "exhaust_fan_duty" @@ -55,7 +61,9 @@ ATTR_EXHAUST_TEMPERATURE = "exhaust_temperature" ATTR_OUTSIDE_HUMIDITY = "outside_humidity" ATTR_OUTSIDE_TEMPERATURE = "outside_temperature" ATTR_POWER_CURRENT = "power_usage" +ATTR_POWER_TOTAL = "power_total" ATTR_PREHEATER_POWER_CURRENT = "preheater_power_usage" +ATTR_PREHEATER_POWER_TOTAL = "preheater_power_total" ATTR_SUPPLY_FAN_DUTY = "supply_fan_duty" ATTR_SUPPLY_FAN_SPEED = "supply_fan_speed" ATTR_SUPPLY_HUMIDITY = "supply_humidity" @@ -74,7 +82,7 @@ SENSOR_TYPES = { ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, ATTR_LABEL: "Inside Temperature", ATTR_UNIT: TEMP_CELSIUS, - ATTR_ICON: "mdi:thermometer", + ATTR_ICON: None, ATTR_ID: SENSOR_TEMPERATURE_EXTRACT, ATTR_MULTIPLIER: 0.1, }, @@ -82,14 +90,22 @@ SENSOR_TYPES = { ATTR_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY, ATTR_LABEL: "Inside Humidity", ATTR_UNIT: PERCENTAGE, - ATTR_ICON: "mdi:water-percent", + ATTR_ICON: None, ATTR_ID: SENSOR_HUMIDITY_EXTRACT, }, + ATTR_CURRENT_RMOT: { + ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, + ATTR_LABEL: "Current RMOT", + ATTR_UNIT: TEMP_CELSIUS, + ATTR_ICON: None, + ATTR_ID: SENSOR_CURRENT_RMOT, + ATTR_MULTIPLIER: 0.1, + }, ATTR_OUTSIDE_TEMPERATURE: { ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, ATTR_LABEL: "Outside Temperature", ATTR_UNIT: TEMP_CELSIUS, - ATTR_ICON: "mdi:thermometer", + ATTR_ICON: None, ATTR_ID: SENSOR_TEMPERATURE_OUTDOOR, ATTR_MULTIPLIER: 0.1, }, @@ -97,14 +113,14 @@ SENSOR_TYPES = { ATTR_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY, ATTR_LABEL: "Outside Humidity", ATTR_UNIT: PERCENTAGE, - ATTR_ICON: "mdi:water-percent", + ATTR_ICON: None, ATTR_ID: SENSOR_HUMIDITY_OUTDOOR, }, ATTR_SUPPLY_TEMPERATURE: { ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, ATTR_LABEL: "Supply Temperature", ATTR_UNIT: TEMP_CELSIUS, - ATTR_ICON: "mdi:thermometer", + ATTR_ICON: None, ATTR_ID: SENSOR_TEMPERATURE_SUPPLY, ATTR_MULTIPLIER: 0.1, }, @@ -112,7 +128,7 @@ SENSOR_TYPES = { ATTR_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY, ATTR_LABEL: "Supply Humidity", ATTR_UNIT: PERCENTAGE, - ATTR_ICON: "mdi:water-percent", + ATTR_ICON: None, ATTR_ID: SENSOR_HUMIDITY_SUPPLY, }, ATTR_SUPPLY_FAN_SPEED: { @@ -147,7 +163,7 @@ SENSOR_TYPES = { ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, ATTR_LABEL: "Exhaust Temperature", ATTR_UNIT: TEMP_CELSIUS, - ATTR_ICON: "mdi:thermometer", + ATTR_ICON: None, ATTR_ID: SENSOR_TEMPERATURE_EXHAUST, ATTR_MULTIPLIER: 0.1, }, @@ -155,7 +171,7 @@ SENSOR_TYPES = { ATTR_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY, ATTR_LABEL: "Exhaust Humidity", ATTR_UNIT: PERCENTAGE, - ATTR_ICON: "mdi:water-percent", + ATTR_ICON: None, ATTR_ID: SENSOR_HUMIDITY_EXHAUST, }, ATTR_AIR_FLOW_SUPPLY: { @@ -190,9 +206,16 @@ SENSOR_TYPES = { ATTR_DEVICE_CLASS: DEVICE_CLASS_POWER, ATTR_LABEL: "Power usage", ATTR_UNIT: POWER_WATT, - ATTR_ICON: "mdi:flash", + ATTR_ICON: None, ATTR_ID: SENSOR_POWER_CURRENT, }, + ATTR_POWER_TOTAL: { + ATTR_DEVICE_CLASS: DEVICE_CLASS_ENERGY, + ATTR_LABEL: "Power total", + ATTR_UNIT: ENERGY_KILO_WATT_HOUR, + ATTR_ICON: None, + ATTR_ID: SENSOR_POWER_TOTAL, + }, ATTR_PREHEATER_POWER_CURRENT: { ATTR_DEVICE_CLASS: DEVICE_CLASS_POWER, ATTR_LABEL: "Preheater power usage", @@ -200,6 +223,13 @@ SENSOR_TYPES = { ATTR_ICON: None, ATTR_ID: SENSOR_PREHEATER_POWER_CURRENT, }, + ATTR_PREHEATER_POWER_TOTAL: { + ATTR_DEVICE_CLASS: DEVICE_CLASS_ENERGY, + ATTR_LABEL: "Preheater power total", + ATTR_UNIT: ENERGY_KILO_WATT_HOUR, + ATTR_ICON: None, + ATTR_ID: SENSOR_PREHEATER_POWER_TOTAL, + }, } PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( diff --git a/requirements_test_all.txt b/requirements_test_all.txt index b3fef08aa67..ed4f0bdac97 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -672,6 +672,9 @@ pycfdns==1.2.1 # homeassistant.components.cast pychromecast==7.7.2 +# homeassistant.components.comfoconnect +pycomfoconnect==0.4 + # homeassistant.components.coolmaster pycoolmasternet-async==0.1.2 diff --git a/tests/components/comfoconnect/__init__.py b/tests/components/comfoconnect/__init__.py new file mode 100644 index 00000000000..8da47b510be --- /dev/null +++ b/tests/components/comfoconnect/__init__.py @@ -0,0 +1 @@ +"""Tests for the comfoconnect component.""" diff --git a/tests/components/comfoconnect/test_sensor.py b/tests/components/comfoconnect/test_sensor.py new file mode 100644 index 00000000000..3ae078cccef --- /dev/null +++ b/tests/components/comfoconnect/test_sensor.py @@ -0,0 +1,93 @@ +"""Tests for the comfoconnect sensor platform.""" +# import json +from unittest.mock import patch + +import pytest + +from homeassistant.components.sensor import DOMAIN +from homeassistant.setup import async_setup_component + +from tests.common import assert_setup_component + +COMPONENT = "comfoconnect" +VALID_CONFIG = { + COMPONENT: {"host": "1.2.3.4"}, + DOMAIN: { + "platform": COMPONENT, + "resources": [ + "current_humidity", + "current_temperature", + "supply_fan_duty", + "power_usage", + "preheater_power_total", + ], + }, +} + + +@pytest.fixture +def mock_bridge_discover(): + """Mock the bridge discover method.""" + with patch("pycomfoconnect.bridge.Bridge.discover") as mock_bridge_discover: + mock_bridge_discover.return_value[0].uuid.hex.return_value = "00" + yield mock_bridge_discover + + +@pytest.fixture +def mock_comfoconnect_command(): + """Mock the ComfoConnect connect method.""" + with patch( + "pycomfoconnect.comfoconnect.ComfoConnect._command" + ) as mock_comfoconnect_command: + yield mock_comfoconnect_command + + +@pytest.fixture +async def setup_sensor(hass, mock_bridge_discover, mock_comfoconnect_command): + """Set up demo sensor component.""" + with assert_setup_component(1, DOMAIN): + await async_setup_component(hass, DOMAIN, VALID_CONFIG) + await hass.async_block_till_done() + + +async def test_sensors(hass, setup_sensor): + """Test the sensors.""" + state = hass.states.get("sensor.comfoairq_inside_humidity") + assert state is not None + + assert state.name == "ComfoAirQ Inside Humidity" + assert state.attributes.get("unit_of_measurement") == "%" + assert state.attributes.get("device_class") == "humidity" + assert state.attributes.get("icon") is None + + state = hass.states.get("sensor.comfoairq_inside_temperature") + assert state is not None + + assert state.name == "ComfoAirQ Inside Temperature" + assert state.attributes.get("unit_of_measurement") == "°C" + assert state.attributes.get("device_class") == "temperature" + assert state.attributes.get("icon") is None + + state = hass.states.get("sensor.comfoairq_supply_fan_duty") + assert state is not None + + assert state.name == "ComfoAirQ Supply Fan Duty" + assert state.attributes.get("unit_of_measurement") == "%" + assert state.attributes.get("device_class") is None + assert state.attributes.get("icon") == "mdi:fan" + + state = hass.states.get("sensor.comfoairq_power_usage") + assert state is not None + + assert state.name == "ComfoAirQ Power usage" + assert state.attributes.get("unit_of_measurement") == "W" + assert state.attributes.get("device_class") == "power" + assert state.attributes.get("icon") is None + + state = hass.states.get("sensor.comfoairq_preheater_power_total") + assert state is not None + + assert state.name == "ComfoAirQ Preheater power total" + assert state.attributes.get("unit_of_measurement") == "kWh" + assert state.attributes.get("device_class") == "energy" + assert state.attributes.get("icon") is None -- GitLab