File indexing completed on 2025-01-12 05:01:50
0001 /* 0002 SPDX-FileCopyrightText: 2007-2009, 2019 Shawn Starr <shawn.starr@rogers.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 /* Ion for NOAA's National Weather Service XML data */ 0008 0009 #pragma once 0010 0011 #include "../ion.h" 0012 0013 #include <Plasma5Support/DataEngineConsumer> 0014 0015 #include <QDateTime> 0016 #include <QXmlStreamReader> 0017 0018 class KJob; 0019 namespace KIO 0020 { 0021 class Job; 0022 } // namespace KIO 0023 0024 class WeatherData 0025 { 0026 public: 0027 WeatherData(); 0028 0029 QString locationName; 0030 QString stationID; 0031 double stationLatitude; 0032 double stationLongitude; 0033 QString stateName; 0034 QString countyID; 0035 0036 // Current observation information. 0037 QString observationTime; 0038 QDateTime observationDateTime; 0039 QString weather; 0040 0041 float temperature_F; 0042 float temperature_C; 0043 float humidity; 0044 QString windString; 0045 QString windDirection; 0046 float windSpeed; 0047 float windGust; 0048 float pressure; 0049 float dewpoint_F; 0050 float dewpoint_C; 0051 float heatindex_F; 0052 float heatindex_C; 0053 float windchill_F; 0054 float windchill_C; 0055 float visibility; 0056 0057 struct Forecast { 0058 QString day; 0059 QString summary; 0060 QString low; 0061 QString high; 0062 int precipitation = 0; 0063 }; 0064 QList<Forecast> forecasts; 0065 0066 struct Alert { 0067 QString headline; 0068 QString description; 0069 QString infoUrl; 0070 int priority; 0071 QDateTime startTime; 0072 QDateTime endTime; 0073 }; 0074 QList<Alert> alerts; 0075 0076 bool isForecastsDataPending = false; 0077 0078 QString solarDataTimeEngineSourceName; 0079 bool isNight = false; 0080 bool isSolarDataPending = false; 0081 }; 0082 0083 Q_DECLARE_TYPEINFO(WeatherData::Forecast, Q_RELOCATABLE_TYPE); 0084 Q_DECLARE_TYPEINFO(WeatherData, Q_RELOCATABLE_TYPE); 0085 0086 class Q_DECL_EXPORT NOAAIon : public IonInterface, public Plasma5Support::DataEngineConsumer 0087 { 0088 Q_OBJECT 0089 0090 public: 0091 NOAAIon(QObject *parent); 0092 ~NOAAIon() override; 0093 0094 public: // IonInterface API 0095 bool updateIonSource(const QString &source) override; 0096 0097 public Q_SLOTS: 0098 // for solar data pushes from the time engine 0099 void dataUpdated(const QString &sourceName, const Plasma5Support::DataEngine::Data &data); 0100 0101 protected: // IonInterface API 0102 void reset() override; 0103 0104 private Q_SLOTS: 0105 void setup_slotJobFinished(KJob *); 0106 void slotJobFinished(KJob *); 0107 void forecast_slotJobFinished(KJob *); 0108 void county_slotJobFinished(KJob *); 0109 void alerts_slotJobFinished(KJob *); 0110 0111 private: 0112 void updateWeather(const QString &source); 0113 0114 /* NOAA Methods - Internal for Ion */ 0115 QMap<QString, ConditionIcons> setupConditionIconMappings() const; 0116 QMap<QString, ConditionIcons> const &conditionIcons() const; 0117 QMap<QString, WindDirections> setupWindIconMappings() const; 0118 QMap<QString, WindDirections> const &windIcons() const; 0119 0120 // Current Conditions Weather info 0121 // bool night(const QString& source); 0122 IonInterface::ConditionIcons getConditionIcon(const QString &weather, bool isDayTime) const; 0123 0124 // Helper to make an API request 0125 KJob *apiRequestJob(const QUrl &url, const QString &source); 0126 0127 // Load and Parse the place XML listing 0128 void getXMLSetup(); 0129 bool readXMLSetup(QXmlStreamReader &xml); 0130 0131 // Load and parse the specific place(s) 0132 void getXMLData(const QString &source); 0133 bool readXMLData(const QString &source, QXmlStreamReader &xml); 0134 0135 // Load and parse upcoming forecast for the next N days 0136 void getForecast(const QString &source); 0137 void readForecast(const QString &source, QXmlStreamReader &xml); 0138 0139 // Methods to get alerts. We need the county ID first 0140 void getCountyID(const QString &source); 0141 void readCountyID(const QString &source, const QJsonDocument &doc); 0142 void getAlerts(const QString &source); 0143 void readAlerts(const QString &source, const QJsonDocument &doc); 0144 0145 // Check if place specified is valid or not 0146 QStringList validate(const QString &source) const; 0147 0148 // Catchall for unknown XML tags 0149 void parseUnknownElement(QXmlStreamReader &xml) const; 0150 0151 // Parse weather XML data 0152 void parseWeatherSite(WeatherData &data, QXmlStreamReader &xml); 0153 void parseStationID(QXmlStreamReader &xml); 0154 void parseStationList(QXmlStreamReader &xml); 0155 0156 void parseFloat(float &value, const QString &string); 0157 void parseFloat(float &value, QXmlStreamReader &xml); 0158 void parseDouble(double &value, QXmlStreamReader &xml); 0159 0160 private: 0161 struct XMLMapInfo { 0162 QString stateName; 0163 QString stationName; 0164 QString stationID; 0165 QString XMLurl; 0166 }; 0167 0168 // Key dicts 0169 QHash<QString, NOAAIon::XMLMapInfo> m_places; 0170 0171 // Weather information 0172 QHash<QString, WeatherData> m_weatherData; 0173 0174 // Store KIO jobs 0175 QHash<KJob *, QByteArray> m_jobData; 0176 QHash<KJob *, QString> m_jobList; 0177 0178 // bool emitWhenSetup; 0179 QStringList m_sourcesToReset; 0180 };