#include "weathercontroller.h" #include "QDir" #include "QFile" #include "QGuiApplication" #include "QStandardPaths" #include "networkmanager.h" #include #include #include #include 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; }