Add support for a dedicated weather station within KNX (#39476)

* Adds support for a dedicated weather station within KNX

* Review

* Change config values to comply with the naming of the other platforms
This commit is contained in:
Marvin Wichmann 2020-08-31 11:38:52 +02:00 committed by GitHub
parent 190611a079
commit bba8b8e759
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 146 additions and 0 deletions

View file

@ -37,6 +37,7 @@ from .schema import (
SceneSchema,
SensorSchema,
SwitchSchema,
WeatherSchema,
)
_LOGGER = logging.getLogger(__name__)
@ -102,6 +103,9 @@ CONFIG_SCHEMA = vol.Schema(
vol.Optional(SupportedPlatforms.scene.value): vol.All(
cv.ensure_list, [SceneSchema.SCHEMA]
),
vol.Optional(SupportedPlatforms.weather.value): vol.All(
cv.ensure_list, [WeatherSchema.SCHEMA]
),
}
)
},

View file

@ -39,6 +39,7 @@ class SupportedPlatforms(Enum):
notify = "notify"
scene = "scene"
sensor = "sensor"
weather = "weather"
# Map KNX operation modes to HA modes. This list might not be complete.

View file

@ -12,6 +12,7 @@ from xknx.devices import (
Scene as XknxScene,
Sensor as XknxSensor,
Switch as XknxSwitch,
Weather as XknxWeather,
)
from homeassistant.const import CONF_ADDRESS, CONF_DEVICE_CLASS, CONF_NAME, CONF_TYPE
@ -28,6 +29,7 @@ from .schema import (
SceneSchema,
SensorSchema,
SwitchSchema,
WeatherSchema,
)
@ -62,6 +64,9 @@ def create_knx_device(
if platform is SupportedPlatforms.binary_sensor:
return _create_binary_sensor(hass, knx_module, config)
if platform is SupportedPlatforms.weather:
return _create_weather(knx_module, config)
def _create_cover(knx_module: XKNX, config: ConfigType) -> XknxCover:
"""Return a KNX Cover device to be used within XKNX."""
@ -263,3 +268,34 @@ def _create_binary_sensor(
reset_after=config.get(BinarySensorSchema.CONF_RESET_AFTER),
actions=actions,
)
def _create_weather(knx_module: XKNX, config: ConfigType) -> XknxWeather:
"""Return a KNX weather device to be used within XKNX."""
return XknxWeather(
knx_module,
name=config[CONF_NAME],
sync_state=config[WeatherSchema.CONF_SYNC_STATE],
expose_sensors=config[WeatherSchema.CONF_KNX_EXPOSE_SENSORS],
group_address_temperature=config[WeatherSchema.CONF_KNX_TEMPERATURE_ADDRESS],
group_address_brightness_south=config.get(
WeatherSchema.CONF_KNX_BRIGHTNESS_SOUTH_ADDRESS
),
group_address_brightness_east=config.get(
WeatherSchema.CONF_KNX_BRIGHTNESS_EAST_ADDRESS
),
group_address_brightness_west=config.get(
WeatherSchema.CONF_KNX_BRIGHTNESS_WEST_ADDRESS
),
group_address_wind_speed=config.get(WeatherSchema.CONF_KNX_WIND_SPEED_ADDRESS),
group_address_rain_alarm=config.get(WeatherSchema.CONF_KNX_RAIN_ALARM_ADDRESS),
group_address_frost_alarm=config.get(
WeatherSchema.CONF_KNX_FROST_ALARM_ADDRESS
),
group_address_wind_alarm=config.get(WeatherSchema.CONF_KNX_WIND_ALARM_ADDRESS),
group_address_day_night=config.get(WeatherSchema.CONF_KNX_DAY_NIGHT_ADDRESS),
group_address_air_pressure=config.get(
WeatherSchema.CONF_KNX_AIR_PRESSURE_ADDRESS
),
group_address_humidity=config.get(WeatherSchema.CONF_KNX_HUMIDITY_ADDRESS),
)

View file

@ -340,3 +340,46 @@ class SceneSchema:
vol.Required(CONF_SCENE_NUMBER): cv.positive_int,
}
)
class WeatherSchema:
"""Voluptuous schema for KNX weather station."""
CONF_SYNC_STATE = CONF_SYNC_STATE
CONF_KNX_TEMPERATURE_ADDRESS = "address_temperature"
CONF_KNX_BRIGHTNESS_SOUTH_ADDRESS = "address_brightness_south"
CONF_KNX_BRIGHTNESS_EAST_ADDRESS = "address_brightness_east"
CONF_KNX_BRIGHTNESS_WEST_ADDRESS = "address_brightness_west"
CONF_KNX_WIND_SPEED_ADDRESS = "address_wind_speed"
CONF_KNX_RAIN_ALARM_ADDRESS = "address_rain_alarm"
CONF_KNX_FROST_ALARM_ADDRESS = "address_frost_alarm"
CONF_KNX_WIND_ALARM_ADDRESS = "address_wind_alarm"
CONF_KNX_DAY_NIGHT_ADDRESS = "address_day_night"
CONF_KNX_AIR_PRESSURE_ADDRESS = "address_air_pressure"
CONF_KNX_HUMIDITY_ADDRESS = "address_humidity"
CONF_KNX_EXPOSE_SENSORS = "expose_sensors"
DEFAULT_NAME = "KNX Weather Station"
SCHEMA = vol.Schema(
{
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_SYNC_STATE, default=True): vol.Any(
vol.All(vol.Coerce(int), vol.Range(min=2, max=1440)),
cv.boolean,
cv.string,
),
vol.Optional(CONF_KNX_EXPOSE_SENSORS, default=False): cv.boolean,
vol.Required(CONF_KNX_TEMPERATURE_ADDRESS): cv.string,
vol.Optional(CONF_KNX_BRIGHTNESS_SOUTH_ADDRESS): cv.string,
vol.Optional(CONF_KNX_BRIGHTNESS_EAST_ADDRESS): cv.string,
vol.Optional(CONF_KNX_BRIGHTNESS_WEST_ADDRESS): cv.string,
vol.Optional(CONF_KNX_WIND_SPEED_ADDRESS): cv.string,
vol.Optional(CONF_KNX_RAIN_ALARM_ADDRESS): cv.string,
vol.Optional(CONF_KNX_FROST_ALARM_ADDRESS): cv.string,
vol.Optional(CONF_KNX_WIND_ALARM_ADDRESS): cv.string,
vol.Optional(CONF_KNX_DAY_NIGHT_ADDRESS): cv.string,
vol.Optional(CONF_KNX_AIR_PRESSURE_ADDRESS): cv.string,
vol.Optional(CONF_KNX_HUMIDITY_ADDRESS): cv.string,
}
)

View file

@ -0,0 +1,62 @@
"""Support for KNX/IP weather station."""
from xknx.devices import Weather as XknxWeather
from homeassistant.components.weather import WeatherEntity
from homeassistant.const import TEMP_CELSIUS
from .const import DATA_KNX
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the scenes for KNX platform."""
entities = []
for device in hass.data[DATA_KNX].xknx.devices:
if isinstance(device, XknxWeather):
entities.append(KNXWeather(device))
async_add_entities(entities)
class KNXWeather(WeatherEntity):
"""Representation of a KNX weather device."""
def __init__(self, device: XknxWeather):
"""Initialize of a KNX sensor."""
self.device = device
@property
def temperature(self):
"""Return current temperature."""
return self.device.temperature
@property
def temperature_unit(self):
"""Return temperature unit."""
return TEMP_CELSIUS
@property
def pressure(self):
"""Return current air pressure."""
# KNX returns pA - HA requires hPa
return (
self.device.air_pressure / 100
if self.device.air_pressure is not None
else None
)
@property
def condition(self):
"""Return current weather condition."""
return self.device.ha_current_state().value
@property
def humidity(self):
"""Return current humidity."""
return self.device.humidity if self.device.humidity is not None else None
@property
def wind_speed(self):
"""Return current wind speed in km/h."""
# KNX only supports wind speed in m/s
return (
self.device.wind_speed * 3.6 if self.device.wind_speed is not None else None
)