Beispiel #1
0
    def daily_forecast(self, name, limit=None):
        """
        Queries the OWM web API for daily weather forecast for the specified
        location (eg: "London,uk"). A *Forecaster* object is returned,
        containing a *Forecast* instance covering a global streak of fourteen
        days by default: this instance encapsulates *Weather* objects, with a
        time interval of one day one from each other

        :param name: the location's toponym
        :type name: str
        :param limit: the maximum number of daily *Weather* items to be
            retrieved (default is ``None``, which stands for any number of
            items)
        :type limit: int or ``None``
        :returns: a *Forecaster* instance or ``None`` if forecast data is not
            available for the specified location
        :raises: *ParseResponseException* when OWM web API responses' data
            cannot be parsed, *APICallException* when OWM web API can not be
            reached, *ValueError* if negative values are supplied for limit
        """
        OWM25._assert_is_string("name", name)
        if limit is not None:
            assert isinstance(limit, int), "'limit' must be an int or None"
            if limit < 1:
                raise ValueError("'limit' must be None or greater than zero")
        params = {'q': name, 'lang': self._language}
        if limit is not None:
            params['cnt'] = limit
        json_data = self._httpclient.call_API(DAILY_FORECAST_URL, params)
        forecast = self._parsers['forecast'].parse_JSON(json_data)
        if forecast is not None:
            forecast.set_interval("daily")
            return forecaster.Forecaster(forecast)
        else:
            return None
Beispiel #2
0
    def three_hours_forecast_at_id(self, id):
        """
        Queries the OWM web API for three hours weather forecast for the
        specified city ID (eg: 5128581). A *Forecaster* object is returned,
        containing a *Forecast* instance covering a global streak of
        five days: this instance encapsulates *Weather* objects, with a time
        interval of three hours one from each other

        :param id: the location's city ID
        :type id: int
        :returns: a *Forecaster* instance or ``None`` if forecast data is not
            available for the specified location
        :raises: *ParseResponseException* when OWM web API responses' data
            cannot be parsed, *APICallException* when OWM web API can not be
            reached
        """
        assert type(id) is int, "'id' must be an int"
        if id < 0:
            raise ValueError("'id' value must be greater than 0")
        json_data = self._httpclient.call_API(THREE_HOURS_FORECAST_URL, {
            'id': id,
            'lang': self._language
        })
        forecast = self._parsers['forecast'].parse_JSON(json_data)
        if forecast is not None:
            forecast.set_interval("3h")
            return forecaster.Forecaster(forecast)
        else:
            return None
Beispiel #3
0
    def three_hours_forecast_at_coords(self, lat, lon):
        """
        Queries the OWM web API for three hours weather forecast for the
        specified geographic coordinate (eg: latitude: 51.5073509,
        longitude: -0.1277583). A *Forecaster* object is returned,
        containing a *Forecast* instance covering a global streak of
        five days: this instance encapsulates *Weather* objects, with a time
        interval of three hours one from each other

        :param lat: location's latitude, must be between -90.0 and 90.0
        :type lat: int/float
        :param lon: location's longitude, must be between -180.0 and 180.0
        :type lon: int/float
        :returns: a *Forecaster* instance or ``None`` if forecast data is not
            available for the specified location
        :raises: *ParseResponseException* when OWM web API responses' data
            cannot be parsed, *APICallException* when OWM web API can not be
            reached
        """
        assert type(lon) is float or type(lon) is int, "'lon' must be a float"
        if lon < -180.0 or lon > 180.0:
            raise ValueError("'lon' value must be between -180 and 180")
        assert type(lat) is float or type(lat) is int, "'lat' must be a float"
        if lat < -90.0 or lat > 90.0:
            raise ValueError("'lat' value must be between -90 and 90")
        params = {'lon': lon, 'lat': lat, 'lang': self._language}
        json_data = self._httpclient.call_API(THREE_HOURS_FORECAST_URL, params)
        forecast = self._parsers['forecast'].parse_JSON(json_data)
        if forecast is not None:
            forecast.set_interval("3h")
            return forecaster.Forecaster(forecast)
        else:
            return None
Beispiel #4
0
    def three_hours_forecast(self, name):
        """
        Queries the OWM web API for three hours weather forecast for the
        specified location (eg: "London,uk"). A *Forecaster* object is
        returned, containing a *Forecast* instance covering a global streak of
        five days: this instance encapsulates *Weather* objects, with a time
        interval of three hours one from each other

        :param name: the location's toponym
        :type name: str
        :returns: a *Forecaster* instance or ``None`` if forecast data is not
            available for the specified location
        :raises: *ParseResponseException* when OWM web API responses' data
            cannot be parsed, *APICallException* when OWM web API can not be
            reached
        """
        OWM25._assert_is_string("name", name)
        json_data = self._httpclient.call_API(THREE_HOURS_FORECAST_URL, {
            'q': name,
            'lang': self._language
        })
        forecast = self._parsers['forecast'].parse_JSON(json_data)
        if forecast is not None:
            forecast.set_interval("3h")
            return forecaster.Forecaster(forecast)
        else:
            return None
Beispiel #5
0
    def daily_forecast_at_coords(self, lat, lon, limit=None):
        """
        Queries the OWM web API for daily weather forecast for the specified
        geographic coordinate (eg: latitude: 51.5073509,
        longitude: -0.1277583).
        A *Forecaster* object is returned, containing a *Forecast* instance
        covering a global streak of fourteen days by default: this instance
        encapsulates *Weather* objects, with a time interval of one day one
        from each other

        :param lat: location's latitude, must be between -90.0 and 90.0
        :type lat: int/float
        :param lon: location's longitude, must be between -180.0 and 180.0
        :type lon: int/float
        :param limit: the maximum number of daily *Weather* items to be
            retrieved (default is ``None``, which stands for any number of
            items)
        :type limit: int or ``None``
        :returns: a *Forecaster* instance or ``None`` if forecast data is not
            available for the specified location
        :raises: *ParseResponseException* when OWM web API responses' data
            cannot be parsed, *APICallException* when OWM web API can not be
            reached, *ValueError* if negative values are supplied for limit
        """
        assert type(lon) is float or type(lon) is int, "'lon' must be a float"
        if lon < -180.0 or lon > 180.0:
            raise ValueError("'lon' value must be between -180 and 180")
        assert type(lat) is float or type(lat) is int, "'lat' must be a float"
        if lat < -90.0 or lat > 90.0:
            raise ValueError("'lat' value must be between -90 and 90")
        if limit is not None:
            assert isinstance(limit, int), "'limit' must be an int or None"
            if limit < 1:
                raise ValueError("'limit' must be None or greater than zero")
        params = {'lon': lon, 'lat': lat, 'lang': self._language}
        if limit is not None:
            params['cnt'] = limit
        json_data = self._httpclient.call_API(DAILY_FORECAST_URL, params)
        forecast = self._parsers['forecast'].parse_JSON(json_data)
        if forecast is not None:
            forecast.set_interval("daily")
            return forecaster.Forecaster(forecast)
        else:
            return None
    def action(self, intent, objs):
        q = None
        owm = pyowm.OWM(settings.OWM_API_KEY)

        #country = jsonentities.find_value(objs['entities'], 'country')
        place = self.slotValue(objs,'location') #location in the house.. kitchen, bedroom 
        weather_item = self.slotValue(objs, 'weatherItem')
        forDate = self.slotDateValue(objs, 'date')

        startDate = datetime.datetime.today()
        endDate = datetime.datetime.today()

        print type(forDate)
        calcTotalDays = 0
        if type(forDate) == dict:
            text = objs['input']
            if 'weekend' in text:
                startDate = forDate["start"] + datetime.timedelta(hours=6)
                endDate = startDate + datetime.timedelta(days=1)
                calcTotalDays = 2
            else:
                startDate = forDate["start"]
                endDate = forDate["end"]
                calcTotalDays = (endDate - startDate).days
        else:
            print "single date"
            startDate = forDate
            endDate = forDate
            calcTotalDays = 1

        calcStartDays = (datetime.date.today() - startDate.date()).days
        calcEndDays = (datetime.date.today() - endDate.date()).days

        if (calcStartDays > 0) and (type(forDate) != dict):
            #we dont do the past
            print "starting date is in the past"
            self.speak('I can not do weather information from the past, only the future', objs)
        elif (type(forDate) == dict) and (calcEndDays >= 0):
            #we dont do the past
            print "date range in the past"
            self.speak('I can not do weather information from the past, only the future', objs)
        elif (type(forDate) == dict) and (calcStartDays >= 0):
            #pad the start date to today to forget about past dates
            #asking for "this week" and if today is wednesday, the dates returned will include the past mon and tues
            startDate = datetime.datetime.today()
            calcTotalDays = (endDate.replace(tzinfo=None) - startDate.replace(tzinfo=None)).days + 1
        elif (calcStartDays < -15):
            #we dont do that far into the future
            print "starting date is to far into the future"
            self.speak('I can not do weather that far into the future', objs)

        startDate = startDate.replace(hour=0, minute=0, second=0)
        endDate = endDate.replace(hour=23, minute=59, second=59)
        
        #****************************************************************************************************
        if place is None:
            #then we are wanting to know about real weather info for the suburb
            q = '%s' % (settings.OWM_LOCATION)
        else:
            #if there was a place then its a reading from an IoT sensor in the house 'location'/'place'
            q = '%s' % (place)
            print 'a reading from an IoT sensor in the house'
            return

        if q is None:
            self.onError(objs)
            return
        
        '''
        ddd = startDate
        c = timeformatutils.to_date(ddd)
        
        strDayName = ''

        calcDays = (datetime.date.today() - c.date()).days
        if calcDays > 0:
            #we dont do the past
            print "in the past"
            self.speak('I can not do weather information from the past, only the future', objs)
        elif calcDays == 0:
            strDayName = 'today'
        elif calcDays == -1:
            strDayName = 'tomorrow'
        else:
            strDayName =  c.strftime("%A")
        
        '''

        fc = owm.daily_forecast(q,16)
        #fc = obs.daily_forecast()
        #print "when raining"
        #print fc.when_rain()

        w = None
      
   
        weathers =[]
        firstDate = startDate
        for x in range(0, calcTotalDays):
            c = timeutils.next_hour(firstDate)
            w = fc.get_weather_at(c)
            weathers.append(w)
            firstDate = firstDate + datetime.timedelta(days=1)

        #nfc = forecaster.Forecaster(weathers)
        current_time = int(round(time.time()))
        #fc.get_forecast().get_interval()
        nfc = forecast.Forecast(None, current_time, fc.get_forecast().get_location(), weathers)
        nfc.set_interval("daily")
        fc = forecaster.Forecaster(nfc)
    
        
        sayString = ''
        sayString = self.parseDateRawValue(objs,"date")
        if sayString == 'weekend':
            sayString = "this " + sayString
        sayString = sayString + ", "
        
        if len(weathers) == 1:
            weather = weathers[0]
            temp = weather.get_temperature(unit=settings.OWM_TEMPUNIT)
            detail = weather.get_detailed_status()
            sayString += "{}, with a top of {}.".format(detail, int(temp["max"]))  
        elif len(weathers) > 1:
            if weather_item is None:
                for weather in weathers:
                    sayString += self.generalWeatherInfo(weather)
                    startDate = startDate + datetime.timedelta(days=1)
            else:
                if 'weekend' in sayString:
                    for weather in weathers:
                        sayString += self.generalWeatherInfo(weather)
                        startDate = startDate + datetime.timedelta(days=1)
                else:
                    if weather_item == 'hot':
                        w = fc.most_hot()
                        sayString += self.generalSlotWeatherInfo(w, "warmest")
                    elif weather_item == 'cold':
                        w = fc.most_cold()
                        sayString += self.generalSlotWeatherInfo(w, "coolest")
                    elif weather_item == 'rain':
                        w = fc.most_rainy()
                        if len(w) > 0:
                            sayString += self.generalSlotWeatherInfo(w, "wettest")
                        else:
                            sayString += "it's not forecast to rain"
        else:
            #there is no weather info
            self.speak('I can not do the weather. Might not be able to access the weather website, the internet, or something went wrong', objs)

        print sayString
        self.speak(sayString, objs)