Ajouts relatifs aux remontées d'alarmes vers ship2net
This commit is contained in:
@@ -1289,6 +1289,112 @@ int main(int argc, char *argv[])
|
||||
return withCors(QHttpServerResponse(QJsonDocument(reponse).toJson()));
|
||||
});
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// GET /alertes?depuis=AAAA-MM-JJ HH:MM:SS - déclenchements et fins des
|
||||
// events d'ALERTE (Alarme_email ou Alarme_sms actif) enregistrés dans
|
||||
// TB_Historique depuis cette date incluse (synthèse §51, lot Alertes).
|
||||
// Appelée par le VPS via NetBird (port 8080) après un coup de sonnette.
|
||||
// Dates en UTC. "depuis" inclus : deux enregistrements dans la même
|
||||
// seconde ne sont jamais manqués - le VPS écarte les doublons.
|
||||
// Au plus 1000 lignes, les plus anciennes d'abord (le VPS avance son
|
||||
// curseur et relit la suite au passage suivant).
|
||||
// Comme les autres routes /archives, réservée au VPS : bloquée dans le
|
||||
// relais /api du nginx du CM5 (location ^~ /api/alertes).
|
||||
// ------------------------------------------------------------------
|
||||
server.route("/alertes", QHttpServerRequest::Method::Get, [](const QHttpServerRequest &request) {
|
||||
assurer_connexion_bdd();
|
||||
|
||||
QUrlQuery query(request.query());
|
||||
const QString depuis = query.queryItemValue("depuis", QUrl::FullyDecoded);
|
||||
static const QRegularExpression format_date(QStringLiteral("^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"));
|
||||
if (!format_date.match(depuis).hasMatch()) {
|
||||
QJsonObject err;
|
||||
err["status"] = "error";
|
||||
err["message"] = "paramètre depuis attendu au format AAAA-MM-JJ HH:MM:SS (UTC)";
|
||||
return withCors(QHttpServerResponse(QJsonDocument(err).toJson(), QHttpServerResponder::StatusCode::BadRequest));
|
||||
}
|
||||
|
||||
// TB_Historique.Date est un TIMESTAMP : lecture forcée en UTC, quel que
|
||||
// soit le fuseau par défaut du serveur MariaDB.
|
||||
QSqlQuery fuseau;
|
||||
fuseau.exec("SET time_zone = '+00:00'");
|
||||
|
||||
QSqlQuery q;
|
||||
q.prepare("SELECT DATE_FORMAT(H.Date, '%Y-%m-%d %H:%i:%s'), H.Type, H.ID_Source, E.Nom,"
|
||||
" E.Alarme_email, E.Alarme_sms, E.Texte_email, E.Texte_sms"
|
||||
" FROM TB_Historique H"
|
||||
" JOIN TB_Events E ON E.Cle_primaire = H.ID_Source"
|
||||
" WHERE H.Type_source = 6 AND H.Type IN (1, 2)" // TYPE_SOURCE_HISTORIQUE_EVENTS ; EVENT_DECLENCHEMENT, EVENT_FIN_DECLENCHEMENT
|
||||
" AND (E.Alarme_email > 0 OR E.Alarme_sms > 0)"
|
||||
" AND H.Date >= ?"
|
||||
" ORDER BY H.Date"
|
||||
" LIMIT 1000");
|
||||
q.addBindValue(depuis);
|
||||
if (!q.exec()) {
|
||||
QJsonObject err;
|
||||
err["status"] = "error";
|
||||
err["message"] = q.lastError().text();
|
||||
return withCors(QHttpServerResponse(QJsonDocument(err).toJson(), QHttpServerResponder::StatusCode::InternalServerError));
|
||||
}
|
||||
|
||||
QJsonArray evenements;
|
||||
while (q.next()) {
|
||||
QJsonObject ev;
|
||||
ev["date"] = q.value(0).toString();
|
||||
ev["type"] = q.value(1).toInt();
|
||||
ev["id_event"] = q.value(2).toInt();
|
||||
ev["nom"] = q.value(3).toString();
|
||||
ev["alarme_email"] = q.value(4).toInt();
|
||||
ev["alarme_sms"] = q.value(5).toInt();
|
||||
ev["texte_email"] = q.value(6).toString();
|
||||
ev["texte_sms"] = q.value(7).toString();
|
||||
evenements.append(ev);
|
||||
}
|
||||
|
||||
QJsonObject reponse;
|
||||
reponse["status"] = "ok";
|
||||
reponse["evenements"] = evenements;
|
||||
return withCors(QHttpServerResponse(QJsonDocument(reponse).toJson()));
|
||||
});
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// POST /archives/demande - demande à l'Appli de produire une archive
|
||||
// IMMÉDIATEMENT (synthèse §50, étape 3d) : TB_Systeme.Demande_sauvegarde_bdd
|
||||
// passe à 1 ; l'Appli le lit, remet son compteur de période à 0 (archive
|
||||
// produite dans la seconde), puis remet l'indicateur à 0.
|
||||
// Appelée par le VPS via NetBird (port 8080), quand un utilisateur ouvre la
|
||||
// page "Données du bateau" sur le portail. Comme les autres routes
|
||||
// /archives, elle n'est PAS accessible via le relais /api du nginx du CM5.
|
||||
// ------------------------------------------------------------------
|
||||
server.route("/archives/demande", QHttpServerRequest::Method::Post, [](const QHttpServerRequest &request) {
|
||||
Q_UNUSED(request)
|
||||
assurer_connexion_bdd();
|
||||
|
||||
// Existence de la ligne vérifiée à part : un UPDATE qui ne change rien
|
||||
// (indicateur déjà à 1) renvoie aussi 0 ligne modifiée.
|
||||
QSqlQuery existe;
|
||||
existe.prepare("SELECT COUNT(*) FROM TB_Systeme WHERE Nom='Demande_sauvegarde_bdd'");
|
||||
if (!existe.exec() || !existe.next() || existe.value(0).toInt() == 0) {
|
||||
QJsonObject err;
|
||||
err["status"] = "error";
|
||||
err["message"] = "paramètre TB_Systeme.Demande_sauvegarde_bdd introuvable";
|
||||
return withCors(QHttpServerResponse(QJsonDocument(err).toJson(), QHttpServerResponder::StatusCode::NotImplemented));
|
||||
}
|
||||
|
||||
QSqlQuery q;
|
||||
q.prepare("UPDATE TB_Systeme SET Valeur='1' WHERE Nom='Demande_sauvegarde_bdd'");
|
||||
if (!q.exec()) {
|
||||
QJsonObject err;
|
||||
err["status"] = "error";
|
||||
err["message"] = q.lastError().text();
|
||||
return withCors(QHttpServerResponse(QJsonDocument(err).toJson(), QHttpServerResponder::StatusCode::InternalServerError));
|
||||
}
|
||||
|
||||
QJsonObject reponse;
|
||||
reponse["status"] = "ok";
|
||||
return withCors(QHttpServerResponse(QJsonDocument(reponse).toJson()));
|
||||
});
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// GET /archives - liste les archives en attente de traitement par le VPS
|
||||
// (cf synthèse §32.5). Remplace le transport sshpass/scp existant.
|
||||
|
||||
Reference in New Issue
Block a user