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
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
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
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
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)