added phpmyadmin and mysql database, change the html so dont flickering and load container only once

This commit is contained in:
cowrie
2026-04-15 22:50:07 +08:00
parent a2f9e06d09
commit 4530afde5f
8 changed files with 925 additions and 66 deletions

View File

@ -2,7 +2,7 @@ FROM node:20-alpine
WORKDIR /app
RUN npm init -y && npm install express
RUN npm init -y && npm install express mysql2
COPY server.js .
COPY data.json .

View File

@ -1,7 +1,7 @@
{
"CO2": 2.43,
"CO": 0.56,
"BZ": 3.11,
"CO2": 2.78,
"CO": 0.62,
"BZ": 3.7,
"AQ": 100,
"updated_at": "2026-01-30T03:48:16.033Z"
"updated_at": "2026-03-11T12:46:55.233Z"
}

98
api/server copy.js Normal file
View File

@ -0,0 +1,98 @@
const express = require("express");
const fs = require("fs");
const app = express();
const PORT = 3000;
const DATA_FILE = "./data.json";
// Helper: read data
function readData() {
return JSON.parse(fs.readFileSync(DATA_FILE, "utf8"));
}
// Helper: write data
function writeData(data) {
fs.writeFileSync(DATA_FILE, JSON.stringify(data, null, 2));
}
// ============================
// GET /api/data → read values
// ============================
app.get("/data", (req, res) => {
try {
const data = readData();
res.json(data);
} catch (err) {
res.status(500).json({ error: "Gagal membaca data" });
}
});
// ============================
// ADD SENSOR
// ============================
app.post("/addSensor", (req, res) => {
const { id } = req.body;
if (!id) {
return res.status(400).json({
error: "Sensor ID is required"
});
}
const sql = `INSERT INTO sensor_data (id) VALUES (?)`;
db.query(sql, [id], (err, result) => {
if (err) {
console.error(err);
// handle duplicate ID (optional but nice)
if (err.code === "ER_DUP_ENTRY") {
return res.status(400).json({
error: "Sensor already exists"
});
}
return res.status(500).json({ error: "DB error" });
}
res.json({
message: "Sensor added successfully",
id: id
});
});
});
// ===========================================
// GET /api/update?co2=&co=&bz=&aq=
// ===========================================
app.get("/update", (req, res) => {
const { co2, co, bz, aq } = req.query;
if (!co2 || !co || !bz || !aq) {
return res.status(400).json({
error: "Parameter wajib: co2, co, bz, aq"
});
}
const newData = {
CO2: Number(co2),
CO: Number(co),
BZ: Number(bz),
AQ: Number(aq),
updated_at: new Date().toISOString()
};
try {
writeData(newData);
res.json({
message: "Data berhasil diperbarui",
data: newData
});
} catch (err) {
res.status(500).json({ error: "Gagal menyimpan data" });
}
});
app.listen(PORT, () => {
console.log(`API berjalan di port ${PORT}`);
});

View File

@ -1,63 +1,306 @@
const express = require("express");
const fs = require("fs");
const mysql = require("mysql2");
const app = express();
const PORT = 3000;
const DATA_FILE = "./data.json";
// Helper: read data
function readData() {
return JSON.parse(fs.readFileSync(DATA_FILE, "utf8"));
}
// Helper: write data
function writeData(data) {
fs.writeFileSync(DATA_FILE, JSON.stringify(data, null, 2));
}
app.use(express.json());
// ============================
// GET /api/data → read values
// DB CONFIG
// ============================
const dbConfig = {
host: "db", // docker service name
user: "leman",
password: "leman123",
database: "air_quality"
};
let db;
// ============================
// CONNECT WITH RETRY
// ============================
function connectDB() {
db = mysql.createConnection(dbConfig);
db.connect(err => {
if (err) {
console.error("❌ DB connection failed:", err.message);
console.log("🔄 Retrying in 5 seconds...");
setTimeout(connectDB, 5000);
} else {
console.log("✅ Connected to MariaDB");
}
});
db.on("error", err => {
console.error("⚠️ DB error:", err.message);
if (err.code === "PROTOCOL_CONNECTION_LOST") {
console.log("🔄 Reconnecting...");
connectDB();
} else {
throw err;
}
});
}
connectDB();
// ============================
// ROOT CHECK
// ============================
app.get("/", (req, res) => {
res.send("API is running 🚀");
});
// ============================
// GET LATEST DATA
// ============================
app.get("/data", (req, res) => {
try {
const data = readData();
res.json(data);
} catch (err) {
res.status(500).json({ error: "Gagal membaca data" });
}
const sql = `
SELECT * FROM air_data
ORDER BY updated_at DESC
LIMIT 1
`;
db.query(sql, (err, results) => {
if (err) {
console.error(err);
return res.status(500).json({ error: "DB error" });
}
res.json(results[0] || {});
});
});
// ===========================================
// GET /api/update?co2=&co=&bz=&aq=
// ===========================================
// ============================
// INSERT DATA
// ============================
app.get("/update", (req, res) => {
const { co2, co, bz, aq } = req.query;
const { co2, co, bz, aq, id } = req.query;
if (!co2 || !co || !bz || !aq) {
if (!co2 || !co || !bz || !aq || !id) {
return res.status(400).json({
error: "Parameter wajib: co2, co, bz, aq"
error: "Parameter wajib: co2, co, bz, aq, id"
});
}
const newData = {
CO2: Number(co2),
CO: Number(co),
BZ: Number(bz),
AQ: Number(aq),
updated_at: new Date().toISOString()
};
const sql = `
INSERT INTO air_data (co2, co, bz, aq, id)
VALUES (?, ?, ?, ?, ?)
`;
try {
writeData(newData);
res.json({
message: "Data berhasil diperbarui",
data: newData
});
} catch (err) {
res.status(500).json({ error: "Gagal menyimpan data" });
}
db.query(
sql,
[
Number(co2),
Number(co),
Number(bz),
Number(aq),
String(id) // sensor id
],
(err, result) => {
if (err) {
console.error(err);
return res.status(500).json({ error: "DB error" });
}
res.json({
message: "Data berhasil disimpan",
insertId: result.insertId
});
}
);
});
app.get("/sensordata/:id", (req, res) => {
const sensorId = req.params.id;
const sql = `
SELECT
air_data.co2,
air_data.co,
air_data.bz,
air_data.aq,
air_data.updated_at,
sensor_data.alamat,
kelurahan.nama AS kelurahan,
kecamatan.nama AS kecamatan
FROM air_data
JOIN sensor_data
ON air_data.id = sensor_data.id
JOIN kelurahan
ON sensor_data.kelurahan = kelurahan.id
JOIN kecamatan
ON kelurahan.kecamatan_id = kecamatan.id
WHERE air_data.id = ?
ORDER BY air_data.updated_at DESC
LIMIT 1
`;
db.query(sql, [sensorId], (err, results) => {
if (err) {
console.error(err);
return res.status(500).json({ error: "DB error" });
}
if (results.length === 0) {
return res.status(404).json({
error: "Sensor not found"
});
}
res.json(results[0]);
});
});
app.get("/sensors", (req, res) => {
const sql = `SELECT id FROM sensor_data`;
db.query(sql, (err, results) => {
if (err) {
return res.status(500).json({ error: "DB error" });
}
res.json(results);
});
});
// ============================
// ADD SENSOR
// ============================
app.post("/addSensor", (req, res) => {
const { kelurahan, alamat } = req.body;
// ============================
// VALIDATION
// ============================
if (!kelurahan || !alamat) {
return res.status(400).json({
error: "kelurahan dan alamat wajib diisi"
});
}
// ============================
// VALIDATE KELURAHAN EXISTS
// ============================
const checkSql = `SELECT id FROM kelurahan WHERE id = ?`;
db.query(checkSql, [kelurahan], (err, rows) => {
if (err) {
console.error(err);
return res.status(500).json({ error: "DB error" });
}
if (rows.length === 0) {
return res.status(400).json({
error: "Kelurahan tidak valid"
});
}
// ============================
// INSERT SENSOR
// ============================
const insertSql = `
INSERT INTO sensor_data (kelurahan, alamat)
VALUES (?, ?)
`;
db.query(insertSql, [kelurahan, alamat], (err, result) => {
if (err) {
console.error(err);
return res.status(500).json({
error: "DB error saat insert"
});
}
res.json({
message: "Sensor berhasil ditambahkan",
sensor_id: result.insertId
});
});
});
});
// ============================
// GET ALL DATA (OPTIONAL)
// ============================
app.get("/history", (req, res) => {
const sql = `
SELECT * FROM air_data
ORDER BY updated_at DESC
LIMIT 100
`;
db.query(sql, (err, results) => {
if (err) {
return res.status(500).json({ error: "DB error" });
}
res.json(results);
});
});
// get kecamatan
app.get("/kecamatan", (req, res) => {
const sql = `SELECT id, nama FROM kecamatan ORDER BY nama ASC`;
db.query(sql, (err, results) => {
if (err) {
console.error(err);
return res.status(500).json({ error: "DB error" });
}
res.json(results);
});
});
// get kelurahan by kecamatan_id
app.get("/kelurahan", (req, res) => {
const { kecamatan_id } = req.query;
let sql = `
SELECT
kelurahan.id,
kelurahan.nama,
kecamatan.nama AS kecamatan
FROM kelurahan
JOIN kecamatan ON kelurahan.kecamatan_id = kecamatan.id
`;
let params = [];
if (kecamatan_id) {
sql += ` WHERE kelurahan.kecamatan_id = ?`;
params.push(kecamatan_id);
}
sql += ` ORDER BY kelurahan.nama ASC`;
db.query(sql, params, (err, results) => {
if (err) {
console.error(err);
return res.status(500).json({ error: "DB error" });
}
res.json(results);
});
});
// ============================
// START SERVER
// ============================
app.listen(PORT, () => {
console.log(`API berjalan di port ${PORT}`);
});
console.log(`🚀 API running on port ${PORT}`);
});