Пример #1
0
    def uvindex_history_around_coords(self, lat, lon, start, end=None):
        """
        Queries for UV index historical values in the
        surroundings of the provided geocoordinates and in the specified
        time frame. If the end of the time frame is not provided, that is
        intended to be the current datetime.

        :param lat: the location's latitude, must be between -90.0 and 90.0
        :type lat: int/float
        :param lon: the location's longitude, must be between -180.0 and 180.0
        :type lon: int/float
        :param start: the object conveying the time value for the start query boundary
        :type start: int, ``datetime.datetime`` or ISO8601-formatted string
        :param end: the object conveying the time value for the end query
            boundary (defaults to ``None``, in which case the current datetime
            will be used)
        :type end: int, ``datetime.datetime`` or ISO8601-formatted string
        :return: a list of *UVIndex* instances or empty list if data is not available
        :raises: *ParseResponseException* when OWM UV Index API responses' data
            cannot be parsed, *APICallException* when OWM UV Index API can not be
            reached, *ValueError* for wrong input values
        """
        geo.assert_is_lon(lon)
        geo.assert_is_lat(lat)
        assert start is not None
        start = formatting.timeformat(start, 'unix')
        if end is None:
            end = timestamps.now(timeformat='unix')
        else:
            end = formatting.timeformat(end, 'unix')
        params = {'lon': lon, 'lat': lat, 'start': start, 'end': end}
        json_data = self.uv_client.get_uvi_history(params)
        uvindex_list = [uvindex.UVIndex.from_dict(item) for item in json_data]
        return uvindex_list
Пример #2
0
def forecast(city: str, timestamp: str):
    time_to_start = time.time()
    global programMetrics
    global processing_time_of_the_request_forecast_weather
    programMetrics[2] += 1
    mgr = owm.weather_manager()

    observation = mgr.forecast_at_place(
        city, "3h"
    )  #данной командой стягивается прогноз погоды на ближайшие 5 дней с частотой 3 часа
    if timestamp == "1h":
        timest = timestamps.next_hour()
    elif timestamp == "3h":
        timest = timestamps.next_three_hours()
    elif timestamp == "tomorrow":
        timest = timestamps.tomorrow()
    elif timestamp == "yesterday":
        timest = timestamps.yesterday()
    else:
        timest = timestamps.now()
    w = observation.get_weather_at(timest)
    temp = w.temperature('celsius')['temp']
    #вывод в консоль
    print(" request: " + city + "\ttime: " + str(timest) + "\t" +
          w.detailed_status + "\t" + str(temp))
    processing_time_of_the_request_forecast_weather.append(time.time() -
                                                           time_to_start)
    return json.dumps({
        "city": city,
        "unit": "celsius",
        "temperature": temp,
        "id_service": my_id
    })
Пример #3
0
    def from_dict(cls, the_dict):
        """
        Parses a *COIndex* instance out of a data dictionary. Only certain properties of the data dictionary
        are used: if these properties are not found or cannot be parsed, an exception is issued.

        :param the_dict: the input dictionary
        :type the_dict: `dict`
        :returns: a *COIndex* instance or ``None`` if no data is available
        :raises: *ParseAPIResponseError* if it is impossible to find or parse the data needed to build the result

        """
        if the_dict is None:
            raise exceptions.ParseAPIResponseError('Data is None')
        try:
            # -- reference time (strip away Z and T on ISO8601 format)
            t = the_dict['time'].replace('Z', '+00:00').replace('T', ' ')
            reference_time = formatting.ISO8601_to_UNIXtime(t)

            # -- reception time (now)
            reception_time = timestamps.now('unix')

            # -- location
            lon = float(the_dict['location']['longitude'])
            lat = float(the_dict['location']['latitude'])
            place = location.Location(None, lon, lat, None)

            # -- CO samples
            co_samples = the_dict['data']

        except KeyError:
            raise exceptions.ParseAPIResponseError(
                      ''.join([__name__, ': impossible to parse COIndex']))

        return COIndex(reference_time, place, None, co_samples, reception_time)
    def from_dict(cls, the_dict):
        """
        Parses an *UVIndex* instance out of raw JSON data. Only certain properties of the data are used: if these
        properties are not found or cannot be parsed, an error is issued.

        :param the_dict: the input dict
        :type the_dict: dict
        :returns: an *UVIndex* instance or ``None`` if no data is available
        :raises: *ParseAPIResponseError* if it is impossible to find or parse the
            data needed to build the result, *APIResponseError* if the input dict embeds an HTTP status error

        """
        if the_dict is None:
            raise exceptions.ParseAPIResponseError('Data is None')
        try:
            # -- reference time
            reference_time = the_dict['date']

            # -- reception time (now)
            reception_time = timestamps.now('unix')

            # -- location
            lon = float(the_dict['lon'])
            lat = float(the_dict['lat'])
            place = location.Location(None, lon, lat, None)

            # -- UV intensity
            uv_intensity = float(the_dict['value'])
        except KeyError:
            raise exceptions.ParseAPIResponseError(''.join(
                [__name__, ': impossible to parse UV Index']))
        return UVIndex(reference_time, place, uv_intensity, reception_time)
 def actualize(self):
     """
     Removes from this forecast all the *Weather* objects having a reference
     timestamp in the past with respect to the current timestamp
     """
     current_time = timestamps.now(timeformat='unix')
     actualized_weathers = filter(lambda x: x.reference_time(timeformat='unix') >= current_time, self.weathers)
     self.weathers = list(actualized_weathers)
Пример #6
0
 def is_forecast(self):
     """
     Tells if the current CO observation refers to the future with respect
     to the current date
     :return: bool
     """
     return timestamps.now(timeformat='unix') < \
            self.reference_time(timeformat='unix')
Пример #7
0
 def test_now(self):
     expected = datetime.now()
     result = timestamps.now()
     self.assertEquals(result.year, expected.year)
     self.assertEquals(result.month, expected.month)
     self.assertEquals(result.day, expected.day)
     self.assertEquals(result.hour, expected.hour)
     self.assertEquals(result.minute, expected.minute)
     self.assertEquals(result.second, expected.second)
 def test_now(self):
     expected = datetime.now(timezone.utc)
     result = timestamps.now()
     self.assertEqual(result.year, expected.year)
     self.assertEqual(result.month, expected.month)
     self.assertEqual(result.day, expected.day)
     self.assertEqual(result.hour, expected.hour)
     self.assertEqual(result.minute, expected.minute)
     self.assertEqual(result.second, expected.second)
     self.is_timezone_aware(result)
Пример #9
0
    async def weather_slash(
        self,
        inter: discord.CommandInteraction,
        where: str = commands.Param(description="Place where show weather"),
        when: str = commands.Param(
            autocomplete=when_autocomplete,
            default="UTC Now",
            description="UTC Time offset of weather prediction")):
        when = when.lower()

        if when == "utc now":
            time = timestamps.now()
        elif when == "utc tomorrow":
            time = timestamps.tomorrow()
        else:
            if when.isnumeric():
                when = int(when)
            else:
                if when[-1] != "h":
                    return await inter.send(
                        embed=general_util.generate_error_message(
                            Strings.weather_slash_invalid_when_format),
                        delete_after=Config.base_error_duration)
                when = int(when[:-1])

            time = timestamps.now() + timestamps.timedelta(hours=when)

        try:
            weather = self.get_time_specific_weather(where, time)
        except commands.CommandOnCooldown:
            return await inter.send(embed=general_util.generate_error_message(
                Strings.weather_api_reached_minute_limit),
                                    delete_after=Config.base_error_duration)

        if weather is None:
            return await inter.send(embed=general_util.generate_error_message(
                Strings.populate_string("weather_failed_to_get_weather",
                                        place=where)),
                                    delete_after=Config.base_error_duration)

        embed = generate_weather_embed(weather, where)
        general_util.add_author_footer(embed, inter.author)
        await inter.send(embed=embed)
Пример #10
0
def forecast_weather(city: str, timestamp: str):
	#обращение к внешнему сервису
	mgr = owm.weather_manager()
	observation = mgr.forecast_at_place(city, "3h") #данной командой стягивается прогноз погоды на ближайшие 5 дней с частотой 3 часа
	if timestamp == "1h":
		time = timestamps.next_hour()
	elif timestamp == "3h":
		time = timestamps.next_three_hours() 
	else:
		time = timestamps.now();
	w = observation.get_weather_at(time)
	temp = w.temperature('celsius')['temp']

	#занесение в бд данных (не совсем корректно, ведь у нас прогноз погоды...)
	rc.set(city, temp, ex=time_storage)

	#возвращение текущей погоды
	return temp
Пример #11
0
    async def weather_now(self, ctx: commands.Context, *, place: str):
        await general_util.delete_message(self.bot, ctx)

        try:
            weather = self.get_time_specific_weather(place, timestamps.now())
        except commands.CommandOnCooldown:
            return await ctx.send(embed=general_util.generate_error_message(
                Strings.weather_api_reached_minute_limit),
                                  delete_after=Config.base_error_duration)

        if weather is None:
            return await ctx.send(embed=general_util.generate_error_message(
                Strings.populate_string("weather_failed_to_get_weather",
                                        place=place)),
                                  delete_after=Config.base_error_duration)

        embed = generate_weather_embed(weather, place)
        general_util.add_author_footer(embed, ctx.author)
        await ctx.send(embed=embed)
Пример #12
0
def forecast(city: str, timestamp: str):
    mgr = owm.weather_manager()

    observation = mgr.forecast_at_place(
        city, "3h"
    )  #данной командой стягивается прогноз погоды на ближайшие 5 дней с частотой 3 часа
    if timestamp == "1h":
        time = timestamps.next_hour()
    elif timestamp == "3h":
        time = timestamps.next_three_hours()
    elif timestamp == "tomorrow":
        time = timestamps.tomorrow()
    elif timestamp == "yesterday":
        time = timestamps.yesterday()
    else:
        time = timestamps.now()
    w = observation.get_weather_at(time)
    temp = w.temperature('celsius')['temp']
    #вывод в консоль
    print(" request: " + city + "\ttime: " + str(time) + "\t" +
          w.detailed_status + "\t" + str(temp))
    return json.dumps({"city": city, "unit": "celsius", "temperature": temp})
    def air_quality_history_at_coords(self, lat, lon, start, end=None):
        """
        Queries the OWM AirPollution API for available forecasted air quality indicators around the specified coordinates.

        :param lat: the location's latitude, must be between -90.0 and 90.0
        :type lat: int/float
        :param lon: the location's longitude, must be between -180.0 and 180.0
        :type lon: int/float
        :param start: the object conveying the start value of the search time window
        :type start: int, ``datetime.datetime`` or ISO8601-formatted string
        :param end: the object conveying the end value of the search time window. Values in the future will be clipped
           to the current timestamp. Defaults to the current UNIX timestamp.
        :type end: int, ``datetime.datetime`` or ISO8601-formatted string
        :return: a `list` of *AirStatus* instances or an empty `list` if data is not available
        :raises: *ParseResponseException* when OWM AirPollution API responses' data
            cannot be parsed, *APICallException* when OWM AirPollution API can not be
            reached, *ValueError* for wrong input values
        """
        geo.assert_is_lon(lon)
        geo.assert_is_lat(lat)
        now = timestamps.now(timeformat='unix')
        assert start is not None
        start = formatting.timeformat(start, 'unix')
        if end is None:
            end = now
        else:
            end = formatting.timeformat(end, 'unix')
            if end > now:
                end = now

        params = {'lon': lon, 'lat': lat, 'start': start, 'end': end}
        json_data = self.new_ap_client.get_historical_air_pollution(params)
        try:
            return airstatus.AirStatus.from_dict(json_data)
        except:
            return []
    def create_trigger(self,
                       start,
                       end,
                       conditions,
                       area,
                       alert_channels=None):
        """
        Create a new trigger on the Alert API with the given parameters
        :param start: time object representing the time when the trigger begins to be checked
        :type start: int, ``datetime.datetime`` or ISO8601-formatted string
        :param end: time object representing the time when the trigger ends to be checked
        :type end: int, ``datetime.datetime`` or ISO8601-formatted string
        :param conditions: the `Condition` objects representing the set of checks to be done on weather variables
        :type conditions: list of `pyowm.utils.alertapi30.Condition` instances
        :param area: the geographic are over which conditions are checked: it can be composed by multiple geoJSON types
        :type area: list of geoJSON types
        :param alert_channels: the alert channels through which alerts originating from this `Trigger` can be consumed.
        Defaults to OWM API polling
        :type alert_channels: list of `pyowm.utils.alertapi30.AlertChannel` instances
        :returns:  a *Trigger* instance
        :raises: *ValueError* when start or end epochs are `None` or when end precedes start or when conditions or area
        are empty collections
        """
        assert start is not None
        assert end is not None

        # prepare time period
        unix_start = formatting.to_UNIXtime(start)
        unix_end = formatting.to_UNIXtime(end)
        unix_current = timestamps.now(timeformat='unix')
        if unix_start >= unix_end:
            raise ValueError(
                "The start timestamp must precede the end timestamp")
        delta_millis_start = timestamps.millis_offset_between_epochs(
            unix_current, unix_start)
        delta_millis_end = timestamps.millis_offset_between_epochs(
            unix_current, unix_end)
        the_time_period = {
            "start": {
                "expression": "after",
                "amount": delta_millis_start
            },
            "end": {
                "expression": "after",
                "amount": delta_millis_end
            }
        }

        assert conditions is not None
        if len(conditions) == 0:
            raise ValueError(
                'A trigger must contain at least one condition: you provided none'
            )
        the_conditions = [
            dict(name=c.weather_param, expression=c.operator, amount=c.amount)
            for c in conditions
        ]

        assert area is not None
        if len(area) == 0:
            raise ValueError(
                'The area for a trigger must contain at least one geoJSON type: you provided none'
            )
        the_area = [a.to_dict() for a in area]

        # >>> for the moment, no specific handling for alert channels

        status, payload = self.http_client.post(
            TRIGGERS_URI,
            params={'appid': self.API_key},
            data=dict(time_period=the_time_period,
                      conditions=the_conditions,
                      area=the_area),
            headers={'Content-Type': 'application/json'})
        return Trigger.from_dict(payload)
Пример #15
0
def send_echo(message):
    try:
        mgr = owm.weather_manager()
        observation = mgr.weather_at_place(message.text)
        w = observation.weather
        temperature = w.temperature('celsius')['temp']
        wind = w.wind()['speed']
        current_time = timestamps.now('iso')
        status = w.status


        thunderstorm = u'\U0001F4A8'    
        drizzle = u'\U0001F4A7'         
        rain = u'\U00002614'            
        snowflake = u'\U00002744'       
        snowman = u'\U000026C4'         
        atmosphere = u'\U0001F301'     
        clearSky = u'\U00002600'       
        fewClouds = u'\U000026C5'       
        clouds = u'\U00002601'          
        hot = u'\U0001F525'             
        defaultEmoji = u'\U0001F60A'    


        def set_emojo (weather_status):
            try:
                if str(weather_status) == "Thunderstorm":
                    return thunderstorm
                elif str(weather_status) == "Drizzle":
                    return drizzle
                elif str(weather_status) == "Rain":
                    return rain
                elif str(weather_status) == "Snowflake":
                    return snowflake
                elif str(weather_status) == "Snowman":
                    return snowman
                elif str(weather_status) == "Atmosphere":
                    return atmosphere
                elif str(weather_status) == "ClearSky" or "Clear":
                    return clearSky
                elif str(weather_status) == "FewClouds":
                    return fewClouds
                elif str(weather_status) == "Clouds":
                    return clouds
                elif str(weather_status) == "Hot":
                    return hot
                else:
                    return defaultEmoji        
            except Exception as e:
                print(e)


        answer = "Сейчас: " + str(current_time) + "\n\n"
        answer += "Температура в " + message.text + ": " + str(temperature) + " ℃" + "\n"
        answer += "Ветер: " + str(wind) + " м/с " + "\n"
        answer += "В общем - " + w.detailed_status + set_emojo(status) + "\n\n"

        if temperature < 10:
            answer += "Сейчас очень холодно, одевайся!"
        elif temperature < 20:
            answer += "Сейчас холодно, оденься теплее."
        else:
            answer += "Сейчас тепло, одевай что хочешь."

        bot.send_message(message.chat.id, answer)
        print(status)
    except Exception as e:
        error = str(e)
        bot.send_message(message.chat.id, error + ". Please try again!")
Пример #16
0
 def __init__(self, station_id):
     assert station_id is not None
     self.station_id = station_id
     self.created_at = timestamps.now(timeformat='unix')
     self.measurements = []
Пример #17
0
    def download_satellite_image(self,
                                 metaimage,
                                 x=None,
                                 y=None,
                                 zoom=None,
                                 palette=None):
        """
        Downloads the satellite image described by the provided metadata. In case the satellite image is a tile, then
        tile coordinates and zoom must be provided. An optional palette ID can be provided, if supported by the
        downloaded preset (currently only NDVI is supported)

        :param metaimage: the satellite image's metadata, in the form of a `MetaImage` subtype instance
        :type metaimage: a `pyowm.agroapi10.imagery.MetaImage` subtype
        :param x: x tile coordinate (only needed in case you are downloading a tile image)
        :type x: int or `None`
        :param y: y tile coordinate (only needed in case you are downloading a tile image)
        :type y: int or `None`
        :param zoom: zoom level (only needed in case you are downloading a tile image)
        :type zoom: int or `None`
        :param palette: ID of the color palette of the downloaded images. Values are provided by `pyowm.agroapi10.enums.PaletteEnum`
        :type palette: str or `None`
        :return: a `pyowm.agroapi10.imagery.SatelliteImage` instance containing both image's metadata and data
        """
        if palette is not None:
            assert isinstance(palette, str)
            params = dict(paletteid=palette)
        else:
            palette = PaletteEnum.GREEN
            params = {}
        # polygon PNG
        if isinstance(metaimage, MetaPNGImage):
            prepared_url = metaimage.url
            status, data = self.png_downloader_http_client.get_png(
                prepared_url, params=params)
            img = Image(data, metaimage.image_type)
            return SatelliteImage(
                metaimage,
                img,
                downloaded_on=timestamps.now(timeformat='unix'),
                palette=palette)
        # GeoTIF
        elif isinstance(metaimage, MetaGeoTiffImage):
            prepared_url = metaimage.url
            status, data = self.geotiff_downloader_http_client.get_geotiff(
                prepared_url, params=params)
            img = Image(data, metaimage.image_type)
            return SatelliteImage(
                metaimage,
                img,
                downloaded_on=timestamps.now(timeformat='unix'),
                palette=palette)
        # tile PNG
        elif isinstance(metaimage, MetaTile):
            assert x is not None
            assert y is not None
            assert zoom is not None
            prepared_url = self._fill_url(metaimage.url, x, y, zoom)
            status, data = self.http_client.get_png(prepared_url,
                                                    params=params)
            img = Image(data, metaimage.image_type)
            tile = Tile(x, y, zoom, None, img)
            return SatelliteImage(
                metaimage,
                tile,
                downloaded_on=timestamps.now(timeformat='unix'),
                palette=palette)
        else:
            raise ValueError("Cannot download: unsupported MetaImage subtype")
Пример #18
0
    def search_satellite_imagery(self,
                                 polygon_id,
                                 acquired_from,
                                 acquired_to,
                                 img_type=None,
                                 preset=None,
                                 min_resolution=None,
                                 max_resolution=None,
                                 acquired_by=None,
                                 min_cloud_coverage=None,
                                 max_cloud_coverage=None,
                                 min_valid_data_coverage=None,
                                 max_valid_data_coverage=None):
        """
        Searches on the Agro API the metadata for all available satellite images that contain the specified polygon and
        acquired during the specified time interval; and optionally matching the specified set of filters:
        - image type (eg. GeoTIF)
        - image preset (eg. false color, NDVI, ...)
        - min/max acquisition resolution
        - acquiring satellite
        - min/max cloud coverage on acquired scene
        - min/max valid data coverage on acquired scene

        :param polygon_id: the ID of the reference polygon
        :type polygon_id: str
        :param acquired_from: lower edge of acquisition interval, UNIX timestamp
        :type acquired_from: int
        :param acquired_to: upper edge of acquisition interval, UNIX timestamp
        :type acquired_to: int
        :param img_type: the desired file format type of the images. Allowed values are given by `pyowm.commons.enums.ImageTypeEnum`
        :type img_type: `pyowm.commons.databoxes.ImageType`
        :param preset: the desired preset of the images. Allowed values are given by `pyowm.agroapi10.enums.PresetEnum`
        :type preset: str
        :param min_resolution: minimum resolution for images, px/meters
        :type min_resolution: int
        :param max_resolution: maximum resolution for images, px/meters
        :type max_resolution: int
        :param acquired_by: short symbol of the satellite that acquired the image (eg. "l8")
        :type acquired_by: str
        :param min_cloud_coverage: minimum cloud coverage percentage on acquired images
        :type min_cloud_coverage: int
        :param max_cloud_coverage: maximum cloud coverage percentage on acquired images
        :type max_cloud_coverage: int
        :param min_valid_data_coverage: minimum valid data coverage percentage on acquired images
        :type min_valid_data_coverage: int
        :param max_valid_data_coverage: maximum valid data coverage percentage on acquired images
        :type max_valid_data_coverage: int
        :return: a list of `pyowm.agro10.imagery.MetaImage` subtypes instances
        """
        assert polygon_id is not None
        assert acquired_from is not None
        assert acquired_to is not None
        assert acquired_from <= acquired_to, 'Start timestamp of acquisition window must come before its end'
        if min_resolution is not None:
            assert min_resolution > 0, 'Minimum resolution must be positive'
        if max_resolution is not None:
            assert max_resolution > 0, 'Maximum resolution must be positive'
        if min_resolution is not None and max_resolution is not None:
            assert min_resolution <= max_resolution, 'Mininum resolution must be lower than maximum resolution'
        if min_cloud_coverage is not None:
            assert min_cloud_coverage >= 0, 'Minimum cloud coverage must be non negative'
        if max_cloud_coverage is not None:
            assert max_cloud_coverage >= 0, 'Maximum cloud coverage must be non negative'
        if min_cloud_coverage is not None and max_cloud_coverage is not None:
            assert min_cloud_coverage <= max_cloud_coverage, 'Minimum cloud coverage must be lower than maximum cloud coverage'
        if min_valid_data_coverage is not None:
            assert min_valid_data_coverage >= 0, 'Minimum valid data coverage must be non negative'
        if max_valid_data_coverage is not None:
            assert max_valid_data_coverage >= 0, 'Maximum valid data coverage must be non negative'
        if min_valid_data_coverage is not None and max_valid_data_coverage is not None:
            assert min_valid_data_coverage <= max_valid_data_coverage, 'Minimum valid data coverage must be lower than maximum valid data coverage'

        # prepare params
        params = dict(appid=self.API_key,
                      polyid=polygon_id,
                      start=acquired_from,
                      end=acquired_to)
        if min_resolution is not None:
            params['resolution_min'] = min_resolution
        if max_resolution is not None:
            params['resolution_max'] = max_resolution
        if acquired_by is not None:
            params['type'] = acquired_by
        if min_cloud_coverage is not None:
            params['clouds_min'] = min_cloud_coverage
        if max_cloud_coverage is not None:
            params['clouds_max'] = max_cloud_coverage
        if min_valid_data_coverage is not None:
            params['coverage_min'] = min_valid_data_coverage
        if max_valid_data_coverage is not None:
            params['coverage_max'] = max_valid_data_coverage

        # call API
        status, data = self.http_client.get_json(SATELLITE_IMAGERY_SEARCH_URI,
                                                 params=params)

        result_set = SatelliteImagerySearchResultSet(
            polygon_id, data, timestamps.now(timeformat='unix'))

        # further filter by img_type and/or preset (if specified)
        if img_type is not None and preset is not None:
            return result_set.with_img_type_and_preset(img_type, preset)
        elif img_type is not None:
            return result_set.with_img_type(img_type)
        elif preset is not None:
            return result_set.with_preset(preset)
        else:
            return result_set.all()