sek
This commit is contained in:
parent
6289cc7629
commit
5d3d5e7ee6
|
|
@ -1,6 +1,14 @@
|
||||||
manifest.json,1768956954743,5edb32bebce763b2b7e55774ae4c5c4354a44df248387cc3c174e8710e85aaa1
|
manifest.json,1768956954743,5edb32bebce763b2b7e55774ae4c5c4354a44df248387cc3c174e8710e85aaa1
|
||||||
flutter.js,1767911992319,970356511bee637e57348b9e01b3218a3d1d6c4add478fdc306033b4b3e21ef4
|
flutter.js,1767911992319,970356511bee637e57348b9e01b3218a3d1d6c4add478fdc306033b4b3e21ef4
|
||||||
favicon.png,1768956954741,19880e004e8357a51f6a64f5d1fdc8828a6432fe9c781f8acb6b730eced2cd13
|
favicon.png,1768956954741,19880e004e8357a51f6a64f5d1fdc8828a6432fe9c781f8acb6b730eced2cd13
|
||||||
|
splash/img/light-4x.png,1779442242118,09ff8858378bb70d5f4b0381eb98dc9a889e541aeb2dd7576da7d62f205de578
|
||||||
|
splash/img/light-3x.png,1779442242118,a1a4d566718037d913ad3287e9b7d1e6d0df8569c285ce3d3680db82b6a96812
|
||||||
|
splash/img/light-2x.png,1779442242116,e8cc8f611a58a4926632edfcd3cb7d95925b6895791632ea1c1739c4f454c8fa
|
||||||
|
splash/img/light-1x.png,1779442242116,c4d52b9b4b1cfdd74194c0192c462e0f14934e1428ab7ff99165f08dc17f9010
|
||||||
|
splash/img/dark-4x.png,1779442242116,09ff8858378bb70d5f4b0381eb98dc9a889e541aeb2dd7576da7d62f205de578
|
||||||
|
splash/img/dark-3x.png,1779442242115,a1a4d566718037d913ad3287e9b7d1e6d0df8569c285ce3d3680db82b6a96812
|
||||||
|
splash/img/dark-2x.png,1779442242115,e8cc8f611a58a4926632edfcd3cb7d95925b6895791632ea1c1739c4f454c8fa
|
||||||
|
splash/img/dark-1x.png,1779442242114,c4d52b9b4b1cfdd74194c0192c462e0f14934e1428ab7ff99165f08dc17f9010
|
||||||
icons/Icon-maskable-512.png,1768956954742,ea58e5c49bc4dcdc5db0a9fe2f25b2a3152f85ef9094f0d020de0aa318451a1d
|
icons/Icon-maskable-512.png,1768956954742,ea58e5c49bc4dcdc5db0a9fe2f25b2a3152f85ef9094f0d020de0aa318451a1d
|
||||||
icons/Icon-maskable-192.png,1768956954742,f7ac56197638aec92f195c5344d15395c2cbf8a5ae74e846c5b4156b64f05e38
|
icons/Icon-maskable-192.png,1768956954742,f7ac56197638aec92f195c5344d15395c2cbf8a5ae74e846c5b4156b64f05e38
|
||||||
icons/Icon-512.png,1768956954742,1de493563deb283e6ad70f0d5a89cfd61e37343df3b919c9862c5a41699ac5bc
|
icons/Icon-512.png,1768956954742,1de493563deb283e6ad70f0d5a89cfd61e37343df3b919c9862c5a41699ac5bc
|
||||||
|
|
@ -17,28 +25,20 @@ canvaskit/canvaskit.js,1767911992193,777116800268972381a4832500bb0aafd96ab254607
|
||||||
canvaskit/chromium/canvaskit.wasm,1767911992256,06f70f0703803c7329be30338b79530564ddc1ab2c3789d608431697a9a30ba2
|
canvaskit/chromium/canvaskit.wasm,1767911992256,06f70f0703803c7329be30338b79530564ddc1ab2c3789d608431697a9a30ba2
|
||||||
canvaskit/chromium/canvaskit.js.symbols,1767911992241,4a8d181b0622d7a4b4254deb591c43f48dd89623c621dec6f84d0a0b2b8f77a7
|
canvaskit/chromium/canvaskit.js.symbols,1767911992241,4a8d181b0622d7a4b4254deb591c43f48dd89623c621dec6f84d0a0b2b8f77a7
|
||||||
canvaskit/chromium/canvaskit.js,1767911992241,e0f423bfd63202fb53a4dd5cffe330143bfb9eabf5e4e8198bb605442a49d3e7
|
canvaskit/chromium/canvaskit.js,1767911992241,e0f423bfd63202fb53a4dd5cffe330143bfb9eabf5e4e8198bb605442a49d3e7
|
||||||
version.json,1779493407408,f7f931727903f67c4b2ec2c38d4c5c4e2ec1be0c03071b8bff0c27f5be3b9e6e
|
|
||||||
index.html,1779493279226,3ffbcfc0c9d82b851ce84d2b1bfc85cea0a34b077bdad955e7cf52643a3cf434
|
|
||||||
flutter_bootstrap.js,1779493279204,ac46b098b9b222a709fa5ec23d1808db44a01d9b73d454c9a583d07a29cea348
|
|
||||||
flutter_service_worker.js,1779493415284,df198e5b7cc03c86b760a3ec2fe6f78f064d02cf545c4fb4b4a6a4ae142c3020
|
|
||||||
splash/img/light-1x.png,1779442242116,c4d52b9b4b1cfdd74194c0192c462e0f14934e1428ab7ff99165f08dc17f9010
|
|
||||||
splash/img/dark-1x.png,1779442242114,c4d52b9b4b1cfdd74194c0192c462e0f14934e1428ab7ff99165f08dc17f9010
|
|
||||||
assets/AssetManifest.bin.json,1779493407814,e23e10111498cc3b8b40e6549dcde13cffa6f45dc78e88194f4a7e284bb68294
|
|
||||||
assets/FontManifest.json,1779493407814,e38b95988f5d060cf9b7ce97cb5ac9236d6f4cc04a11d69567df97b2b4cbc5e5
|
|
||||||
assets/AssetManifest.bin,1779493407814,fe7319a65158e186661b7edfcc1c2b6c0a6bc6823b923a13e1e932cd66407fa2
|
|
||||||
assets/shaders/stretch_effect.frag,1779493407940,586ff23669838dd33070077916f0b971a8800f67093ae8d6eed47e6cea50926f
|
|
||||||
assets/packages/cupertino_icons/assets/CupertinoIcons.ttf,1779493409456,85140ea453cd3e02bd93650fe8add6a724ae8c0ac73d0c491085b301e7bd21d2
|
|
||||||
assets/shaders/ink_sparkle.frag,1779493407944,591c7517d5cb43eb91ea451e0d3f9f585cbf8298cf6c46a9144b77cb0775a406
|
|
||||||
assets/images/windy.png,1776157890991,b9d34ed004fff60a4fea365c23508823943f3f0793375f34ca9202069d9c9955
|
assets/images/windy.png,1776157890991,b9d34ed004fff60a4fea365c23508823943f3f0793375f34ca9202069d9c9955
|
||||||
assets/images/atmosfer.png,1776157890990,c3a9ddfa5676b5f0e1cf833f73c0f09c1dfb9d2e202906c1afcdd7a50dcf2506
|
|
||||||
assets/fonts/MaterialIcons-Regular.otf,1779493409477,1c7547588fe9c202b730590aab269e1bae9988240caeba41da28091251a87dbe
|
|
||||||
assets/images/google-icon-logo.png,1776157890990,333cfafcd5c87738a4098359e18e02ff5848b2b1b819ec8aff29424c3f82d32b
|
|
||||||
splash/img/light-2x.png,1779442242116,e8cc8f611a58a4926632edfcd3cb7d95925b6895791632ea1c1739c4f454c8fa
|
|
||||||
splash/img/dark-2x.png,1779442242115,e8cc8f611a58a4926632edfcd3cb7d95925b6895791632ea1c1739c4f454c8fa
|
|
||||||
splash/img/light-3x.png,1779442242118,a1a4d566718037d913ad3287e9b7d1e6d0df8569c285ce3d3680db82b6a96812
|
|
||||||
splash/img/dark-3x.png,1779442242115,a1a4d566718037d913ad3287e9b7d1e6d0df8569c285ce3d3680db82b6a96812
|
|
||||||
splash/img/light-4x.png,1779442242118,09ff8858378bb70d5f4b0381eb98dc9a889e541aeb2dd7576da7d62f205de578
|
|
||||||
assets/images/logo_klimatologi.png,1777103040742,e042ff556e356926fcd5ff92555519a569a71316ab2f7074f86f4ea4a215f325
|
assets/images/logo_klimatologi.png,1777103040742,e042ff556e356926fcd5ff92555519a569a71316ab2f7074f86f4ea4a215f325
|
||||||
splash/img/dark-4x.png,1779442242116,09ff8858378bb70d5f4b0381eb98dc9a889e541aeb2dd7576da7d62f205de578
|
assets/images/google-icon-logo.png,1776157890990,333cfafcd5c87738a4098359e18e02ff5848b2b1b819ec8aff29424c3f82d32b
|
||||||
assets/NOTICES,1779493407816,62963000bb4f8b466d5b97db77a0f9563f047723e134974be6bf170da0f821b2
|
assets/images/atmosfer.png,1776157890990,c3a9ddfa5676b5f0e1cf833f73c0f09c1dfb9d2e202906c1afcdd7a50dcf2506
|
||||||
main.dart.js,1779493365556,91f95baa75b37e85885a3fc9b0fc953ed2245277abde8ca4682b0707131a2056
|
version.json,1779597551680,f7f931727903f67c4b2ec2c38d4c5c4e2ec1be0c03071b8bff0c27f5be3b9e6e
|
||||||
|
index.html,1779597409382,3ffbcfc0c9d82b851ce84d2b1bfc85cea0a34b077bdad955e7cf52643a3cf434
|
||||||
|
flutter_service_worker.js,1779597560727,6a808567675f0224b1af9ad8047f11ef5a7d664aa42a4805536cda3a2f3ef4d4
|
||||||
|
assets/FontManifest.json,1779597552223,e38b95988f5d060cf9b7ce97cb5ac9236d6f4cc04a11d69567df97b2b4cbc5e5
|
||||||
|
assets/AssetManifest.bin.json,1779597552223,e23e10111498cc3b8b40e6549dcde13cffa6f45dc78e88194f4a7e284bb68294
|
||||||
|
flutter_bootstrap.js,1779597409344,5477d2c4d175fd91e3398d585c6f47786ab282fa386db0d7a1962e6111c4db7f
|
||||||
|
assets/AssetManifest.bin,1779597552222,fe7319a65158e186661b7edfcc1c2b6c0a6bc6823b923a13e1e932cd66407fa2
|
||||||
|
assets/shaders/stretch_effect.frag,1779597552364,586ff23669838dd33070077916f0b971a8800f67093ae8d6eed47e6cea50926f
|
||||||
|
assets/shaders/ink_sparkle.frag,1779597552364,591c7517d5cb43eb91ea451e0d3f9f585cbf8298cf6c46a9144b77cb0775a406
|
||||||
|
assets/packages/cupertino_icons/assets/CupertinoIcons.ttf,1779597553861,85140ea453cd3e02bd93650fe8add6a724ae8c0ac73d0c491085b301e7bd21d2
|
||||||
|
assets/fonts/MaterialIcons-Regular.otf,1779597553863,1c7547588fe9c202b730590aab269e1bae9988240caeba41da28091251a87dbe
|
||||||
|
assets/NOTICES,1779597552226,62963000bb4f8b466d5b97db77a0f9563f047723e134974be6bf170da0f821b2
|
||||||
|
main.dart.js,1779597496677,fce3d453f3b298a9672bb06cd23598463329fddd17aff0a00e85491492561209
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import '../../../blocs/notification_bloc/notification_bloc.dart';
|
||||||
import '../../monitoring/wind_speed/blocs/wind_speed_bloc.dart';
|
import '../../monitoring/wind_speed/blocs/wind_speed_bloc.dart';
|
||||||
import '../../monitoring/evaporasi/blocs/evaporasi_bloc.dart';
|
import '../../monitoring/evaporasi/blocs/evaporasi_bloc.dart';
|
||||||
import '../../monitoring/atmospheric_conditions/blocs/atmospheric_conditions_bloc.dart';
|
import '../../monitoring/atmospheric_conditions/blocs/atmospheric_conditions_bloc.dart';
|
||||||
|
import '../../auth/views/welcome_screen.dart';
|
||||||
import '../widgets/notification_panel.dart';
|
import '../widgets/notification_panel.dart';
|
||||||
import '../widgets/sensor_grid.dart';
|
import '../widgets/sensor_grid.dart';
|
||||||
import '../widgets/dashboard_charts.dart';
|
import '../widgets/dashboard_charts.dart';
|
||||||
|
|
@ -76,104 +77,115 @@ class _HomeScreenState extends State<HomeScreen>
|
||||||
)..add(WatchAtmosphericConditionsStarted()),
|
)..add(WatchAtmosphericConditionsStarted()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: GestureDetector(
|
child: BlocListener<AuthenticationBloc, AuthenticationState>(
|
||||||
onTap: () {
|
listener: (context, state) {
|
||||||
if (_showNotifications) _toggleNotifications();
|
if (state.status == AuthenticationStatus.unauthenticated) {
|
||||||
|
Navigator.pushAndRemoveUntil(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (_) => const WelcomeScreen()),
|
||||||
|
(route) => false,
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: Scaffold(
|
child: GestureDetector(
|
||||||
drawer: const MainDrawer(),
|
onTap: () {
|
||||||
appBar: AppBar(
|
if (_showNotifications) _toggleNotifications();
|
||||||
backgroundColor: Colors.white,
|
},
|
||||||
elevation: 0.5,
|
child: Scaffold(
|
||||||
centerTitle: false,
|
drawer: const MainDrawer(),
|
||||||
leading: Builder(
|
appBar: AppBar(
|
||||||
builder: (context) => IconButton(
|
backgroundColor: Colors.white,
|
||||||
icon: const Icon(Icons.menu, color: Colors.black),
|
elevation: 0.5,
|
||||||
onPressed: () => Scaffold.of(context).openDrawer(),
|
centerTitle: false,
|
||||||
|
leading: Builder(
|
||||||
|
builder: (context) => IconButton(
|
||||||
|
icon: const Icon(Icons.menu, color: Colors.black),
|
||||||
|
onPressed: () => Scaffold.of(context).openDrawer(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
title: Image.asset(
|
||||||
title: Image.asset(
|
'images/logo_klimatologi.png',
|
||||||
'images/logo_klimatologi.png',
|
height: 90,
|
||||||
height: 90,
|
fit: BoxFit.contain,
|
||||||
fit: BoxFit.contain,
|
),
|
||||||
),
|
actions: [
|
||||||
actions: [
|
// Icon lonceng dengan badge
|
||||||
// Icon lonceng dengan badge
|
BlocBuilder<NotificationBloc, NotificationState>(
|
||||||
BlocBuilder<NotificationBloc, NotificationState>(
|
buildWhen: (prev, cur) =>
|
||||||
buildWhen: (prev, cur) =>
|
prev.unreadCount != cur.unreadCount ||
|
||||||
prev.unreadCount != cur.unreadCount ||
|
prev.hasActiveAlerts != cur.hasActiveAlerts,
|
||||||
prev.hasActiveAlerts != cur.hasActiveAlerts,
|
builder: (context, state) {
|
||||||
builder: (context, state) {
|
return Stack(
|
||||||
return Stack(
|
children: [
|
||||||
children: [
|
IconButton(
|
||||||
IconButton(
|
icon: Icon(
|
||||||
icon: Icon(
|
_showNotifications
|
||||||
_showNotifications
|
? Icons.notifications
|
||||||
? Icons.notifications
|
: Icons.notifications_none,
|
||||||
: Icons.notifications_none,
|
color: Colors.black,
|
||||||
color: Colors.black,
|
),
|
||||||
|
onPressed: _toggleNotifications,
|
||||||
),
|
),
|
||||||
onPressed: _toggleNotifications,
|
if (state.unreadCount > 0)
|
||||||
),
|
Positioned(
|
||||||
if (state.unreadCount > 0)
|
right: 6,
|
||||||
Positioned(
|
top: 6,
|
||||||
right: 6,
|
child: Container(
|
||||||
top: 6,
|
padding: const EdgeInsets.all(3),
|
||||||
child: Container(
|
decoration: const BoxDecoration(
|
||||||
padding: const EdgeInsets.all(3),
|
color: Colors.red,
|
||||||
decoration: const BoxDecoration(
|
shape: BoxShape.circle,
|
||||||
color: Colors.red,
|
),
|
||||||
shape: BoxShape.circle,
|
constraints: const BoxConstraints(
|
||||||
),
|
minWidth: 16,
|
||||||
constraints: const BoxConstraints(
|
minHeight: 16,
|
||||||
minWidth: 16,
|
),
|
||||||
minHeight: 16,
|
child: Text(
|
||||||
),
|
state.unreadCount > 9
|
||||||
child: Text(
|
? '9+'
|
||||||
state.unreadCount > 9
|
: '${state.unreadCount}',
|
||||||
? '9+'
|
style: const TextStyle(
|
||||||
: '${state.unreadCount}',
|
color: Colors.white,
|
||||||
style: const TextStyle(
|
fontSize: 9,
|
||||||
color: Colors.white,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 9,
|
),
|
||||||
fontWeight: FontWeight.bold,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
),
|
IconButton(
|
||||||
IconButton(
|
icon: const Icon(Icons.logout, color: Colors.black),
|
||||||
icon: const Icon(Icons.logout, color: Colors.black),
|
onPressed: () => context
|
||||||
onPressed: () => context
|
.read<AuthenticationBloc>()
|
||||||
.read<AuthenticationBloc>()
|
.add(AuthenticationLogoutRequested()),
|
||||||
.add(AuthenticationLogoutRequested()),
|
),
|
||||||
),
|
const SizedBox(width: 8),
|
||||||
const SizedBox(width: 8),
|
],
|
||||||
],
|
),
|
||||||
),
|
body: Stack(
|
||||||
body: Stack(
|
children: [
|
||||||
children: [
|
// Konten utama
|
||||||
// Konten utama
|
const _HomeBody(),
|
||||||
const _HomeBody(),
|
// Dropdown notification panel
|
||||||
// Dropdown notification panel
|
if (_showNotifications)
|
||||||
if (_showNotifications)
|
Positioned(
|
||||||
Positioned(
|
top: 0,
|
||||||
top: 0,
|
left: 0,
|
||||||
left: 0,
|
right: 0,
|
||||||
right: 0,
|
child: FadeTransition(
|
||||||
child: FadeTransition(
|
opacity: _fadeAnim,
|
||||||
opacity: _fadeAnim,
|
child: GestureDetector(
|
||||||
child: GestureDetector(
|
onTap: () {}, // cegah tap di panel menutup panel
|
||||||
onTap: () {}, // cegah tap di panel menutup panel
|
child: const NotificationPanel(),
|
||||||
child: const NotificationPanel(),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -474,13 +474,6 @@ class _EvaporasiScreenState extends State<EvaporasiScreen> {
|
||||||
Icons.water,
|
Icons.water,
|
||||||
Colors.blue,
|
Colors.blue,
|
||||||
),
|
),
|
||||||
_miniCard(
|
|
||||||
cardWidth,
|
|
||||||
'Acuan Air Pagi',
|
|
||||||
'${(state.currentData?.acuanPagi ?? 0.0).toStringAsFixed(1)} cm',
|
|
||||||
Icons.wb_sunny_outlined,
|
|
||||||
Colors.amber.shade700,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -42,24 +42,22 @@ class Evaporasi {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Evaporasi (mm) ───────────────────────────────────
|
// ── Evaporasi (mm) ───────────────────────────────────
|
||||||
// Dibalik: Mengambil dari field tinggi_air karena ditukar
|
|
||||||
final evaporasiRaw = toDoubleSafe(
|
final evaporasiRaw = toDoubleSafe(
|
||||||
json['tinggi_air_cm'] ??
|
json['evaporasi_mm'] ??
|
||||||
json['tinggi_air'] ??
|
json['evaporasi'] ??
|
||||||
json['tinggiAir'] ??
|
json['evaporasiMm'] ??
|
||||||
json['tinggiAir_cm'] ??
|
json['evaporation_mm'] ??
|
||||||
json['water_level'] ??
|
json['evap_mm'] ??
|
||||||
json['waterLevel'] ??
|
json['evaporasi_value'] ??
|
||||||
json['tinggi_air_m'] ??
|
json['evaporasi_k'],
|
||||||
json['tinggiAir_m'],
|
|
||||||
);
|
);
|
||||||
// Konversi cm ke mm dengan mengalikan 10
|
// Sudah dalam mm, tidak perlu konversi
|
||||||
final evaporasiVal = evaporasiRaw * 10.0;
|
final evaporasiVal = evaporasiRaw;
|
||||||
|
|
||||||
// ── Suhu (°C) ────────────────────────────────────────
|
// ── Suhu (°C) ────────────────────────────────────────
|
||||||
// FIX: tambah 'suhu_air_c' sesuai field yang dikirim ESP32
|
// FIX: tambah 'suhu_air_c' sesuai field yang dikirim ESP32
|
||||||
final suhuRaw = toDoubleSafe(
|
final suhuRaw = toDoubleSafe(
|
||||||
json['suhu_air_c'] ?? // ← ESP32 kirim field ini
|
json['suhu_air_c'] ?? // ← ESP32 kirim field ini
|
||||||
json['suhu_air'] ??
|
json['suhu_air'] ??
|
||||||
json['suhu'] ??
|
json['suhu'] ??
|
||||||
json['suhuAir'] ??
|
json['suhuAir'] ??
|
||||||
|
|
@ -69,29 +67,27 @@ class Evaporasi {
|
||||||
final suhuVal = (suhuRaw < -50 || suhuRaw > 100) ? -1.0 : suhuRaw;
|
final suhuVal = (suhuRaw < -50 || suhuRaw > 100) ? -1.0 : suhuRaw;
|
||||||
|
|
||||||
// ── Tinggi Air (cm) ──────────────────────────────────
|
// ── Tinggi Air (cm) ──────────────────────────────────
|
||||||
// Dibalik: Mengambil dari field evaporasi karena ditukar
|
|
||||||
final tinggiRaw = toDoubleSafe(
|
final tinggiRaw = toDoubleSafe(
|
||||||
json['evaporasi_mm'] ??
|
json['tinggi_air_cm'] ??
|
||||||
json['evaporasi'] ??
|
json['tinggi_air'] ??
|
||||||
json['evaporasiMm'] ??
|
json['tinggiAir'] ??
|
||||||
json['evaporation_mm'] ??
|
json['tinggiAir_cm'] ??
|
||||||
json['evap_mm'] ??
|
json['water_level'] ??
|
||||||
json['evaporasi_value'] ??
|
json['waterLevel'] ??
|
||||||
json['evaporasi_k'],
|
json['tinggi_air_m'] ??
|
||||||
|
json['tinggiAir_m'],
|
||||||
);
|
);
|
||||||
// Konversi mm ke cm dengan membagi 10 (misal 241.78 mm -> 24.18 cm)
|
// Sudah dalam cm, tidak perlu konversi
|
||||||
final tinggiVal = tinggiRaw / 10.0;
|
final tinggiVal = tinggiRaw;
|
||||||
|
|
||||||
// ── Sanity check ─────────────────────────────────────
|
// ── Sanity check ─────────────────────────────────────
|
||||||
final evaporasiFiltered =
|
final evaporasiFiltered = (evaporasiVal < 0 || evaporasiVal > 50)
|
||||||
(evaporasiVal < 0 || evaporasiVal > 50) ? 0.0 : evaporasiVal;
|
? 0.0
|
||||||
final tinggiFiltered =
|
: evaporasiVal;
|
||||||
(tinggiVal < 0 || tinggiVal > 100) ? 0.0 : tinggiVal;
|
final tinggiFiltered = (tinggiVal < 0 || tinggiVal > 100) ? 0.0 : tinggiVal;
|
||||||
|
|
||||||
// ── Acuan Pagi (cm) ──────────────────────────────────
|
// ── Acuan Pagi (cm) ──────────────────────────────────
|
||||||
final acuanPagiVal = toDoubleSafe(
|
final acuanPagiVal = toDoubleSafe(json['acuan_pagi_cm'] ?? 0.0);
|
||||||
json['acuan_pagi_cm'] ?? json['acuan_pagi'] ?? 0.0,
|
|
||||||
);
|
|
||||||
|
|
||||||
// ── Status ───────────────────────────────────────────
|
// ── Status ───────────────────────────────────────────
|
||||||
final statusVal = json['status']?.toString() ?? "Normal";
|
final statusVal = json['status']?.toString() ?? "Normal";
|
||||||
|
|
@ -103,8 +99,9 @@ class Evaporasi {
|
||||||
try {
|
try {
|
||||||
if (rawTimestamp is int) {
|
if (rawTimestamp is int) {
|
||||||
if (rawTimestamp < 1000000000000) {
|
if (rawTimestamp < 1000000000000) {
|
||||||
return DateTime.fromMillisecondsSinceEpoch(rawTimestamp * 1000)
|
return DateTime.fromMillisecondsSinceEpoch(
|
||||||
.toLocal();
|
rawTimestamp * 1000,
|
||||||
|
).toLocal();
|
||||||
}
|
}
|
||||||
return DateTime.fromMillisecondsSinceEpoch(rawTimestamp).toLocal();
|
return DateTime.fromMillisecondsSinceEpoch(rawTimestamp).toLocal();
|
||||||
}
|
}
|
||||||
|
|
@ -124,8 +121,9 @@ class Evaporasi {
|
||||||
final unixValue = int.tryParse(s);
|
final unixValue = int.tryParse(s);
|
||||||
if (unixValue != null) {
|
if (unixValue != null) {
|
||||||
if (unixValue < 1000000000000) {
|
if (unixValue < 1000000000000) {
|
||||||
return DateTime.fromMillisecondsSinceEpoch(unixValue * 1000)
|
return DateTime.fromMillisecondsSinceEpoch(
|
||||||
.toLocal();
|
unixValue * 1000,
|
||||||
|
).toLocal();
|
||||||
}
|
}
|
||||||
return DateTime.fromMillisecondsSinceEpoch(unixValue).toLocal();
|
return DateTime.fromMillisecondsSinceEpoch(unixValue).toLocal();
|
||||||
}
|
}
|
||||||
|
|
@ -151,8 +149,7 @@ class Evaporasi {
|
||||||
|
|
||||||
DateTime timestamp = DateTime.fromMillisecondsSinceEpoch(0);
|
DateTime timestamp = DateTime.fromMillisecondsSinceEpoch(0);
|
||||||
|
|
||||||
final rawTimestamp =
|
final rawTimestamp = json['timestamp'] ?? json['time'] ?? json['datetime'];
|
||||||
json['timestamp'] ?? json['time'] ?? json['datetime'];
|
|
||||||
|
|
||||||
if (rawTimestamp != null) {
|
if (rawTimestamp != null) {
|
||||||
timestamp = parseTimestamp(rawTimestamp);
|
timestamp = parseTimestamp(rawTimestamp);
|
||||||
|
|
@ -164,11 +161,9 @@ class Evaporasi {
|
||||||
if (parts.length >= 2) {
|
if (parts.length >= 2) {
|
||||||
final jam = int.tryParse(parts[0]) ?? 0;
|
final jam = int.tryParse(parts[0]) ?? 0;
|
||||||
final menit = int.tryParse(parts[1]) ?? 0;
|
final menit = int.tryParse(parts[1]) ?? 0;
|
||||||
final detik =
|
final detik = parts.length >= 3 ? (int.tryParse(parts[2]) ?? 0) : 0;
|
||||||
parts.length >= 3 ? (int.tryParse(parts[2]) ?? 0) : 0;
|
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
timestamp =
|
timestamp = DateTime(now.year, now.month, now.day, jam, menit, detik);
|
||||||
DateTime(now.year, now.month, now.day, jam, menit, detik);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -182,4 +177,4 @@ class Evaporasi {
|
||||||
timestamp: timestamp,
|
timestamp: timestamp,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue