etm-powersync-app/lib/providers/scheduler_provider.dart
pakutz79 c19c9d1a98 feat: navigation drawer, EMS setup, scheduler, tarifs, paramètres app
- Drawer custom (overlay Stack) avec mode installateur PIN SHA-256
- GoRouter + ShellRoute : navigation préservée entre onglets
- 6 providers : NavigationProvider, InstallerModeProvider, AppSettingsProvider,
  EnergySetupProvider, SchedulerProvider, TariffProvider
- Écrans Energy Manager : RoleConfigFlow (3 étapes), Scheduler, Tarifs, Timeline
- Écrans Paramètres : Apparence, Écrans actifs, AppSettingsScreen
- DrawerMenuButton présent dans les 5 AppBars principaux
- Simulation : _thingClasses générées avec interfaces EMS pour filtrage des rôles
- Compteur solaire : ajout smartmeter aux interfaces compatibles
- Thème ETM (etm_theme.dart), ProLockBadge, widgets PowerBar/RoleCard/TimelineSlotCard
- Dépendances : go_router, shared_preferences, crypto, url_launcher

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:52:32 +01:00

112 lines
3.7 KiB
Dart

import 'dart:async';
import 'package:flutter/foundation.dart';
import '../services/nymea_service.dart';
enum SchedulerStrategy { rulesBased, manual, aiPro }
extension SchedulerStrategyExt on SchedulerStrategy {
String get label => switch (this) {
SchedulerStrategy.rulesBased => 'Basée sur les règles',
SchedulerStrategy.manual => 'Manuelle',
SchedulerStrategy.aiPro => 'AI (Pro)',
};
bool get isPro => this == SchedulerStrategy.aiPro;
}
class SchedulerConfig {
final double priceThreshold; // €/kWh
final double minSurplus; // W
final int planningHorizon; // heures
final int recalcInterval; // minutes
final double selfSufficiencyGoal; // %
const SchedulerConfig({
this.priceThreshold = 0.08,
this.minSurplus = 200,
this.planningHorizon = 24,
this.recalcInterval = 15,
this.selfSufficiencyGoal = 70,
});
SchedulerConfig copyWith({
double? priceThreshold,
double? minSurplus,
int? planningHorizon,
int? recalcInterval,
double? selfSufficiencyGoal,
}) => SchedulerConfig(
priceThreshold: priceThreshold ?? this.priceThreshold,
minSurplus: minSurplus ?? this.minSurplus,
planningHorizon: planningHorizon ?? this.planningHorizon,
recalcInterval: recalcInterval ?? this.recalcInterval,
selfSufficiencyGoal: selfSufficiencyGoal ?? this.selfSufficiencyGoal,
);
}
enum SchedulerStatus { ok, degraded, error }
class SchedulerState {
final SchedulerStatus status;
final String reason;
final DateTime? lastPlanning;
final DateTime? nextPlanning;
const SchedulerState({
this.status = SchedulerStatus.ok,
this.reason = '',
this.lastPlanning,
this.nextPlanning,
});
}
/// Gère la stratégie, la configuration et l'état du scheduler EMS.
class SchedulerProvider extends ChangeNotifier {
SchedulerStrategy _strategy = SchedulerStrategy.rulesBased;
SchedulerConfig _config = const SchedulerConfig();
SchedulerState _state = const SchedulerState();
bool _loading = false;
SchedulerStrategy get strategy => _strategy;
SchedulerConfig get config => _config;
SchedulerState get state => _state;
bool get loading => _loading;
// ── Chargement depuis nymea (stub — à brancher sur RPC réel) ────────────────
Future<void> load(NymeaService service) async {
_loading = true;
notifyListeners();
await Future.delayed(const Duration(milliseconds: 300));
_state = SchedulerState(
status: SchedulerStatus.ok,
reason: 'TariffManager: aWATTar AT actif',
lastPlanning: DateTime.now().subtract(const Duration(minutes: 8)),
nextPlanning: DateTime.now().add(const Duration(minutes: 7)),
);
_loading = false;
notifyListeners();
}
// ── Mutations ────────────────────────────────────────────────────────────────
void setStrategy(SchedulerStrategy s) {
_strategy = s;
notifyListeners();
// TODO: _sendRequest('Energy.SetSchedulerStrategy', ...)
}
void updateConfig(SchedulerConfig c) {
_config = c;
notifyListeners();
// TODO: _sendRequest('Energy.SetSchedulerConfig', ...)
}
Future<void> forceRecalc(NymeaService service) async {
_loading = true;
notifyListeners();
await Future.delayed(const Duration(seconds: 1));
_state = _state; // Mettre à jour depuis la réponse RPC
_loading = false;
notifyListeners();
}
}