Patrick Schurig 9dce12e721 docs(doxygen): 14 → 6 avertissements, et correction de la note sur le graphe
Première génération réelle avec Graphviz (doxygen 1.9.8, la version de référence) : 14
avertissements, dont 8 introduits par moi cette session — \return et \param manquants sur
la charge utile sg-ready, claimedThingIds(), validateSet() et claimedRelays(). Corrigés.

Les 6 restants sont exactement relayrouter.h et energyarbitrator.h, les deux fichiers
différés jusqu'après l'étape 3 puisqu'ils vont être restructurés. Le résidu est donc
entièrement connu et daté.

CORRECTION — la note que j'avais écrite en tête du Doxyfile était fausse. Elle annonçait
que l'arête « EnergyArbitrator : public SmartChargingManager » n'apparaîtrait pas. Elle
apparaît : doxygen rend une classe de base non résolue en boîte simple. Ce qui manque est
derrière — la boîte est un cul-de-sac, sans membres, sans ancêtres, non cliquable (aucun
href dans le SVG). La conclusion ne change pas, ne pas élargir INPUT ; la description, si.

101 graphes SVG produits, 3,2 Mo de HTML, 1,8 Mo de XML.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 06:54:56 +02:00

79 lines
3.6 KiB
C++

// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (C) 2025 - 2026, Patrick Schurig / ETM PowerSync
#pragma once
#include <QObject>
#include <QString>
#include "../types/loadconfig.h"
/*!
* \brief Store persistant des configs de charge pilotée (contrat etmvariableload §4).
*
* Master store unique : \c setConfigs() valide, **persiste** (\c /var/lib/nymea/\c
* energy-load-configuration.json, à côté de \c energy-manager-configuration.json) et émet
* \c changed() — l'arbitre reconstruit ses adaptateurs sur ce signal, le handler notifie l'app.
*
* Format fichier : \c {"version":1,"loads":[ ... ]}, chaque entrée étant un \c LoadConfig §4.
* Le tableau \c loads[] est **mot pour mot** le \c LoadDescriptor §4 (jonction inter-repos
* avec l'app).
*
* \invariant Écriture atomique (fichier temporaire + \c rename) — jamais de fichier mi-écrit.
* \invariant \c setConfigs() rejette en bloc (rien persisté) si une seule entrée est invalide.
*/
class LoadConfigStore : public QObject
{
Q_OBJECT
public:
/*!
* \brief Construit le store et charge le fichier s'il existe.
* \param parent Propriétaire Qt.
* \note Un fichier absent, illisible ou au JSON invalide n'est pas une erreur :
* le store démarre à vide. Une ENTRÉE invalide est ignorée individuellement
* (tolérance ascendante) — on ne perd pas les autres pour une seule.
*/
explicit LoadConfigStore(QObject *parent = nullptr);
/*! \brief Configs actuellement en mémoire (chargées au démarrage ou via setConfigs).
* \return Copie de l'ensemble courant ; toutes ont passé \c LoadConfig::isValid(). */
LoadConfigs configs() const { return m_configs; }
/*!
* \brief Remplace l'ensemble des configs : valide tout → persiste → \c emit changed().
* \param configs Nouvel ensemble (remplace l'existant — l'app envoie la liste complète).
* \param[out] error Message FR si rejet (aucune écriture dans ce cas).
* \return true si validé + persisté ; false si invalide ou échec d'écriture.
*/
bool setConfigs(const LoadConfigs &configs, QString *error = nullptr);
/*! \brief Cohérence de l'ENSEMBLE, ce qu'aucune charge ne peut vérifier seule.
*
* ECS-110 s'arrête au bord d'une charge : \c LoadConfig::isValid() ne voit pas les
* autres. Deux exigences ne vivent donc que ici — identifiants uniques, et un Thing
* revendiqué par au plus UNE charge active. Le second cas est le même défaut que la
* garde de l'arbitre contre la PAC codée en dur, mais entre deux charges de
* configuration : deux commandes contradictoires sur un organe, et sa puissance
* comptée deux fois dans le budget (règle absolue 1).
*
* \note Seules les charges \c enabled sont confrontées. Une charge désactivée ne
* construit aucun adaptateur et ne commande rien ; l'interdire empêcherait de
* préparer une configuration de remplacement. La bascule \c enabled repasse par
* \c setConfigs(), donc par cette vérification.
*
* \param configs Ensemble complet à confronter (les charges désactivées sont ignorées).
* \param[out] error Motif de refus, en français, exploitable tel quel.
* \return true si l'ensemble est cohérent ; false au PREMIER conflit rencontré.
*/
static bool validateSet(const LoadConfigs &configs, QString *error = nullptr);
signals:
/*! \brief Émis après une persistance réussie de \c setConfigs(). */
void changed();
private:
QString filePath() const;
bool load();
bool save(QString *error) const;
LoadConfigs m_configs;
};