Example #1
0
def run_8d_readout(hat, curr_x):
    """Displays a text readout of the forecast for the next 8 days
       and gives the respective dates"""
    global program_state
    readout_8d = []
    readout_string = ""
    #Send another request for data
    owm = OWM(API_KEY)

    #Retrieve daily forecast for 8 days (includes today)
    fc = owm.daily_forecast_at_id(SomeCity, limit=8)
    f = fc.get_forecast()
    i = 0
    for weather in f:
        readout_8d.append(weather)
        if (i == 8):
            break
        i += 1
    for weather in readout_8d:
        readout_string = readout_string + " For " + str(
            utc_to_eastern(weather.get_reference_time('date')))[0:10]
        readout_string = readout_string + " " + weather.get_detailed_status(
        ) + " - "

    hat.show_message(readout_string, scroll_speed=0.035, text_colour=nwhite)

    #Goes here after break
    program_state = 0  #Main menu
    return_to_main_menu(hat, curr_x)

    #--------------------------- SOME NEW READOUT OR LOOP ------------------------#
    """
Example #2
0
class OpenWeatherMapModel:
    def __init__(self, api_key: str, city_id: int):
        self.owm = OWM(api_key)
        self._city_id = city_id
        self._unit = 'celsius'

    @property
    def city_id(self):
        return self._city_id

    @city_id.setter
    def city_id(self, city_id: int):
        self._city_id = city_id

    @property
    def temperature_unit(self):
        return self._unit

    @temperature_unit.setter
    def temperature_unit(self, unit: str):
        assert unit == 'fahrenheit' or unit == 'celsius'
        self._unit = unit

    def _parse_weather(self, weather):
        temperature = weather.get_temperature(unit=self.temperature_unit)
        humidity = weather.get_humidity()
        weather_code = weather.get_weather_code()
        return (weather_code,
                temperature.get('temp_min', temperature.get('min')),
                temperature.get('temp_max', temperature.get('max')), humidity)

    def get_current_weather(self):
        """
        Get the current weather data
        :return: Tuple of weather code, temperature range, and humidity
        """
        try:
            obs = self.owm.weather_at_id(self.city_id)
            weather = obs.get_weather()
            return self._parse_weather(weather)
        except pyowm.exceptions.api_call_error.APICallTimeoutError:
            return 0, 0, 0, 0

    def get_daily_forecast(self, limit=14, include_today=False):
        """
        Get a list of forecasts
        :param limit: The max number of forecasts to get
        :param include_today: whether include today in the forecast
        :return: list of tuples of weather code, temperature range and humidity
        """
        forecaster = self.owm.daily_forecast_at_id(self.city_id, limit=limit)
        weathers = forecaster.get_forecast().get_weathers()
        today = datetime.datetime.now().date()
        if not include_today:
            weathers = filter(
                lambda weather: not (weather.get_reference_time(
                    timeformat='date') == today), weathers)
        return list(map(lambda weather: self._parse_weather(weather),
                        weathers))
Example #3
0
def run_outdoor_hud_loop(hat, curr_x):
    """Run the program loop for this mini program"""
    global program_state

    #How often do you want to request the forecast data?
    REFRESH_RATE = 600  #Every 10 min (600 seconds)
    #Clear the screen
    hat.clear()
    #We are initializing this screen now
    init = True
    #Capture the start time for refresh rate calculations
    start_time = time.time()
    #Run the sub program loop
    while (True):
        #Check to see if user wants to return to main menu
        return_requested = check_stick_events_2(hat)
        if (return_requested):
            break  #Exit while to return to main menu

        counter = time.time() - start_time
        #If it's been < 10 min since the first, or most recent data download...
        if (counter > REFRESH_RATE or init):
            #Send another request for data
            owm = OWM(API_KEY)
            """FOR 8-DAY FORECAST (ROW 1 & ROW 2)"""
            #Retrieve daily forecast for 8 days (includes today)
            fc = owm.daily_forecast_at_id(SomeCity, limit=8)
            f = fc.get_forecast()
            i = 0
            for weather in f:
                #FOR DEBUGGING
                #print("At " , str(utc_to_eastern(weather.get_reference_time('date'))),weather.get_weather_code())
                if (i == 8):
                    break

                # Where W_CODES[weather.get_weather_code()][0] is giving the
                #  [weather.get_weather_code()] as a KEY to get the data object
                #  that holds the color at index [0] and description string
                #  (unused here) at index [1]

                #Top row
                hat.set_pixel(i, 0, W_CODES[weather.get_weather_code()][0])

                #Second row down from top
                hat.set_pixel(i, 1, W_CODES[weather.get_weather_code()][0])
                i += 1
            """FOR 3 HOUR FORECAST (ROW 3 & ROW 4)"""
            #Current conditions
            w = get_observation(SomeCity, owm)

            #Set leftmost pixels to show current status
            #Row 3
            hat.set_pixel(0, 2, W_CODES[w.get_weather_code()][0])
            #Row 4
            hat.set_pixel(0, 3, W_CODES[w.get_weather_code()][0])

            #Get current temperature
            temp_now = w.get_temperature('fahrenheit')["temp"]
            #Restrict temp_now readings to bound for display purposes
            if (temp_now > 100.00):
                temp_now = 100.00
            elif (temp_now < 0.00):
                temp_now = 0.00

            #Get current humidity
            humi_now = w.get_humidity()
            #Get current pressure
            pres_now = w.get_pressure()["press"]
            #Set current temperature color here for leftmost pixels
            curr_temp_color = cold_ok_or_hot(temp_now)
            """ROW 5 Code -- 3HR temperature forecast"""
            #Set leftmost pixel for ROW 5
            hat.set_pixel(0, 4, curr_temp_color)

            #Get the 3hr forecast for the next 7 days
            fc = owm.three_hours_forecast_at_id(SomeCity)
            #A list of weather objects
            f = fc.get_forecast()
            i = 1
            #Fill in the rest of the row after first pixels for rows 3,4,5
            for weather in f:
                if (i == 8):
                    break
                #Row 3
                hat.set_pixel(i, 2, W_CODES[weather.get_weather_code()][0])
                #Row 4
                hat.set_pixel(i, 3, W_CODES[weather.get_weather_code()][0])
                #Get the temp for the 3hr interval
                temp_then = weather.get_temperature('fahrenheit')["temp"]
                #Also set the temperature indicator row color to show if
                # the temp is high, low, or tolerable at
                # ROW 5
                hat.set_pixel(i, 4, cold_ok_or_hot(temp_then))
                i += 1
            """TEMPERATURE (ROW 6)"""
            #Where 8/100 = 12.5, so every pixel is 12.5 degrees F of temp.
            num_pixels = int(temp_now / 12.5)
            #Temperature displays on row y == 5(6th row) from 0
            # to 100 degrees where each pixel represents 12.5 degrees F
            for i in range(num_pixels):
                hat.set_pixel(i, 5, curr_temp_color)
            for i in range(8 - num_pixels):
                hat.set_pixel(i + num_pixels, 5, nwhite)
            """HUMIDITY (ROW 7)"""
            curr_humi_color = dry_humid_or_ok(humi_now)
            num_pixels = int(humi_now / 12.5)
            #Humidity displays on row y == 6 (7th row)
            #as a relative percent
            for i in range(num_pixels):
                hat.set_pixel(i, 6, curr_humi_color)
            for i in range(8 - num_pixels):
                hat.set_pixel(i + num_pixels, 6, nwhite)
            """AIR PRESSURE (ROW 8)"""
            #Air pressure (in millibars) displays on
            # the last row as one of three colors indicating
            # if the air pressure is high, low, or reasonable
            # for normal conditions
            curr_pres_color = pres_lo_hi_or_ok(pres_now)
            for i in range(8):
                hat.set_pixel(i, 7, curr_pres_color)

            #Reset counter for refreshing
            start_time = time.time()
            init = False

    #Goes here after "break"
    program_state = 0  #Main menu
    return_to_main_menu(hat, curr_x)
Example #4
0
class OpenWeatherMapModel:
    def __init__(self, api_key: str, city_id: int) -> None:
        self.owm = OWM(api_key)
        self._city_id = city_id
        self._unit = 'celsius'
        self._current_weather = (0, 0.0, 0.0, 0.0, 0.0)
        self._forecast = []  # type:List[Tuple[int, float, float, float, float]]

    @property
    def city_id(self) -> int:
        return self._city_id

    @city_id.setter
    def city_id(self, city_id: int) -> None:
        self._city_id = city_id

    @property
    def temperature_unit(self) -> str:
        return self._unit

    @temperature_unit.setter
    def temperature_unit(self, unit: str) -> None:
        assert unit == 'fahrenheit' or unit == 'celsius'
        self._unit = unit

    def _parse_weather(self, weather: Weather) -> Tuple[int, float, float,
                                                        float, float]:
        temperature = weather.get_temperature(unit=self.temperature_unit)
        humidity = weather.get_humidity()
        weather_code = weather.get_weather_code()
        return (weather_code,
                temperature.get('temp_min', temperature.get('min')),
                temperature.get('temp_max', temperature.get('max')),
                temperature.get('temp'),
                humidity)

    def get_current_weather(self) -> Tuple[int, float, float, float, float]:
        """
        Get the current weather data
        :return: Tuple of weather code, temperature range, current temperature
                 and humidity
        """
        try:
            obs = self.owm.weather_at_id(self.city_id)
            weather = obs.get_weather()
            self._current_weather = self._parse_weather(weather)
        except Exception as exception:
            print(exception)
        return self._current_weather

    def get_daily_forecast(self, limit: int = 14,
                           include_today: bool = False) -> List[Tuple[int,
                                                                      float,
                                                                      float,
                                                                      float,
                                                                      float]]:
        """
        Get a list of forecasts
        :param limit: The max number of forecasts to get
        :param include_today: whether include today in the forecast
        :return: list of tuples of weather code, temperature range, temperature
                 and humidity
        """
        try:
            forecaster = self.owm.daily_forecast_at_id(self.city_id,
                                                       limit=limit)
            weathers = forecaster.get_forecast().get_weathers()
            today = datetime.datetime.now().date()
            if not include_today:
                weathers = filter(
                    lambda weather: not (weather.get_reference_time(
                        timeformat='date').date() == today), weathers)
            self._forecast = list(
                map(lambda weather: self._parse_weather(weather), weathers))
        except Exception as exception:
            print(exception)
        return self._forecast
Example #5
0
class WeatherPoller(object):

    API_key = '9ef86a5c847ad6a5c67d09dd9b72e9a6'
    API_fetch_interval = timedelta(days=1)
    map_city_id = {'kitchener': 5992996}
    temperature_change_threshold = 5.0

    def __init__(self, city='kitchener'):
        if city in WeatherPoller.map_city_id:
            self.city_id = WeatherPoller.map_city_id[city]
        else:
            logging.error(' '.join([self.__class__.__name__, ": city:", city,
                                    "not found in map_city_id dict."]))
            raise Exception("city:", city, " not found in map_city_id dict.")

        self.owm = None
        self.last_api_fetch_time = None

    def poll_data(self):
        if self.owm is None or self.last_api_fetch_time is None \
                or self.forecast is None or \
                (datetime.utcnow() - self.last_api_fetch_time >
                 WeatherPoller.API_fetch_interval):
            self.owm = OWM(WeatherPoller.API_key)
            self.forecast = self.owm.daily_forecast_at_id(self.city_id)
            self.last_api_fetch_time = datetime.utcnow()
            logging.info(' '.join(
                [self.__class__.__name__, ": poll_data() fetched new data at:",
                 self.last_api_fetch_time.isoformat()]))
        else:
            logging.info(' '.join([self.__class__.__name__, (
                ": poll_data() called within fetch "
                "interval threshold, use previous "
                "fetched data at:"), self.last_api_fetch_time.isoformat()]))

    def trigger_notification(self, message):
        print message

    def check_temperature_change(self):
        weather_lst = self.forecast.get_forecast().get_weathers()
        today = datetime.utcnow()
        tomorrow = today + timedelta(days=1)
        today_temp = weather_lst[0].get_temperature(unit='celsius')
        tomorrow_temp = self.forecast.get_weather_at(tomorrow).get_temperature(
            unit='celsius')

        logging.debug(' '.join(
            [self.__class__.__name__, ": check_temperature_change", "\ntoday:",
             str(today_temp), "\ntomorrow", str(tomorrow_temp)]))

        alert_lst = []
        for item in today_temp:
            if abs(today_temp[item] - tomorrow_temp[
                    item]) >= WeatherPoller.temperature_change_threshold:
                alert_lst.append(
                    "Temperature change alert:"
                    "item: {key}, today:{today}, tomorrow:{tomorrow}".format(
                        key=item,
                        today=today_temp[item],
                        tomorrow=tomorrow_temp[item]))
        return alert_lst