Skip to content

Commit

Permalink
Merge branch 'master' of github.com:eifinger/homeassistant-config
Browse files Browse the repository at this point in the history
  • Loading branch information
eifinger committed Mar 14, 2021
2 parents 19ac932 + b34eb05 commit 34371a6
Show file tree
Hide file tree
Showing 35 changed files with 499 additions and 159 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/homeassistant-installed.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ jobs:
- name: Create secrets.yaml
run: mv travis_secrets.yaml secrets.yaml
- name: Home Assistant Check Installed
uses: "docker://homeassistant/home-assistant:2021.2.3"
uses: "docker://homeassistant/home-assistant:2021.3.3"
with:
args: python -m homeassistant --config . --script check_config --info all
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ version: '2.1'
services:
homeassistant:
container_name: homeassistant
image: homeassistant/home-assistant:2021.2.3
image: homeassistant/home-assistant:2021.3.3
volumes:
- /home/admin/homeassistant:/config
- /etc/localtime:/etc/localtime:ro
Expand Down
11 changes: 10 additions & 1 deletion custom_components/alexa_media/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,15 @@ async def update_last_called(login_obj, last_called=None, force=False):
to notify listeners.
"""
if not last_called or not (last_called and last_called.get("summary")):
last_called = await AlexaAPI.get_last_device_serial(login_obj)
try:
last_called = await AlexaAPI.get_last_device_serial(login_obj)
except TypeError:
_LOGGER.debug(
"%s: Error updating last_called: %s",
hide_email(email),
hide_serial(last_called),
)
return
_LOGGER.debug(
"%s: Updated last_called: %s", hide_email(email), hide_serial(last_called)
)
Expand Down Expand Up @@ -859,6 +867,7 @@ async def ws_handler(message_obj):
)
elif command in [
"PUSH_DELETE_DOPPLER_ACTIVITIES", # delete Alexa history
"PUSH_LIST_CHANGE", # clear a shopping list https://github.com/custom-components/alexa_media_player/issues/1190
"PUSH_LIST_ITEM_CHANGE", # update shopping list
"PUSH_CONTENT_FOCUS_CHANGE", # likely prime related refocus
"PUSH_DEVICE_SETUP_STATE_CHANGE", # likely device changes mid setup
Expand Down
2 changes: 1 addition & 1 deletion custom_components/alexa_media/alexa_media.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Alexa Devices Base Class.
# SPDX-License-Identifier: Apache-2.0
SPDX-License-Identifier: Apache-2.0
For more details about this platform, please refer to the documentation at
https://community.home-assistant.io/t/echo-devices-alexa-as-media-player-testers-needed/58639
Expand Down
2 changes: 1 addition & 1 deletion custom_components/alexa_media/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"""
from datetime import timedelta

__version__ = "3.8.1"
__version__ = "3.8.3"
PROJECT_URL = "https://github.com/custom-components/alexa_media_player/"
ISSUE_URL = f"{PROJECT_URL}issues"

Expand Down
4 changes: 2 additions & 2 deletions custom_components/alexa_media/manifest.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"domain": "alexa_media",
"name": "Alexa Media Player",
"version": "3.8.1",
"version": "3.8.3",
"config_flow": true,
"documentation": "https://github.com/custom-components/alexa_media_player/wiki",
"issue_tracker": "https://github.com/custom-components/alexa_media_player/issues",
"dependencies": ["persistent_notification", "http"],
"codeowners": ["@keatontaylor", "@alandtse"],
"requirements": ["alexapy==1.24.1", "packaging~=20.3", "wrapt~=1.12.1"]
"requirements": ["alexapy==1.24.3", "packaging~=20.3", "wrapt~=1.12.1"]
}
20 changes: 19 additions & 1 deletion custom_components/dwd_weather/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .connector import DWDWeatherData
from .const import (
CONF_STATION_ID,
CONF_WEATHER_INTERVAL,
DEFAULT_SCAN_INTERVAL,
DOMAIN,
DWDWEATHER_COORDINATOR,
Expand All @@ -36,9 +37,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
latitude = entry.data[CONF_LATITUDE]
longitude = entry.data[CONF_LONGITUDE]
site_name = entry.data[CONF_NAME]
time_window = entry.data[CONF_WEATHER_INTERVAL]
station_id = entry.data[CONF_STATION_ID]

dwd_weather_data = DWDWeatherData(hass, latitude, longitude, station_id)
dwd_weather_data = DWDWeatherData(
hass, latitude, longitude, station_id, time_window
)

# Update data initially
# await dwd_weather_data.async_update()
Expand Down Expand Up @@ -75,6 +79,20 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
return True


async def async_migrate_entry(hass, config_entry: ConfigEntry):
"""Migrate old entry."""
_LOGGER.debug("Migrating from version %s", config_entry.version)

if config_entry.version == 1:
new = {**config_entry.data}
new[CONF_WEATHER_INTERVAL] = 24
config_entry.data = {**new}
config_entry.version = 2

_LOGGER.info("Migration to version %s successful", config_entry.version)
return True


async def async_update(self):
"""Async wrapper for update method."""
return await self._hass.async_add_executor_job(self._update)
Expand Down
35 changes: 30 additions & 5 deletions custom_components/dwd_weather/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
from homeassistant.helpers import config_validation as cv

from .connector import DWDWeatherData
from .const import CONF_STATION_ID, DOMAIN
from .const import (
CONF_STATION_ID,
DOMAIN,
CONF_WEATHER_INTERVAL,
)

_LOGGER = logging.getLogger(__name__)

Expand All @@ -20,14 +24,21 @@ async def validate_input(hass: core.HomeAssistant, data):
"""
latitude = data[CONF_LATITUDE]
longitude = data[CONF_LONGITUDE]
weather_interval = data[CONF_WEATHER_INTERVAL]
station_id = data[CONF_STATION_ID]
_LOGGER.debug(
"validate_input:: CONF_LATITUDE: {}, CONF_LONGITUDE: {}, CONF_STATION_ID: {}".format(
latitude, longitude, station_id
"validate_input:: CONF_LATITUDE: {}, CONF_LONGITUDE: {}, CONF_WEATHER_INTERVAL: {}, CONF_STATION_ID: {}".format(
latitude, longitude, weather_interval, station_id
)
)
if weather_interval > 24:
raise WeatherIntervalTooBig()
if 24 % weather_interval != 0:
raise WeatherIntervalRemainderNotZero()

dwd_weather_data = DWDWeatherData(hass, latitude, longitude, station_id)
dwd_weather_data = DWDWeatherData(
hass, latitude, longitude, station_id, weather_interval
)
_LOGGER.debug(
"Initialized new DWDWeatherData with id: {}".format(dwd_weather_data.station_id)
)
Expand All @@ -41,7 +52,7 @@ async def validate_input(hass: core.HomeAssistant, data):
class DWDWeatherConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for DWD weather integration."""

VERSION = 1
VERSION = 2
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL

async def async_step_user(self, user_input=None):
Expand All @@ -55,6 +66,11 @@ async def async_step_user(self, user_input=None):
errors["base"] = "cannot_connect"
except ValueError:
errors["base"] = "invalid_station_id"
except WeatherIntervalTooBig:
errors["base"] = "weather_interval_too_big"
except WeatherIntervalRemainderNotZero:
errors["base"] = "weather_interval_remainder_not_zero"

except Exception: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
Expand All @@ -74,6 +90,7 @@ async def async_step_user(self, user_input=None):
vol.Required(
CONF_LONGITUDE, default=self.hass.config.longitude
): cv.longitude,
vol.Required(CONF_WEATHER_INTERVAL, default=24): cv.positive_int,
vol.Optional(CONF_STATION_ID, default=""): str,
},
)
Expand All @@ -85,3 +102,11 @@ async def async_step_user(self, user_input=None):

class CannotConnect(exceptions.HomeAssistantError):
"""Error to indicate we cannot connect."""


class WeatherIntervalTooBig(exceptions.HomeAssistantError):
"""Error to indicate only values to 24 are allowed."""


class WeatherIntervalRemainderNotZero(exceptions.HomeAssistantError):
"""Error to indicate that the remainder of 24 divided by the value has to be zero."""
124 changes: 81 additions & 43 deletions custom_components/dwd_weather/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@


class DWDWeatherData:
def __init__(self, hass, latitude, longitude, station_id):
def __init__(self, hass, latitude, longitude, station_id, time_window):
"""Initialize the data object."""
self._hass = hass
self.forecast = None
Expand All @@ -33,6 +33,7 @@ def __init__(self, hass, latitude, longitude, station_id):
# Public attributes
self.latitude = latitude
self.longitude = longitude
self.time_window = time_window
self.infos = {}

# Checks if station_id was set by the user
Expand Down Expand Up @@ -70,41 +71,62 @@ def _update(self):
)
forecast_data = []
timestamp = datetime.now(timezone.utc)
for x in range(0, 9):
temp_max = self.dwd_weather.get_daily_max(
dwdforecast.WeatherDataType.TEMPERATURE, timestamp, False
)
if temp_max is not None:
temp_max = int(round(temp_max - 273.1, 0))

temp_min = self.dwd_weather.get_daily_min(
dwdforecast.WeatherDataType.TEMPERATURE, timestamp, False
)
if temp_min is not None:
temp_min = int(round(temp_min - 273.1, 0))

precipitation_prop = self.dwd_weather.get_daily_max(
dwdforecast.WeatherDataType.PRECIPITATION_PROBABILITY,
timestamp,
False,
)
if precipitation_prop is not None:
precipitation_prop = int(precipitation_prop)
forecast_data.append(
{
ATTR_FORECAST_TIME: timestamp.strftime("%Y-%m-%d"),
ATTR_FORECAST_CONDITION: self.dwd_weather.get_daily_condition(
timestamp, False
),
ATTR_FORECAST_TEMP: temp_max,
ATTR_FORECAST_TEMP_LOW: temp_min,
ATTR_FORECAST_PRECIPITATION: self.dwd_weather.get_daily_sum(
dwdforecast.WeatherDataType.PRECIPITATION, timestamp, False
),
"precipitation_probability": precipitation_prop, # ATTR_FORECAST_PRECIPITATION_PROBABILITY
}
)
timestamp = timestamp + timedelta(days=1)
timestep = datetime(
timestamp.year, timestamp.month, timestamp.day, tzinfo=timezone.utc
)
# Find the next timewindow from actual time
while timestep < timestamp:
timestep += timedelta(hours=self.time_window)
# Reduce by one to include the current timewindow
timestep -= timedelta(hours=self.time_window)
for _ in range(0, 9):
for _ in range(int(24 / self.time_window)):
temp_max = self.dwd_weather.get_timeframe_max(
dwdforecast.WeatherDataType.TEMPERATURE,
timestep,
self.time_window,
False,
)
if temp_max is not None:
temp_max = int(round(temp_max - 273.1, 0))

temp_min = self.dwd_weather.get_timeframe_min(
dwdforecast.WeatherDataType.TEMPERATURE,
timestep,
self.time_window,
False,
)
if temp_min is not None:
temp_min = int(round(temp_min - 273.1, 0))

precipitation_prop = self.dwd_weather.get_timeframe_max(
dwdforecast.WeatherDataType.PRECIPITATION_PROBABILITY,
timestep,
self.time_window,
False,
)
if precipitation_prop is not None:
precipitation_prop = int(precipitation_prop)
forecast_data.append(
{
ATTR_FORECAST_TIME: timestep.strftime("%Y-%m-%dT%H:00:00Z"),
ATTR_FORECAST_CONDITION: self.dwd_weather.get_timeframe_condition(
timestep,
self.time_window,
False,
),
ATTR_FORECAST_TEMP: temp_max,
ATTR_FORECAST_TEMP_LOW: temp_min,
ATTR_FORECAST_PRECIPITATION: self.dwd_weather.get_timeframe_sum(
dwdforecast.WeatherDataType.PRECIPITATION,
timestep,
self.time_window,
False,
),
"precipitation_probability": precipitation_prop, # ATTR_FORECAST_PRECIPITATION_PROBABILITY
}
)
timestep += timedelta(hours=self.time_window)
self.forecast = forecast_data

def get_condition(self):
Expand All @@ -114,24 +136,33 @@ def get_condition(self):

def get_temperature(self):
value = self.dwd_weather.get_forecast_data(
dwdforecast.WeatherDataType.TEMPERATURE, datetime.now(timezone.utc), False,
dwdforecast.WeatherDataType.TEMPERATURE,
datetime.now(timezone.utc),
False,
)
if value is not None:
return value - 273.1

def get_pressure(self):
value = self.dwd_weather.get_forecast_data(
dwdforecast.WeatherDataType.PRESSURE, datetime.now(timezone.utc), False,
dwdforecast.WeatherDataType.PRESSURE,
datetime.now(timezone.utc),
False,
)
if value is not None:
return value / 100

def get_wind_speed(self):
value = self.dwd_weather.get_forecast_data(
dwdforecast.WeatherDataType.WIND_SPEED, datetime.now(timezone.utc), False,
dwdforecast.WeatherDataType.WIND_SPEED,
datetime.now(timezone.utc),
False,
)
if value is not None:
return round(value * 3.6, 1,)
return round(
value * 3.6,
1,
)

def get_wind_direction(self):
return self.dwd_weather.get_forecast_data(
Expand All @@ -142,16 +173,23 @@ def get_wind_direction(self):

def get_visibility(self):
value = self.dwd_weather.get_forecast_data(
dwdforecast.WeatherDataType.VISIBILITY, datetime.now(timezone.utc), False,
dwdforecast.WeatherDataType.VISIBILITY,
datetime.now(timezone.utc),
False,
)
if value is not None:
return round(value / 1000, 1,)
return round(
value / 1000,
1,
)

def get_humidity(self):
rh_c2 = 17.5043
rh_c3 = 241.2
T = self.dwd_weather.get_forecast_data(
dwdforecast.WeatherDataType.TEMPERATURE, datetime.now(timezone.utc), False,
dwdforecast.WeatherDataType.TEMPERATURE,
datetime.now(timezone.utc),
False,
)
TD = self.dwd_weather.get_forecast_data(
dwdforecast.WeatherDataType.DEWPOINT, datetime.now(timezone.utc), False
Expand Down
1 change: 1 addition & 0 deletions custom_components/dwd_weather/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
DWDWEATHER_NAME = "dwd_weather_name"

CONF_STATION_ID = "station_id"
CONF_WEATHER_INTERVAL = "weather_interval"
3 changes: 2 additions & 1 deletion custom_components/dwd_weather/manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"domain": "dwd_weather",
"version": "1.2.3",
"name": "Deutscher Wetterdienst (DWD)",
"documentation": "https://github.com/FL550/dwd_weather",
"issue_tracker": "https://github.com/FL550/dwd_weather/issues",
Expand All @@ -8,5 +9,5 @@
"codeowners": [
"@FL550"
],
"requirements": ["simple_dwd_weatherforecast==1.0.6"]
"requirements": ["simple_dwd_weatherforecast==1.0.10"]
}
Loading

0 comments on commit 34371a6

Please sign in to comment.