diff --git a/shared/mycroft/configuration/mycroft.conf b/shared/mycroft/configuration/mycroft.conf index 0d6ea695..09852064 100644 --- a/shared/mycroft/configuration/mycroft.conf +++ b/shared/mycroft/configuration/mycroft.conf @@ -96,6 +96,12 @@ "sync_skill_settings": true }, + // Open Weather Map direct access info + "openweathermap": { + "url": "https://api.openweathermap.org/data/2.5" + // "key": "INSERT-YOUR-OWN-OWM-API-KEY-HERE" + }, + // The mycroft-core messagebus websocket "websocket": { "host": "127.0.0.1", diff --git a/skills/weather.mark2/__init__.py b/skills/weather.mark2/__init__.py index 0840981e..15b55d3f 100644 --- a/skills/weather.mark2/__init__.py +++ b/skills/weather.mark2/__init__.py @@ -87,8 +87,13 @@ def handle_get_local_forecast(self, _): to get it. """ temperature_unit = self.weather_config.temperature_unit - + self.log.debug("Entering handle_get_local_forecast.") try: + self.log.debug("Calling get_weather_for_coordinates.") + self.log.debug(f"temperature_unit {temperature_unit}") + self.log.debug(f"self.weather_config.latitude {self.weather_config.latitude}") + self.log.debug(f"self.weather_config.longitude {self.weather_config.longitude}") + self.log.debug(f"self.lang {self.lang}") weather = self.weather_api.get_weather_for_coordinates( temperature_unit, self.weather_config.latitude, diff --git a/skills/weather.mark2/skill/api.py b/skills/weather.mark2/skill/api.py index 692ca6de..8705a5b5 100644 --- a/skills/weather.mark2/skill/api.py +++ b/skills/weather.mark2/skill/api.py @@ -22,8 +22,13 @@ provided, precluding us from having to do the conversions. """ +import base64 +import json +import requests + from mycroft.api import Api from mycroft.util.log import LOG +from mycroft.configuration import Configuration from .weather import WeatherReport @@ -127,7 +132,6 @@ def get_weather_for_coordinates( measurement_system = "imperial" else: measurement_system = "metric" - query_parameters = dict( exclude="minutely", lang=owm_language(lang), @@ -135,9 +139,25 @@ def get_weather_for_coordinates( lon=longitude, units=measurement_system, ) - LOG.debug(f"Parameters: {query_parameters}") + path = "/onecall" api_request = dict(path="/onecall", query=query_parameters) - response = self.request(api_request) - local_weather = WeatherReport(response) + try: + response = self.request(api_request) + local_weather = WeatherReport(response) + except Exception: + # For whatever reason, we didn't get back a usable response. + # This is a direct attempt to hit the api as fallback. + weather_config = Configuration.get().get("openweathermap") + + # Yeah we know... + default_yek = base64.b64decode(b'OWU0NzdkMDk0YmYxOWFiMDE4NzFjOTIwZDI3ZGJiODg=') + owm_key = weather_config.get("key", default_yek.decode("utf-8")) + owm_url = weather_config["url"] + + query_parameters["APPID"] = owm_key + # Call will look like this: "https://api.openweathermap.org/data/2.5/onecall?exclude=minutely&lang=en&lat=37.9577&lon=-121.29078&units=imperial&APPID={query_parameters['APPID']}" + response = requests.get(owm_url + "/" + path, params=query_parameters) + decoded = json.loads(response.content.decode("utf-8")) + local_weather = WeatherReport(decoded) return local_weather diff --git a/skills/weather.mark2/skill/weather.py b/skills/weather.mark2/skill/weather.py index c5fce912..150c6170 100644 --- a/skills/weather.mark2/skill/weather.py +++ b/skills/weather.mark2/skill/weather.py @@ -16,6 +16,8 @@ from pathlib import Path from typing import List +from mycroft.util.log import LOG + from .config import MILES_PER_HOUR from .util import convert_to_local_datetime @@ -124,14 +126,27 @@ class Weather: """Abstract data representation of commonalities in forecast types.""" def __init__(self, weather: dict, timezone: str): + LOG.debug(f"Weather: {weather}") self.date_time = convert_to_local_datetime(weather["dt"], timezone) - self.feels_like = weather["feelsLike"] + try: + self.feels_like = weather["feelsLike"] + except: + self.feels_like = weather["feels_like"] self.pressure = weather["pressure"] self.humidity = weather["humidity"] - self.dew_point = weather["dewPoint"] + try: + self.dew_point = weather["dewPoint"] + except: + self.dew_point = weather["dew_point"] self.clouds = weather["clouds"] - self.wind_speed = int(weather["windSpeed"]) - self.wind_direction = self._determine_wind_direction(weather["windDeg"]) + try: + self.wind_speed = int(weather["windSpeed"]) + except: + self.wind_speed = int(weather["wind_speed"]) + try: + self.wind_direction = self._determine_wind_direction(weather["windDeg"]) + except: + self.wind_direction = self._determine_wind_direction(weather["wind_deg"]) self.condition = WeatherCondition(weather["weather"][0]) @staticmethod @@ -216,7 +231,10 @@ def __init__(self, weather: dict, timezone: str): self.sunrise = convert_to_local_datetime(weather["sunrise"], timezone) self.sunset = convert_to_local_datetime(weather["sunset"], timezone) self.temperature = DailyTemperature(weather["temp"]) - self.feels_like = DailyFeelsLike(weather["feelsLike"]) + try: + self.feels_like = DailyFeelsLike(weather["feelsLike"]) + except: + self.feels_like = DailyFeelsLike(weather["feels_like"]) self.chance_of_precipitation = int(weather["pop"] * 100) @@ -244,6 +262,10 @@ class WeatherReport: """Full representation of the data returned by the Open Weather Maps One Call API""" def __init__(self, report): + LOG.debug(f"Report: {report}") + LOG.debug(f"Type: {type(report)}") + LOG.debug(f'Timezone: {report["timezone"]}') + timezone = report["timezone"] self.current = CurrentWeather(report["current"], timezone) self.hourly = [HourlyWeather(hour, timezone) for hour in report["hourly"]]