{"id":25066807,"url":"https://github.com/packruble/weather_pack","last_synced_at":"2025-04-14T19:33:22.639Z","repository":{"id":61976088,"uuid":"554189076","full_name":"PackRuble/weather_pack","owner":"PackRuble","description":"The project is designed to obtain weather via the OpenWeatherMap API. With handy features. :)","archived":false,"fork":false,"pushed_at":"2025-02-06T07:31:46.000Z","size":2639,"stargazers_count":4,"open_issues_count":14,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T07:51:11.981Z","etag":null,"topics":["api","dart","flutter","openweathermap","openweathermap-api","weather"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/weather_pack","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PackRuble.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-19T11:55:51.000Z","updated_at":"2025-02-06T07:31:49.000Z","dependencies_parsed_at":"2025-01-30T11:22:38.395Z","dependency_job_id":"1c7be746-d303-4444-bd89-cdd1cd238487","html_url":"https://github.com/PackRuble/weather_pack","commit_stats":{"total_commits":30,"total_committers":1,"mean_commits":30.0,"dds":0.0,"last_synced_commit":"5b54f986655366cee2475a7190d7f3aa7fe5992a"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PackRuble%2Fweather_pack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PackRuble%2Fweather_pack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PackRuble%2Fweather_pack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PackRuble%2Fweather_pack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PackRuble","download_url":"https://codeload.github.com/PackRuble/weather_pack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248946248,"owners_count":21187473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","dart","flutter","openweathermap","openweathermap-api","weather"],"created_at":"2025-02-06T20:28:03.411Z","updated_at":"2025-04-14T19:33:22.590Z","avatar_url":"https://github.com/PackRuble.png","language":"Dart","funding_links":["https://www.buymeacoffee.com/"],"categories":[],"sub_categories":[],"readme":"\u003ca href=\"https://github.com/PackRuble/weather_pack/\"\u003e\u003cimg src=\"https://github.com/PackRuble/weather_pack/blob/master/assets/images/banner.png?raw=true\"/\u003e\u003c/a\u003e\n\n\n## weather_pack\n\n[![telegram_badge]][telegram_link]\n[![pub_badge]][pub_link]\n[![repo_star_badge]][repo_link]\n[![mit_license_badge]][mit_license]\n[![code_size_badge]][repo_link]\n\nA quick way to get access to weather conditions 🌦.\n\n\u003e Put a ![][pub_like_icon] on [Pub][pub_link] and favorite ⭐ on [Github][repo_link] to keep up with changes and not miss new releases!\n\n**Why choose this library?**\n\n**_basic:_**\n1. 🚲 Easy to use - you only need the APIKEY.\n2. 🏝 Built-in geocoding - search for locations by assumed names or by coordinates.\n3. 🩺 Various units of measurement - speed, temperature, pressure and cardinal points.\n4. 🌤 There are original weather icons.\n\n\u003cdetails\u003e \u003csummary\u003e \u003cb\u003e\u003ci\u003eadvanced:\u003c/i\u003e\u003c/b\u003e (Click to open)\u003c/summary\u003e\n\u003col\u003e\n\u003cli\u003e🔮 At least one release application is already based on this package. Therefore, there is an \nadditional guarantee of security and timely updates of this package.\u003c/li\u003e\n\u003cli\u003e🔓 There is a method for checking your api for correctness.\u003c/li\u003e\n\u003cli\u003e🧱 It is very easy to customize data models. Create your own data models and take only what \nyou need from the built-in ones.\u003c/li\u003e\n\u003cli\u003e🧾 The code is well documented and each class is labeled and decoded. There are unit tests \nfor the main functions of the package.\u003c/li\u003e\n\u003cli\u003e🦺 Safe unpacking of types. If the server stops outputting values - your weather model \nwill have a null field and the application will not crash.\u003c/li\u003e\n\u003cli\u003e🔧 This package has no unnecessary dependencies and contains minimal code. \nAlso, all platforms are supported.\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/details\u003e\n\n\n## Endpoints openweathermap.org\n\nLet's agree to designate _Openweathermap_ as _**OWM**_.\n\nThe library uses the following site endpoints [openweathermap.org](https://openweathermap.org/):\n\n| api.openweathermap.org\u003cbr/\u003e{/path/endpoint} | A {Class.method} that uses this endpoint          | See more               |\n|---------------------------------------------|---------------------------------------------------|------------------------|\n| /data/2.5/weather                           | `WeatherService.currentWeatherByLocation`         | [current]              |\n| /data/2.5/onecall                           | `WeatherService.oneCallWeatherByLocation`         | [one-call-api]         |\n| /data/3.0/onecall                           | `WeatherService.oneCallWeatherByLocation`         | [one-call-3]           |\n| /geo/1.0/direct                             | `GeocodingService.getLocationByCityName`          | [geocoding-direct]     |\n| /geo/1.0/reverse                            | `GeocodingService.getLocationByCoordinates`       | [geocoding-reverse]    |\n| /geo/1.0/zip                                | `GeocodingService.getLocationByZipAndCountryCode` | [geocoding-direct_zip] |\n\n\u003c!-- Links --\u003e\n[current]: https://openweathermap.org/current\n[one-call-api]: https://openweathermap.org/api/one-call-api\n[one-call-3]: https://openweathermap.org/api/one-call-3\n[geocoding-direct]: https://openweathermap.org/api/geocoding-api#direct\n[geocoding-direct_zip]: https://openweathermap.org/api/geocoding-api#direct_zip\n[geocoding-reverse]: https://openweathermap.org/api/geocoding-api#reverse\n\n\n## Table of Contents\n\u003c!-- TOC --\u003e\n  * [weather_pack](#weather_pack)\n  * [Endpoints openweathermap.org](#endpoints-openweathermaporg)\n  * [Table of Contents](#table-of-contents)\n  * [Installing](#installing)\n  * [Getting Started](#getting-started)\n  * [Usage weather service](#usage-weather-service)\n  * [Usage geocoding service](#usage-geocoding-service)\n  * [Usage units measure](#usage-units-measure)\n  * [Exception handling](#exception-handling)\n  * [Usage custom client](#usage-custom-client)\n  * [Usage weather icons](#usage-weather-icons)\n  * [API key testing](#api-key-testing)\n  * [Resources](#resources)\n  * [Author](#author)\n  * [Support](#support)\n\u003c!-- TOC --\u003e\n\n\n## Installing\n\n1. Add dependency to your `pubspec.yaml`:\n   ```yaml\n   dependencies:\n     weather_pack: ^\u003clatest_version\u003e\n    ```\n2. Run the command: `flutter pub get`\n3. Use in your code:\n   ```dart\n   import 'package:weather_pack/weather_pack.dart';\n   ```\n4. \\*Additionally, pull package locally to examine `example` folder:\n   ```shell\n   flutter pub unpack\n    ```\n   - `weather_in_console` - Dart console application\n   - `create_code_for_readme` - all examples from current manual\n   - `example` - easy use\n\n## Getting Started\n\nThe easiest way to get the current weather:\n```dart\nFuture\u003cvoid\u003e main() async {\n  const api = 'YOUR_APIKEY'; // TODO: change to your openweathermap APIkey\n  final wService = WeatherService(api);\n\n  // get the current weather in Amsterdam\n  final WeatherCurrent currently = await wService.currentWeatherByLocation(\n      latitude: 52.374, longitude: 4.88969);\n  \n  print(currently);\n}\n```\n\nYou can also change the request language:\n```dart\nfinal lang = WeatherLanguage.arabic;\n\nfinal wService = WeatherService(api, language: lang);\n```\n\n\u003cdetails\u003e \u003csummary\u003e \u003cb\u003e\u003ci\u003eSupported languages:\u003c/i\u003e\u003c/b\u003e (Click to open)\u003c/summary\u003e\n\n1. Afrikaans\n2. Albanian\n3. Arabic\n4. Azerbaijani\n5. Bulgarian\n6. Catalan\n7. Czech\n8. Danish\n9. German\n10. Greek\n11. English\n12. Basque\n13. Persian\n14. Farsi\n15. Finnish\n16. French\n17. Galician\n18. Hebrew\n19. Hindi\n20. Croatian\n21. Hungarian\n22. Indonesian\n23. Italian\n24. Japanese\n25. Korean\n26. Latvian\n27. Latvian\n28. Macedonian\n29. Norwegian\n30. Dutch\n31. Polish\n32. Portuguese\n33. Português Brasil\n34. Romanian\n35. Russian\n36. Swedish\n37. Slovak\n38. Slovenian\n39. Spanish\n40. Serbian\n41. Thai\n42. Turkish\n43. Ukrainian\n44. Vietnamese\n45. Chinese Simplified\n46. Chinese Traditional\n47. Zulu\n\n\u003c/details\u003e\n\nAccording to OWM service ([See more](https://openweathermap.org/current#multi)):\n\u003e You can use the `lang` parameter to get the output in your language.\n\u003e \n\u003e Translation is applied for the `city name` and `description` fields.\n\n\n## Usage weather service\n\nNow there are two weather models - `WeatherCurrent` and `WeatherOneCall`.\n\n`WeatherOneCall` includes:\n1. `WeatherCurrent`\n2. `List\u003cWeatherHourly\u003e`\n3. `List\u003cWeatherMinutely\u003e`\n4. `List\u003cWeatherDaily\u003e`\n5. `List\u003cWeatherAlert\u003e`\n\n**How to use?**\n\nYou can get the weather in the following way:\n\n```dart\nFuture\u003cvoid\u003e getOnecallWeatherWays({String api = 'Your_APIkey'}) async {\n  final wService2_5 = WeatherService(api, oneCallApi: OneCallApi.api_2_5);\n\n  final WeatherOneCall onecall2_5 = await wService2_5.oneCallWeatherByLocation(\n      latitude: 52.374, longitude: 4.88969);\n\n  print(onecall2_5);\n\n  // if you use the \"One Call API 3.0\" subscription that...\n\n  final wService3_0 = WeatherService(api, oneCallApi: OneCallApi.api_3_0);\n\n  final WeatherOneCall onecall3_0 = await wService3_0.oneCallWeatherByLocation(\n      latitude: 52.374, longitude: 4.88969);\n\n  print(onecall3_0);\n}\n```\n\n**_Why do you only use the weather search by coordinates?_**\n\nAccording to the website OWM:\n\u003e Please use Geocoder API if you need automatic convert city names and zip-codes to geo \n\u003e coordinates and the other way around.\n\u003e \n\u003e Please note that built-in geocoder has been deprecated. Although it is still available for use, \n\u003e bug fixing and updates are no longer available for this functionality.\n\n\n## Usage geocoding service\n\n`GeocodingService` is a service for easy location search when working with geographical names\nand coordinates. Supports both the direct and reverse methods:\n- Direct geocoding converts the specified name of a location or zip/post code into\n  the exact geographical coordinates;\n- Reverse geocoding converts the geographical coordinates into the names of the nearby locations;\n\nYou can find out more at this link: [Geocoding API OpenWeather](https://openweathermap.org/api/geocoding-api)\n\n**How to use?**\n\nCreate `GeocodingService` in the following way:\n```dart\nfinal String cityName = 'suggested location name';\nfinal String apiKey = 'your api key for OWM';\n\nfinal GeocodingService gService = GeocodingService(apiKey);\n```\n\nTo find using place names use direct geocoding:\n```dart\nfinal List\u003cPlaceGeocode\u003e places = await gService.getLocationByCityName(cityName);\n```\n\nor use reverse geocoding:\n```dart\nfinal List\u003cPlaceGeocode\u003e places = await gService.getLocationByCoordinates(\n    latitude: 52.374, longitude: 4.88969);\n```\n\nTo find using country code and zip code use zip geocoding:\n```dart\nfinal PlaceGeocode place = await gService.getLocationByZipAndCountryCode(\n  zipCode: 'E14',\n  countryCode: 'GB',\n);\n```\n\n\n## Usage units measure\n\nBy default, all weather models, e.g. `WeatherCurrent`, have measurable values of type `double`.\nTo display the data in a convenient format, it is necessary use the conversion method `value`\nor `valueToString`:\n```dart\nvoid worksTempUnits({\n  double temp = 270.78, // ex. received from [WeatherCurrent.temp]\n  int precision = 3,\n  Temp unitsMeasure = Temp.celsius,\n}) {\n  // The default temperature is measured in Kelvin of the `double` type.\n  // We need the temperature to be displayed in Celsius to 3 decimal places\n\n  print(unitsMeasure.value(temp, precision)); // `-2.37` type `double`\n  print(unitsMeasure.valueToString(temp, precision)); // `-2.370` type `String`\n\n  // if precision is 0:\n  print(unitsMeasure.value(temp, 0)); // `-2.0` type `double`\n  print(unitsMeasure.valueToString(temp, 0)); // `-2` type `String`\n}\n```\n\n_By and large, the `valueToString()` method is needed to display correctly in ui,\nand the `value()` method is for accurate calculations._\n\nThere are several units of measurement:\n\n| Units of measure | Class            | Supported units                     | Conversion |\n|------------------|------------------|-------------------------------------|------------|\n| Temperature      | `Temp`           | kelvin, celsius, fahrenheit         | +          |\n| Speed            | `Speed`          | ms, mph, kph                        | +          |\n| Pressure         | `Pressure`       | hectoPa, mbar, mmHg, kPa, atm, inHg | +          |\n| Cardinal points  | `SideOfTheWorld` | n, ne, e, se, s, sw, w, nw          | +(another) |\n\n💡 **Tip**: The `SideOfTheWorld` enum contains a static method `fromDegrees()` for converting degrees\nto cardinal directions.\n\n\n## Exception handling\n\nEach of the methods in the `WeatherService` and `GeocodingService` services can throw an `OwmApiException` exception. You can process them as follows:\n\n```dart\nvoid exceptionHandling() async {\n  final wService = WeatherService('bRoKen_aPi');\n\n  WeatherCurrent? current;\n  try {\n    current =\n        await wService.currentWeatherByLocation(latitude: 1, longitude: 1);\n  } on OwmApiException catch (e, s) {\n    print(e.code);\n    print(e.message);\n    print(s);\n  }\n}\n```\n\n\n## Usage custom client\n\nFor `GeocodingService` and `WeatherService` you can create a custom `OWMBuilder` for debugging and logging cases:\n\n```dart\nclass OWMBuilderCustom extends OWMBuilder {\n  /// We output the url to the console for debugging and logging\n  @override\n  Future\u003cT\u003e getData\u003cT\u003e(\n      {required Uri uri, required T Function(dynamic data) builder}) {\n    print(uri);\n    return super.getData(uri: uri, builder: builder);\n  }\n}\n\nvoid workOwmBuilder({\n  String api = 'your_apikey',\n}) async {\n  final customOWMBuilder = OWMBuilderCustom();\n  final gService = GeocodingService(api, owmBuilder: customOWMBuilder);\n\n  final List\u003cPlaceGeocode\u003e places = await gService.getLocationByCoordinates(\n      latitude: 52.374, longitude: 4.88969);\n\n  print(places);\n}\n```\n\nFor `OWMTestService` you can create a custom `Client`. A more low-level way, would require an explicit dependency on the `http` package:\n\n```dart\nclass CustomClient extends IOClient {\n  /// We output the url to the console\n  @override\n  Future\u003cResponse\u003e get(Uri url, {Map\u003cString, String\u003e? headers}) {\n    print(url);\n    return super.get(url, headers: headers);\n  }\n}\n\n/// We output the url to the console for debugging\nvoid workCustomClient({\n  String api = 'your_apikey',\n}) async {\n  final customClient = CustomClient();\n  final testService = OWMTestService(api, customClient);\n\n  final bool isValidKey = await testService.isValidApikey();\n\n  print(isValidKey);\n}\n```\n\n## Usage weather icons\n\nYou can use weather icons provided by the OWM service. See more about [weather conditions](https://openweathermap.org/weather-conditions).\n\nIcons are stored locally in this package at the path `assets/weather_icons/`. \nThey are ordered according to [Declaring resolution-aware image assets](https://docs.flutter.dev/development/ui/assets-and-images#resolution-aware).\nThis reflects the following correspondences:\n\n```text\n100*100 - in default(implied resolution @1)\n200x200 - @2\n300x300 - @3\n400x400 - @4\n```\n\nwith the preservation of image quality.\n\n**How to use?**\n\nGet the weather icon in a safe way:\n```dart\nImage getWeatherIcon(String weatherIcon) {\n  return Image.asset(\n    ImagePathWeather.getPathWeatherIcon(weatherIcon),\n    filterQuality: FilterQuality.high, // optional\n    package: ImagePathWeather.packageName,\n  );\n}\n```\n\nor to process it completely by hand:\n```dart\nWidget getWeatherIcon(WeatherCurrent weather) {\n  return Image.asset(\n    'assets/weather_icons/${weather.weatherIcon}.png', // icon path\n    package: 'weather_pack', // name package\n    filterQuality: FilterQuality.high, // optional\n    errorBuilder: (c, e, s) =\u003e Text(e), // will return the widget in case of an error\n  );\n}\n```\n\nIn this case, you can use the best quality regardless of platform resolution by specifying `@4` to path:\n```text\n'assets/weather_icons/@4/$weatherIcon.png'\n```\n\n## API key testing\n\nIt is possible to test the API key. \nTo do this, the `OWMTestService` class has a method `isValidApikeyForOneCall`:\n```dart\n/// If the apikey is valid, `OWMApiTest` methods will return `true`\nFuture\u003cvoid\u003e testAPIkey({\n  String testedAPIkey = 'your_apikey',\n}) async {\n  // checking key for geocoding service and for (fetching WeatherCurrent)\n  final bool isValid = await OWMTestService(testedAPIkey).isValidApikey();\n\n  // checking key for \"One Call API 2.5\" service (fetching WeatherOneCall)\n  final bool isValidOneCall2 = await OWMTestService(testedAPIkey)\n      .isValidApikeyForOneCall(OneCallApi.api_2_5);\n\n  // or\n  // checking key for \"One Call by Call 3.0\" service (fetching WeatherOneCall)\n  final bool isValidOneCall3 = await OWMTestService(testedAPIkey)\n      .isValidApikeyForOneCall(OneCallApi.api_3_0);\n}\n```\n\n## Resources\n\n- folder [`example`](https://github.com/PackRuble/weather_pack/tree/master/example).\n  There is a simple example of how to use the basic functions of the package, as well as a console mini-application without using flutter\n    - [![habr_badge]][habr_link] [Как создать консольное приложение на языке dart, используя пакет weather_pack?][habr_link]\n    - [![medium_badge]][medium_link] [How to create a console application in dart using the weather_pack package?][medium_link]\n\n\u003c!-- Links --\u003e\n\n[habr_badge]: https://img.shields.io/badge/habr-RU-F9DFCF?style=plastic\u0026logo=habr\n[habr_link]: https://habr.com/ru/post/708854/\n[medium_badge]: https://img.shields.io/badge/medium-EN-C8A2C8?style=plastic\u0026logo=medium\n[medium_link]: https://medium.com/@pack.ruble/how-to-create-a-console-application-in-dart-using-the-weather-pack-package-68ed814f1903\n\n![](example/weather_in_console/assets/result_in_console.gif)\n\nFeel free to suggest materials for inclusion in this list ^_~\n\n\n## Author\n\nYou can contact me or check out my activities on the following platforms:\n\n- [Github](https://github.com/PackRuble)\n- [Telegram Group](https://t.me/+AkGV73kZi_Q1YTMy)\n- [StackOverflow](https://stackoverflow.com/users/17991131/ruble)\n- [Medium](https://medium.com/@pack.ruble)\n- [Habr](https://habr.com/ru/users/PackRuble/)\n\n\u003e Made with ❤️. Enjoy it!\n\n## Support\n\nFeel free to contribute to this project.\n\nIf you find a bug or want a feature, but don't know how to fix/implement it, please fill an [issue][issue].  \n\nIf you fixed a bug or implemented a feature, please send a [pull request][pr]. Use `dev` branch for this.\n\n---\n\n\u003ch6\u003e\n🏷 tags: weather, openWeather, openweathermap, weather forecast, metcast, W/F, reverse/direct geocoding, units measure, temperature, pressure, speed \n\u003c/h6\u003e\n\n\u003c!-- Links --\u003e\n\n[mit_license_badge]: https://img.shields.io/badge/license-MIT-green?style=plastic\n[mit_license]: https://github.com/PackRuble/weather_pack/blob/master/LICENSE\n[code_size_badge]: https://img.shields.io/github/languages/code-size/PackRuble/weather_pack?style=plastic\n[repo_star_badge]: https://img.shields.io/github/stars/PackRuble/weather_pack?style=plastic\n[repo_link]: https://github.com/PackRuble/weather_pack\n[pub_badge]: https://img.shields.io/pub/v/weather_pack.svg?style=plastic\u0026color=orange\n[pub_link]: https://pub.dev/packages/weather_pack\n[pub_like_icon]: https://pub.dev/static/hash-ffjootqp/img/like-active.svg\n[buy_me_a_coffee]: https://www.buymeacoffee.com/\u003c\u003e\n[issue]: https://github.com/PackRuble/weather_pack/issues\n[pr]: https://github.com/PackRuble/weather_pack/pulls\n[telegram_badge]: https://img.shields.io/badge/telegram-❤️-33cccc?style=plastic\u0026logo=telegram\n[telegram_link]: https://t.me/+AkGV73kZi_Q1YTMy","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpackruble%2Fweather_pack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpackruble%2Fweather_pack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpackruble%2Fweather_pack/lists"}