From b0e6700de5c412ee1a69f4a2319cc95d4d6afbc4 Mon Sep 17 00:00:00 2001 From: Ammaar Alam Date: Mon, 13 Jan 2025 13:06:26 -0500 Subject: [PATCH] making global variable live update instead --- public/index.html | 37 +++++++-------- public/script.js | 113 ++++++++++++++++++++++++++-------------------- public/styles.css | 38 ++++++++++++---- 3 files changed, 113 insertions(+), 75 deletions(-) diff --git a/public/index.html b/public/index.html index 99948f0..c0d6ac5 100644 --- a/public/index.html +++ b/public/index.html @@ -37,13 +37,16 @@

Door Status

OPEN - +
+ + +

- PS: i know my friends, and to avoid getting kidnapped in the middle of the - night, i enable password authentication when I sleep or when i'm gone for + + PS: i know my friends, and to avoid getting kidnapped in the + middle of the night, i enable password authentication when I sleep or when i'm gone for days :P

@@ -52,23 +55,21 @@

Door Status

About This Project

This is a personal project I worked on over the summer. The switch at the top - really does open or close my door hehe; it sends a command to my proxy server - which routes that command to the Arduino IoT cloud server, relaying that command - to the arduino. That arduino is connected to a motor driver which then spins a - DC motor, reeling a fishing line knotted around my door handle, pulling it down. + really does open or close my door; it sends a command to my proxy server + which routes that command to the Arduino IoT cloud server, and then the Arduino + is connected to a motor driver and DC motor that reels a fishing line around my + door handle.

- For now, I don't really plan to add any more automation, this project was mainly - inspired by my girlfriend, who joked about wanting to have her own prox for my - room, and (just partly) by my very real problem of locking myself out somewhat - frequently; although it was really fun to learn how to work with arduinos and - circuitry,,, so maybe idk + For now, I don't plan to add more automation. This project was partly + inspired by my girlfriend wanting her own prox for my room, and partly by + my real problem of locking myself out frequently. So, it was fun to learn about + Arduinos and circuitry along the way.

- All the parts I used, including those bought and printed, are all open - source on the Github Repo, including the code, so feel free to make one - yourself :) + All the parts I used, including 3D-printed components and code, are open + source on the Github Repo. Feel free to try making one yourself!


@@ -101,4 +102,4 @@

Connect with Me

© 2024–25 Ammaar Alam. All rights reserved.

- + \ No newline at end of file diff --git a/public/script.js b/public/script.js index e31d466..904eadb 100644 --- a/public/script.js +++ b/public/script.js @@ -1,6 +1,6 @@ // redirect to HTTPS if accessed over HTTP // not necessary, but google crawler/url inspect is slow to update cache -if (window.location.protocol !== "https:") { +if (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1' && window.location.protocol !== "https:") { window.location.href = "https://" + window.location.hostname + window.location.pathname + window.location.search; } @@ -25,6 +25,8 @@ document.addEventListener("DOMContentLoaded", function () { localStorage.setItem("authToken", data.token); document.querySelector("#login-section").style.display = "none"; document.querySelector(".control-panel").style.display = "block"; + // After successful login, fetch the current door status to sync UI. + getDoorStatus(); } else { document.getElementById("login-error").style.display = "block"; } @@ -45,27 +47,58 @@ document.addEventListener("DOMContentLoaded", function () { // if auth isn't required, hide login and show control panel document.querySelector("#login-section").style.display = "none"; document.querySelector(".control-panel").style.display = "block"; + getDoorStatus(); } }) .catch((error) => console.error("Error checking auth status:", error)); + // fetch door status from server + async function getDoorStatus() { + try { + const headers = { "Content-Type": "application/json" }; + if (authRequired) { + const token = localStorage.getItem("authToken"); + if (token) { + headers["Authorization"] = token; + } + } + const response = await fetch("/status", { + method: "GET", + headers, + }); + if (!response.ok) { + console.error("Failed to get door status:", await response.text()); + return; + } + const data = await response.json(); + setToggle(data.doorOpen); + } catch (error) { + console.error("Error fetching door status:", error); + } + } + + // set toggle state based on doorOpen boolean + function setToggle(isOpen) { + const doorSwitch = document.getElementById("doorSwitch"); + doorSwitch.checked = !!isOpen; + updateStatus(); + } + async function sendCommand(command) { try { + const headers = { "Content-Type": "application/json" }; if (authRequired) { - // if auth is required, check for token const token = localStorage.getItem("authToken"); if (!token) { - console.error("No auth token found. please log in again."); + console.error("No auth token found. Please log in again."); return; } + headers["Authorization"] = token; } const response = await fetch("/command", { method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: authRequired ? localStorage.getItem("authToken") : "", // only add token if auth is required - }, + headers, body: JSON.stringify({ command }), }); @@ -74,8 +107,9 @@ document.addEventListener("DOMContentLoaded", function () { console.error("Failed to send command:", errorDetail); return; } - console.log(await response.text()); + // Refresh door status after sending command so UI stays in sync + getDoorStatus(); } catch (error) { console.error("Error during the request:", error); } @@ -86,15 +120,17 @@ document.addEventListener("DOMContentLoaded", function () { const openStatus = document.getElementById("open"); const closedStatus = document.getElementById("closed"); - if (!doorSwitch.checked) { - closedStatus.style.color = "rgba(76, 175, 80, 1)"; // solid green - openStatus.style.color = "#888"; // default gray - } else { + // If switch is checked, door is considered open; otherwise closed + if (doorSwitch.checked) { openStatus.style.color = "rgba(255, 94, 85, 1)"; // solid red closedStatus.style.color = "#888"; // default gray + } else { + closedStatus.style.color = "rgba(76, 175, 80, 1)"; // solid green + openStatus.style.color = "#888"; // default gray } } + // handle user toggling the switch function toggleSwitch() { const doorSwitch = document.getElementById("doorSwitch"); const command = doorSwitch.checked ? "open" : "close"; @@ -102,49 +138,30 @@ document.addEventListener("DOMContentLoaded", function () { updateStatus(); } - async function emergencyClose() { - try { - if (authRequired) { - // if auth is required, check for token - const token = localStorage.getItem("authToken"); - if (!token) { - console.error("No auth token found. please log in again."); - return; - } - } - - const response = await fetch("/emergency-close", { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: authRequired ? localStorage.getItem("authToken") : "", // only add token if auth is required - }, - }); - - if (!response.ok) { - const errorDetail = await response.text(); - console.error("Failed to send emergency close command:", errorDetail); - return; - } + // manual open door + function manualOpen() { + sendCommand("open"); + } - console.log(await response.text()); - } catch (error) { - console.error("Error during emergency close request:", error); - } + // manual close door + function manualClose() { + sendCommand("close"); } const doorSwitch = document.getElementById("doorSwitch"); if (doorSwitch) { - doorSwitch.onclick = toggleSwitch; - updateStatus(); // initialize the status on page load + doorSwitch.addEventListener("change", toggleSwitch); } else { console.error("doorSwitch element not found"); } - const emergencyCloseButton = document.getElementById("emergencyCloseButton"); - if (emergencyCloseButton) { - emergencyCloseButton.onclick = emergencyClose; - } else { - console.error("emergencyCloseButton element not found"); + // new manual open/close buttons + const openButton = document.getElementById("manualOpenButton"); + const closeButton = document.getElementById("manualCloseButton"); + if (openButton) { + openButton.onclick = manualOpen; + } + if (closeButton) { + closeButton.onclick = manualClose; } -}); +}); \ No newline at end of file diff --git a/public/styles.css b/public/styles.css index 74c9d45..1969594 100644 --- a/public/styles.css +++ b/public/styles.css @@ -259,24 +259,44 @@ footer p { align-items: stretch; padding: 10px; } - + .social-links a { justify-content: center; } } + #emergencyCloseButton { - background-color: #ff0d00; /* red */ - color: #f8f7f9; /* seasalt */ + display: none; /* Removed the old emergency close button. */ +} + +.manual-buttons-container { + display: flex; + align-items: center; + justify-content: center; + margin-top: 20px; + gap: 20px; +} + +.manual-btn { border: none; border-radius: 5px; - padding: 10px 20px; - font-size: 16px; + padding: 12px 20px; + font-size: 12px; cursor: pointer; transition: background-color 0.3s ease; - margin-top: 20px; - margin-bottom: 10px; + color: #f8f7f9; /* seasalt */ + background-color: #444; /* fallback */ + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); +} + +.manual-btn:hover { + opacity: 0.9; } -#emergencyCloseButton:hover { - background-color: #b80900; /* this colour is called "engineering orange" lol seems fitting */ +.open-btn { + background-color: #4caf50; /* green */ } + +.close-btn { + background-color: #ff5e55; /* red */ +} \ No newline at end of file