From c45291d36f98381c33d8824f65e2a8dffe7bcd69 Mon Sep 17 00:00:00 2001 From: Dwikyyy Date: Thu, 30 Jul 2026 12:51:08 +0700 Subject: [PATCH] Upload files to "Source Code Mobile" --- Source Code Mobile/notification_model.dart | 41 ++++++++ Source Code Mobile/sensor_model.dart | 112 +++++++++++++++++++++ Source Code Mobile/user_model.dart | 26 +++++ 3 files changed, 179 insertions(+) create mode 100644 Source Code Mobile/notification_model.dart create mode 100644 Source Code Mobile/sensor_model.dart create mode 100644 Source Code Mobile/user_model.dart diff --git a/Source Code Mobile/notification_model.dart b/Source Code Mobile/notification_model.dart new file mode 100644 index 0000000..53c68c9 --- /dev/null +++ b/Source Code Mobile/notification_model.dart @@ -0,0 +1,41 @@ +class NotificationModel { + final String title; + final String message; + final bool isRead; + final String timestamp; + + NotificationModel({ + required this.title, + required this.message, + required this.isRead, + required this.timestamp, + }); + + factory NotificationModel.fromMap(Map json) { + return NotificationModel( + title: json['title'] ?? 'Notifikasi Sistem', + message: json['message'] ?? '', + isRead: json['is_read'] ?? json['read'] ?? false, + timestamp: _parseTimestamp(json['timestamp']), + ); + } + + Map toMap() { + return { + 'title': title, + 'message': message, + 'is_read': isRead, + 'timestamp': timestamp, + }; + } +} + +String _parseTimestamp(dynamic value) { + if (value == null) return ''; + if (value is int) { + final dt = DateTime.fromMillisecondsSinceEpoch(value * 1000); + return "${dt.year}-${dt.month.toString().padLeft(2, '0')}-${dt.day.toString().padLeft(2, '0')} " + "${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}:${dt.second.toString().padLeft(2, '0')}"; + } + return value.toString(); +} diff --git a/Source Code Mobile/sensor_model.dart b/Source Code Mobile/sensor_model.dart new file mode 100644 index 0000000..db94302 --- /dev/null +++ b/Source Code Mobile/sensor_model.dart @@ -0,0 +1,112 @@ +class SensorModel { + final double temperature; + final double humidity; + final double co2; + final double pm25; + + final String temperatureStatus; + final String humidityStatus; + final String co2Status; + final String pm25Status; + + final String overallStatus; + + final bool acPower; + final String acMode; + final int acTemp; + final String acFan; + + final String timestamp; + + SensorModel({ + required this.temperature, + required this.humidity, + required this.co2, + required this.pm25, + required this.temperatureStatus, + required this.humidityStatus, + required this.co2Status, + required this.pm25Status, + required this.overallStatus, + required this.acPower, + required this.acMode, + required this.acTemp, + required this.acFan, + required this.timestamp, + }); + + factory SensorModel.fromMap(Map json) { + return SensorModel( + // Support both ESP32 field names (suhu, kelembapan) and Flutter field names + temperature: ((json['temperature'] ?? json['suhu']) ?? 0).toDouble(), + + humidity: ((json['humidity'] ?? json['kelembapan']) ?? 0).toDouble(), + + co2: ((json['co2'] ?? json['co2_ppm']) ?? 0).toDouble(), + + pm25: ((json['pm25'] ?? json['pm25_ugm3']) ?? 0).toDouble(), + + temperatureStatus: + (json['temperature_status'] ?? json['suhu_status'] ?? ''), + + humidityStatus: + (json['humidity_status'] ?? json['kelembapan_status'] ?? ''), + + co2Status: (json['co2_status'] ?? json['co2_status'] ?? ''), + + pm25Status: (json['pm25_status'] ?? json['pm25_status'] ?? ''), + + overallStatus: + (json['overall_status'] ?? json['status_keseluruhan'] ?? ''), + + acPower: json['ac_power'] ?? false, + + acMode: json['ac_mode'] ?? 'OFF', + + acTemp: json['ac_temp'] ?? 24, + + acFan: json['ac_fan'] ?? 'AUTO', + + timestamp: _parseTimestamp(json['timestamp'] ?? json['last_update']), + ); + } + + Map toMap() { + return { + 'temperature': temperature, + 'humidity': humidity, + 'co2': co2, + 'pm25': pm25, + + 'temperature_status': temperatureStatus, + + 'humidity_status': humidityStatus, + + 'co2_status': co2Status, + + 'pm25_status': pm25Status, + + 'overall_status': overallStatus, + + 'ac_power': acPower, + 'ac_mode': acMode, + 'ac_temp': acTemp, + 'ac_fan': acFan, + + 'timestamp': timestamp, + }; + } +} + +String _parseTimestamp(dynamic value) { + if (value == null) return ''; + if (value is int) { + // ESP32 mengirim unix timestamp dalam detik, konversi ke milliseconds + // Jika value > 10000000000 berarti sudah dalam milliseconds + final timestampMs = value > 10000000000 ? value : value * 1000; + final dt = DateTime.fromMillisecondsSinceEpoch(timestampMs); + return "${dt.year}-${dt.month.toString().padLeft(2, '0')}-${dt.day.toString().padLeft(2, '0')} " + "${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}:${dt.second.toString().padLeft(2, '0')}"; + } + return value.toString(); +} diff --git a/Source Code Mobile/user_model.dart b/Source Code Mobile/user_model.dart new file mode 100644 index 0000000..7a58c62 --- /dev/null +++ b/Source Code Mobile/user_model.dart @@ -0,0 +1,26 @@ +class UserModel { + final String uid; + final String name; + final String email; + final String createdAt; + + UserModel({ + required this.uid, + required this.name, + required this.email, + required this.createdAt, + }); + + factory UserModel.fromMap(Map json) { + return UserModel( + uid: json['uid'] ?? '', + name: json['name'] ?? '', + email: json['email'] ?? '', + createdAt: json['created_at'] ?? '', + ); + } + + Map toMap() { + return {'uid': uid, 'name': name, 'email': email, 'created_at': createdAt}; + } +}