Spaces:
Sleeping
Sleeping
File size: 4,062 Bytes
fe9b24f 800d973 1329aed 800d973 fe9b24f 800d973 fe9b24f 800d973 2dca8eb 800d973 2dca8eb 800d973 2dca8eb 800d973 2dca8eb 800d973 1329aed 800d973 1329aed 800d973 2dca8eb 800d973 2dca8eb 800d973 1329aed 2dca8eb 1329aed 2dca8eb 800d973 2dca8eb 800d973 fe9b24f 800d973 fe9b24f 800d973 2dca8eb 800d973 2dca8eb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | const express = require("express");
const http = require("http");
const app = express();
const server = http.createServer(app);
// Store LED states
let ledStates = {
led1: false,
led2: false,
led3: false,
led4: false,
chase: false
};
// Store SSE clients (ESP8266 devices)
let sseClients = [];
app.use(express.json());
app.use(express.static("."));
// SSE endpoint for ESP8266
app.get("/events", (req, res) => {
res.setHeader("Content-Type", "text/event-stream");
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Connection", "keep-alive");
res.setHeader("Access-Control-Allow-Origin", "*");
console.log("New SSE client connected");
// Send current state immediately
Object.keys(ledStates).forEach(led => {
const message = `data: ${led}:${ledStates[led] ? 1 : 0}\n\n`;
res.write(message);
console.log(`Sent initial state: ${led}:${ledStates[led] ? 1 : 0}`);
});
// Add client to list
sseClients.push(res);
console.log(`Total ESP8266 clients: ${sseClients.length}`);
// Send keepalive every 30 seconds
const keepaliveInterval = setInterval(() => {
try {
res.write(`:keepalive\n\n`);
} catch (err) {
clearInterval(keepaliveInterval);
}
}, 30000);
// Remove client on disconnect
req.on("close", () => {
clearInterval(keepaliveInterval);
sseClients = sseClients.filter(client => client !== res);
console.log(`ESP8266 disconnected. Total clients: ${sseClients.length}`);
});
});
// Get current LED states (for frontend)
app.get("/api/leds", (req, res) => {
res.json(ledStates);
});
// Get connection status
app.get("/api/status", (req, res) => {
res.json({
connected: sseClients.length > 0,
clientCount: sseClients.length
});
});
// Toggle individual LED (for frontend)
app.post("/api/led/:ledName", (req, res) => {
const { ledName } = req.params;
const { state } = req.body;
if (!ledStates.hasOwnProperty(ledName)) {
return res.status(400).json({ error: "Invalid LED name" });
}
ledStates[ledName] = state;
// If turning on chase, turn off individual LEDs 1-3
if (ledName === "chase" && state) {
ledStates.led1 = false;
ledStates.led2 = false;
ledStates.led3 = false;
}
// Broadcast to all ESP8266 devices via SSE
const message = `data: ${ledName}:${state ? 1 : 0}\n\n`;
console.log(`Broadcasting: ${ledName}:${state ? 1 : 0} to ${sseClients.length} clients`);
sseClients.forEach((client, index) => {
try {
client.write(message);
} catch (err) {
console.error(`Error sending to client ${index}:`, err.message);
}
});
// If chase was turned on, also send LED1-3 off commands
if (ledName === "chase" && state) {
["led1", "led2", "led3"].forEach(led => {
const msg = `data: ${led}:0\n\n`;
console.log(`Broadcasting: ${led}:0`);
sseClients.forEach(client => {
try {
client.write(msg);
} catch (err) {
console.error("Error sending to client:", err.message);
}
});
});
}
console.log(`${ledName} set to ${state ? "ON" : "OFF"}`);
res.json({ success: true, ledStates });
});
// Turn all LEDs off
app.post("/api/all-off", (req, res) => {
Object.keys(ledStates).forEach(led => {
ledStates[led] = false;
const message = `data: ${led}:0\n\n`;
console.log(`Broadcasting: ${led}:0`);
sseClients.forEach(client => {
try {
client.write(message);
} catch (err) {
console.error("Error sending to client:", err.message);
}
});
});
console.log("All LEDs turned OFF");
res.json({ success: true, ledStates });
});
const PORT = process.env.PORT || 3000;
const HOST = "0.0.0.0";
server.listen(PORT, HOST, () => {
console.log(`\n=================================`);
console.log(`Server running at http://${HOST}:${PORT}`);
console.log(`SSE endpoint: http://${HOST}:${PORT}/events`);
console.log(`API endpoint: http://${HOST}:${PORT}/api/leds`);
console.log(`=================================\n`);
}); |