TKK_E32230206/lib/features/iot/providers/control_state.dart

178 lines
5.2 KiB
Dart

import 'package:flutter/material.dart';
// ── Model: WateringSchedule ────────────────────────────────────
class WateringSchedule {
final String id;
final TimeOfDay time;
final String repeat;
final bool isEnabled;
final String? cron;
final int durationS;
const WateringSchedule({
required this.id,
required this.time,
this.repeat = 'Setiap Hari',
this.isEnabled = true,
this.cron,
this.durationS = 30,
});
String get formattedTime {
final h = time.hour.toString().padLeft(2, '0');
final m = time.minute.toString().padLeft(2, '0');
return '$h.$m';
}
WateringSchedule copyWith({
String? id,
TimeOfDay? time,
String? repeat,
bool? isEnabled,
String? cron,
int? durationS,
}) {
return WateringSchedule(
id: id ?? this.id,
time: time ?? this.time,
repeat: repeat ?? this.repeat,
isEnabled: isEnabled ?? this.isEnabled,
cron: cron ?? this.cron,
durationS: durationS ?? this.durationS,
);
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is WateringSchedule &&
runtimeType == other.runtimeType &&
id == other.id);
@override
int get hashCode => id.hashCode;
}
// ── Enum: DeviceMode ─────────────────────────────────────────────────
enum DeviceMode { auto_, manual, offline }
extension DeviceModeX on DeviceMode {
String get apiValue {
switch (this) {
case DeviceMode.auto_: return 'auto';
case DeviceMode.manual: return 'manual';
case DeviceMode.offline: return 'offline';
}
}
String get label {
switch (this) {
case DeviceMode.auto_: return 'AUTO';
case DeviceMode.manual: return 'MANUAL';
case DeviceMode.offline: return 'OFFLINE';
}
}
static DeviceMode fromString(String s) {
final str = s.toLowerCase();
if (str.startsWith('manual')) {
return DeviceMode.manual;
} else if (str.startsWith('offline')) {
return DeviceMode.offline;
} else {
return DeviceMode.auto_;
}
}
}
// ── State: ControlState ────────────────────────────────────────────
class ControlState {
final bool isLoading;
final bool isPumpOn;
final double suhuLimit;
final double kelembapanLimit;
final List<WateringSchedule> schedules;
final String? errorMessage;
final String? successMessage;
final int? activePumpDuration;
final DateTime? pumpTurnedOnAt;
final DeviceMode deviceMode;
final bool isModeLoading;
const ControlState({
this.isLoading = false,
this.isPumpOn = false,
this.suhuLimit = 30,
this.kelembapanLimit = 75,
this.schedules = const [],
this.errorMessage,
this.successMessage,
this.activePumpDuration,
this.pumpTurnedOnAt,
this.deviceMode = DeviceMode.auto_,
this.isModeLoading = false,
});
factory ControlState.initial() => const ControlState(
isLoading: true, // Saat mulai aplikasi, data sedang di-fetch
schedules: [],
);
ControlState copyWith({
bool? isLoading,
bool? isPumpOn,
double? suhuLimit,
double? kelembapanLimit,
List<WateringSchedule>? schedules,
String? errorMessage,
String? successMessage,
int? activePumpDuration,
DateTime? pumpTurnedOnAt,
DeviceMode? deviceMode,
bool? isModeLoading,
bool clearError = false,
bool clearSuccess = false,
bool clearTimer = false,
}) {
return ControlState(
isLoading: isLoading ?? this.isLoading,
isPumpOn: isPumpOn ?? this.isPumpOn,
suhuLimit: suhuLimit ?? this.suhuLimit,
kelembapanLimit: kelembapanLimit ?? this.kelembapanLimit,
schedules: schedules ?? this.schedules,
errorMessage: clearError ? null : (errorMessage ?? this.errorMessage),
successMessage: clearSuccess ? null : (successMessage ?? this.successMessage),
activePumpDuration: clearTimer ? null : (activePumpDuration ?? this.activePumpDuration),
pumpTurnedOnAt: clearTimer ? null : (pumpTurnedOnAt ?? this.pumpTurnedOnAt),
deviceMode: deviceMode ?? this.deviceMode,
isModeLoading: isModeLoading ?? this.isModeLoading,
);
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is ControlState &&
isLoading == other.isLoading &&
isPumpOn == other.isPumpOn &&
suhuLimit == other.suhuLimit &&
kelembapanLimit == other.kelembapanLimit &&
errorMessage == other.errorMessage &&
successMessage == other.successMessage &&
activePumpDuration == other.activePumpDuration &&
pumpTurnedOnAt == other.pumpTurnedOnAt &&
schedules == other.schedules);
@override
int get hashCode =>
isLoading.hashCode ^
isPumpOn.hashCode ^
suhuLimit.hashCode ^
kelembapanLimit.hashCode ^
errorMessage.hashCode ^
successMessage.hashCode ^
activePumpDuration.hashCode ^
pumpTurnedOnAt.hashCode ^
schedules.hashCode;
}