added history for 1h prevision
This commit is contained in:
@@ -10,13 +10,13 @@ struct ForecastResult
|
||||
{
|
||||
QString message;
|
||||
int urgency = 0; // 0-5
|
||||
QString colorCode = ""; // "vert", "jaune", ...
|
||||
bool snowRisk;
|
||||
bool rainRisk;
|
||||
bool stormRisk;
|
||||
bool blackIce;
|
||||
QString prevision1h;
|
||||
quint8 confiance;
|
||||
QString icons = ""; // "vert", "jaune", ...
|
||||
bool snowRisk = false;
|
||||
bool rainRisk = false;
|
||||
bool stormRisk = false;
|
||||
bool blackIce = false;
|
||||
QString prevision1h ="";
|
||||
quint8 confiance = 50;
|
||||
};
|
||||
|
||||
class BarometerTrend : public QObject
|
||||
@@ -25,7 +25,10 @@ class BarometerTrend : public QObject
|
||||
public:
|
||||
explicit BarometerTrend(QObject *parent = nullptr)
|
||||
: QObject(parent)
|
||||
{}
|
||||
{
|
||||
m_values.reserve(360 + 16); // évite reallocs fréquentes
|
||||
m_timestamps.reserve(360 + 16);
|
||||
}
|
||||
|
||||
void addPressure(double pressure_hPa)
|
||||
{
|
||||
@@ -64,162 +67,175 @@ public:
|
||||
|
||||
}
|
||||
|
||||
// Variation de pression sur les dernières 3h
|
||||
double deltaPressure3h() const
|
||||
{
|
||||
if (m_values.size() < 2)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QDateTime target = now.addSecs(-3 * 3600);
|
||||
|
||||
// Cherche la valeur la plus proche d’il y a 3 heures
|
||||
int idx = -1;
|
||||
for (int i = 0; i < m_timestamps.size(); ++i)
|
||||
{
|
||||
if (m_timestamps[i] >= target)
|
||||
{
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == -1)
|
||||
{
|
||||
idx = 0; // Pas assez vieux, on prend la plus ancienne
|
||||
}
|
||||
double p_now = smoothedPressure();
|
||||
double p_past = m_values[idx];
|
||||
debug(DEBUGMACRO, "delta pressure : " + QByteArray::number(p_now - p_past), DEBUG);
|
||||
return p_now - p_past;
|
||||
}
|
||||
|
||||
ForecastResult forecast(double temperatureC, double humidityPercent) const
|
||||
// Retourne la pression moyenne autour d'un instant cible (fenêtre +/- windowSecs)
|
||||
double pressureAround(const QDateTime &target, int windowSecs = 60) const
|
||||
{
|
||||
if (m_values.isEmpty()) return 0.0;
|
||||
const QDateTime from = target.addSecs(-windowSecs);
|
||||
const QDateTime to = target.addSecs(+windowSecs);
|
||||
double sum = 0.0;
|
||||
int count = 0;
|
||||
for (int i = 0; i < m_timestamps.size(); ++i) {
|
||||
if (m_timestamps[i] >= from && m_timestamps[i] <= to) {
|
||||
sum += m_values[i];
|
||||
++count;
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
// pas d'échantillon proche -> fallback sur la valeur la plus proche dans le passé
|
||||
for (int i = m_timestamps.size() - 1; i >= 0; --i) {
|
||||
if (m_timestamps[i] <= target) {
|
||||
return m_values[i];
|
||||
}
|
||||
}
|
||||
return m_values.first();
|
||||
}
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
// Variation de pression sur N heures (ex: 1 ou 3)
|
||||
double deltaPressureHours(double hours) const
|
||||
{
|
||||
if (m_values.size() < 2) return 0.0;
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
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;
|
||||
|
||||
|
||||
r.confiance = 50;
|
||||
double p = currentPressure();
|
||||
double d = deltaPressure3h();
|
||||
|
||||
r.snowRisk = false;
|
||||
r.rainRisk = false;
|
||||
r.stormRisk = false;
|
||||
r.blackIce = false;
|
||||
double d3 = deltaPressure3h();
|
||||
double d1 = deltaPressure1h();
|
||||
|
||||
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
|
||||
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.urgency = 0;
|
||||
r.colorCode = "sunny";
|
||||
icons << "sunny";
|
||||
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.urgency = 0;
|
||||
r.colorCode = "sunny";
|
||||
icons << "sunny";
|
||||
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.urgency = 4;
|
||||
r.colorCode = "sun_behind_large_cloud";
|
||||
icons << "sun_behind_large_cloud";
|
||||
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.urgency = 1;
|
||||
r.colorCode = "sun_behind_small_cloud";
|
||||
icons << "sun_behind_small_cloud";
|
||||
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.urgency = 0;
|
||||
r.colorCode = "sunny";
|
||||
icons << "sunny";
|
||||
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.urgency = 4;
|
||||
r.colorCode = "sun_behind_small_cloud";
|
||||
icons << "sun_behind_small_cloud";
|
||||
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.urgency = 0;
|
||||
r.colorCode = "sun_behind_large_cloud";
|
||||
icons << "sun_behind_large_cloud";
|
||||
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.urgency = 4;
|
||||
r.colorCode = "sun_behind_rain_cloud";
|
||||
icons << "sun_behind_rain_cloud";
|
||||
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.urgency = 2;
|
||||
r.colorCode = "sun_behind_rain_cloud";
|
||||
icons << "sun_behind_rain_cloud";
|
||||
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.urgency = 2;
|
||||
r.colorCode = "sun_behind_large_cloud";
|
||||
icons << "sun_behind_large_cloud";
|
||||
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.urgency = 4;
|
||||
r.colorCode = "sun_behind_large_cloud";
|
||||
icons << "sun_behind_large_cloud";
|
||||
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.urgency = 0;
|
||||
r.colorCode = "sun_behind_large_cloud";
|
||||
icons << "sun_behind_large_cloud";
|
||||
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.urgency = 4;
|
||||
r.colorCode = "cloud_with_rain";
|
||||
icons << "cloud_with_rain";
|
||||
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.urgency = 2;
|
||||
r.colorCode = "cloud_with_rain";
|
||||
icons << "cloud_with_rain";
|
||||
debug(DEBUGMACRO, "message : " + r.message, DEBUG);
|
||||
}else if (p < 990 && d <= -3)
|
||||
{
|
||||
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)
|
||||
}else if (p < 1000 && d3 >= +3.0)
|
||||
{
|
||||
r.message = "- Pluie avec accalmie temporaire, amélioration rapide \n";
|
||||
r.urgency = 1;
|
||||
r.colorCode = "sun_behind_rain_cloud";
|
||||
icons << "sun_behind_rain_cloud";
|
||||
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.urgency = 1;
|
||||
r.colorCode = "sun_behind_rain_cloud";
|
||||
icons << "sun_behind_rain_cloud";
|
||||
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.urgency = 4;
|
||||
r.colorCode = "cloud_with_rain";
|
||||
icons << "cloud_with_rain";
|
||||
debug(DEBUGMACRO, "message : " + r.message, DEBUG);
|
||||
}
|
||||
if (qAbs(d) < 1)
|
||||
if (qAbs(d3) < 1)
|
||||
{
|
||||
r.message += "- Stable, pas de changement significatif \n";
|
||||
r.urgency = 0;
|
||||
@@ -227,38 +243,38 @@ public:
|
||||
}
|
||||
|
||||
// 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.message += "- Risque de neige \n";
|
||||
r.urgency = qMax(r.urgency, 3);
|
||||
r.colorCode += "snowflake,";
|
||||
icons << "snowflake";
|
||||
debug(DEBUGMACRO, "message : " + r.message, DEBUG);
|
||||
}
|
||||
|
||||
// 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.message += "- Risque de pluie \n";
|
||||
r.urgency = qMax(r.urgency, 2);
|
||||
r.colorCode += "cloud_with_rain,";
|
||||
icons << "cloud_with_rain";
|
||||
debug(DEBUGMACRO, "message : " + r.message, DEBUG);
|
||||
}
|
||||
|
||||
// Risque d’orage
|
||||
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.message += "- Risque d’orage \n";
|
||||
r.urgency = qMax(r.urgency, 4);
|
||||
r.colorCode += "cloud_with_lightning,";
|
||||
icons << "cloud_with_lightning";
|
||||
debug(DEBUGMACRO, "message : " + r.message, DEBUG);
|
||||
}
|
||||
|
||||
if (temperatureC <= 0.5 && humidityPercent >= 85.0) {
|
||||
// conditions classiques de gel
|
||||
if (d >= -1 && d <= +1)
|
||||
if (d3 >= -1.0 && d3 <= +1.0)
|
||||
{
|
||||
r.blackIce = true; // temps stable = ciel clair = refroidissement
|
||||
}else if (d < -1 && p > 995)
|
||||
@@ -270,13 +286,13 @@ public:
|
||||
if (r.blackIce)
|
||||
{
|
||||
r.message += "- Risque de verglas \n";
|
||||
r.colorCode += "ice_cube,";
|
||||
icons << "ice_cube";
|
||||
r.urgency = qMax(r.urgency, 4);
|
||||
debug(DEBUGMACRO, "message : " + r.message, DEBUG);
|
||||
}
|
||||
|
||||
// --- 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 l’heure \n";
|
||||
r.urgency = qMax(r.urgency, 4);
|
||||
@@ -285,7 +301,7 @@ public:
|
||||
{
|
||||
r.prevision1h = "🌤 Amélioration probable dans l’heure \n";
|
||||
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.confiance = 70;
|
||||
@@ -321,6 +337,8 @@ public:
|
||||
}
|
||||
debug(DEBUGMACRO, "message : " + r.message, DEBUG);
|
||||
|
||||
if (!icons.isEmpty()) r.icons = icons.join(",");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -325,7 +325,7 @@ void Pws2mqtt::parseData(QList<std::pair<QString, QString>> queryList)
|
||||
prevision = newPrevision;
|
||||
propertyList["prevision"] = prevision;
|
||||
priority = setPriority(priority, ret.urgency);
|
||||
tag += ret.colorCode;
|
||||
tag += ret.icons;
|
||||
}
|
||||
debug (DEBUGMACRO, "priority = " + QString::number(priority), DEBUG);
|
||||
}else if (name == "UV")
|
||||
|
||||
Reference in New Issue
Block a user