Consigne app §G (décision Patrick du 2026-10-16) et motifs etm70 (§H). G — la carte « Héos pilote en ce moment » affichait des décisions inventées (HeosDecision.demo : voiture 3,6 kW, batterie en charge sur un banc sans batterie). Remplacée par EnCeMomentCard : une ligne par charge de GetLoadTelemetry — libellé de la configuration, decision.code + params rendus par decisionText, puissance MESURÉE seulement (jamais l'allocation à sa place). Titre en clé l10n. Rien sur « optimiseur actif » tant que l'objet de capacités n'existe pas. Marque retirée des identifiants (HeosDecisionCard, HeosDecision, HeosAction, _HeosChip, _HeosBadgeSmall, heosActive → pilotageActif…), des fichiers (heos_decision_card.dart, dashboard_models.dart supprimés), des textes affichés (hub du flux, écran A/C) et des commentaires : grep -ri héos/heos vide sur lib/, test/, assets/ et les .arb. H — contre INTERFACE.md local de la branche moteur, etm70 pas encore sur le banc : - motifs éco publiés à la racine (R7, part majoritaire) rendus en clair ; ventilation des niveaux affichée (« 83 W éco + 0 W confort », vu sur la trame réelle etm69) ; - ECO_FLOOR_MISSED retenu par charge (publié un seul cycle), y compris pour une charge sortie de loads[] ; « manque non chiffrable » quand missingWh est absent, jamais 0 Wh ; - PRICE_SLOT et OPTIMIZER_DECISION en FR / DE / EN (app_en.arb et app_de.arb créés pour ces seules clés ; le reste retombe sur le français, listé dans l10n_untranslated.json). Code inconnu : repli générique avec le code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
1.5 KiB
Dart
64 lines
1.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
/// Icône du cœur HEMS : étincelle au centre,
|
|
/// 4 nœuds pilotés alignés sur les pointes.
|
|
class HemsIcon extends StatelessWidget {
|
|
final double size;
|
|
final Color? color;
|
|
|
|
const HemsIcon({super.key, this.size = 24, this.color});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final c = color ??
|
|
IconTheme.of(context).color ??
|
|
const Color(0xFF28A06A);
|
|
return SizedBox(
|
|
width: size,
|
|
height: size,
|
|
child: CustomPaint(painter: _HemsPainter(c)),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _HemsPainter extends CustomPainter {
|
|
final Color color;
|
|
_HemsPainter(this.color);
|
|
|
|
static const _nodes = <Offset>[
|
|
Offset(12, 3.4),
|
|
Offset(20.6, 12),
|
|
Offset(12, 20.6),
|
|
Offset(3.4, 12),
|
|
];
|
|
static const _nodeR = 1.7;
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
final s = size.width / 24.0;
|
|
final paint = Paint()
|
|
..color = color
|
|
..style = PaintingStyle.fill
|
|
..isAntiAlias = true;
|
|
|
|
final spark = Path()
|
|
..moveTo(12 * s, 7.4 * s)
|
|
..lineTo(13.25 * s, 10.75 * s)
|
|
..lineTo(16.6 * s, 12 * s)
|
|
..lineTo(13.25 * s, 13.25 * s)
|
|
..lineTo(12 * s, 16.6 * s)
|
|
..lineTo(10.75 * s, 13.25 * s)
|
|
..lineTo(7.4 * s, 12 * s)
|
|
..lineTo(10.75 * s, 10.75 * s)
|
|
..close();
|
|
canvas.drawPath(spark, paint);
|
|
|
|
for (final n in _nodes) {
|
|
canvas.drawCircle(Offset(n.dx * s, n.dy * s), _nodeR * s, paint);
|
|
}
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(_HemsPainter old) => old.color != color;
|
|
}
|