From 5f6e45af0934d866fe79e29ed4a8323e1376d413 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Sun, 11 Jan 2026 21:34:17 +1300 Subject: [PATCH] Clean up obsolete files - Remove old web.py, wifi.py, patterns.py - Remove old static files from root - Remove unused component files --- src/patterns.py | 291 --------------------------------- src/static/light-component.js | 143 ---------------- src/static/light-components.js | 90 ---------- src/static/main.js | 99 ++++++++--- src/static/styles.css | 51 ++++-- src/static/websocket.js | 26 --- src/templates/index.html | 14 +- src/web.py | 113 ------------- src/wifi.py | 38 ----- static/index.html | 14 -- static/main.js | 81 --------- static/rgb-slider.js | 195 ---------------------- static/styles.css | 37 ----- 13 files changed, 114 insertions(+), 1078 deletions(-) delete mode 100644 src/patterns.py delete mode 100644 src/static/light-component.js delete mode 100644 src/static/light-components.js delete mode 100644 src/static/websocket.js delete mode 100644 src/web.py delete mode 100644 src/wifi.py delete mode 100644 static/index.html delete mode 100644 static/main.js delete mode 100644 static/rgb-slider.js delete mode 100644 static/styles.css diff --git a/src/patterns.py b/src/patterns.py deleted file mode 100644 index 58de83d..0000000 --- a/src/patterns.py +++ /dev/null @@ -1,291 +0,0 @@ -from machine import Pin -from neopixel import NeoPixel -import utime -import random - -class Patterns: - def __init__(self, pin, num_leds, color1=(0,0,0), color2=(0,0,0), brightness=127, selected="rainbow_cycle", delay=100): - self.n = NeoPixel(Pin(pin, Pin.OUT), num_leds) - self.num_leds = num_leds - self.pattern_step = 0 - self.last_update = utime.ticks_ms() - self.delay = delay - self.brightness = brightness - self.patterns = { - "off": self.off, - "on" : self.on, - "color_wipe": self.color_wipe_step, - "rainbow_cycle": self.rainbow_cycle_step, - "theater_chase": self.theater_chase_step, - "blink": self.blink_step, - "random_color_wipe": self.random_color_wipe_step, - "random_rainbow_cycle": self.random_rainbow_cycle_step, - "random_theater_chase": self.random_theater_chase_step, - "random_blink": self.random_blink_step, - "color_transition": self.color_transition_step, - "external": None - } - self.selected = selected - self.color1 = color1 - self.color2 = color2 - self.transition_duration = 50 # Duration of color transition in milliseconds - self.transition_step = 0 - - def sync(self): - self.pattern_step=0 - self.last_update = utime.ticks_ms() - - def tick(self): - if self.patterns[self.selected]: - self.patterns[self.selected]() - - def update_num_leds(self, pin, num_leds): - self.n = NeoPixel(Pin(pin, Pin.OUT), num_leds) - self.num_leds = num_leds - self.pattern_step = 0 - - def set_delay(self, delay): - self.delay = delay - - def set_brightness(self, brightness): - self.brightness = brightness - - def set_color1(self, color): - print(color) - self.color1 = self.apply_brightness(color) - - def set_color2(self, color): - self.color2 = self.apply_brightness(color) - - def apply_brightness(self, color): - return tuple(int(c * self.brightness / 255) for c in color) - - def select(self, pattern): - if pattern in self.patterns: - self.selected = pattern - return True - return False - - def set(self, i, color): - self.n[i] = color - - def write(self): - self.n.write() - - def fill(self): - for i in range(self.num_leds): - self.n[i] = self.color1 - self.n.write() - - def off(self): - color = self.color1 - self.color1 = (0,0,0) - self.fill() - self.color1 = color - - def on(self): - color = self.color1 - self.color1 = self.apply_brightness(self.color1) - self.fill() - self.color1 = color - - - def color_wipe_step(self): - color = self.apply_brightness(self.color1) - current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: - if self.pattern_step < self.num_leds: - for i in range(self.num_leds): - self.n[i] = (0, 0, 0) - self.n[self.pattern_step] = self.apply_brightness(color) - self.n.write() - self.pattern_step += 1 - else: - self.pattern_step = 0 - self.last_update = current_time - - def rainbow_cycle_step(self): - current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay/5: - def wheel(pos): - if pos < 85: - return (pos * 3, 255 - pos * 3, 0) - elif pos < 170: - pos -= 85 - return (255 - pos * 3, 0, pos * 3) - else: - pos -= 170 - return (0, pos * 3, 255 - pos * 3) - - for i in range(self.num_leds): - rc_index = (i * 256 // self.num_leds) + self.pattern_step - self.n[i] = self.apply_brightness(wheel(rc_index & 255)) - self.n.write() - self.pattern_step = (self.pattern_step + 1) % 256 - self.last_update = current_time - - def theater_chase_step(self): - current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: - for i in range(self.num_leds): - if (i + self.pattern_step) % 3 == 0: - self.n[i] = self.apply_brightness(self.color1) - else: - self.n[i] = (0, 0, 0) - self.n.write() - self.pattern_step = (self.pattern_step + 1) % 3 - self.last_update = current_time - - def blink_step(self): - current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: - if self.pattern_step % 2 == 0: - for i in range(self.num_leds): - self.n[i] = self.apply_brightness(self.color1) - else: - for i in range(self.num_leds): - self.n[i] = (0, 0, 0) - self.n.write() - self.pattern_step = (self.pattern_step + 1) % 2 - self.last_update = current_time - - def random_color_wipe_step(self): - current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: - color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) - if self.pattern_step < self.num_leds: - for i in range(self.num_leds): - self.n[i] = (0, 0, 0) - self.n[self.pattern_step] = self.apply_brightness(color) - self.n.write() - self.pattern_step += 1 - else: - self.pattern_step = 0 - self.last_update = current_time - - def random_rainbow_cycle_step(self): - current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: - def wheel(pos): - if pos < 85: - return (pos * 3, 255 - pos * 3, 0) - elif pos < 170: - pos -= 85 - return (255 - pos * 3, 0, pos * 3) - else: - pos -= 170 - return (0, pos * 3, 255 - pos * 3) - - random_offset = random.randint(0, 255) - for i in range(self.num_leds): - rc_index = (i * 256 // self.num_leds) + self.pattern_step + random_offset - self.n[i] = self.apply_brightness(wheel(rc_index & 255)) - self.n.write() - self.pattern_step = (self.pattern_step + 1) % 256 - self.last_update = current_time - - def random_theater_chase_step(self): - current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: - color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) - for i in range(self.num_leds): - if (i + self.pattern_step) % 3 == 0: - self.n[i] = self.apply_brightness(color) - else: - self.n[i] = (0, 0, 0) - self.n.write() - self.pattern_step = (self.pattern_step + 1) % 3 - self.last_update = current_time - - def random_blink_step(self): - current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: - color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) - if self.pattern_step % 2 == 0: - for i in range(self.num_leds): - self.n[i] = self.apply_brightness(color) - else: - for i in range(self.num_leds): - self.n[i] = (0, 0, 0) - self.n.write() - self.pattern_step = (self.pattern_step + 1) % 2 - self.last_update = current_time - - def color_transition_step(self): - current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: - # Calculate transition factor based on elapsed time - transition_factor = (self.pattern_step * 100) / self.transition_duration - if transition_factor > 100: - transition_factor = 100 - color = self.interpolate_color(self.color1, self.color2, transition_factor / 100) - - # Apply the interpolated color to all LEDs - for i in range(self.num_leds): - self.n[i] = self.apply_brightness(color) - self.n.write() - - self.pattern_step += self.delay - if self.pattern_step > self.transition_duration: - self.pattern_step = 0 - - self.last_update = current_time - - def interpolate_color(self, color1, color2, factor): - return ( - int(color1[0] + (color2[0] - color1[0]) * factor), - int(color1[1] + (color2[1] - color1[1]) * factor), - int(color1[2] + (color2[2] - color1[2]) * factor) - ) - - def two_steps_forward_one_step_back_step(self): - current_time = utime.ticks_ms() - if utime.ticks_diff(current_time, self.last_update) >= self.delay: - # Move forward 2 steps and backward 1 step - if self.direction == 1: # Moving forward - if self.scanner_position < self.num_leds - 2: - self.scanner_position += 2 # Move forward 2 steps - else: - self.direction = -1 # Change direction to backward - else: # Moving backward - if self.scanner_position > 0: - self.scanner_position -= 1 # Move backward 1 step - else: - self.direction = 1 # Change direction to forward - - # Set all LEDs to off - for i in range(self.num_leds): - self.n[i] = (0, 0, 0) - - # Set the current position to the color - self.n[self.scanner_position] = self.apply_brightness(self.color1) - - # Apply the color transition - transition_factor = (self.pattern_step * 100) / self.transition_duration - if transition_factor > 100: - transition_factor = 100 - color = self.interpolate_color(self.color1, self.color2, transition_factor / 100) - self.n[self.scanner_position] = self.apply_brightness(color) - - self.n.write() - self.pattern_step += self.delay - if self.pattern_step > self.transition_duration: - self.pattern_step = 0 - - self.last_update = current_time - -if __name__ == "__main__": - p = Patterns(4, 180) - p.set_color1((255,0,0)) - p.set_color2((0,255,0)) - #p.set_delay(10) - try: - while True: - for key in p.patterns: - print(key) - p.select(key) - for _ in range(2000): - p.tick() - utime.sleep_ms(1) - except KeyboardInterrupt: - p.fill((0, 0, 0)) diff --git a/src/static/light-component.js b/src/static/light-component.js deleted file mode 100644 index 1f32642..0000000 --- a/src/static/light-component.js +++ /dev/null @@ -1,143 +0,0 @@ -import { getWebSocket } from "./websocket.js"; - -export class LightComponent extends HTMLElement { - constructor() { - super(); - - // Create a shadow DOM for encapsulation - const shadow = this.attachShadow({ mode: "open" }); - - // Create the content for the component - const style = document.createElement("style"); - style.textContent = ` - :host { - display: block; - width: 100px; - height: 100px; - background-color: #4caf50; - color: white; - text-align: center; - line-height: 100px; - cursor: grab; - position: absolute; - border-radius: 8px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); - } - - :host:active { - cursor: grabbing; - box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); - } - - .color-picker { - position: absolute; - top: 0; - right: 0; - width: 50px; - height: 50px; - cursor: pointer; - } - `; - - // Create the main content (draggable area) - const content = document.createElement("div"); - content.textContent = this.textContent || "Light Me Up!"; - content.style.position = "absolute"; - content.style.top = "0"; - content.style.left = "0"; - content.style.width = "100%"; - content.style.height = "100%"; - content.style.display = "flex"; - content.style.justifyContent = "center"; - content.style.alignItems = "center"; - - // Create the color picker - const colorPicker = document.createElement("input"); - colorPicker.type = "color"; - colorPicker.classList.add("color-picker"); - colorPicker.value = "#4caf50"; // Default color - colorPicker.addEventListener("input", () => { - this.style.backgroundColor = colorPicker.value; - this.dispatchEvent( - new CustomEvent("color-change", { - detail: { lightId: this.lightId, color: colorPicker.value }, - }), - ); - }); - - // Append the style, content, and color picker to the shadow DOM - shadow.appendChild(style); - shadow.appendChild(content); - shadow.appendChild(colorPicker); - - // Add event listeners for drag-and-drop - content.addEventListener("mousedown", this.handleMouseDown.bind(this)); - document.addEventListener("mousemove", this.handleMouseMove.bind(this)); - document.addEventListener("mouseup", this.handleMouseUp.bind(this)); - } - - // Track the initial mouse position and component position - handleMouseDown(event) { - event.preventDefault(); - - // Get the initial mouse position relative to the component - this.initialMouseX = event.clientX; - this.initialMouseY = event.clientY; - - // Get the initial position of the component - const rect = this.getBoundingClientRect(); - this.initialComponentX = rect.left; - this.initialComponentY = rect.top; - - // Add a class to indicate dragging - this.classList.add("dragging"); - } - - // Update the component's position as the mouse moves - handleMouseMove(event) { - if (!this.classList.contains("dragging")) return; - - // Calculate the new position of the component - const newX = this.initialComponentX + (event.clientX - this.initialMouseX); - const newY = this.initialComponentY + (event.clientY - this.initialMouseY); - - // Update the component's position - this.style.left = `${newX}px`; - this.style.top = `${newY}px`; - } - - // Stop dragging when the mouse is released - handleMouseUp() { - // Check if the component is being dragged - if (!this.classList.contains("dragging")) { - return; // Do nothing if not dragging - } - - // Remove the dragging class - this.classList.remove("dragging"); - - // Get the current position of the component - const rect = this.getBoundingClientRect(); - const newX = rect.left; - const newY = rect.top; - - // Dispatch an event to notify the parent about the updated position - this.dispatchEvent( - new CustomEvent("position-change", { - detail: { lightId: this.lightId, x: newX, y: newY }, - }), - ); - } - - // Add a property to hold the lightId - set lightId(id) { - this._lightId = id; - } - - get lightId() { - return this._lightId; - } -} - -// Define the custom element -customElements.define("light-component", LightComponent); diff --git a/src/static/light-components.js b/src/static/light-components.js deleted file mode 100644 index 14b5953..0000000 --- a/src/static/light-components.js +++ /dev/null @@ -1,90 +0,0 @@ -// light-components.js -import { LightComponent } from "./light-component.js"; -import { getWebSocket } from "./websocket.js"; - -// Map to store backend IDs and their corresponding components -const componentMap = new Map(); - -// Function to create and configure a light component -function createLightComponent(data, key, appContainer) { - const lightComponent = document.createElement("light-component"); - lightComponent.style.left = `${data.x}px`; // Set the x position - lightComponent.style.top = `${data.y}px`; // Set the y position - lightComponent.style.backgroundColor = data.settings?.color || "#4caf50"; // Set the background color - lightComponent.textContent = data.name || "Light Me Up!"; // Set the text content - - // Set the lightId property - lightComponent.lightId = key; // Use the backend ID as the lightId - - // Store the component in the map - componentMap.set(key, lightComponent); - - // Append the light component to the container - appContainer.appendChild(lightComponent); - - // Handle position change - lightComponent.addEventListener("position-change", (event) => { - const { lightId, x, y } = event.detail; - updatePositionOnServer(lightId, x, y); - }); - - // Handle color change - lightComponent.addEventListener("color-change", (event) => { - const { lightId, color } = event.detail; - sendColorToServer(lightId, color); - }); - - // Example: Add a click event listener to the light-component - lightComponent.addEventListener("click", () => { - console.log(`Light component clicked! ID: ${lightComponent.lightId}`); - }); -} - -// Function to create light components from the fetched data -export function createLightComponents(appContainer, lightData) { - for (const key in lightData) { - if (lightData.hasOwnProperty(key)) { - const light = lightData[key]; - createLightComponent(light, key, appContainer); // Pass the backend ID - } - } -} - -// Function to send the updated position to the server via a PATCH request -async function updatePositionOnServer(componentId, x, y) { - try { - const response = await fetch(`/light/${componentId}`, { - method: "PATCH", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ x, y }), - }); - - if (!response.ok) { - throw new Error(`HTTP error! Status: ${response.status}`); - } - - console.log( - `Updated position for component ${componentId}: x=${x}, y=${y}`, - ); - } catch (error) { - console.error("Error updating position on server:", error); - } -} - -// Function to send the selected color to the server via WebSocket -function sendColorToServer(componentId, color) { - const websocket = getWebSocket(); - const message = JSON.stringify({ - componentId, - color, - }); - - if (websocket.readyState === WebSocket.OPEN) { - websocket.send(message); - console.log("Sent color to server:", message); - } else { - console.warn("WebSocket is not open. Unable to send color."); - } -} diff --git a/src/static/main.js b/src/static/main.js index cdf56ce..6dce033 100644 --- a/src/static/main.js +++ b/src/static/main.js @@ -1,32 +1,81 @@ -// main.js -import { createLightComponents } from "./light-components.js"; -import { getWebSocket } from "./websocket.js"; +import "./rgb-slider.js"; -// Wait for the DOM to be fully loaded -document.addEventListener("DOMContentLoaded", async () => { - // Select the container where the light-components will be added - const appContainer = document.getElementById("app"); +const ws = new WebSocket("ws://localhost:8000/ws"); - // Fetch the JSON data from the /light endpoint - try { - const response = await fetch("/light"); - if (!response.ok) { - throw new Error(`HTTP error! Status: ${response.status}`); +ws.onopen = () => { + console.log("WebSocket connection established"); +}; + +ws.onclose = () => { + console.log("WebSocket connection closed"); +}; + +ws.onerror = (error) => { + console.error("WebSocket error:", error); +}; + +// Number of sliders (tabs) you want to create +const numTabs = 3; + +// Select the container for tabs and content +const tabsContainer = document.querySelector(".tabs"); +const tabContentContainer = document.querySelector(".tab-content"); + +// Create tabs dynamically +for (let i = 1; i <= numTabs; i++) { + // Create the tab button + const tabButton = document.createElement("button"); + tabButton.classList.add("tab"); + tabButton.id = `tab${i}`; + tabButton.textContent = `Tab ${i}`; + + // Add the tab button to the container + tabsContainer.appendChild(tabButton); + + // Create the corresponding tab content (RGB slider) + const tabContent = document.createElement("div"); + tabContent.classList.add("tab-pane"); + tabContent.id = `content${i}`; + const slider = document.createElement("rgb-slider"); + slider.id = i; + tabContent.appendChild(slider); + + // Add the tab content to the container + tabContentContainer.appendChild(tabContent); + + // Listen for color change on each RGB slider + slider.addEventListener("color-change", (e) => { + const { r, g, b } = e.detail; + console.log(`Color changed in tab ${i}:`, e.detail); + // Send RGB data to WebSocket server + if (ws.readyState === WebSocket.OPEN) { + const colorData = { r, g, b }; + ws.send(JSON.stringify(colorData)); } - const lightData = await response.json(); + }); +} - // Create and configure light components - createLightComponents(appContainer, lightData); +// Function to switch tabs +function switchTab(tabId) { + const tabs = document.querySelectorAll(".tab"); + const tabContents = document.querySelectorAll(".tab-pane"); - // Initialize WebSocket connection - const websocket = getWebSocket(); - websocket.addEventListener("open", () => { - console.log("WebSocket connection established."); - }); - websocket.addEventListener("message", (event) => { - console.log("Message from server:", event.data); - }); - } catch (error) { - console.error("Error fetching light data:", error); + tabs.forEach((tab) => tab.classList.remove("active")); + tabContents.forEach((content) => content.classList.remove("active")); + + // Activate the clicked tab and corresponding content + document.getElementById(tabId).classList.add("active"); + document + .getElementById("content" + tabId.replace("tab", "")) + .classList.add("active"); +} + +// Add event listeners to tabs +tabsContainer.addEventListener("click", (e) => { + if (e.target.classList.contains("tab")) { + switchTab(e.target.id); } }); + +// Initially set the first tab as active +switchTab("tab1"); diff --git a/src/static/styles.css b/src/static/styles.css index e238081..e3ecf1c 100644 --- a/src/static/styles.css +++ b/src/static/styles.css @@ -1,20 +1,37 @@ -/* Default styles for the light component */ -light-component { - display: block; - width: 100px; - height: 100px; - background-color: #4caf50; - color: white; - text-align: center; - line-height: 100px; - cursor: grab; - position: absolute; - border-radius: 8px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); +/* General tab styles */ +.tabs { + display: flex; + justify-content: center; + margin-bottom: 20px; } -/* Styles when the component is being dragged */ -light-component:active { - cursor: grabbing; - box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); +.tab { + padding: 10px 20px; + margin: 0 10px; + cursor: pointer; + background-color: #f1f1f1; + border: 1px solid #ccc; + border-radius: 4px; + transition: background-color 0.3s ease; +} + +.tab:hover { + background-color: #ddd; +} + +.tab.active { + background-color: #ccc; +} + +.tab-content { + display: flex; + justify-content: center; +} + +.tab-pane { + display: none; +} + +.tab-pane.active { + display: block; } diff --git a/src/static/websocket.js b/src/static/websocket.js deleted file mode 100644 index 10c8333..0000000 --- a/src/static/websocket.js +++ /dev/null @@ -1,26 +0,0 @@ -// websocket.js -let websocket = null; - -export function getWebSocket() { - if (!websocket) { - // Replace 'ws://your-server-url' with your WebSocket server URL - websocket = new WebSocket(`ws://${window.location.host}/ws`); - - // Handle WebSocket connection open - websocket.onopen = () => { - console.log("WebSocket connection established"); - }; - - // Handle WebSocket connection close - websocket.onclose = () => { - console.log("WebSocket connection closed"); - }; - - // Handle WebSocket errors - websocket.onerror = (error) => { - console.error("WebSocket error:", error); - }; - } - - return websocket; -} diff --git a/src/templates/index.html b/src/templates/index.html index 3e4bbc4..5431954 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -2,15 +2,13 @@ - - Light Component - - + RGB Slider Tabs + - -
- - +
+
+ + diff --git a/src/web.py b/src/web.py deleted file mode 100644 index 1457446..0000000 --- a/src/web.py +++ /dev/null @@ -1,113 +0,0 @@ -from microdot import Microdot, send_file, Response -from microdot.utemplate import Template -from microdot.websocket import with_websocket -import json - -def web(settings): - app = Microdot() - Response.default_content_type = 'text/html' - - @app.route('/') - async def index_handler(request): - return Template('/index.html').render(settings=settings) - - @app.route("/static/") - def static_handler(request, path): - if '..' in path: - # Directory traversal is not allowed - return 'Not found', 404 - return send_file('static/' + path) - - @app.route("/ws") - @with_websocket - async def ws(request, ws): - # Register the client's WebSocket connection - print("WebSocket connection established") - - while True: - data = await ws.receive() - if data: - try: - # Parse the JSON message from the client - message = json.loads(data) - light = message.get("light") - if message["light"] in settings.get("lights"): - settings["lights"][light].update(message["settings"]) - if message["save"]: - settings.save() - except json.JSONDecodeError: - print("Invalid JSON received") - - else: - break - - print("WebSocket connection closed") - - @app.get("/light") - async def get_lights(request): - return json.dumps(settings) - - @app.get("/light/") - async def get_light(request, light): - light_data = settings.get(light, None) - if light_data: - return json.dumps(light_data), 200 - else: - return json.dumps({"error": "Light not found"}), 404 - - @app.post("/light/") - async def add_light(request, light): - try: - # Parse the JSON request body - data = request.json - # Check if the light already exists - if light in settings: - return json.dumps({"error": "Light already exists"}), 409 - - # Add the new light to the settings - settings[light] = data - print(settings) - settings.save() - return json.dumps( - {"message": "Light added successfully", - "light": light} - ), 200 - except Exception as e: - print(f"Exception: {e}") - return json.dumps({"error": "Invalid JSON request"}), 400 - - @app.patch("/light/") - async def update_light(request, light): - try: - # Parse the JSON request body - data = request.json - print(light, data) - # Check if the light exists - if light not in settings: - return json.dumps({"error": "Light not found"}), 404 - - # Update the existing light with the provided data - settings[light].update(data) - settings.save() # Uncomment if using persistent storage - return json.dumps( - {"message": "Light updated successfully", "light": settings[light]} - ), 200 - except json.JSONDecodeError: - return json.dumps({"error": "Invalid JSON request"}), 400 - - @app.delete("/light/") - async def del_light(request, light): - if light in settings: - # Remove the light from the settings - del settings[light] - settings.save() - return json.dumps({"message": "Light deleted successfully"}) - else: - return json.dumps({"error": "Light not found"}), 404 - - return app - -# Example usage -if __name__ == "__main__": - app = web(settings) - app.run() diff --git a/src/wifi.py b/src/wifi.py deleted file mode 100644 index 5839234..0000000 --- a/src/wifi.py +++ /dev/null @@ -1,38 +0,0 @@ -import network -from time import sleep - -def connect(ssid, password, ip, gateway): - if ssid is None or password is None: - print("Missing ssid or password") - return None - try: - sta_if = network.WLAN(network.STA_IF) - if ip is not None and gateway is not None: - sta_if.ifconfig((ip, '255.255.255.0', gateway, '1.1.1.1')) - if not sta_if.isconnected(): - print('connecting to network...') - sta_if.active(True) - sta_if.connect(ssid, password) - sleep(0.1) - if sta_if.isconnected(): - return sta_if.ifconfig() - return None - return sta_if.ifconfig() - except Exception as e: - print(f"Failed to connect to wifi {e}") - return None - - -def ap(ssid, password): - ap_if = network.WLAN(network.AP_IF) - ap_mac = ap_if.config('mac') - print(ssid) - ap_if.active(True) - ap_if.config(essid=ssid, password=password) - ap_if.active(False) - ap_if.active(True) - print(ap_if.ifconfig()) - -def get_mac(): - ap_if = network.WLAN(network.AP_IF) - return ap_if.config('mac') diff --git a/static/index.html b/static/index.html deleted file mode 100644 index 5431954..0000000 --- a/static/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - RGB Slider Tabs - - - -
-
- - - - diff --git a/static/main.js b/static/main.js deleted file mode 100644 index 6dce033..0000000 --- a/static/main.js +++ /dev/null @@ -1,81 +0,0 @@ -import "./rgb-slider.js"; - -const ws = new WebSocket("ws://localhost:8000/ws"); - -ws.onopen = () => { - console.log("WebSocket connection established"); -}; - -ws.onclose = () => { - console.log("WebSocket connection closed"); -}; - -ws.onerror = (error) => { - console.error("WebSocket error:", error); -}; - -// Number of sliders (tabs) you want to create -const numTabs = 3; - -// Select the container for tabs and content -const tabsContainer = document.querySelector(".tabs"); -const tabContentContainer = document.querySelector(".tab-content"); - -// Create tabs dynamically -for (let i = 1; i <= numTabs; i++) { - // Create the tab button - const tabButton = document.createElement("button"); - tabButton.classList.add("tab"); - tabButton.id = `tab${i}`; - tabButton.textContent = `Tab ${i}`; - - // Add the tab button to the container - tabsContainer.appendChild(tabButton); - - // Create the corresponding tab content (RGB slider) - const tabContent = document.createElement("div"); - tabContent.classList.add("tab-pane"); - tabContent.id = `content${i}`; - const slider = document.createElement("rgb-slider"); - slider.id = i; - tabContent.appendChild(slider); - - // Add the tab content to the container - tabContentContainer.appendChild(tabContent); - - // Listen for color change on each RGB slider - slider.addEventListener("color-change", (e) => { - const { r, g, b } = e.detail; - console.log(`Color changed in tab ${i}:`, e.detail); - // Send RGB data to WebSocket server - if (ws.readyState === WebSocket.OPEN) { - const colorData = { r, g, b }; - ws.send(JSON.stringify(colorData)); - } - }); -} - -// Function to switch tabs -function switchTab(tabId) { - const tabs = document.querySelectorAll(".tab"); - const tabContents = document.querySelectorAll(".tab-pane"); - - tabs.forEach((tab) => tab.classList.remove("active")); - tabContents.forEach((content) => content.classList.remove("active")); - - // Activate the clicked tab and corresponding content - document.getElementById(tabId).classList.add("active"); - document - .getElementById("content" + tabId.replace("tab", "")) - .classList.add("active"); -} - -// Add event listeners to tabs -tabsContainer.addEventListener("click", (e) => { - if (e.target.classList.contains("tab")) { - switchTab(e.target.id); - } -}); - -// Initially set the first tab as active -switchTab("tab1"); diff --git a/static/rgb-slider.js b/static/rgb-slider.js deleted file mode 100644 index 0c986df..0000000 --- a/static/rgb-slider.js +++ /dev/null @@ -1,195 +0,0 @@ -// rgb-slider.js - -export class RGBSlider extends HTMLElement { - constructor() { - super(); - const shadow = this.attachShadow({ mode: "open" }); - - shadow.innerHTML = ` - - - -
-
- -
-
- - -
-
- - -
-
- - -
-
- -
-
- - -
-
- - -
-
- - -
-
-
- `; - - const get = (id) => shadow.querySelector(id); - this.r = get("#r"); - this.g = get("#g"); - this.b = get("#b"); - this.rInput = get("#rInput"); - this.gInput = get("#gInput"); - this.bInput = get("#bInput"); - this.preview = get("#preview"); - - const updateColor = (r, g, b) => { - this.preview.style.backgroundColor = `rgb(${r}, ${g}, ${b})`; - this.rInput.value = r; - this.gInput.value = g; - this.bInput.value = b; - this.dispatchEvent( - new CustomEvent("color-change", { - detail: { r, g, b }, - bubbles: true, - composed: true, - }), - ); - }; - - const syncFromSliders = () => { - const r = +this.r.value; - const g = +this.g.value; - const b = +this.b.value; - updateColor(r, g, b); - }; - - const syncFromInputs = () => { - const r = Math.min(255, Math.max(0, +this.rInput.value)); - const g = Math.min(255, Math.max(0, +this.gInput.value)); - const b = Math.min(255, Math.max(0, +this.bInput.value)); - this.r.value = r; - this.g.value = g; - this.b.value = b; - updateColor(r, g, b); - }; - - this.r.addEventListener("input", syncFromSliders); - this.g.addEventListener("input", syncFromSliders); - this.b.addEventListener("input", syncFromSliders); - - this.rInput.addEventListener("change", syncFromInputs); - this.gInput.addEventListener("change", syncFromInputs); - this.bInput.addEventListener("change", syncFromInputs); - } -} - -customElements.define("rgb-slider", RGBSlider); diff --git a/static/styles.css b/static/styles.css deleted file mode 100644 index e3ecf1c..0000000 --- a/static/styles.css +++ /dev/null @@ -1,37 +0,0 @@ -/* General tab styles */ -.tabs { - display: flex; - justify-content: center; - margin-bottom: 20px; -} - -.tab { - padding: 10px 20px; - margin: 0 10px; - cursor: pointer; - background-color: #f1f1f1; - border: 1px solid #ccc; - border-radius: 4px; - transition: background-color 0.3s ease; -} - -.tab:hover { - background-color: #ddd; -} - -.tab.active { - background-color: #ccc; -} - -.tab-content { - display: flex; - justify-content: center; -} - -.tab-pane { - display: none; -} - -.tab-pane.active { - display: block; -}