Patrick Schurig 1db79b481a fix(scheduler): ECS-309-b — le motif ne nomme un verrou que s'il a déplacé la consigne
Le critère était « consigne > budget ». Il est vrai dès que le budget passe sous zéro à
palier nul — 0 > -389 — et le motif annonçait alors « Verrou minOn — chauffe-eau maintenue
à 0 W (puissance engagée, budget -389 W) » : un verrou qui ne mordait pas, sur une
puissance engagée nulle, quand le soutirage était la seule cause.

Constaté au banc le 2026-08-13 sur +etm10, sept fois en quatre heures, toujours au cycle
suivant un palier 0. Le défaut est antérieur à ECS-309 : celui-ci a ajouté la branche
minOff après la branche minOn sans voir que la première capturait déjà un cas étranger.
Corriger une branche ne dit rien de ses voisines.

Le critère compare désormais la consigne appliquée à la consigne VOULUE avant écrêtage —
la mémoire qu'ECS-309 avait justement introduite. Relevée par le verrou → minOn ; rabaissée
→ minOff ; inchangée → le budget. Les deux branches se lisent sur le même axe, et le motif
nomme un mécanisme parce qu'il a agi, non parce qu'il aurait pu.

Ce n'était pas qu'un défaut de lisibilité. La branche minOn étant évaluée en premier, elle
masquait le motif d'armement à froid d'ECS-412 chaque fois que le budget était négatif au
redémarrage — c'est-à-dire au fond du creux, précisément l'instant où il faut redémarrer
pour observer minOff. La campagne du volet 2 aurait mesuré le mauvais verrou.

Le test reproduit le cas du banc : palier 0, budget négatif, aucun verrou actif. Sans le
correctif il produit le texte exact relevé sur la machine. Suite complète : 112 tests
(34 simulation + 46 charging + 32 spotmarket), 0 échec.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 07:32:42 +02:00

459 lines
20 KiB
Plaintext

powersync-energy-plugin-nymea (1.15.2+etm11) trixie; urgency=medium
* ECS-309-b — le motif ne nomme un verrou que si ce verrou a déplacé la consigne. Le
critère était « consigne > budget », vrai dès que le budget passe sous zéro à palier
nul : 0 > -389. Le motif annonçait alors « Verrou minOn — chauffe-eau maintenue à 0 W
(puissance engagée, budget -389 W) » — un verrou qui ne mordait pas, sur une puissance
engagée nulle, quand le soutirage était la seule cause. Le critère compare désormais la
consigne appliquée à la consigne VOULUE avant écrêtage : relevée → minOn, rabaissée →
minOff, inchangée → le budget. Les deux branches se lisent sur le même axe.
* Constaté au banc le 2026-08-13 sur +etm10, sept fois en quatre heures, toujours au
cycle suivant un palier 0. Le défaut est antérieur à ECS-309, qui a ajouté la branche
minOff après lui sans voir que la première capturait déjà un cas étranger.
* Il ne s'agissait pas que de lisibilité. La branche minOn étant évaluée en premier, ce
défaut masquait le motif d'armement à froid d'ECS-412 chaque fois que le budget était
négatif au redémarrage — soit au fond du creux, précisément l'instant où il faut
redémarrer pour observer minOff. La campagne aurait mesuré le mauvais verrou.
* Suite complète : 112 tests, 0 échec. Le cas est vérifié échouant sans le correctif,
où il reproduit le texte exact relevé sur la machine.
-- Patrick Schurig <etm.schurig@gmail.com> Thu, 13 Aug 2026 08:00:00 +0200
powersync-energy-plugin-nymea (1.15.2+etm10) trixie; urgency=medium
* ECS-309 — motif de décision fidèle au mécanisme. Lorsqu'un verrou, et non le budget,
produit le palier appliqué, le decisionReason nomme le verrou et la contrainte qu'il
impose. Le chemin minOff — celui de l'armement à froid d'ECS-412 — publiait
« Surplus insuffisant (7706 W) » alors que 7706 W étaient précisément disponibles :
la décision était juste, le motif accusait le budget. Il cite maintenant le budget
DISPONIBLE, pour couper court à l'explication budgétaire.
* Les trois causes sont distinguables à la lecture : budget réellement insuffisant,
verrou minOn maintenant un palier au-dessus du budget, verrou minOff empêchant
l'enclenchement. Les cas minOn et minStateHold (PAC) étaient déjà fidèles.
* La règle 7 d'AGENTS.md exigeait un motif non vide ; ECS-309 l'étend de la présence à
la fidélité, et exige que les tests portent sur le mécanisme annoncé plutôt que sur
la non-vacuité de la chaîne — un test « motif non vide » n'aurait rien vu.
-- Patrick Schurig <etm.schurig@gmail.com> Tue, 11 Aug 2026 10:00:00 +0200
powersync-energy-plugin-nymea (1.15.2+etm9) trixie; urgency=medium
* Corrige le va-et-vient JSON-RPC cassé par l'union LM-300. GetLoadConfig sérialise
une charge via le méta-objet, donc toutes les propriétés déclarées — y compris un
« sgReady » VIDE sur une charge qui n'est pas SG-Ready. Le schéma SetLoadConfig
exigeant « states » dès que la clé est présente, nymea rejetait la requête AVANT le
handler : lire puis réécrire une configuration relay-router était impossible.
« states » et « minStateHoldS » passent en optionnels ; l'exigence réelle (states
non vide, état 2 présent) reste tenue par LoadConfig::isValid().
* Constaté au banc à la première tentative réelle de SetLoadConfig. Aucun test ne
rejouait le geste de l'app — lire, modifier un champ, réécrire. C'est désormais le
cas (testLoadConfigRpc §3bis, vérifié échouant sans le correctif).
-- Patrick Schurig <etm.schurig@gmail.com> Mon, 10 Aug 2026 09:00:00 +0200
powersync-energy-plugin-nymea (1.15.2+etm8) trixie; urgency=medium
* ECS-110-b — un Thing n'appartient qu'à UNE charge active. Le cas général n'était
pas couvert : deux charges de configuration pouvaient revendiquer le même relais
(déclaré à la fois dans la charge ECS et dans un état SG-Ready), soit deux
commandes contradictoires sur un organe et sa puissance comptée deux fois dans le
budget. LoadConfig::isValid() s'arrête au bord d'une charge ; la vérification
d'ensemble est portée par LoadConfigStore::validateSet().
* Deux doublons intra-charge également refusés : deux étages relay-router sur le même
Thing (le routeur les fusionnait en silence en annonçant le double de la puissance)
et un relais répété dans un même état SG-Ready. Un relais présent dans PLUSIEURS
états reste légitime — l'état 4 est l'union des états 1 et 3.
* Identifiants de charge dupliqués refusés : la seconde entrée était perdue en
silence à la construction. ThingIds normalisés via QUuid, « {uuid} » et « UUID »
désignant le même organe.
* Au chargement du fichier, une entrée en conflit est écartée plutôt que de perdre
toute la configuration : écarter une charge ne commande rien, la charger
commanderait faux.
-- Patrick Schurig <etm.schurig@gmail.com> Sun, 09 Aug 2026 15:00:00 +0200
powersync-energy-plugin-nymea (1.15.2+etm7) trixie; urgency=medium
* SG-Ready configurable — première implémentation réelle de spec_loadmodel.md §3.
LoadConfig devient une union discriminée par mécanisme (LM-300) : le champ
`adapter` est le discriminant, chaque mécanisme a une charge utile et valide la
sienne. `sg-ready` porte states[] { state, relays[], estimatedPowerW } et
minStateHoldS ; les paliers de la PAC ne sont plus codés en dur.
* Une configuration sg-ready dépourvue de l'état 2 est REFUSÉE, pas construite :
l'état 2 est le plancher de repli du mode dégradé L2 et de la désactivation.
Les deux Q_ASSERT de SgReadyAdapter, absents du binaire release, sont retirés au
profit de ce refus et d'un drapeau m_usable (ECS-110).
* La PAC de configuration vit dans la même table que les autres charges : elle
hérite d'ECS-412 (reconstruction incrémentale) et d'ECS-413 (état sûr = état 2)
sans code dédié.
* Garde de double propriété : si une PAC de configuration vise les contacts de la
PAC de banc enregistrée en dur, cette dernière est retirée — deux adaptateurs sur
un même contact commanderaient en contradiction et compteraient la charge deux
fois dans le budget.
* spec_loadmodel.md 0.1.2 — LM-104 : supposer conservateur pour annoncer, tenter
systématiquement pour agir. Vaut pour tout mécanisme, pas pour l'ECS seul.
-- Patrick Schurig <etm.schurig@gmail.com> Sun, 09 Aug 2026 12:00:00 +0200
powersync-energy-plugin-nymea (1.15.2+etm6) trixie; urgency=medium
* ECS-414 — l'échelle d'échec d'écriture (ECS-410) est généralisée à SgReadyAdapter et
EtmVariableLoadAdapter : suivi asynchrone des acquittements, échelle bornée, défaut
collant levé par NymeaEnergy.ClearLoadFault.
* Plancher propre à chaque adaptateur : consigne 0 W pour la charge continue, ÉTAT 2
pour la PAC SG-Ready — jamais « contacts ouverts », qui est une commande et peut valoir
le blocage selon l'encodage câblé.
* Le repli SG-Ready honore le même contrat d'atomicité que le chemin aller : il part du
motif de contacts RÉELLEMENT lu et ordonne les commutations par transientHarm, de sorte
que la récupération ne traverse pas le blocage. Il contourne minStateHoldS (900 s).
* Un contact injoignable est supposé FERMÉ pour la télémétrie (cohérence ECS-411) mais
TOUJOURS commandé : sans quoi l'hypothèse conservatrice masquerait l'échec.
* Test : testSgReadyPartialFailure. Suite 18/18.
-- Patrick Schurig <etm.schurig@gmail.com> Sun, 09 Aug 2026 21:00:00 +0200
powersync-energy-plugin-nymea (1.15.2+etm5) trixie; urgency=medium
* ECS-410 — échec d'écriture relais : l'adaptateur suit désormais l'acquittement de
chaque executeAction, sans jamais bloquer le cycle (AGENTS règle 5). Échelle bornée
à trois barreaux — cible, retour arrière, arrêt total — puis état de défaut COLLANT,
levé seulement par le nouvel appel NymeaEnergy.ClearLoadFault.
* Pendant une transition, la télémétrie annonce max(palier précédent, palier cible) :
ne jamais annoncer moins que ce qui peut être appliqué (même direction qu'ECS-411).
* LoadContext.available ajouté — il gouverne l'ALLOCATION, pas la COMPTABILITÉ : une
charge en défaut ne reçoit plus de consigne mais reste comptée au budget.
OPTIMIZER_PROTOCOL.md mis à jour dans le même lot.
* ECS-413 — désactiver une charge (enabled: false) la laisse dans l'état SÛR de son
adaptateur, appliqué AVANT destruction : relais ouverts pour un routeur, 0 W pour une
charge continue, état 2 pour une PAC SG-Ready — jamais le blocage. Un rebuild sans
désactivation ne coupe rien (ECS-412 préservé).
* Tests : testEcsPartialFailure, testEcsDisableLeavesSafeState. Suite 17/17.
-- Patrick Schurig <etm.schurig@gmail.com> Sun, 09 Aug 2026 18:00:00 +0200
powersync-energy-plugin-nymea (1.15.2+etm4) trixie; urgency=medium
* ECS-412 — correction d'un blocage circulaire du verrou au démarrage à froid,
constaté AU BANC (charge figée à 0 W sous 4 kW de surplus disponible).
Un horodatage de dernière commutation nul servait de sentinelle « écoulé = 0 »
à chaque cycle : toute charge relay-router démarrant relais ouverts avec
minOffS > 0 ne pouvait jamais s'enclencher, donc jamais commuter, donc jamais
valider son horodatage.
* L'armement du verrou devient PARESSEUX et TRANSITOIRE : posé au premier temps
de cycle reçu par applyAction(), il expire après sa durée configurée.
L'invariant « temps = paramètre, jamais l'horloge » est préservé.
* Test : testEcsColdStartLockExpires — palier 0 au départ, minOffS = 120,
budget 5000 W ; éteinte pendant le verrou, enclenchée après. Suite 15/15.
-- Patrick Schurig <etm.schurig@gmail.com> Sun, 09 Aug 2026 10:00:00 +0200
powersync-energy-plugin-nymea (1.15.2+etm3) trixie; urgency=medium
* Étape 1 (specs/spec_ecs.md) — trois corrections de comportement sur les
charges pilotées à relais :
* ECS-306 : le budget décrémenté par le scheduler suit le palier RÉELLEMENT
applicable. La fenêtre de verrou est de nouveau exposée à l'arbitre, en watts
(lockMinPowerW/lockMaxPowerW) — aucun index de palier ne franchit la
frontière. Sans ce canal, les charges de priorité suivante recevaient un
résidu surestimé pendant toute la fenêtre minOn, donc soutirage réseau.
* ECS-411 : le palier courant est déduit de l'état réel des Things relais au
démarrage, au lieu de repartir de 0 — le moteur ne croit plus 0 W pendant que
le ballon chauffe.
* ECS-412 : rebuild incrémental des adaptateurs. Un SetLoadConfig qui ne change
qu'un rang ne détruit plus l'adaptateur, donc ne réarme plus les verrous : sur
un ballon thermodynamique à minOn de 300-600 s, réordonner ses priorités
depuis l'app pouvait faire court-cycler le compresseur. Au démarrage à froid,
le verrou est ARMÉ (défaut sûr), jamais purgé.
* Tests : testEcsBudgetUnderLock, testEcsRestartRecovery,
testEcsRebuildPreservesLock. Suite simulation 14/14.
-- Patrick Schurig <etm.schurig@gmail.com> Sat, 08 Aug 2026 14:40:00 +0200
powersync-energy-plugin-nymea (1.15.2+etm2) trixie; urgency=medium
* Charge pilotée rév. 3 — frontière optimiseur (watt-pur) ↔ routeur (watts→relais, experience-plugin).
* RelayRouter : combinatoire watts→relais ; paliers DÉRIVÉS des relais (things "power"), verrous
minOn/minOff internes, off-before-on, agrégation currentPowerW (mesuré sinon nominal commandé).
* Optimiseur watt-pur : suppression du kind Stage ; buildSetpointAction (arrondi powerLevels / résidu).
* LoadConfig : forme relay-router (relays[]=[{thingId,powerW}] + minOnS/minOffS), validation
conditionnelle ; Get/SetLoadConfig (schéma SET "o:" pour les deux formes exclusives).
* Repli L2 unifié : compteur muet → Setpoint(0) force=true sur tous les ILoadAdapter (RelayRouter
coupe TOUS les relais). EtmVariableLoadAdapter (continu/triac) conservé.
* Tests : combinatoire/off-before-on/déduplication, repli L2 relais, chaîne config→routeur, RPC.
-- Patrick Schurig <etm.schurig@gmail.com> Sun, 28 Jun 2026 13:38:36 +0200
powersync-energy-plugin-nymea (1.15.2+etm1) trixie; urgency=medium
* Build contre nymea 1.15.2. EcsRelayAdapter + SgReadyAdapter dans init() (§1.d banc hems).
-- Patrick Schurig <etm.schurig@gmail.com> Thu, 25 Jun 2026 15:30:00 +0200
powersync-energy-plugin-nymea (1.15.0+etm1) trixie; urgency=medium
* Renommage paquet powersync-* + version 1.15.0 alignée sur libnymea-energy cible hems
* EnergyArbitrator : waterfall ECS+PAC, RuleBasedScheduler, watchdog L2
* EcsRelayAdapter : 8 paliers binaires, off-before-on, verrous minOn/minOff
* SgReadyAdapter : 4 états SG-Ready, hystérésis kForceMargin=1.2, zone morte
* §1.d banc hems : enregistrement EcsRelayAdapter+SgReadyAdapter dans init()
* Build deb : tests exclus (CONFIG+=build_tests requis séparément)
-- Patrick Schurig / ETM PowerSync <etm.schurig@gmail.com> Wed, 25 Jun 2026 12:00:00 +0200
nymea-energy-plugin-nymea (1.13.0+etm1) jammy; urgency=medium
* Fork ETM PowerSync de nymea-energy-plugin-nymea
-- Patrick Schurig / ETM PowerSync <etm.schurig@gmail.com> Sun, 07 Jun 2026 21:38:25 +0200
nymea-energy-plugin-nymea (1.13.0) jammy; urgency=medium
[ Simon Stürz ]
* Update license text and add SPDX identifier
-- jenkins <developer@nymea.io> Tue, 02 Dec 2025 10:40:27 +0100
nymea-energy-plugin-nymea (1.12.4) jammy; urgency=medium
-- jenkins <developer@nymea.io> Thu, 27 Nov 2025 11:21:05 +0100
nymea-energy-plugin-nymea (1.12.3) jammy; urgency=medium
-- jenkins <developer@nymea.io> Tue, 04 Nov 2025 11:39:56 +0100
nymea-energy-plugin-nymea (1.12.2) jammy; urgency=medium
[ Simon Stürz ]
* debian: Fix debian packaging for Qt6 packages
-- jenkins <developer@nymea.io> Wed, 29 Oct 2025 12:29:18 +0100
nymea-energy-plugin-nymea (1.12.1) jammy; urgency=medium
-- jenkins <developer@nymea.io> Mon, 13 Oct 2025 15:29:39 +0200
nymea-energy-plugin-nymea (1.12.0) jammy; urgency=medium
[ Simon Stürz ]
* Add Qt6 support
* Fix phase switching available logic
-- jenkins <developer@nymea.io> Thu, 11 Sep 2025 14:27:01 +0200
nymea-energy-plugin-nymea (1.11.1) jammy; urgency=medium
[ Simon Stürz ]
* Stop charging if the battery is under the consideration point
* Fix wrong warning regarding configuration ENV loading
-- jenkins <developer@nymea.io> Thu, 22 May 2025 15:29:54 +0200
nymea-energy-plugin-nymea (1.11.0) jammy; urgency=medium
[ Martin Lukas ]
* Add support for houshold battery level consideration
[ Simon Stürz ]
* Update permissions in order to allow a non admin system user
* Improve overload protection
* Improve phase switching logic
* Fix invalid max phase count calculation on single phase car with
phase switching charger
-- jenkins <developer@nymea.io> Thu, 20 Mar 2025 14:17:07 +0100
nymea-energy-plugin-nymea (1.10.0) jammy; urgency=medium
[ Simon Stürz ]
* Add spot market charing
-- jenkins <developer@nymea.io> Tue, 26 Nov 2024 20:53:11 +0100
nymea-energy-plugin-nymea (1.9.5) jammy; urgency=medium
-- jenkins <developer@nymea.io> Mon, 21 Oct 2024 21:05:52 +0200
nymea-energy-plugin-nymea (1.9.4) jammy; urgency=medium
-- jenkins <developer@nymea.io> Wed, 14 Aug 2024 18:36:34 +0200
nymea-energy-plugin-nymea (1.9.3) jammy; urgency=medium
[ Simon Stürz ]
* Update debian packaging and compat level
-- jenkins <developer@nymea.io> Fri, 19 Jul 2024 21:07:54 +0200
nymea-energy-plugin-nymea (1.9.2) jammy; urgency=medium
-- jenkins <developer@nymea.io> Thu, 11 Apr 2024 15:47:40 +0200
nymea-energy-plugin-nymea (1.9.1) jammy; urgency=medium
-- jenkins <developer@nymea.io> Thu, 04 Jan 2024 19:14:46 +0100
nymea-energy-plugin-nymea (1.9.0) jammy; urgency=medium
-- jenkins <developer@nymea.io> Thu, 23 Nov 2023 09:55:12 +0100
nymea-energy-plugin-nymea (1.8.4) jammy; urgency=medium
[ Michael Zanetti ]
* Don't use acquisitiontolerance to determine wheter to switcht to 3
phases
* Fix minimum car amps not being regarded in ECO mode
-- jenkins <developer@nymea.io> Tue, 14 Nov 2023 09:12:06 +0100
nymea-energy-plugin-nymea (1.8.2) jammy; urgency=medium
[ Michael Zanetti ]
* Fix effective phase count after switching phases
-- jenkins <developer@nymea.io> Wed, 28 Jun 2023 09:49:36 +0200
nymea-energy-plugin-nymea (1.8.1) jammy; urgency=medium
[ Michael Zanetti ]
* Include car minimum amps in calculation for enoughFor3PhaseCharging
-- jenkins <developer@nymea.io> Tue, 13 Jun 2023 10:20:45 +0200
nymea-energy-plugin-nymea (1.8.0) jammy; urgency=medium
[ Michael Zanetti ]
* Add support for dynamically setting the phase count
* Use currentPower instead of current for calculating the allowance
* Don't drain batteries during daytime if solar power fluctuates
* Also regard minimum charging amps for the assigned car
-- jenkins <developer@nymea.io> Tue, 16 May 2023 16:53:01 +0200
nymea-energy-plugin-nymea (1.7.0) jammy; urgency=medium
[ Simon Stürz ]
* Make sure effective phase count will be evaluated in any case for
the charger
* Fix time calculation for immediately charging required
* Fix running tests in dpkg
[ Michael Zanetti ]
* Add a lockOnUnplug setting
-- jenkins <developer@nymea.io> Thu, 09 Mar 2023 15:13:24 +0100
nymea-energy-plugin-nymea (1.6.3) jammy; urgency=medium
-- jenkins <developer@nymea.io> Wed, 01 Feb 2023 12:19:29 +0100
nymea-energy-plugin-nymea (1.6.2) jammy; urgency=medium
-- jenkins <developer@nymea.io> Mon, 16 Jan 2023 14:37:17 +0100
nymea-energy-plugin-nymea (1.6.1) jammy; urgency=medium
[ Michael Zanetti ]
* Allow ECO mode without time restriction
* No notification for normal charging
-- jenkins <developer@nymea.io> Fri, 23 Dec 2022 11:33:56 +0100
nymea-energy-plugin-nymea (1.6.0) jammy; urgency=medium
[ Simon Stürz ]
* Introduce tests and simulations
[ Michael Zanetti ]
* Allow ECO mode without time restriction
* No notification for normal charging
-- jenkins <developer@nymea.io> Sat, 10 Dec 2022 14:56:05 +0100
nymea-energy-plugin-nymea (1.5.1) jammy; urgency=medium
-- jenkins <developer@nymea.io> Mon, 07 Nov 2022 12:49:43 +0100
nymea-energy-plugin-nymea (1.5.0) jammy; urgency=medium
[ Michael Zanetti ]
* Fix current power calculation for evchargers without meter
-- jenkins <developer@nymea.io> Mon, 17 Oct 2022 14:06:35 +0200
nymea-energy-plugin-nymea (1.4.1) jammy; urgency=medium
[ Michael Zanetti ]
* Fix a crash when the root meter is removed
* Fixes for the automatic SoC calculation
* Fix acquisition tolerance
-- jenkins <developer@nymea.io> Thu, 29 Sep 2022 20:11:39 +0200
nymea-energy-plugin-nymea (1.4.0) jammy; urgency=medium
[ Michael Zanetti ]
* Add deep linking data to plugged in push notification
* Add acquisitionTolerance setting
-- jenkins <developer@nymea.io> Mon, 22 Aug 2022 17:00:54 +0200
nymea-energy-plugin-nymea (1.3.1) jammy; urgency=medium
[ Michael Zanetti ]
* Fix SoC calculation
-- jenkins <developer@nymea.io> Mon, 11 Jul 2022 15:36:45 +0200
nymea-energy-plugin-nymea (1.3.0) jammy; urgency=medium
[ Michael Zanetti ]
* Count up manual SoC while charging
* Add translations
[ Simon Stürz ]
* Update business logic behavior
-- jenkins <developer@nymea.io> Fri, 01 Jul 2022 22:50:18 +0200
nymea-energy-plugin-nymea (1.2.0) jammy; urgency=medium
-- jenkins <developer@nymea.io> Tue, 07 Jun 2022 19:45:44 +0200
nymea-energy-plugin-nymea (1.1.0) jammy; urgency=medium
[ Michael Zanetti ]
* Add CharingState information to API
* Fix calculation of remaining charging time if SoC is higher than
TSoC
* Some fixes in the smart charging logic
-- jenkins <developer@nymea.io> Tue, 10 May 2022 12:47:01 +0200
nymea-energy-plugin-nymea (1.0.0) xenial; urgency=medium
[ Michael Zanetti ]
* Improve calculation for charging power
[ Jenkins ]
-- Jenkins <jenkins@nymea.io> Thu, 10 Mar 2022 17:55:05 +0100
nymea-energy-plugin-nymea (0.1) xenial; urgency=medium
[ Michael Zanetti ]
* Import code from nymea-experience-plugin-energy
-- Jenkins <jenkins@nymea.io> Wed, 15 Dec 2021 11:54:55 +0100