added history for 1h prevision

This commit is contained in:
2025-10-18 16:09:43 +02:00
parent 6f28fd5001
commit a251412ec4
2 changed files with 116 additions and 98 deletions
+115 -97
View File
@@ -10,13 +10,13 @@ struct ForecastResult
{ {
QString message; QString message;
int urgency = 0; // 0-5 int urgency = 0; // 0-5
QString colorCode = ""; // "vert", "jaune", ... QString icons = ""; // "vert", "jaune", ...
bool snowRisk; bool snowRisk = false;
bool rainRisk; bool rainRisk = false;
bool stormRisk; bool stormRisk = false;
bool blackIce; bool blackIce = false;
QString prevision1h; QString prevision1h ="";
quint8 confiance; quint8 confiance = 50;
}; };
class BarometerTrend : public QObject class BarometerTrend : public QObject
@@ -25,7 +25,10 @@ class BarometerTrend : public QObject
public: public:
explicit BarometerTrend(QObject *parent = nullptr) explicit BarometerTrend(QObject *parent = nullptr)
: QObject(parent) : QObject(parent)
{} {
m_values.reserve(360 + 16); // évite reallocs fréquentes
m_timestamps.reserve(360 + 16);
}
void addPressure(double pressure_hPa) void addPressure(double pressure_hPa)
{ {
@@ -64,162 +67,175 @@ public:
} }
// Variation de pression sur les dernières 3h // Retourne la pression moyenne autour d'un instant cible (fenêtre +/- windowSecs)
double deltaPressure3h() const double pressureAround(const QDateTime &target, int windowSecs = 60) const
{ {
if (m_values.size() < 2) if (m_values.isEmpty()) return 0.0;
{ const QDateTime from = target.addSecs(-windowSecs);
return 0.0; const QDateTime to = target.addSecs(+windowSecs);
} double sum = 0.0;
QDateTime now = QDateTime::currentDateTime(); int count = 0;
QDateTime target = now.addSecs(-3 * 3600); for (int i = 0; i < m_timestamps.size(); ++i) {
if (m_timestamps[i] >= from && m_timestamps[i] <= to) {
// Cherche la valeur la plus proche dil y a 3 heures sum += m_values[i];
int idx = -1; ++count;
for (int i = 0; i < m_timestamps.size(); ++i) }
{ }
if (m_timestamps[i] >= target) if (count == 0) {
{ // pas d'échantillon proche -> fallback sur la valeur la plus proche dans le passé
idx = i; for (int i = m_timestamps.size() - 1; i >= 0; --i) {
break; if (m_timestamps[i] <= target) {
} return m_values[i];
} }
}
if (idx == -1) return m_values.first();
{ }
idx = 0; // Pas assez vieux, on prend la plus ancienne return sum / count;
} }
double p_now = smoothedPressure();
double p_past = m_values[idx]; // Variation de pression sur N heures (ex: 1 ou 3)
debug(DEBUGMACRO, "delta pressure : " + QByteArray::number(p_now - p_past), DEBUG); double deltaPressureHours(double hours) const
return p_now - p_past; {
} if (m_values.size() < 2) return 0.0;
QDateTime now = QDateTime::currentDateTime();
ForecastResult forecast(double temperatureC, double humidityPercent) const QDateTime past = now.addSecs(-qRound(hours * 3600.0));
double p_now = smoothedPressure(); // moyenne récente (~5 min)
double p_past = pressureAround(past, 60); // moyenne autour de l'instant passé
double delta = p_now - p_past;
// debug(DEBUGMACRO, "delta " + QByteArray::number(hours) + "h : " + QByteArray::number(delta), DEBUG);
return delta;
}
// helpers spécifiques
double deltaPressure3h() const { return deltaPressureHours(3.0); }
double deltaPressure1h() const { return deltaPressureHours(1.0); }
ForecastResult forecast(double temperatureC, double humidityPercent) const
{ {
ForecastResult r; ForecastResult r;
r.confiance = 50;
double p = currentPressure(); double p = currentPressure();
double d = deltaPressure3h(); double d = deltaPressure3h();
double d3 = deltaPressure3h();
r.snowRisk = false; double d1 = deltaPressure1h();
r.rainRisk = false;
r.stormRisk = false;
r.blackIce = false;
debug(DEBUGMACRO, "current pressure : " + QByteArray::number(p) + " - delta pressure 3h" + QByteArray::number(d), DEBUG); debug(DEBUGMACRO, "current pressure : " + QByteArray::number(p) + " - delta pressure 3h" + QByteArray::number(d), DEBUG);
// build icon list to produce colorCode
QStringList icons;
// Logique combinée pression / tendance // Logique combinée pression / tendance
if (p >= 1020 && d >= +3) if (p < 990 && d3 <= -3.0)
{
r.message = "- Tempête ou orage \n";
r.urgency = 5;
icons << "cloud_with_lightning";
debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1020 && d3 >= +3.0)
{ {
r.message = "- Très beau temps durable \n"; r.message = "- Très beau temps durable \n";
r.urgency = 0; r.urgency = 0;
r.colorCode = "sunny"; icons << "sunny";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1020 && d >= +1) }else if (p >= 1020 && d3 >= +1.0)
{ {
r.message = "- Beau temps durable \n"; r.message = "- Beau temps durable \n";
r.urgency = 0; r.urgency = 0;
r.colorCode = "sunny"; icons << "sunny";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1020 && d < -3) }else if (p >= 1020 && d3 < -3.0)
{ {
r.message = "- Beau, mais rapide dégradation \n"; r.message = "- Beau, mais rapide dégradation \n";
r.urgency = 4; r.urgency = 4;
r.colorCode = "sun_behind_large_cloud"; icons << "sun_behind_large_cloud";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1020 && d < -1) }else if (p >= 1020 && d3 < -1.0)
{ {
r.message = "- Beau, mais possible dégradation \n"; r.message = "- Beau, mais possible dégradation \n";
r.urgency = 1; r.urgency = 1;
r.colorCode = "sun_behind_small_cloud"; icons << "sun_behind_small_cloud";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
/*}else if (p >= 1020 && d < 0.5) /*}else if (p >= 1020 && d3 < 0.5.0)
{ {
r.message = "- Beau temps \n"; r.message = "- Beau temps \n";
r.urgency = 0; r.urgency = 0;
r.colorCode = "sunny"; icons << "sunny";
debug(DEBUGMACRO, "message : " + r.message, DEBUG);*/ debug(DEBUGMACRO, "message : " + r.message, DEBUG);*/
}else if (p >= 1010 && d >= +3) }else if (p >= 1010 && d3 >= +3.0)
{ {
r.message = "- Nuageux, rapide amélioration \n"; r.message = "- Nuageux, rapide amélioration \n";
r.urgency = 4; r.urgency = 4;
r.colorCode = "sun_behind_small_cloud"; icons << "sun_behind_small_cloud";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1010 && d >= +1) }else if (p >= 1010 && d3 >= +1.0)
{ {
r.message = "- Nuageux, en amélioration \n"; r.message = "- Nuageux, en amélioration \n";
r.urgency = 0; r.urgency = 0;
r.colorCode = "sun_behind_large_cloud"; icons << "sun_behind_large_cloud";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1010 && d <= -3) }else if (p >= 1010 && d3 <= -3.0)
{ {
r.message = "- Nuageux, fort risque de pluie ou vent \n"; r.message = "- Nuageux, fort risque de pluie ou vent \n";
r.urgency = 4; r.urgency = 4;
r.colorCode = "sun_behind_rain_cloud"; icons << "sun_behind_rain_cloud";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1010 && d <= -1) }else if (p >= 1010 && d3 <= -1.0)
{ {
r.message = "- nuageux, risque de pluie ou vent \n"; r.message = "- nuageux, risque de pluie ou vent \n";
r.urgency = 2; r.urgency = 2;
r.colorCode = "sun_behind_rain_cloud"; icons << "sun_behind_rain_cloud";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1010 && d <= 0.5) }else if (p >= 1010 && d3 <= 0.5)
{ {
r.message = "- Nuageux avec des éclaircies \n"; r.message = "- Nuageux avec des éclaircies \n";
r.urgency = 2; r.urgency = 2;
r.colorCode = "sun_behind_large_cloud"; icons << "sun_behind_large_cloud";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1000 && d >= +3) }else if (p >= 1000 && d3 >= +3.0)
{ {
r.message = "- Variable, amélioration rapide \n"; r.message = "- Variable, amélioration rapide \n";
r.urgency = 4; r.urgency = 4;
r.colorCode = "sun_behind_large_cloud"; icons << "sun_behind_large_cloud";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1000 && d >= +1) }else if (p >= 1000 && d3 >= +1.0)
{ {
r.message = "- Variable, tendance au beau \n"; r.message = "- Variable, tendance au beau \n";
r.urgency = 0; r.urgency = 0;
r.colorCode = "sun_behind_large_cloud"; icons << "sun_behind_large_cloud";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1000 && d <= -3) }else if (p >= 1000 && d3 <= -3.0)
{ {
r.message = "- Pluie ou perturbation, dégradation rapide \n"; r.message = "- Pluie ou perturbation, dégradation rapide \n";
r.urgency = 4; r.urgency = 4;
r.colorCode = "cloud_with_rain"; icons << "cloud_with_rain";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p >= 1000 && d <= -1) }else if (p >= 1000 && d3 <= -1.0)
{ {
r.message = "- Pluie ou perturbation \n"; r.message = "- Pluie ou perturbation \n";
r.urgency = 2; r.urgency = 2;
r.colorCode = "cloud_with_rain"; icons << "cloud_with_rain";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p < 990 && d <= -3) }else if (p < 1000 && d3 >= +3.0)
{
r.message = "- Tempête ou orage \n";
r.urgency = 5;
r.colorCode = "cloud_with_lightning";
debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p < 1000 && d >= +3)
{ {
r.message = "- Pluie avec accalmie temporaire, amélioration rapide \n"; r.message = "- Pluie avec accalmie temporaire, amélioration rapide \n";
r.urgency = 1; r.urgency = 1;
r.colorCode = "sun_behind_rain_cloud"; icons << "sun_behind_rain_cloud";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p < 1000 && d >= +1) }else if (p < 1000 && d3 >= +1.0)
{ {
r.message = "- Pluie avec accalmie temporaire \n"; r.message = "- Pluie avec accalmie temporaire \n";
r.urgency = 1; r.urgency = 1;
r.colorCode = "sun_behind_rain_cloud"; icons << "sun_behind_rain_cloud";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
}else if (p < 1000 && d <= -1) }else if (p < 1000 && d3 <= -1.0)
{ {
r.message = "- Mauvais temps durable \n"; r.message = "- Mauvais temps durable \n";
r.urgency = 4; r.urgency = 4;
r.colorCode = "cloud_with_rain"; icons << "cloud_with_rain";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
} }
if (qAbs(d) < 1) if (qAbs(d3) < 1)
{ {
r.message += "- Stable, pas de changement significatif \n"; r.message += "- Stable, pas de changement significatif \n";
r.urgency = 0; r.urgency = 0;
@@ -227,38 +243,38 @@ public:
} }
// Risque de neige // Risque de neige
if (p < 1000 && d < -1 && temperatureC <= 1.0 && humidityPercent > 80.0) if (p < 1000 && d3 < -1.0 && temperatureC <= 1.0 && humidityPercent > 80.0)
{ {
r.snowRisk = true; r.snowRisk = true;
r.message += "- Risque de neige \n"; r.message += "- Risque de neige \n";
r.urgency = qMax(r.urgency, 3); r.urgency = qMax(r.urgency, 3);
r.colorCode += "snowflake,"; icons << "snowflake";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
} }
// Risque de pluie // Risque de pluie
else if (p < 1010 && d < -1 && temperatureC > 1.0 && humidityPercent > 70.0) else if (p < 1010 && d3 < -1.0 && temperatureC > 1.0 && humidityPercent > 70.0)
{ {
r.rainRisk = true; r.rainRisk = true;
r.message += "- Risque de pluie \n"; r.message += "- Risque de pluie \n";
r.urgency = qMax(r.urgency, 2); r.urgency = qMax(r.urgency, 2);
r.colorCode += "cloud_with_rain,"; icons << "cloud_with_rain";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
} }
// Risque dorage // Risque dorage
if (p < 995 && d < -3 && temperatureC > 20.0 && humidityPercent > 70.0) if (p < 995 && d3 < -3.0 && temperatureC > 20.0 && humidityPercent > 70.0)
{ {
r.stormRisk = true; r.stormRisk = true;
r.message += "- Risque dorage \n"; r.message += "- Risque dorage \n";
r.urgency = qMax(r.urgency, 4); r.urgency = qMax(r.urgency, 4);
r.colorCode += "cloud_with_lightning,"; icons << "cloud_with_lightning";
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
} }
if (temperatureC <= 0.5 && humidityPercent >= 85.0) { if (temperatureC <= 0.5 && humidityPercent >= 85.0) {
// conditions classiques de gel // conditions classiques de gel
if (d >= -1 && d <= +1) if (d3 >= -1.0 && d3 <= +1.0)
{ {
r.blackIce = true; // temps stable = ciel clair = refroidissement r.blackIce = true; // temps stable = ciel clair = refroidissement
}else if (d < -1 && p > 995) }else if (d < -1 && p > 995)
@@ -270,13 +286,13 @@ public:
if (r.blackIce) if (r.blackIce)
{ {
r.message += "- Risque de verglas \n"; r.message += "- Risque de verglas \n";
r.colorCode += "ice_cube,"; icons << "ice_cube";
r.urgency = qMax(r.urgency, 4); r.urgency = qMax(r.urgency, 4);
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
} }
// --- Prévision à 1 heure --- // --- Prévision à 1 heure ---
if (d <= -1.5 && p < 1010 && humidityPercent > 80) if (d <= -1.5 && p < 1010 && humidityPercent > 80.0)
{ {
r.prevision1h = "☔ Pluie probable dans lheure \n"; r.prevision1h = "☔ Pluie probable dans lheure \n";
r.urgency = qMax(r.urgency, 4); r.urgency = qMax(r.urgency, 4);
@@ -285,7 +301,7 @@ public:
{ {
r.prevision1h = "🌤 Amélioration probable dans lheure \n"; r.prevision1h = "🌤 Amélioration probable dans lheure \n";
r.confiance = 85; r.confiance = 85;
}else if (qAbs(d) < 0.3 && qAbs(temperatureC) < 0.5) }else if (qAbs(d1) < 0.3 && qAbs(temperatureC) < 0.5)
{ {
r.prevision1h = "⛅ Conditions stables pour la prochaine heure \n"; r.prevision1h = "⛅ Conditions stables pour la prochaine heure \n";
r.confiance = 70; r.confiance = 70;
@@ -321,6 +337,8 @@ public:
} }
debug(DEBUGMACRO, "message : " + r.message, DEBUG); debug(DEBUGMACRO, "message : " + r.message, DEBUG);
if (!icons.isEmpty()) r.icons = icons.join(",");
return r; return r;
} }
+1 -1
View File
@@ -325,7 +325,7 @@ void Pws2mqtt::parseData(QList<std::pair<QString, QString>> queryList)
prevision = newPrevision; prevision = newPrevision;
propertyList["prevision"] = prevision; propertyList["prevision"] = prevision;
priority = setPriority(priority, ret.urgency); priority = setPriority(priority, ret.urgency);
tag += ret.colorCode; tag += ret.icons;
} }
debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG); debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG);
}else if (name == "UV") }else if (name == "UV")