Lot Connexions multi-HEMS : - modèle Installation + InstallationStore (persistance par UUID ; métadonnées SharedPreferences, token via flutter_secure_storage) - ConnectionManager au-dessus de nymea_service : mono-connexion, switchTo, connectNew, enterDemo (démo = active factice), contrôle d'identité DHCP - nymea_service : connect() réveillé (ws://4444, token par UUID), capture Hello (uuid/name/initialSetupRequired), authenticate/createUser, resetState - écran Installations (3 états) + déverrouillage installateur depuis la racine - écran Connexion : auth 2 branches (JSONRPC.Authenticate / CreateUser), détection auto via initialSetupRequired, segmenteur de repli - gate de routage (redirect + refreshListenable merge[cm,svc]) ; hasActiveConnection = isSimulation || (connected && authenticated) - en-tête drawer cliquable → Installations - invalidation des caches au switch (service.resetState + clearForSwitch rôles/scheduler/tariff), sans persist() Lot Rôles & appareils : - EnergySetupProvider refondu en tri-état (present/absent/non-configuré) - écran roles_devices_screen (3 zones, drag-priorité, inférence solaire/batterie) - LoadDescriptor (etmvariableload, rév.2 : PAC exclue → SG-Ready) ; Energy.SetRootMeter réel, Get/SetLoadConfig en stub loggé Correctifs : - bug signe énergie : production +, consommation NÉGATIVE sur nymea 1.15.2 → consumptionW/home en .abs() (autoconso n'est plus clouée à 0) - UUID Hello brace-wrapped normalisé Tests : flutter analyze 0 erreur ; gate + zéro-fuite au switch (5/5 verts). Validé en vrai : login auth .120, .75 ouvert, switch, déverrouillage installateur. Note : embarque aussi le WIP dashboard/thème déjà présent dans l'arbre. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
48 lines
1.2 KiB
Dart
48 lines
1.2 KiB
Dart
import 'dart:math' as math;
|
|
import 'package:flutter/material.dart';
|
|
|
|
class RingPainter extends CustomPainter {
|
|
final double value;
|
|
final Color color;
|
|
final double strokeWidth;
|
|
|
|
const RingPainter({
|
|
required this.value,
|
|
required this.color,
|
|
this.strokeWidth = 9.0,
|
|
});
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
final center = Offset(size.width / 2, size.height / 2);
|
|
final radius = (math.min(size.width, size.height) - strokeWidth) / 2;
|
|
|
|
canvas.drawCircle(
|
|
center,
|
|
radius,
|
|
Paint()
|
|
..color = color.withValues(alpha: 0.12)
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = strokeWidth,
|
|
);
|
|
|
|
if (value > 0.005) {
|
|
canvas.drawArc(
|
|
Rect.fromCircle(center: center, radius: radius),
|
|
-math.pi / 2,
|
|
2 * math.pi * value.clamp(0.0, 1.0),
|
|
false,
|
|
Paint()
|
|
..color = color
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = strokeWidth
|
|
..strokeCap = StrokeCap.round,
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(RingPainter old) =>
|
|
old.value != value || old.color != color || old.strokeWidth != strokeWidth;
|
|
}
|