257 lines
5.3 KiB
JavaScript
257 lines
5.3 KiB
JavaScript
const express = require("express");
|
|
const mysql = require("mysql2");
|
|
|
|
const app = express();
|
|
const PORT = 3000;
|
|
app.use(express.json());
|
|
|
|
// ============================
|
|
// 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) => {
|
|
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] || {});
|
|
});
|
|
});
|
|
|
|
// ============================
|
|
// INSERT DATA
|
|
// ============================
|
|
app.get("/update", (req, res) => {
|
|
const { co2, co, bz, aq, id } = req.query;
|
|
|
|
if (!co2 || !co || !bz || !aq || !id) {
|
|
return res.status(400).json({
|
|
error: "Parameter wajib: co2, co, bz, aq, id"
|
|
});
|
|
}
|
|
|
|
const sql = `
|
|
INSERT INTO air_data (co2, co, bz, aq, id)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
`;
|
|
|
|
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,
|
|
alamat_data.alamat AS alamat
|
|
FROM air_data
|
|
JOIN alamat_data
|
|
ON alamat_data.id = air_data.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 * FROM alamat_data where status = 1 ORDER BY id ASC`;
|
|
|
|
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 { id } = req.body;
|
|
|
|
// check if id is provided
|
|
if (!id) {
|
|
return res.status(400).json({
|
|
error: "Sensor ID is required"
|
|
});
|
|
}
|
|
|
|
// check if id is numeric
|
|
if (isNaN(id)) {
|
|
return res.status(400).json({
|
|
error: "Sensor ID must be numeric"
|
|
});
|
|
}
|
|
|
|
// check if id exists in alamat_data table, if available then continue
|
|
const checkSql = `SELECT id FROM alamat_data WHERE id = ?`;
|
|
|
|
db.query(checkSql, [id], (err, results) => {
|
|
if (err) {
|
|
console.error(err);
|
|
return res.status(500).json({ error: "DB error" });
|
|
}
|
|
|
|
if (results.length === 0) {
|
|
return res.status(400).json({
|
|
error: "Sensor ID not found in alamat_data table"
|
|
});
|
|
}
|
|
});
|
|
|
|
// update the status field to 1 to the id in alamat_data table
|
|
const updateSql = `UPDATE alamat_data SET status = 1 WHERE id = ?`;
|
|
|
|
db.query(updateSql, [id], (err, result) => {
|
|
if (err) {
|
|
console.error(err);
|
|
return res.status(500).json({ error: "DB error" });
|
|
}
|
|
res.json({
|
|
message: "Sensor added successfully",
|
|
id: id
|
|
});
|
|
});
|
|
|
|
});
|
|
|
|
// ============================
|
|
// 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("/alamat", (req, res) => {
|
|
const sql = `SELECT * from alamat_data where status = 0 ORDER BY id ASC`;
|
|
|
|
db.query(sql, (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 running on port ${PORT}`);
|
|
}); |