File indexing completed on 2025-01-12 05:01:49

0001 /*
0002     SPDX-FileCopyrightText: 2021 Emily Ehlert
0003 
0004     Based upon BBC Weather Ion and ENV Canada Ion by Shawn Starr
0005     SPDX-FileCopyrightText: 2007-2009 Shawn Starr <shawn.starr@rogers.com>
0006 
0007     also
0008 
0009     the wetter.com Ion by Thilo-Alexander Ginkel
0010     SPDX-FileCopyrightText: 2009 Thilo-Alexander Ginkel <thilo@ginkel.com>
0011 
0012     SPDX-License-Identifier: GPL-2.0-or-later
0013 */
0014 
0015 /* Ion for weather data from Deutscher Wetterdienst (DWD) / German Weather Service */
0016 
0017 #pragma once
0018 
0019 #include "../ion.h"
0020 
0021 #include <QList>
0022 
0023 #define CATALOGUE_URL "https://www.dwd.de/DE/leistungen/met_verfahren_mosmix/mosmix_stationskatalog.cfg?view=nasPublication&nn=16102"
0024 #define FORECAST_URL "https://app-prod-ws.warnwetter.de/v30/stationOverviewExtended?stationIds=%1"
0025 #define MEASURE_URL "https://s3.eu-central-1.amazonaws.com/app-prod-static.warnwetter.de/v16/current_measurement_%1.json"
0026 
0027 class KJob;
0028 namespace KIO
0029 {
0030 class Job;
0031 class TransferJob;
0032 }
0033 
0034 class WeatherData
0035 {
0036 public:
0037     WeatherData();
0038 
0039     QString place;
0040 
0041     // Current observation information.
0042     QDateTime observationDateTime;
0043 
0044     QString conditionIcon;
0045     QString windDirection;
0046     float temperature;
0047     float humidity;
0048     float pressure;
0049     float windSpeed;
0050     float gustSpeed;
0051     float dewpoint;
0052 
0053     // If current observations not available, use forecast data for current day
0054     QString windDirectionAlt;
0055     float windSpeedAlt;
0056     float gustSpeedAlt;
0057 
0058     // 7 forecast
0059     struct ForecastInfo {
0060         ForecastInfo();
0061         QDateTime period;
0062         QString iconName;
0063         QString summary;
0064         float tempHigh;
0065         float tempLow;
0066         int precipitation;
0067         float windSpeed;
0068         QString windDirection;
0069     };
0070 
0071     // 7 day forecast
0072     QList<WeatherData::ForecastInfo *> forecasts;
0073 
0074     struct WarningInfo {
0075         QString type;
0076         int priority;
0077         QString headline;
0078         QString description;
0079         QDateTime timestamp;
0080     };
0081 
0082     QList<WeatherData::WarningInfo *> warnings;
0083 
0084     bool isForecastsDataPending = false;
0085     bool isMeasureDataPending = false;
0086 };
0087 
0088 class Q_DECL_EXPORT DWDIon : public IonInterface
0089 {
0090     Q_OBJECT
0091 
0092 public:
0093     DWDIon(QObject *parent);
0094     ~DWDIon() override;
0095 
0096 public: // IonInterface API
0097     bool updateIonSource(const QString &source) override;
0098 
0099 protected: // IonInterface API
0100     void reset() override;
0101 
0102 private Q_SLOTS:
0103     void setup_slotDataArrived(KIO::Job *, const QByteArray &);
0104     void setup_slotJobFinished(KJob *);
0105 
0106     void measure_slotDataArrived(KIO::Job *, const QByteArray &);
0107     void measure_slotJobFinished(KJob *);
0108 
0109     void forecast_slotDataArrived(KIO::Job *, const QByteArray &);
0110     void forecast_slotJobFinished(KJob *);
0111 
0112 private:
0113     QMap<QString, ConditionIcons> setupDayIconMappings() const;
0114     QMap<QString, WindDirections> setupWindIconMappings() const;
0115 
0116     QMap<QString, ConditionIcons> const &dayIcons() const;
0117     QMap<QString, WindDirections> const &windIcons() const;
0118 
0119     void findPlace(const QString &searchText);
0120     void parseStationData(QByteArray data);
0121     void searchInStationList(const QString place);
0122 
0123     void validate(const QString &source);
0124 
0125     void fetchWeather(QString placeName, QString placeID);
0126     void parseForecastData(const QString source, QJsonDocument doc);
0127     void parseMeasureData(const QString source, QJsonDocument doc);
0128     void updateWeather(const QString &source);
0129 
0130     void deleteForecasts();
0131 
0132     // Helper methods
0133     void calculatePositions(QStringList lines, QList<int> &namePositionalInfo, QList<int> &stationIdPositionalInfo);
0134     QString camelCaseString(const QString text);
0135     QString extractString(QByteArray array, int start, int length);
0136     QString roundWindDirections(int windDirection);
0137     float parseNumber(QVariant number);
0138 
0139 private:
0140     // Key dicts
0141     QMap<QString, QString> m_place;
0142     QList<QString> m_locations;
0143 
0144     // Weather information
0145     QHash<QString, WeatherData> m_weatherData;
0146 
0147     QHash<KJob *, QByteArray> m_searchJobData;
0148     QHash<KJob *, QString> m_searchJobList;
0149 
0150     QHash<KJob *, QByteArray> m_forecastJobJSON;
0151     QHash<KJob *, QString> m_forecastJobList;
0152 
0153     QHash<KJob *, QByteArray> m_measureJobJSON;
0154     QHash<KJob *, QString> m_measureJobList;
0155 
0156     QStringList m_sourcesToReset;
0157 };
0158 // kate: indent-mode cstyle; space-indent on; indent-width 4;