Utilidad meteorológica de la consola C # usando .Net

¿Qué necesita obtener y aprender para comenzar a obtener un pronóstico del tiempo de 5 días? 





Primero, elija un proveedor de datos meteorológicos. En segundo lugar, analizar de qué forma se suministran los datos y cómo podemos recopilarlos y visualizarlos utilizando el lenguaje de programación C #. 





Elegí el servicio Accuweather como mi proveedor de datos meteorológicos. La cuenta gratuita actualmente permite 50 solicitudes por día. Esto es suficiente para poder ver los datos meteorológicos varias veces al día (¡incluso puede compartirlos con un amigo!). 





Para registrarse, siga el enlace: https://developer.accuweather.com . Después de registrarse, debe hacer clic en el botón "Agregar una nueva aplicación" y completar un breve formulario. Como resultado, recibirás tu ApiKey personal con la que luego podrás recibir datos actualizados. 





Entonces comienza la diversión. Analizaremos cómo y de qué forma llega la información y qué se necesita para recibir los datos meteorológicos de una ciudad en particular. 





En la sección "Referencia de API", la primera lista se establece en la sección " API de ubicaciones " y comencemos. De cara al futuro, diré de inmediato que no puede simplemente tomar y enviar el nombre de la ciudad en una solicitud GET. Para hacer esto, primero necesitamos obtener la clave de ubicación de una ciudad específica. Este valor se presenta en forma de números y es único para cada ciudad. 





Entonces, en la sección API de ubicaciones, estamos interesados ​​en el método de búsqueda de ciudades . Leímos una breve descripción del mismo: Devuelve información para una serie de ciudades que coinciden con el texto de búsqueda. Tome nota inmediatamente de que se nos devuelve una matriz con los nombres de las ciudades. 





En la página de la solicitud, inserte ApiKey, el nombre de la ciudad de interés y ponga RU, si queremos recibir datos localizados. 





Después de hacer clic en el botón "Enviar esta solicitud" a continuación en la página, recibirá el resultado de la ejecución. En mi caso, se ve así:





[
  {
    "Version": 1,
    "Key": "292332",
    "Type": "City",
    "Rank": 21,
    "LocalizedName": "Chelyabinsk",
    "EnglishName": "Chelyabinsk",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "ASI",
      "LocalizedName": "Asia",
      "EnglishName": "Asia"
    },
    "Country": {
      "ID": "RU",
      "LocalizedName": "Russia",
      "EnglishName": "Russia"
    },
    "AdministrativeArea": {
      "ID": "CHE",
      "LocalizedName": "Chelyabinsk",
      "EnglishName": "Chelyabinsk",
      "Level": 1,
      "LocalizedType": "Oblast",
      "EnglishType": "Oblast",
      "CountryID": "RU"
    },
    "TimeZone": {
      "Code": "YEKT",
      "Name": "Asia/Yekaterinburg",
      "GmtOffset": 5,
      "IsDaylightSaving": false,
      "NextOffsetChange": null
    },
    "GeoPosition": {
      "Latitude": 55.16,
      "Longitude": 61.403,
      "Elevation": {
        "Metric": {
          "Value": 233,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 764,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "Chelyabinsk",
        "EnglishName": "Chelyabinsk"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts",
      "ForecastConfidence"
    ]
  }
]
      
      



Como puede ver, hemos devuelto una matriz de una ciudad. ¿Cómo se verá el resultado si hay dos o más ciudades con el mismo nombre?





[
  {
    "Version": 1,
    "Key": "294021",
    "Type": "City",
    "Rank": 10,
    "LocalizedName": "",
    "EnglishName": "Moscow",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "ASI",
      "LocalizedName": "",
      "EnglishName": "Asia"
    },
    "Country": {
      "ID": "RU",
      "LocalizedName": "",
      "EnglishName": "Russia"
    },
    "AdministrativeArea": {
      "ID": "MOW",
      "LocalizedName": "",
      "EnglishName": "Moscow",
      "Level": 1,
      "LocalizedType": "  ",
      "EnglishType": "Federal City",
      "CountryID": "RU"
    },
    "TimeZone": {
      "Code": "MSK",
      "Name": "Europe/Moscow",
      "GmtOffset": 3,
      "IsDaylightSaving": false,
      "NextOffsetChange": null
    },
    "GeoPosition": {
      "Latitude": 55.752,
      "Longitude": 37.619,
      "Elevation": {
        "Metric": {
          "Value": 155,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 508,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "Tsentralny",
        "EnglishName": "Tsentralny"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts",
      "ForecastConfidence"
    ]
  },
  {
    "Version": 1,
    "Key": "1397263",
    "Type": "City",
    "Rank": 85,
    "LocalizedName": "",
    "EnglishName": "Moskwa",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "EUR",
      "LocalizedName": "",
      "EnglishName": "Europe"
    },
    "Country": {
      "ID": "PL",
      "LocalizedName": "",
      "EnglishName": "Poland"
    },
    "AdministrativeArea": {
      "ID": "10",
      "LocalizedName": " ",
      "EnglishName": "Łódź",
      "Level": 1,
      "LocalizedType": "",
      "EnglishType": "Voivodship",
      "CountryID": "PL"
    },
    "TimeZone": {
      "Code": "CET",
      "Name": "Europe/Warsaw",
      "GmtOffset": 1,
      "IsDaylightSaving": false,
      "NextOffsetChange": "2021-03-28T01:00:00Z"
    },
    "GeoPosition": {
      "Latitude": 51.816,
      "Longitude": 19.657,
      "Elevation": {
        "Metric": {
          "Value": 238,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 780,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "- ",
        "EnglishName": "Łódź East"
      },
      {
        "Level": 3,
        "LocalizedName": "",
        "EnglishName": "Nowosolna"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts",
      "ForecastConfidence",
      "FutureRadar",
      "MinuteCast",
      "Radar"
    ]
  },
  {
    "Version": 1,
    "Key": "580845",
    "Type": "City",
    "Rank": 85,
    "LocalizedName": "",
    "EnglishName": "Moskva",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "ASI",
      "LocalizedName": "",
      "EnglishName": "Asia"
    },
    "Country": {
      "ID": "RU",
      "LocalizedName": "",
      "EnglishName": "Russia"
    },
    "AdministrativeArea": {
      "ID": "KIR",
      "LocalizedName": "",
      "EnglishName": "Kirov",
      "Level": 1,
      "LocalizedType": "",
      "EnglishType": "Republic",
      "CountryID": "RU"
    },
    "TimeZone": {
      "Code": "MSK",
      "Name": "Europe/Moscow",
      "GmtOffset": 3,
      "IsDaylightSaving": false,
      "NextOffsetChange": null
    },
    "GeoPosition": {
      "Latitude": 57.968,
      "Longitude": 49.104,
      "Elevation": {
        "Metric": {
          "Value": 207,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 678,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "Verkhoshizhemsky",
        "EnglishName": "Verkhoshizhemsky"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts",
      "ForecastConfidence"
    ]
  },
  {
    "Version": 1,
    "Key": "2488304",
    "Type": "City",
    "Rank": 85,
    "LocalizedName": "",
    "EnglishName": "Moskva",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "ASI",
      "LocalizedName": "",
      "EnglishName": "Asia"
    },
    "Country": {
      "ID": "RU",
      "LocalizedName": "",
      "EnglishName": "Russia"
    },
    "AdministrativeArea": {
      "ID": "PSK",
      "LocalizedName": "",
      "EnglishName": "Pskov",
      "Level": 1,
      "LocalizedType": "",
      "EnglishType": "Oblast",
      "CountryID": "RU"
    },
    "TimeZone": {
      "Code": "MSK",
      "Name": "Europe/Moscow",
      "GmtOffset": 3,
      "IsDaylightSaving": false,
      "NextOffsetChange": null
    },
    "GeoPosition": {
      "Latitude": 57.449,
      "Longitude": 29.185,
      "Elevation": {
        "Metric": {
          "Value": 161,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 528,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "Porkhovsky",
        "EnglishName": "Porkhovsky"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts",
      "Radar"
    ]
  },
  {
    "Version": 1,
    "Key": "580847",
    "Type": "City",
    "Rank": 85,
    "LocalizedName": "",
    "EnglishName": "Moskva",
    "PrimaryPostalCode": "",
    "Region": {
      "ID": "ASI",
      "LocalizedName": "",
      "EnglishName": "Asia"
    },
    "Country": {
      "ID": "RU",
      "LocalizedName": "",
      "EnglishName": "Russia"
    },
    "AdministrativeArea": {
      "ID": "TVE",
      "LocalizedName": "",
      "EnglishName": "Tver'",
      "Level": 1,
      "LocalizedType": "",
      "EnglishType": "Oblast",
      "CountryID": "RU"
    },
    "TimeZone": {
      "Code": "MSK",
      "Name": "Europe/Moscow",
      "GmtOffset": 3,
      "IsDaylightSaving": false,
      "NextOffsetChange": null
    },
    "GeoPosition": {
      "Latitude": 56.918,
      "Longitude": 32.163,
      "Elevation": {
        "Metric": {
          "Value": 251,
          "Unit": "m",
          "UnitType": 5
        },
        "Imperial": {
          "Value": 823,
          "Unit": "ft",
          "UnitType": 0
        }
      }
    },
    "IsAlias": false,
    "SupplementalAdminAreas": [
      {
        "Level": 2,
        "LocalizedName": "Penovsky",
        "EnglishName": "Penovsky"
      }
    ],
    "DataSets": [
      "AirQualityCurrentConditions",
      "AirQualityForecasts",
      "Alerts"
    ]
  }
]
      
      



, . , Key, . .





, , . , C#. , C# VSCodium. OpenSuSe Leap 15.2.





, ApiKey, , ApiKey , ApiKey .





, UserApi:





namespace habraweatherappconsole
{
    public class UserApi
    {
        public string UserApiProperty { get;set; }
    }
}
      
      



, , :





        /// <summary>
        ///      APIKey  
        /// </summary>
        public static void ReadUserApiToLocalStorage()
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(ObservableCollection<UserApi>));

            try
            {
                using (StreamReader sr = new StreamReader("UserApi.xml"))
                {
                    userApiList = xmlSerializer.Deserialize(sr) as ObservableCollection<UserApi>;
                }
            }

            catch(Exception ex)
            {
                /*      .  ,     
                /     .       - -    
                /          ?
                */
            }
        }
      
      



, XML , , , XML.





. , , . , Json . , .





, :





    "Version": 1,
    "Key": "292332",
    "Type": "City",
    "Rank": 21,
    "LocalizedName": "Chelyabinsk",
    "EnglishName": "Chelyabinsk",
    "PrimaryPostalCode": "",

      
      



API , , , ( , ) , . , , - .





, :





    public class RootBasicCityInfo    {
        public int Version { get; set; } 
        public string Key { get; set; } 
        public string Type { get; set; } 
        public int Rank { get; set; } 
        public string LocalizedName { get; set; } 
        public string EnglishName { get; set; } 
        public string PrimaryPostalCode { get; set; } 

      
      



, json :





      "Region": {
        "ID": "ASI",
        "LocalizedName": "",
        "EnglishName": "Asia"
      },
      "Country": {
        "ID": "RU",
        "LocalizedName": "",
        "EnglishName": "Russia"
      },
      "AdministrativeArea": {
        "ID": "MOW",
        "LocalizedName": "",
        "EnglishName": "Moscow",
        "Level": 1,
        "LocalizedType": "  ",
        "EnglishType": "Federal City",
        "CountryID": "RU"
      },

      
      



, Region, Country, AdministrativeArea :





public class Region    {
        public string ID { get; set; } 
        public string LocalizedName { get; set; } 
        public string EnglishName { get; set; } 
    }

    public class Country    {
        public string ID { get; set; } 
        public string LocalizedName { get; set; } 
        public string EnglishName { get; set; } 
    }

    public class AdministrativeArea    {
        public string ID { get; set; } 
        public string LocalizedName { get; set; } 
        public string EnglishName { get; set; } 
        public int Level { get; set; } 
        public string LocalizedType { get; set; } 
        public string EnglishType { get; set; } 
        public string CountryID { get; set; } 
    }

      
      



:





    public class RootBasicCityInfo    {
        public int Version { get; set; } 
        public string Key { get; set; } 
        public string Type { get; set; } 
        public int Rank { get; set; } 
        public string LocalizedName { get; set; } 
        public string EnglishName { get; set; } 
        public string PrimaryPostalCode { get; set; } 
        public Region Region { get; set; } 
        public Country Country { get; set; } 
        public AdministrativeArea AdministrativeArea { get; set; } 
        public TimeZone TimeZone { get; set; } 
        public GeoPosition GeoPosition { get; set; } 
        public bool IsAlias { get; set; } 
        public List<SupplementalAdminArea> SupplementalAdminAreas { get; set; } 
        public List<string> DataSets { get; set; } 
    }

      
      



, , :





using System;
using System.Collections.ObjectModel;
using System.Net;
using System.Text.Json;

using static System.Console;

namespace habraweatherappconsole
{
    /// <summary>
    ///     
    ///       .
    /// </summary>
    public static class SearchCity
    {
        /// <summary>
        ///      .
        ///       
        ///       MainMenu.
        /// </summary>
        /// <param name="formalCityName"></param>
        public static void GettingListOfCitiesOnRequest(string formalCityName)
        {
            //  ApiKey  
            string apiKey = UserApiManager.userApiList[0].UserApiProperty;
            try
            {
                string jsonOnWeb = $"http://dataservice.accuweather.com/locations/v1/cities/search?apikey={apiKey}&q={formalCityName}";

                WebClient webClient = new WebClient();
                string prepareString = webClient.DownloadString(jsonOnWeb);

                ObservableCollection<RootBasicCityInfo> rbci = JsonSerializer.Deserialize<ObservableCollection<RootBasicCityInfo>>(prepareString);

                DataRepo.Printeceivedities(rbci);
            }
            catch (Exception ex)
            {
                WriteLine("   ."
                + " : \n" + 
                "*    \n"
                + "*    \n"
                + " : \n"
                + ex.Message);
            }

        }
    }
}
      
      



, :





        /// <summary>
        ///       
        /// (     ,  1).
        /// </summary>
        /// <param name="formalListOfCityes"></param>
        public static void Printeceivedities (ObservableCollection<RootBasicCityInfo> formalListOfCityes)
        {
            string pattern = "=====\n" + "  : {0}\n" + "  : {1}\n"
            + " :  {2} \n" + ": {3}\n" + " : {4}\n"
            + ": {5}\n" + "====\n";
            int numberInList = 0;

            foreach (var item in formalListOfCityes)
            {
                WriteLine(pattern, numberInList.ToString(),
                item.EnglishName, item.LocalizedName, item.Country.LocalizedName,
                item.AdministrativeArea.LocalizedName, item.AdministrativeArea.LocalizedType);
                numberInList++;
            }

            Write ("     : ");
            int num = Convert.ToInt32(Console.ReadLine());

            try
            {
                listOfCityForMonitorWeather.Add(formalListOfCityes[num]);
            }

            catch (Exception ex)
            {
                WriteLine(",   .\n");
                WriteLine(ex.Message);
            }
            WriteListOfCityMonitoring();
        }

      
      



, ( APIKey)





         /// <summary>
        ///       
        ///   .
        /// </summary>
        private static void WriteListOfCityMonitoring()
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(ObservableCollection<RootBasicCityInfo>));

            using (StreamWriter sw = new StreamWriter("RootBasicCityInfo.xml"))
            {
                xmlSerializer.Serialize(sw, listOfCityForMonitorWeather);
            }
        }

      
      



. , - 5 .





Json , , , .





Accuweather 1 , 5, 10 15 . json . Get .





, json :





  "Headline": {
    "EffectiveDate": "2021-02-23T07:00:00+03:00",
    "EffectiveEpochDate": 1614052800,
    "Severity": 3,
    "Text": "  : ",
    "Category": "cold",
    "EndDate": "2021-02-24T19:00:00+03:00",
    "EndEpochDate": 1614182400,
    "MobileLink": "http://m.accuweather.com/ru/ru/moscow/294021/extended-weather-forecast/294021?unit=c",
    "Link": "http://www.accuweather.com/ru/ru/moscow/294021/daily-weather-forecast/294021?unit=c"
  },
  "DailyForecasts": [
    {
      "Date": "2021-02-23T07:00:00+03:00",
      "EpochDate": 1614052800,
      "Temperature": {
        "Minimum": {
          "Value": -24.4,
          "Unit": "C",
          "UnitType": 17
        },
        "Maximum": {
          "Value": -20.6,
          "Unit": "C",
          "UnitType": 17
        }
      },
      "Day": {
        "Icon": 31,
        "IconPhrase": "",
        "HasPrecipitation": false
      },
      "Night": {
        "Icon": 31,
        "IconPhrase": "",
        "HasPrecipitation": false
      },
      "Sources": [
        "AccuWeather"
      ],
      "MobileLink": "http://m.accuweather.com/ru/ru/moscow/294021/daily-weather-forecast/294021?day=1&unit=c",
      "Link": "http://www.accuweather.com/ru/ru/moscow/294021/daily-weather-forecast/294021?day=1&unit=c"
    },

      
      



, :





    public class DailyForecast    {
        public DateTime Date { get; set; } 
        public int EpochDate { get; set; } 
        public Temperature Temperature { get; set; } 
        public Day Day { get; set; } 
        public Night Night { get; set; } 
        public List<string> Sources { get; set; } 
        public string MobileLink { get; set; } 
        public string Link { get; set; } 
    }
    

     public class RootWeather    {
        public Headline Headline { get; set; } 
        public List<DailyForecast> DailyForecasts { get; set; } 
    }

      
      



, ( ) . , , , :





            string pattern = "=====\n" + "  : {0}\n" + "  : {1}\n"
            + " :  {2} \n" + ": {3}\n" + " : {4}\n"
            + ": {5}\n" + "====\n";
            int numberInList = 0;

            foreach (var item in DataRepo.listOfCityForMonitorWeather)
            {
                WriteLine(pattern, numberInList.ToString(),
                item.EnglishName, item.LocalizedName, item.Country.LocalizedName,
                item.AdministrativeArea.LocalizedName, item.AdministrativeArea.LocalizedType);
                numberInList++;
            }
            
            bool ifNotExists = false;
            string cityKey = null;
            int num = 0;
            do
            {
                ifNotExists = false;
                Write("    : ");
                num = Convert.ToInt32(Console.ReadLine());
                
                if (num < 0 || num > DataRepo.listOfCityForMonitorWeather.Count - 1)
                {
                    WriteLine("  .   .");
                    ifNotExists = true;
                }
            } while(ifNotExists);
            
            cityKey = DataRepo.listOfCityForMonitorWeather[num].Key;

      
      



:





 //  ApiKey  
            string apiKey = UserApiManager.userApiList[0].UserApiProperty;
            
            string jsonUrl = $"http://dataservice.accuweather.com/forecasts/v1/daily/5day/{cityKey}?apikey={apiKey}&language=ru&metric=true";

            jsonUrl = webClient.DownloadString(jsonUrl);

            RootWeather weatherData = JsonSerializer.Deserialize<RootWeather>(jsonUrl);

            string patternWeather = "=====\n" + ": {0}\n" + " : {1}\n"
            +" : {2}\n" + "  : {3}\n" + "  : {4}\n" + "====\n";

            foreach (var item in weatherData.DailyForecasts)
            {
                WriteLine(patternWeather, item.Date, item.Temperature.Minimum.Value,
                item.Temperature.Maximum.Value, item.Day.IconPhrase, item.Night.IconPhrase);
            }
      
      



5 .





En conclusión: en este artículo he mostrado los puntos principales que eran necesarios para que se mostraran los datos meteorológicos. El código fuente completo de la utilidad se puede encontrar en GitLab y GitHub. Además, estaré encantado de recibir cualquier crítica del caso y consejos de programadores senior.





Gracias por tu tiempo, ¡buena suerte!








All Articles