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:
parent
190611a079
commit
bba8b8e759
5 changed files with 146 additions and 0 deletions
|
@ -37,6 +37,7 @@ from .schema import (
|
||||||
SceneSchema,
|
SceneSchema,
|
||||||
SensorSchema,
|
SensorSchema,
|
||||||
SwitchSchema,
|
SwitchSchema,
|
||||||
|
WeatherSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -102,6 +103,9 @@ CONFIG_SCHEMA = vol.Schema(
|
||||||
vol.Optional(SupportedPlatforms.scene.value): vol.All(
|
vol.Optional(SupportedPlatforms.scene.value): vol.All(
|
||||||
cv.ensure_list, [SceneSchema.SCHEMA]
|
cv.ensure_list, [SceneSchema.SCHEMA]
|
||||||
),
|
),
|
||||||
|
vol.Optional(SupportedPlatforms.weather.value): vol.All(
|
||||||
|
cv.ensure_list, [WeatherSchema.SCHEMA]
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -39,6 +39,7 @@ class SupportedPlatforms(Enum):
|
||||||
notify = "notify"
|
notify = "notify"
|
||||||
scene = "scene"
|
scene = "scene"
|
||||||
sensor = "sensor"
|
sensor = "sensor"
|
||||||
|
weather = "weather"
|
||||||
|
|
||||||
|
|
||||||
# Map KNX operation modes to HA modes. This list might not be complete.
|
# Map KNX operation modes to HA modes. This list might not be complete.
|
||||||
|
|
|
@ -12,6 +12,7 @@ from xknx.devices import (
|
||||||
Scene as XknxScene,
|
Scene as XknxScene,
|
||||||
Sensor as XknxSensor,
|
Sensor as XknxSensor,
|
||||||
Switch as XknxSwitch,
|
Switch as XknxSwitch,
|
||||||
|
Weather as XknxWeather,
|
||||||
)
|
)
|
||||||
|
|
||||||
from homeassistant.const import CONF_ADDRESS, CONF_DEVICE_CLASS, CONF_NAME, CONF_TYPE
|
from homeassistant.const import CONF_ADDRESS, CONF_DEVICE_CLASS, CONF_NAME, CONF_TYPE
|
||||||
|
@ -28,6 +29,7 @@ from .schema import (
|
||||||
SceneSchema,
|
SceneSchema,
|
||||||
SensorSchema,
|
SensorSchema,
|
||||||
SwitchSchema,
|
SwitchSchema,
|
||||||
|
WeatherSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,6 +64,9 @@ def create_knx_device(
|
||||||
if platform is SupportedPlatforms.binary_sensor:
|
if platform is SupportedPlatforms.binary_sensor:
|
||||||
return _create_binary_sensor(hass, knx_module, config)
|
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:
|
def _create_cover(knx_module: XKNX, config: ConfigType) -> XknxCover:
|
||||||
"""Return a KNX Cover device to be used within XKNX."""
|
"""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),
|
reset_after=config.get(BinarySensorSchema.CONF_RESET_AFTER),
|
||||||
actions=actions,
|
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),
|
||||||
|
)
|
||||||
|
|
|
@ -340,3 +340,46 @@ class SceneSchema:
|
||||||
vol.Required(CONF_SCENE_NUMBER): cv.positive_int,
|
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,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
62
homeassistant/components/knx/weather.py
Normal file
62
homeassistant/components/knx/weather.py
Normal 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
|
||||||
|
)
|
Loading…
Add table
Add a link
Reference in a new issue