rechange display dashbord with other function
This commit is contained in:
parent
b6297f1b50
commit
08e5986328
|
@ -5,8 +5,8 @@
|
|||
#include <DHT.h>
|
||||
|
||||
// Konfigurasi WiFi
|
||||
#define WIFI_SSID "KONTRAKAN OYI"
|
||||
#define WIFI_PASSWORD "warkopoyi"
|
||||
#define WIFI_SSID "smartcab"
|
||||
#define WIFI_PASSWORD "123123123"
|
||||
|
||||
// Konfigurasi Firebase
|
||||
#define FIREBASE_HOST "smartcab-8bb42-default-rtdb.firebaseio.com"
|
||||
|
@ -64,7 +64,7 @@ void setup() {
|
|||
Firebase.begin(&firebaseConfig, &firebaseAuth);
|
||||
Firebase.reconnectWiFi(true);
|
||||
|
||||
// Tambahkan status device online setelah koneksi berhasil
|
||||
// Update status device saat startup
|
||||
Firebase.setString(firebaseData, "/logs/systemESP", "Device online");
|
||||
|
||||
// Inisialisasi sensor
|
||||
|
@ -105,18 +105,27 @@ void setup() {
|
|||
}
|
||||
|
||||
void loop() {
|
||||
// Tambahkan heartbeat check di awal loop
|
||||
// Update lastActive dengan unix timestamp
|
||||
if (millis() - lastHeartbeatTime >= heartbeatInterval) {
|
||||
lastHeartbeatTime = millis();
|
||||
// Kirim timestamp dalam format epoch (unix timestamp)
|
||||
unsigned long epochTime = time(nullptr);
|
||||
if (Firebase.setInt(firebaseData, "/device/lastActive", epochTime)) {
|
||||
Serial.println("Heartbeat sent: " + String(epochTime));
|
||||
// Tambahkan update status Device online saat heartbeat berhasil
|
||||
Firebase.setString(firebaseData, "/logs/systemESP", "Device online");
|
||||
Serial.println("Device status updated: Online");
|
||||
} else {
|
||||
Serial.println("Failed to send heartbeat");
|
||||
// Jika gagal mengirim heartbeat, set status offline
|
||||
Firebase.setString(firebaseData, "/logs/systemESP", "Device offline");
|
||||
}
|
||||
}
|
||||
|
||||
// Cek jika tidak ada perubahan dalam 70 detik
|
||||
if (millis() - lastHeartbeatTime > 70000) {
|
||||
Firebase.setString(firebaseData, "/logs/systemESP", "Device offline");
|
||||
}
|
||||
|
||||
// Tambahkan pengecekan status restart di awal loop
|
||||
if (Firebase.getString(firebaseData, "/control/restartESP")) {
|
||||
String restartStatus = firebaseData.stringData();
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
#include <ESP8266WiFi.h>
|
||||
#include <FirebaseESP8266.h>
|
||||
#include <SPI.h>
|
||||
#include <MFRC522.h>
|
||||
#include <Servo.h>
|
||||
#include <time.h>
|
||||
|
||||
// WiFi Credentials
|
||||
#define WIFI_SSID "smartcab"
|
||||
#define WIFI_PASSWORD "123123123"
|
||||
|
||||
// Firebase Configuration
|
||||
#define FIREBASE_HOST "smartcab-8bb42-default-rtdb.firebaseio.com"
|
||||
#define FIREBASE_AUTH "kiiQoFa6Ckp7bL2oRLbaTSGQth9z0PgN64Ybv8dw"
|
||||
|
||||
FirebaseConfig config;
|
||||
FirebaseAuth auth;
|
||||
FirebaseData firebaseData;
|
||||
|
||||
// RFID Configuration
|
||||
#define SS_PIN D4 // Pin SDA RFID
|
||||
#define RST_PIN D3 // Pin RST RFID
|
||||
MFRC522 mfrc522(SS_PIN, RST_PIN);
|
||||
|
||||
// Servo Configuration
|
||||
Servo myServo;
|
||||
#define SERVO_PIN D2 // Pin servo
|
||||
|
||||
// **ID kartu yang diizinkan**
|
||||
String kartuTerdaftar[] = {"53ed8434", "3b4f7d9e", "5b85e19d", "cb31e19f", "5b58179f", "1b22e9f"};
|
||||
bool servoTerbuka = false; // Status awal servo (tertutup)
|
||||
|
||||
// Tambahkan variabel global untuk last active
|
||||
unsigned long previousMillis = 0;
|
||||
const long interval = 60000; // interval 1 menit dalam milliseconds
|
||||
|
||||
// Tambahkan di bagian global variables
|
||||
unsigned long lastHeartbeatTime = 0;
|
||||
const long heartbeatInterval = 60000; // 1 menit dalam milliseconds
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
// Koneksi ke WiFi
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||
Serial.print("Menghubungkan ke WiFi");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(500);
|
||||
}
|
||||
Serial.println("\nWiFi Terhubung!");
|
||||
|
||||
// Konfigurasi Firebase
|
||||
config.host = FIREBASE_HOST;
|
||||
config.signer.tokens.legacy_token = FIREBASE_AUTH;
|
||||
Firebase.begin(&config, &auth);
|
||||
Firebase.reconnectWiFi(true);
|
||||
|
||||
// Inisialisasi RFID
|
||||
SPI.begin();
|
||||
mfrc522.PCD_Init();
|
||||
|
||||
// Cek koneksi RFID dengan cara yang lebih aman
|
||||
byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
|
||||
if (v == 0x00 || v == 0xFF) {
|
||||
Firebase.setString(firebaseData, "/logs/RFID/status", "Disconnected");
|
||||
Serial.println("RFID Connection Failed!");
|
||||
} else {
|
||||
Firebase.setString(firebaseData, "/logs/RFID/status", "Connected");
|
||||
Serial.println("RFID Connected!");
|
||||
}
|
||||
|
||||
// Inisialisasi Servo
|
||||
myServo.attach(SERVO_PIN, 500, 2500);
|
||||
if (myServo.attached()) {
|
||||
Firebase.setString(firebaseData, "/logs/servo/status", "Connected");
|
||||
Serial.println("Servo Connected!");
|
||||
} else {
|
||||
Firebase.setString(firebaseData, "/logs/servo/status", "Disconnected");
|
||||
Serial.println("Servo Connection Failed!");
|
||||
}
|
||||
myServo.write(0);
|
||||
|
||||
// Update path untuk restart control
|
||||
Firebase.setBool(firebaseData, "/control/restartWemos", false);
|
||||
|
||||
// Konfigurasi NTP
|
||||
configTime(7 * 3600, 0, "pool.ntp.org"); // GMT+7
|
||||
|
||||
// Kirim timestamp pertama kali
|
||||
unsigned long epochTime = time(nullptr);
|
||||
Firebase.setInt(firebaseData, "/device/lastActiveWemos", epochTime);
|
||||
|
||||
// Update status device saat startup
|
||||
Firebase.setString(firebaseData, "/logs/systemWemos", "Device Online");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Update path untuk pengecekan restart
|
||||
if (Firebase.getBool(firebaseData, "/control/restartWemos")) {
|
||||
if (firebaseData.boolData() == true) {
|
||||
// Update status sebelum restart
|
||||
Firebase.setString(firebaseData, "/logs/systemWemos", "Device auto-restarting...");
|
||||
Firebase.setBool(firebaseData, "/control/restartWemos", false);
|
||||
delay(1000);
|
||||
ESP.restart();
|
||||
}
|
||||
}
|
||||
|
||||
// Cek status RFID secara periodik dengan cara yang lebih aman
|
||||
byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
|
||||
if (v == 0x00 || v == 0xFF) {
|
||||
if (Firebase.getString(firebaseData, "/logs/RFID/status") &&
|
||||
firebaseData.stringData() != "Disconnected") {
|
||||
Firebase.setString(firebaseData, "/logs/RFID/status", "Disconnected");
|
||||
Serial.println("RFID Disconnected!");
|
||||
}
|
||||
} else {
|
||||
if (Firebase.getString(firebaseData, "/logs/RFID/status") &&
|
||||
firebaseData.stringData() != "Connected") {
|
||||
Firebase.setString(firebaseData, "/logs/RFID/status", "Connected");
|
||||
Serial.println("RFID Connected!");
|
||||
}
|
||||
}
|
||||
|
||||
// Cek status Servo
|
||||
if (!myServo.attached()) {
|
||||
Firebase.setString(firebaseData, "/logs/servo/status", "Disconnected");
|
||||
Serial.println("Servo Disconnected!");
|
||||
}
|
||||
|
||||
// Update lastActive dengan unix timestamp
|
||||
if (millis() - lastHeartbeatTime >= heartbeatInterval) {
|
||||
lastHeartbeatTime = millis();
|
||||
unsigned long epochTime = time(nullptr);
|
||||
if (Firebase.setInt(firebaseData, "/device/lastActiveWemos", epochTime)) {
|
||||
Serial.println("Heartbeat sent: " + String(epochTime));
|
||||
// Tambahkan update status Device Online saat heartbeat berhasil
|
||||
Firebase.setString(firebaseData, "/logs/systemWemos", "Device Online");
|
||||
Serial.println("Device status updated: Online");
|
||||
} else {
|
||||
Serial.println("Failed to send heartbeat");
|
||||
// Jika gagal mengirim heartbeat, set status offline
|
||||
Firebase.setString(firebaseData, "/logs/systemWemos", "Device Offline");
|
||||
}
|
||||
}
|
||||
|
||||
// Cek jika tidak ada perubahan dalam 70 detik
|
||||
if (millis() - lastHeartbeatTime > 70000) {
|
||||
Firebase.setString(firebaseData, "/logs/systemWemos", "Device Offline");
|
||||
}
|
||||
|
||||
// Cek apakah kartu RFID terdeteksi
|
||||
if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
|
||||
Serial.println("Kartu Terdeteksi!");
|
||||
|
||||
// Membaca UID kartu
|
||||
String rfidUID = "";
|
||||
for (byte i = 0; i < mfrc522.uid.size; i++) {
|
||||
rfidUID += String(mfrc522.uid.uidByte[i], HEX);
|
||||
}
|
||||
|
||||
Serial.print("UID: ");
|
||||
Serial.println(rfidUID);
|
||||
|
||||
// **Cek apakah kartu terdaftar**
|
||||
bool isCardRegistered = false;
|
||||
for (int i = 0; i < sizeof(kartuTerdaftar)/sizeof(kartuTerdaftar[0]); i++) {
|
||||
if (rfidUID == kartuTerdaftar[i]) {
|
||||
isCardRegistered = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isCardRegistered) {
|
||||
Serial.println("Kartu Terdaftar!");
|
||||
|
||||
if (!servoTerbuka) {
|
||||
Serial.println("Membuka kunci...");
|
||||
myServo.write(180);
|
||||
servoTerbuka = true;
|
||||
Firebase.setString(firebaseData, "/smartcab/servo_status", "Terbuka");
|
||||
} else {
|
||||
Serial.println("Mengunci kunci...");
|
||||
myServo.write(0);
|
||||
servoTerbuka = false;
|
||||
Firebase.setString(firebaseData, "/smartcab/servo_status", "Terkunci");
|
||||
}
|
||||
|
||||
// Kirim status ke Firebase
|
||||
Firebase.setString(firebaseData, "/smartcab/last_access", "Terdaftar");
|
||||
Firebase.setString(firebaseData, "/smartcab/status_device", rfidUID);
|
||||
}
|
||||
else {
|
||||
Serial.println("Kartu Tidak Terdaftar! Mengunci servo...");
|
||||
|
||||
// Paksa servo terkunci jika kartu tidak dikenal
|
||||
myServo.write(0);
|
||||
servoTerbuka = false;
|
||||
Firebase.setString(firebaseData, "/smartcab/servo_status", "Terkunci");
|
||||
Firebase.setString(firebaseData, "/smartcab/last_access", "Tidak Terdaftar");
|
||||
Firebase.setString(firebaseData, "/smartcab/status_device", rfidUID);
|
||||
}
|
||||
|
||||
mfrc522.PICC_HaltA(); // Hentikan komunikasi RFID
|
||||
mfrc522.PCD_StopCrypto1();
|
||||
}
|
||||
|
||||
delay(500);
|
||||
}
|
|
@ -20,15 +20,37 @@ public function index()
|
|||
$dht11 = $this->database->getReference('dht11')->getValue() ?? [];
|
||||
$security = $this->database->getReference('security')->getValue() ?? [];
|
||||
$smartcab = $this->database->getReference('smartcab')->getValue() ?? [];
|
||||
$logs = $this->database->getReference('logs')->getValue() ?? [];
|
||||
$device = $this->database->getReference('device')->getValue() ?? [];
|
||||
$control = $this->database->getReference('control')->getValue() ?? [];
|
||||
|
||||
// Ambil nilai spesifik
|
||||
$humidity = $dht11['humidity'] ?? 'N/A';
|
||||
$temperature = $dht11['temperature'] ?? 'N/A';
|
||||
$motion = $security['motion'] ?? 'N/A';
|
||||
$status = $security['status'] ?? 'N/A';
|
||||
$fan = $security['fan'] ?? 'N/A';
|
||||
$last_access = $smartcab['last_access'] ?? 'N/A';
|
||||
$status_device = $smartcab['status_device'] ?? 'N/A';
|
||||
$servo_status = $smartcab['servo_status'] ?? 'N/A';
|
||||
|
||||
// Status perangkat
|
||||
$lastActiveESP = $device['lastActive'] ?? 'N/A';
|
||||
$lastActiveWemos = $device['lastActiveWemos'] ?? 'N/A';
|
||||
|
||||
// Status logs
|
||||
$dhtStatus = $logs['dht']['status'] ?? 'N/A';
|
||||
$dhtMessage = $logs['dht']['message'] ?? 'N/A';
|
||||
$mpuStatus = $logs['mpu']['status'] ?? 'N/A';
|
||||
$mpuMessage = $logs['mpu']['message'] ?? 'N/A';
|
||||
$rfidStatus = $logs['RFID']['status'] ?? 'N/A';
|
||||
$servoStatus = $logs['servo']['status'] ?? 'N/A';
|
||||
$systemESP = $logs['systemESP'] ?? 'N/A';
|
||||
$systemWemos = $logs['systemWemos'] ?? 'N/A';
|
||||
|
||||
// Control
|
||||
$restartESP = $control['restartESP'] ?? false;
|
||||
$restartWemos = $control['restartWemos'] ?? false;
|
||||
|
||||
// Kirim data ke tampilan
|
||||
return view('welcome', compact(
|
||||
|
@ -36,9 +58,22 @@ public function index()
|
|||
'temperature',
|
||||
'motion',
|
||||
'status',
|
||||
'fan',
|
||||
'last_access',
|
||||
'status_device',
|
||||
'servo_status'
|
||||
'servo_status',
|
||||
'lastActiveESP',
|
||||
'lastActiveWemos',
|
||||
'dhtStatus',
|
||||
'dhtMessage',
|
||||
'mpuStatus',
|
||||
'mpuMessage',
|
||||
'rfidStatus',
|
||||
'servoStatus',
|
||||
'systemESP',
|
||||
'systemWemos',
|
||||
'restartESP',
|
||||
'restartWemos'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Kreait\Firebase\Factory;
|
||||
use Kreait\Firebase\Auth as FirebaseAuth;
|
||||
use Kreait\Firebase\Contract\Database;
|
||||
|
||||
class FirebaseServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register()
|
||||
{
|
||||
$this->app->singleton(FirebaseAuth::class, function ($app) {
|
||||
$factory = (new Factory)
|
||||
->withServiceAccount(json_decode(env('FIREBASE_CREDENTIALS'), true))
|
||||
->withDatabaseUri(env('FIREBASE_DATABASE_URL'));
|
||||
|
||||
return $factory->createAuth();
|
||||
});
|
||||
|
||||
$this->app->singleton(Database::class, function ($app) {
|
||||
$factory = (new Factory)
|
||||
->withServiceAccount(config('firebase.credentials'))
|
||||
->withDatabaseUri(config('firebase.database_url'));
|
||||
|
||||
return $factory->createDatabase();
|
||||
});
|
||||
}
|
||||
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
koneksi web
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Kreait\Firebase\Factory;
|
||||
use Kreait\Firebase\Auth as FirebaseAuth;
|
||||
use Kreait\Firebase\Contract\Database;
|
||||
|
||||
class FirebaseServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register()
|
||||
{
|
||||
$this->app->singleton(FirebaseAuth::class, function ($app) {
|
||||
$factory = (new Factory)
|
||||
->withServiceAccount(config('firebase.credentials'))
|
||||
->withDatabaseUri(config('firebase.database_url'));
|
||||
|
||||
return $factory->createAuth();
|
||||
});
|
||||
|
||||
$this->app->singleton(Database::class, function ($app) {
|
||||
$factory = (new Factory)
|
||||
->withServiceAccount(config('firebase.credentials'))
|
||||
->withDatabaseUri(config('firebase.database_url'));
|
||||
|
||||
return $factory->createDatabase();
|
||||
});
|
||||
}
|
||||
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 152 KiB |
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
Binary file not shown.
After Width: | Height: | Size: 208 KiB |
Binary file not shown.
After Width: | Height: | Size: 103 KiB |
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
|
@ -0,0 +1,38 @@
|
|||
/* Toast animations */
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideOut {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.toast-enter {
|
||||
animation: slideIn 0.3s ease-out;
|
||||
}
|
||||
|
||||
.toast-exit {
|
||||
animation: slideOut 0.3s ease-in;
|
||||
}
|
||||
|
||||
#toast-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#toast-container > div {
|
||||
pointer-events: auto;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
const NOTIFICATION_TYPES = {
|
||||
MOTION: 'motion',
|
||||
DOOR: 'door',
|
||||
DEVICE: 'device'
|
||||
};
|
||||
|
||||
const NOTIFICATION_COLORS = {
|
||||
[NOTIFICATION_TYPES.MOTION]: 'bg-red-500',
|
||||
[NOTIFICATION_TYPES.DOOR]: 'bg-green-500',
|
||||
[NOTIFICATION_TYPES.DEVICE]: 'bg-blue-500'
|
||||
};
|
||||
|
||||
const DEVICE_STATUSES = {
|
||||
ESP_ONLINE: 'Device online',
|
||||
WEMOS_ONLINE: 'Device Online',
|
||||
SENSOR_CONNECTED: 'connected',
|
||||
RFID_CONNECTED: 'Connected'
|
||||
};
|
|
@ -0,0 +1,108 @@
|
|||
// RFID Access Monitoring
|
||||
database.ref('smartcab').on('value', (snapshot) => {
|
||||
const smartcabData = snapshot.val();
|
||||
if (smartcabData) {
|
||||
// Door Status Change
|
||||
if (smartcabData.servo_status) {
|
||||
this.addNotification(
|
||||
'door',
|
||||
'Door Status Changed',
|
||||
`Door is now ${smartcabData.servo_status}`
|
||||
);
|
||||
}
|
||||
|
||||
// Access Attempt
|
||||
if (smartcabData.last_access) {
|
||||
const accessMessage = smartcabData.last_access === 'Terdaftar'
|
||||
? 'Authorized access granted'
|
||||
: 'Unauthorized access attempt';
|
||||
|
||||
this.addNotification(
|
||||
'door',
|
||||
'Access Event',
|
||||
`${accessMessage} (ID: ${smartcabData.status_device || 'Unknown'})`
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
initializeDeviceMonitoring() {
|
||||
// ESP8266 Status
|
||||
database.ref('logs/systemESP').on('value', (snapshot) => {
|
||||
const status = snapshot.val();
|
||||
if (status && status !== NOTIFICATION_CONSTANTS.STATUS.DEVICE.ESP_ONLINE) {
|
||||
this.addNotification(
|
||||
'device',
|
||||
'ESP8266 Status Change',
|
||||
`ESP8266: ${status}`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Device Heartbeat Monitoring
|
||||
database.ref('device/lastActive').on('value', (snapshot) => {
|
||||
const lastActive = snapshot.val();
|
||||
if (lastActive) {
|
||||
const timeDiff = Date.now() - (lastActive * 1000);
|
||||
if (timeDiff > 120000) { // 2 minutes threshold
|
||||
this.addNotification(
|
||||
'device',
|
||||
'Device Connection Warning',
|
||||
'ESP8266 device has not reported for over 2 minutes'
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// DHT11 Sensor Status
|
||||
database.ref('logs/dht').on('value', (snapshot) => {
|
||||
const dhtStatus = snapshot.val();
|
||||
if (dhtStatus && dhtStatus.status !== NOTIFICATION_CONSTANTS.STATUS.SENSOR.CONNECTED) {
|
||||
this.addNotification(
|
||||
'sensor',
|
||||
'DHT11 Sensor Issue',
|
||||
dhtStatus.message || 'Temperature sensor is not responding'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Device Restart Monitoring
|
||||
database.ref('control/restartESP').on('value', (snapshot) => {
|
||||
const restartStatus = snapshot.val();
|
||||
if (restartStatus === true) {
|
||||
this.addNotification(
|
||||
'device',
|
||||
'Device Restart',
|
||||
'ESP8266 device is restarting'
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addNotification(type, title, message) {
|
||||
const notification = {
|
||||
type,
|
||||
title,
|
||||
message,
|
||||
timestamp: Date.now(),
|
||||
color: NOTIFICATION_CONSTANTS.COLORS[type.toUpperCase()] || NOTIFICATION_CONSTANTS.COLORS.DEVICE
|
||||
};
|
||||
|
||||
this.notifications.unshift(notification);
|
||||
if (this.notifications.length > this.maxNotifications) {
|
||||
this.notifications.pop();
|
||||
}
|
||||
|
||||
this.updateNotificationPanel();
|
||||
this.updateNotificationBadge();
|
||||
|
||||
if (Notification.permission === "granted") {
|
||||
new Notification(title, {
|
||||
body: message,
|
||||
icon: '/icons/' + type + '.png' // Pastikan menyediakan icon yang sesuai
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ... (metode lain tetap sama seperti sebelumnya)
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<!-- Notification Panel -->
|
||||
<div
|
||||
x-show="isNotificationsPanelOpen"
|
||||
x-transition:enter="transform transition ease-in-out duration-300"
|
||||
x-transition:enter-start="-translate-x-full"
|
||||
x-transition:enter-end="translate-x-0"
|
||||
x-transition:leave="transform transition ease-in-out duration-300"
|
||||
x-transition:leave-start="translate-x-0"
|
||||
x-transition:leave-end="-translate-x-full"
|
||||
class="fixed inset-0 z-50"
|
||||
>
|
||||
<!-- Backdrop -->
|
||||
<div
|
||||
class="fixed inset-0 bg-black bg-opacity-50"
|
||||
@click="isNotificationsPanelOpen = false"
|
||||
></div>
|
||||
|
||||
<!-- Panel -->
|
||||
<div
|
||||
class="fixed inset-y-0 left-0 w-full max-w-xs bg-white dark:bg-gray-800 overflow-y-auto"
|
||||
>
|
||||
<div class="flex flex-col h-screen">
|
||||
<!-- Header -->
|
||||
<div class="flex items-center justify-between p-4 border-b dark:border-gray-700">
|
||||
<h2 class="text-xl font-semibold text-gray-700 dark:text-light">Notifications</h2>
|
||||
<button @click="isNotificationsPanelOpen = false" class="p-2 text-gray-600 rounded-md hover:bg-gray-100 dark:text-light dark:hover:bg-primary">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Notification Items Container -->
|
||||
<div id="notificationContainer" class="flex-1 p-4 space-y-4 overflow-y-auto">
|
||||
<!-- Notifications will be dynamically inserted here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"control": {
|
||||
"restartESP": false,
|
||||
"restartWemos": false
|
||||
},
|
||||
"device": {
|
||||
"lastActive": 1742129368,
|
||||
"lastActiveWemos": 7
|
||||
},
|
||||
"dht11": {
|
||||
"humidity": 78,
|
||||
"temperature": 27
|
||||
},
|
||||
"logs": {
|
||||
"RFID": {
|
||||
"status": "Connected"
|
||||
},
|
||||
"dht": {
|
||||
"message": "DHT11 terhubung dengan baik",
|
||||
"status": "connected"
|
||||
},
|
||||
"mpu": {
|
||||
"message": "MPU6050 terhubung dengan baik",
|
||||
"status": "connected"
|
||||
},
|
||||
"servo": {
|
||||
"status": "Connected"
|
||||
},
|
||||
"systemESP": "Device online",
|
||||
"systemWemos": "Device Online"
|
||||
},
|
||||
"security": {
|
||||
"fan": "OFF",
|
||||
"motion": "clear",
|
||||
"status": "on"
|
||||
},
|
||||
"smartcab": {
|
||||
"last_access": "Terdaftar",
|
||||
"servo_status": "Terbuka",
|
||||
"status_device": "53ed8434"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue