Add weather routes project progress
This commit is contained in:
42
WeatherRoutes/mvc/controller/networkmanager.cpp
Normal file
42
WeatherRoutes/mvc/controller/networkmanager.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include "networkmanager.h"
|
||||
#include "QStandardPaths"
|
||||
#include <QFile>
|
||||
#include <QGuiApplication>
|
||||
#include <QJsonDocument>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
|
||||
NetworkManager *NetworkManager::m_instance;
|
||||
|
||||
NetworkManager::NetworkManager(QObject *parent) : QObject{parent} {}
|
||||
|
||||
NetworkManager *NetworkManager::Instance() {
|
||||
if (m_instance != nullptr) {
|
||||
return m_instance;
|
||||
}
|
||||
m_instance = new NetworkManager();
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
void NetworkManager::fetchJSONfromAPI(QUrl url, QJsonDocument &doc)
|
||||
{
|
||||
qDebug() << "Fetch URL::" << url.toDisplayString();
|
||||
QNetworkAccessManager m_manager;
|
||||
QNetworkRequest request(url);
|
||||
QNetworkReply *reply = m_manager.get(request);
|
||||
QEventLoop loop;
|
||||
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
loop.exec();
|
||||
if (reply->error() == QNetworkReply::NoError)
|
||||
{
|
||||
QByteArray response = reply->readAll();
|
||||
doc = QJsonDocument::fromJson(response);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Invalid JSON response:: " << reply->errorString();
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
22
WeatherRoutes/mvc/controller/networkmanager.h
Normal file
22
WeatherRoutes/mvc/controller/networkmanager.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef NETWORKMANAGER_H
|
||||
#define NETWORKMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class NetworkManager : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
void fetchJSONfromAPI(QUrl url, QJsonDocument &doc);
|
||||
static NetworkManager *m_instance;
|
||||
static NetworkManager *Instance();
|
||||
|
||||
NetworkManager(const NetworkManager&) = delete;
|
||||
NetworkManager& operator=(const NetworkManager&) = delete;
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
explicit NetworkManager(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
#endif // NETWORKMANAGER_H
|
||||
30
WeatherRoutes/mvc/controller/stylecontroller.cpp
Normal file
30
WeatherRoutes/mvc/controller/stylecontroller.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "stylecontroller.h"
|
||||
|
||||
StyleController* StyleController::m_instance;
|
||||
|
||||
StyleController *StyleController::Instance()
|
||||
{
|
||||
if(m_instance != nullptr)
|
||||
{
|
||||
return m_instance;
|
||||
}
|
||||
m_instance = new StyleController();
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
StyleController::StyleController(QObject *parent)
|
||||
: QObject{parent}
|
||||
{}
|
||||
|
||||
int StyleController::colorMode() const
|
||||
{
|
||||
return m_colorMode;
|
||||
}
|
||||
|
||||
void StyleController::setColorMode(int newColorMode)
|
||||
{
|
||||
if (m_colorMode == newColorMode)
|
||||
return;
|
||||
m_colorMode = newColorMode;
|
||||
emit colorModeChanged();
|
||||
}
|
||||
59
WeatherRoutes/mvc/controller/stylecontroller.h
Normal file
59
WeatherRoutes/mvc/controller/stylecontroller.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef STYLECONTROLLER_H
|
||||
#define STYLECONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QColor>
|
||||
|
||||
class StyleController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static StyleController* m_instance;
|
||||
StyleController(const StyleController&) = delete;
|
||||
StyleController& operator=(const StyleController&) = delete;
|
||||
StyleController* Instance();
|
||||
|
||||
enum COLOR_MODE
|
||||
{
|
||||
DARK = 0,
|
||||
LIGHT,
|
||||
SYSTEM
|
||||
}
|
||||
Q_ENUMS(COLOR_MODE);
|
||||
|
||||
|
||||
Q_PROPERTY(int colorMode READ colorMode WRITE setColorMode NOTIFY colorModeChanged FINAL)
|
||||
|
||||
//Dark Mode
|
||||
Q_PROPERTY(QColor textPrimary READ textPrimary NOTIFY colorChanged FINAL)
|
||||
QColor textPrimary() const {return QColor(255,255,255);}
|
||||
|
||||
Q_PROPERTY(QColor textSecondary READ textSecondary NOTIFY colorChanged FINAL)
|
||||
QColor textSecondary() const {return QColor(255,255,255,179);}
|
||||
|
||||
Q_PROPERTY(QColor textDisabled READ textDisabled NOTIFY colorChanged FINAL)
|
||||
QColor textDisabled() const {return QColor(255,255,255,125);}
|
||||
|
||||
Q_PROPERTY(QColor buttonActive READ buttonActive NOTIFY colorChanged FINAL)
|
||||
QColor buttonActive() const {return QColor(255,255,255);}
|
||||
|
||||
Q_PROPERTY(QColor buttonDisabled READ buttonDisabled NOTIFY colorChanged FINAL)
|
||||
QColor buttonDisabled() const {return QColor(255,255,255, 77);}
|
||||
|
||||
Q_PROPERTY(QColor buttonSelected READ buttonSelected NOTIFY colorChanged FINAL)
|
||||
QColor buttonSelected() const {return QColor(255,255,255, 40);}
|
||||
|
||||
int colorMode() const;
|
||||
void setColorMode(int newColorMode);
|
||||
|
||||
|
||||
signals:
|
||||
void colorChanged();
|
||||
void colorModeChanged();
|
||||
|
||||
private:
|
||||
explicit StyleController(QObject *parent = nullptr);
|
||||
int m_colorMode = COLOR_MODE::DARK;
|
||||
};
|
||||
|
||||
#endif // STYLECONTROLLER_H
|
||||
224
WeatherRoutes/mvc/controller/weathercontroller.cpp
Normal file
224
WeatherRoutes/mvc/controller/weathercontroller.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
#include "weathercontroller.h"
|
||||
#include "QDir"
|
||||
#include "QFile"
|
||||
#include "QGuiApplication"
|
||||
#include "QStandardPaths"
|
||||
#include "networkmanager.h"
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <qdebug.h>
|
||||
|
||||
const QString WeatherController::FILENAME = "static.json";
|
||||
|
||||
WeatherController::WeatherController(QObject *parent) : QObject{parent} {}
|
||||
|
||||
bool WeatherController::parseJSONData() {
|
||||
QJsonDocument doc;
|
||||
if (this->checkToDownload(doc)) {
|
||||
QJsonObject jsonObject = doc.object();
|
||||
QJsonArray dataArray = jsonObject["data"].toArray();
|
||||
for (QJsonArray::const_iterator iter = dataArray.constBegin();
|
||||
iter != dataArray.constEnd(); ++iter) {
|
||||
QJsonObject weatherObject = (*iter).toObject();
|
||||
|
||||
// Extract values from the JSON object
|
||||
long tijd = weatherObject["tijd"].toString().toLong();
|
||||
QString tijd_nl = weatherObject["tijd_nl"].toString();
|
||||
int offset = weatherObject["offset"].toInt();
|
||||
float temp = weatherObject["temp"].toString().toFloat();
|
||||
int wind_ms = weatherObject["windb"].toInt();
|
||||
int wind_bf = weatherObject["winds"].toInt();
|
||||
int wind_knp = weatherObject["windknp"].toInt();
|
||||
int wind_kmh = weatherObject["windkmh"].toString().toFloat();
|
||||
int wind_r = weatherObject["windr"].toInt();
|
||||
QString wind_ltr = weatherObject["windrltr"].toString();
|
||||
int visibility = weatherObject["vis"].toInt();
|
||||
int neersl = weatherObject["neersl"].toString().toFloat() *
|
||||
10; // Converted from 0.1 to 1 decimal scale
|
||||
float luchtd_bar = weatherObject["luchtd"].toString().toFloat();
|
||||
float luchtdmmhg = weatherObject["luchtdmmhg"].toString().toFloat();
|
||||
float luchtdinHg = weatherObject["luchtdinhg"].toString().toFloat();
|
||||
int hw = weatherObject["hw"].toInt();
|
||||
int mw = weatherObject["mw"].toInt();
|
||||
int lw = weatherObject["lw"].toInt();
|
||||
int tw = weatherObject["tw"].toInt();
|
||||
int rv = weatherObject["rv"].toInt();
|
||||
int gr = weatherObject["gr"].toInt();
|
||||
int gr_w = weatherObject["gr_w"].toInt();
|
||||
QString cape = weatherObject["cape"].toString();
|
||||
int snd = weatherObject["snd"].toInt();
|
||||
int snv = weatherObject["snv"].toInt();
|
||||
int cond = weatherObject["cond"].toInt();
|
||||
int iconCode = weatherObject["ico"].toInt();
|
||||
QString sameenv = weatherObject["samenv"].toString();
|
||||
QString icoon = weatherObject["icoon"].toString();
|
||||
|
||||
// Create WeatherData object and add it to the list using initializer list
|
||||
// constructor
|
||||
mData.append(WeatherData(tijd, tijd_nl, offset, temp, wind_ms, wind_bf,
|
||||
wind_knp, wind_kmh, wind_r, wind_ltr, visibility,
|
||||
neersl, luchtd_bar, luchtdmmhg, luchtdinHg, hw,
|
||||
mw, lw, tw, rv, gr, gr_w, cape, snd, snv, cond,
|
||||
iconCode, sameenv, icoon));
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QJsonObject WeatherController::fetchCurrentWeatherData(const QGeoCoordinate &coord)
|
||||
{
|
||||
QJsonDocument doc;
|
||||
readWeatherData(doc, "liveweer");
|
||||
QJsonArray liveweerArray = doc.array();
|
||||
QJsonObject firstEntry = liveweerArray.at(0).toObject();
|
||||
|
||||
//Will fetch live data when the time difference is more than 10 mins from last fetch
|
||||
if (qAbs(QDateTime::currentSecsSinceEpoch() - firstEntry["timestamp"].toString().toUInt()) > 600)
|
||||
{
|
||||
// NetworkManager::Instance()->fetchJSONfromAPI(prepareURL(coord), doc);
|
||||
// if(!doc.isNull() && doc.isObject())
|
||||
// {
|
||||
// updateWeatherData(doc);
|
||||
// }
|
||||
}
|
||||
return doc.object();
|
||||
}
|
||||
|
||||
bool WeatherController::readWeatherData(QJsonDocument &doc, QString objName)
|
||||
{
|
||||
QString cacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||
QString fileName = cacheDir + "/" + WeatherController::FILENAME;
|
||||
|
||||
QFile file(fileName);
|
||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QTextStream in(&file);
|
||||
QJsonParseError error;
|
||||
doc = QJsonDocument::fromJson(in.readAll().toStdString().c_str(), &error);
|
||||
file.close();
|
||||
if(doc.isNull())
|
||||
{
|
||||
qWarning() << "Error:: " << error.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!doc.isObject()) {
|
||||
qWarning() << "Invalid JSON format";
|
||||
return false;
|
||||
}
|
||||
if(!objName.isNull())
|
||||
{
|
||||
QJsonArray ary = doc.object()[objName].toArray();
|
||||
QJsonDocument temp_doc(ary);
|
||||
doc = temp_doc;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WeatherController::saveWeatherData(QJsonDocument &doc)
|
||||
{
|
||||
QString cacheDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||
// Ensure the directory exists
|
||||
QDir dir(cacheDir);
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(cacheDir);
|
||||
}
|
||||
|
||||
QString fileName = cacheDir + "/" + WeatherController::FILENAME;
|
||||
|
||||
QFile file(fileName);
|
||||
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QTextStream out(&file);
|
||||
out << doc.toJson();
|
||||
file.close();
|
||||
qDebug() << "Data saved to hidden cache file.";
|
||||
return true;
|
||||
} else {
|
||||
qDebug() << "Failed to open file for writing";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool WeatherController::fetchWeatherData(QUrl url, QJsonDocument &doc)
|
||||
{
|
||||
NetworkManager::Instance()->fetchJSONfromAPI(url, doc);
|
||||
if (doc.isObject() && !doc.isNull()) {
|
||||
QJsonObject jsonObject = doc.object();
|
||||
|
||||
QString todayDate = QDate::currentDate().toString("dd-MM-yyyy");
|
||||
|
||||
jsonObject["downloaddatum"] = todayDate;
|
||||
|
||||
QString timeOfDownload = QDateTime::currentDateTime().toString("hh:mm:ss");
|
||||
|
||||
jsonObject["downloadtime"] = timeOfDownload;
|
||||
|
||||
QJsonDocument updatedDoc(jsonObject);
|
||||
saveWeatherData(updatedDoc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WeatherController::updateWeatherData(QJsonDocument &inputDoc)
|
||||
{
|
||||
QJsonDocument doc;
|
||||
readWeatherData(doc);
|
||||
QJsonObject rootObj = doc.object();
|
||||
QJsonObject inputObj = inputDoc.object();
|
||||
QJsonArray liveweerArray = inputObj["liveweer"].toArray();
|
||||
rootObj["liveweer"] = liveweerArray;
|
||||
|
||||
QJsonDocument updatedDoc(rootObj);
|
||||
saveWeatherData(updatedDoc);
|
||||
}
|
||||
|
||||
QUrl WeatherController::prepareURL(const QString &plaats)
|
||||
{
|
||||
return QUrl(QString("http://data.meteoserver.nl/api/uurverwachting.php?locatie=%1&key=785f0630f0").arg(plaats));
|
||||
}
|
||||
|
||||
QUrl WeatherController::prepareURL(const QGeoCoordinate &coord)
|
||||
{
|
||||
return QUrl(QString("http://data.meteoserver.nl/api/liveweer_synop.php?lat=%1&long=%2&key=785f0630f0&select=1").arg(coord.latitude()).arg(coord.longitude()));
|
||||
}
|
||||
|
||||
bool WeatherController::checkToDownload(QJsonDocument &doc)
|
||||
{
|
||||
bool toDownloadData = false;
|
||||
readWeatherData(doc);
|
||||
|
||||
if (doc.isObject() && !doc.isNull()) {
|
||||
|
||||
// Get the root object
|
||||
QJsonObject jsonObject = doc.object();
|
||||
|
||||
// Extract the 'downloaddatum' value
|
||||
QString downloaddatum = jsonObject.value("downloaddatum").toString();
|
||||
if(downloaddatum != QDate::currentDate().toString("dd-MM-yyyy"))
|
||||
toDownloadData = true;
|
||||
|
||||
QJsonArray plaatsnaamArray = jsonObject.value("plaatsnaam").toArray();
|
||||
|
||||
if (!plaatsnaamArray.isEmpty()) {
|
||||
QJsonObject plaatsObject = plaatsnaamArray.at(0).toObject();
|
||||
QString plaats = plaatsObject.value("plaats").toString();
|
||||
if(plaats != "Raalte")
|
||||
toDownloadData = true;
|
||||
} else {
|
||||
qWarning() << "plaatsnaam array is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
qWarning() << "Failed to open file for reading";
|
||||
return false;
|
||||
}
|
||||
if(toDownloadData)
|
||||
return fetchWeatherData(prepareURL("Raalte"), doc);
|
||||
return false;
|
||||
}
|
||||
|
||||
30
WeatherRoutes/mvc/controller/weathercontroller.h
Normal file
30
WeatherRoutes/mvc/controller/weathercontroller.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef WEATHERCONTROLLER_H
|
||||
#define WEATHERCONTROLLER_H
|
||||
|
||||
#include "../data/weatherdata.h"
|
||||
#include <QGeoCoordinate>
|
||||
#include <QObject>
|
||||
|
||||
class WeatherController : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WeatherController(QObject *parent = nullptr);
|
||||
|
||||
static const QString FILENAME;
|
||||
bool parseJSONData();
|
||||
QJsonObject fetchCurrentWeatherData(const QGeoCoordinate &coord);
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
bool readWeatherData(QJsonDocument &doc, QString objName = NULL);
|
||||
bool checkToDownload(QJsonDocument &doc);
|
||||
bool saveWeatherData(QJsonDocument &doc);
|
||||
bool fetchWeatherData(QUrl url, QJsonDocument &doc);
|
||||
void updateWeatherData(QJsonDocument &inputDoc);
|
||||
QUrl prepareURL(const QString &plaats);
|
||||
QUrl prepareURL(const QGeoCoordinate &coord);
|
||||
QList<WeatherData> mData;
|
||||
};
|
||||
|
||||
#endif // WEATHERCONTROLLER_H
|
||||
Reference in New Issue
Block a user