Add Somfy battery sensor (#44311)

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Thibaut 2020-12-17 16:46:22 +01:00 committed by GitHub
parent 94e1f8e631
commit 524db33f13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 39 deletions

View File

@ -47,7 +47,7 @@ CONFIG_SCHEMA = vol.Schema(
extra=vol.ALLOW_EXTRA, extra=vol.ALLOW_EXTRA,
) )
SOMFY_COMPONENTS = ["cover", "switch", "climate"] SOMFY_COMPONENTS = ["climate", "cover", "sensor", "switch"]
async def async_setup(hass, config): async def async_setup(hass, config):

View File

@ -1,7 +1,6 @@
"""Support for Somfy Thermostat.""" """Support for Somfy Thermostat."""
import logging from typing import List, Optional
from typing import Any, Dict, List, Optional
from pymfy.api.devices.category import Category from pymfy.api.devices.category import Category
from pymfy.api.devices.thermostat import ( from pymfy.api.devices.thermostat import (
@ -14,9 +13,6 @@ from pymfy.api.devices.thermostat import (
from homeassistant.components.climate import ClimateEntity from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import ( from homeassistant.components.climate.const import (
CURRENT_HVAC_COOL,
CURRENT_HVAC_HEAT,
CURRENT_HVAC_IDLE,
HVAC_MODE_AUTO, HVAC_MODE_AUTO,
HVAC_MODE_COOL, HVAC_MODE_COOL,
HVAC_MODE_HEAT, HVAC_MODE_HEAT,
@ -26,13 +22,11 @@ from homeassistant.components.climate.const import (
SUPPORT_PRESET_MODE, SUPPORT_PRESET_MODE,
SUPPORT_TARGET_TEMPERATURE, SUPPORT_TARGET_TEMPERATURE,
) )
from homeassistant.const import ATTR_BATTERY_LEVEL, ATTR_TEMPERATURE, TEMP_CELSIUS from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
from . import SomfyEntity from . import SomfyEntity
from .const import API, COORDINATOR, DOMAIN from .const import API, COORDINATOR, DOMAIN
_LOGGER = logging.getLogger(__name__)
SUPPORTED_CATEGORIES = {Category.HVAC.value} SUPPORTED_CATEGORIES = {Category.HVAC.value}
PRESET_FROST_GUARD = "Frost Guard" PRESET_FROST_GUARD = "Frost Guard"
@ -88,11 +82,6 @@ class SomfyClimate(SomfyEntity, ClimateEntity):
"""Return the list of supported features.""" """Return the list of supported features."""
return SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE return SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE
@property
def device_state_attributes(self) -> Dict[str, Any]:
"""Return the state attributes of the device."""
return {ATTR_BATTERY_LEVEL: self._climate.get_battery()}
@property @property
def temperature_unit(self): def temperature_unit(self):
"""Return the unit of measurement used by the platform.""" """Return the unit of measurement used by the platform."""
@ -145,13 +134,11 @@ class SomfyClimate(SomfyEntity, ClimateEntity):
HEAT and COOL mode are exclusive. End user has to enable a mode manually within the Somfy application. HEAT and COOL mode are exclusive. End user has to enable a mode manually within the Somfy application.
So only one mode can be displayed. Auto mode is a scheduler. So only one mode can be displayed. Auto mode is a scheduler.
""" """
hvac_state = HVAC_MODES_MAPPING.get(self._climate.get_hvac_state()) hvac_state = HVAC_MODES_MAPPING[self._climate.get_hvac_state()]
return [HVAC_MODE_AUTO, hvac_state] return [HVAC_MODE_AUTO, hvac_state]
def set_hvac_mode(self, hvac_mode: str) -> None: def set_hvac_mode(self, hvac_mode: str) -> None:
"""Set new target hvac mode.""" """Set new target hvac mode."""
if hvac_mode == self.hvac_mode:
return
if hvac_mode == HVAC_MODE_AUTO: if hvac_mode == HVAC_MODE_AUTO:
self._climate.cancel_target() self._climate.cancel_target()
else: else:
@ -159,26 +146,6 @@ class SomfyClimate(SomfyEntity, ClimateEntity):
TargetMode.MANUAL, self.target_temperature, DurationType.FURTHER_NOTICE TargetMode.MANUAL, self.target_temperature, DurationType.FURTHER_NOTICE
) )
@property
def hvac_action(self) -> str:
"""Return the current running hvac operation if supported."""
if not self.current_temperature or not self.target_temperature:
return CURRENT_HVAC_IDLE
if (
self.hvac_mode == HVAC_MODE_HEAT
and self.current_temperature < self.target_temperature
):
return CURRENT_HVAC_HEAT
if (
self.hvac_mode == HVAC_MODE_COOL
and self.current_temperature > self.target_temperature
):
return CURRENT_HVAC_COOL
return CURRENT_HVAC_IDLE
@property @property
def preset_mode(self) -> Optional[str]: def preset_mode(self) -> Optional[str]:
"""Return the current preset mode.""" """Return the current preset mode."""
@ -206,8 +173,7 @@ class SomfyClimate(SomfyEntity, ClimateEntity):
elif preset_mode in [PRESET_MANUAL, PRESET_GEOFENCING]: elif preset_mode in [PRESET_MANUAL, PRESET_GEOFENCING]:
temperature = self.target_temperature temperature = self.target_temperature
else: else:
_LOGGER.error("Preset mode not supported: %s", preset_mode) raise ValueError(f"Preset mode not supported: {preset_mode}")
return
self._climate.set_target( self._climate.set_target(
REVERSE_PRESET_MAPPING[preset_mode], temperature, DurationType.NEXT_MODE REVERSE_PRESET_MAPPING[preset_mode], temperature, DurationType.NEXT_MODE

View File

@ -0,0 +1,58 @@
"""Support for Somfy Thermostat Battery."""
from pymfy.api.devices.category import Category
from pymfy.api.devices.thermostat import Thermostat
from homeassistant.const import DEVICE_CLASS_BATTERY, PERCENTAGE
from . import SomfyEntity
from .const import API, COORDINATOR, DOMAIN
SUPPORTED_CATEGORIES = {Category.HVAC.value}
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up the Somfy climate platform."""
def get_thermostats():
"""Retrieve thermostats."""
domain_data = hass.data[DOMAIN]
coordinator = domain_data[COORDINATOR]
api = domain_data[API]
return [
SomfyThermostatBatterySensor(coordinator, device_id, api)
for device_id, device in coordinator.data.items()
if SUPPORTED_CATEGORIES & set(device.categories)
]
async_add_entities(await hass.async_add_executor_job(get_thermostats))
class SomfyThermostatBatterySensor(SomfyEntity):
"""Representation of a Somfy thermostat battery."""
def __init__(self, coordinator, device_id, api):
"""Initialize the Somfy device."""
super().__init__(coordinator, device_id, api)
self._climate = None
self._create_device()
def _create_device(self):
"""Update the device with the latest data."""
self._climate = Thermostat(self.device, self.api)
@property
def state(self) -> int:
"""Return the state of the sensor."""
return self._climate.get_battery()
@property
def device_class(self) -> str:
"""Return the device class of the sensor."""
return DEVICE_CLASS_BATTERY
@property
def unit_of_measurement(self) -> str:
"""Return the unit of measurement of the sensor."""
return PERCENTAGE