Compare commits
2 Commits
9c9fffc3ff
...
c2b55972d3
Author | SHA1 | Date |
---|---|---|
Jimmy | c2b55972d3 | |
Jimmy | c0b0833905 |
73
index.html
73
index.html
|
@ -1,31 +1,60 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>LED Control</title>
|
<title>LED Control</title>
|
||||||
<script src="main.js" defer></script>
|
<script src="main.js"></script>
|
||||||
|
<link rel="stylesheet" href="main.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Control LEDs</h1>
|
<h1>Control LEDs</h1>
|
||||||
<form id="led_form" method="post" action="/num_leds">
|
<button onclick="selectControls()">Controls</button>
|
||||||
<label for="num_leds">Number of LEDs:</label>
|
<button onclick="selectSettings()">Settings</button>
|
||||||
<input type="text" id="num_leds" name="num_leds" value="{num_leds}">
|
|
||||||
<input type="submit" value="Update">
|
|
||||||
</form>
|
|
||||||
<div id="pattern_buttons">
|
|
||||||
<!-- Pattern buttons will be inserted here -->
|
|
||||||
</div>
|
|
||||||
<form id="delay_form" method="post" action="/delay">
|
|
||||||
<label for="delay">Delay:</label>
|
|
||||||
<input type="range" id="delay" name="delay" min="10" max="1000" value="{delay}" step="10">
|
|
||||||
</form>
|
|
||||||
<form id="color_form" method="post" action="/color">
|
|
||||||
<label for="color">Select Color:</label>
|
|
||||||
<input type="color" id="color" name="color" value="{color}">
|
|
||||||
</form>
|
|
||||||
<form id="color2_form" method="post" action="/color2">
|
|
||||||
<label for="color2">Select Color2:</label>
|
|
||||||
<input type="color" id="color2" name="color2" value="{color2}">
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
<!-- Main LED Controls -->
|
||||||
|
<div id="controls">
|
||||||
|
<div id="pattern_buttons">
|
||||||
|
<!-- Pattern buttons will be inserted here -->
|
||||||
|
</div>
|
||||||
|
<form id="delay_form" method="post" action="/delay">
|
||||||
|
<label for="delay">Delay:</label>
|
||||||
|
<input type="range" id="delay" name="delay" min="1" max="1000" value="{delay}" step="10">
|
||||||
|
</form>
|
||||||
|
<form id="brightness_form" method="post" action="/brightness">
|
||||||
|
<label for="brightness">Brightness:</label>
|
||||||
|
<input type="range" id="brightness" name="brightness" min="0" max="100" value="{brightness}" step="1">
|
||||||
|
</form>
|
||||||
|
<form id="color_form" method="post" action="/color">
|
||||||
|
<input type="color" id="color" name="color" value="{color}">
|
||||||
|
</form>
|
||||||
|
<form id="color2_form" method="post" action="/color2">
|
||||||
|
<input type="color" id="color2" name="color2" value="{color2}">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Settings Menu for num_leds, Wi-Fi SSID, and Password -->
|
||||||
|
|
||||||
|
<div id="settings_menu" style="display: none;">
|
||||||
|
<h2>Settings</h2>
|
||||||
|
|
||||||
|
<!-- Separate form for submitting num_leds -->
|
||||||
|
<form id="num_leds_form" method="post" action="/num_leds">
|
||||||
|
<label for="num_leds">Number of LEDs:</label>
|
||||||
|
<input type="text" id="num_leds" name="num_leds" value="{num_leds}">
|
||||||
|
<input type="submit" value="Update Number of LEDs">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- Form for Wi-Fi SSID and password -->
|
||||||
|
<form id="wifi_form" method="post" action="/wifi_settings">
|
||||||
|
<label for="ssid">Wi-Fi SSID:</label>
|
||||||
|
<input type="text" id="ssid" name="ssid" value="{ssid}">
|
||||||
|
<br>
|
||||||
|
<label for="password">Wi-Fi Password:</label>
|
||||||
|
<input type="password" id="password" name="password">
|
||||||
|
<br>
|
||||||
|
<input type="submit" value="Save Wi-Fi Settings">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
112
main.css
112
main.css
|
@ -1,40 +1,74 @@
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
background-color: #f0f0f0;
|
max-width: 600px;
|
||||||
margin: 0;
|
margin: 0 auto;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
line-height: 1.6;
|
||||||
|
}
|
||||||
h1 {
|
h1 {
|
||||||
color: #333;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
form {
|
||||||
form {
|
margin-bottom: 20px;
|
||||||
margin-bottom: 20px;
|
}
|
||||||
}
|
label {
|
||||||
|
display: block;
|
||||||
label {
|
margin-bottom: 5px;
|
||||||
display: block;
|
}
|
||||||
margin-bottom: 5px;
|
input[type="text"], input[type="submit"], input[type="range"], input[type="color"] {
|
||||||
font-weight: bold;
|
width: 100%;
|
||||||
}
|
|
||||||
|
margin-bottom: 10px;
|
||||||
input[type="text"],
|
box-sizing: border-box;
|
||||||
input[type="range"],
|
}
|
||||||
input[type="color"],
|
input[type="range"] {
|
||||||
button {
|
-webkit-appearance: none;
|
||||||
margin-bottom: 10px;
|
appearance: none;
|
||||||
padding: 10px;
|
height: 25px;
|
||||||
font-size: 16px;
|
background: #d3d3d3;
|
||||||
}
|
outline: none;
|
||||||
|
opacity: 0.7;
|
||||||
button:disabled {
|
transition: opacity .2s;
|
||||||
background-color: #ccc;
|
}
|
||||||
}
|
input[type="range"]:hover {
|
||||||
|
opacity: 1;
|
||||||
button {
|
}
|
||||||
margin-right: 5px;
|
input[type="range"]::-webkit-slider-thumb {
|
||||||
padding: 10px 20px;
|
-webkit-appearance: none;
|
||||||
font-size: 16px;
|
appearance: none;
|
||||||
cursor: pointer;
|
width: 25px;
|
||||||
}
|
height: 25px;
|
||||||
|
background: #4CAF50;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
input[type="range"]::-moz-range-thumb {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
background: #4CAF50;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
#pattern_buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
#pattern_buttons button {
|
||||||
|
flex: 1 0 calc(33.333% - 10px);
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
#pattern_buttons button:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
#pattern_buttons button {
|
||||||
|
flex: 1 0 calc(50% - 10px);
|
||||||
|
}
|
||||||
|
}
|
58
main.js
58
main.js
|
@ -1,4 +1,7 @@
|
||||||
let delayTimeout;
|
let delayTimeout;
|
||||||
|
let brightnessTimeout;
|
||||||
|
let colorTimeout;
|
||||||
|
let color2Timeout;
|
||||||
|
|
||||||
async function post(path, value) {
|
async function post(path, value) {
|
||||||
console.log(path, value);
|
console.log(path, value);
|
||||||
|
@ -32,14 +35,20 @@ async function get(path) {
|
||||||
|
|
||||||
async function updateColor(event) {
|
async function updateColor(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const color = document.getElementById('color').value;
|
clearTimeout(colorTimeout);
|
||||||
await post("/color", color);
|
colorTimeout = setTimeout(async function() {
|
||||||
|
const color = document.getElementById('color').value;
|
||||||
|
await post("/color", color);
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateColor2(event) {
|
async function updateColor2(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const color = document.getElementById('color2').value;
|
clearTimeout(color2Timeout);
|
||||||
await post("/color2", color);
|
color2Timeout = setTimeout(async function() {
|
||||||
|
const color = document.getElementById('color2').value;
|
||||||
|
await post("/color2", color);
|
||||||
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updatePattern(pattern) {
|
async function updatePattern(pattern) {
|
||||||
|
@ -47,6 +56,15 @@ async function updatePattern(pattern) {
|
||||||
await post("/pattern", pattern);
|
await post("/pattern", pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateBrightness(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
clearTimeout(brightnessTimeout);
|
||||||
|
brightnessTimeout = setTimeout(async function() {
|
||||||
|
const brightness = document.getElementById('brightness').value;
|
||||||
|
await post('/brightness', brightness);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
async function updateDelay(event) {
|
async function updateDelay(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
clearTimeout(delayTimeout);
|
clearTimeout(delayTimeout);
|
||||||
|
@ -62,6 +80,14 @@ async function updateNumLeds(event) {
|
||||||
await post('/num_leds', numLeds);
|
await post('/num_leds', numLeds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateWifi(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const ssid = document.getElementById('ssid').value;
|
||||||
|
const password = document.getElementById('password').value;
|
||||||
|
console.log(ssid, password);
|
||||||
|
//await post('/num_leds', numLeds);
|
||||||
|
}
|
||||||
|
|
||||||
function createPatternButtons(patterns) {
|
function createPatternButtons(patterns) {
|
||||||
const container = document.getElementById('pattern_buttons');
|
const container = document.getElementById('pattern_buttons');
|
||||||
container.innerHTML = ''; // Clear previous buttons
|
container.innerHTML = ''; // Clear previous buttons
|
||||||
|
@ -83,7 +109,11 @@ document.addEventListener('DOMContentLoaded', async function() {
|
||||||
document.getElementById('color').addEventListener('input', updateColor);
|
document.getElementById('color').addEventListener('input', updateColor);
|
||||||
document.getElementById('color2').addEventListener('input', updateColor2);
|
document.getElementById('color2').addEventListener('input', updateColor2);
|
||||||
document.getElementById('delay').addEventListener('input', updateDelay);
|
document.getElementById('delay').addEventListener('input', updateDelay);
|
||||||
document.getElementById('led_form').addEventListener('submit', updateNumLeds);
|
document.getElementById('brightness').addEventListener('input', updateBrightness);
|
||||||
|
document.getElementById('num_leds_form').addEventListener('submit', updateNumLeds);
|
||||||
|
document.getElementById('wifi_form').addEventListener('submit', updateWifi);
|
||||||
|
document.getElementById('delay').addEventListener('touchend', updateDelay);
|
||||||
|
document.getElementById('brightness').addEventListener('touchend', updateBrightness);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const patterns = await get("/patterns");
|
const patterns = await get("/patterns");
|
||||||
|
@ -92,4 +122,22 @@ document.addEventListener('DOMContentLoaded', async function() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching patterns:', error);
|
console.error('Error fetching patterns:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Function to toggle the display of the settings menu
|
||||||
|
function selectSettings() {
|
||||||
|
const settingsMenu = document.getElementById('settings_menu');
|
||||||
|
controls = document.getElementById('controls');
|
||||||
|
settingsMenu.style.display = 'block';
|
||||||
|
controls.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectControls() {
|
||||||
|
const settingsMenu = document.getElementById('settings_menu');
|
||||||
|
controls = document.getElementById('controls');
|
||||||
|
settingsMenu.style.display = 'none';
|
||||||
|
controls.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
182
main.py
182
main.py
|
@ -1,21 +1,24 @@
|
||||||
from machine import Pin
|
from machine import Pin
|
||||||
from patterns import Patterns
|
from patterns import Patterns
|
||||||
|
from settings import Settings
|
||||||
import socket
|
import socket
|
||||||
import select
|
import select
|
||||||
import json
|
import json
|
||||||
|
import utime
|
||||||
|
import sys
|
||||||
|
|
||||||
class LEDServer:
|
class LEDServer:
|
||||||
SETTINGS_FILE = "/settings.json" # Path should be adjusted for MicroPython's filesystem
|
SETTINGS_FILE = "/settings.json" # Path should be adjusted for MicroPython's filesystem
|
||||||
|
|
||||||
def __init__(self, num_leds=50, pin=4, led_pin=8, brigtness=255):
|
def __init__(self, num_leds=50, pin=4, led_pin=8, brigtness=255):
|
||||||
# Initialize NeoPixel Patterns
|
# Initialize NeoPixel Patterns
|
||||||
self.num_leds = num_leds
|
self.settings = Settings()
|
||||||
self.patterns = Patterns(pin, num_leds)
|
|
||||||
self.selected_pattern = "blink"
|
|
||||||
self.color = (16, 16, 0)
|
|
||||||
self.color2 = (16, 16, 0)
|
|
||||||
self.delay = 100
|
|
||||||
|
|
||||||
|
print(self.settings)
|
||||||
|
self.patterns = Patterns(pin, num_leds)
|
||||||
|
self.patterns.select(self.settings["selected_pattern"])
|
||||||
|
self.patterns.set_color1(tuple(int(self.settings["color1"][i:i+2], 16) for i in (1, 5, 3)))
|
||||||
|
self.patterns.set_color2(tuple(int(self.settings["color2"][i:i+2], 16) for i in (1, 5, 3)))
|
||||||
# Initialize single LED
|
# Initialize single LED
|
||||||
self.led = Pin(led_pin, Pin.OUT)
|
self.led = Pin(led_pin, Pin.OUT)
|
||||||
|
|
||||||
|
@ -29,13 +32,7 @@ class LEDServer:
|
||||||
self.poll = select.poll()
|
self.poll = select.poll()
|
||||||
self.poll.register(self.server_socket, select.POLLIN)
|
self.poll.register(self.server_socket, select.POLLIN)
|
||||||
|
|
||||||
# Load settings from file
|
self.html = self.read_file("/index.html")
|
||||||
self.load_settings()
|
|
||||||
# Read static files
|
|
||||||
color = f'#{self.color[0]:02x}{self.color[1]:02x}{self.color[2]:02x}'
|
|
||||||
color2 = f'#{self.color2[0]:02x}{self.color2[1]:02x}{self.color2[2]:02x}'
|
|
||||||
print(color)
|
|
||||||
self.html = self.read_file("/index.html").format(num_leds=self.num_leds, delay=self.delay, color=color, color2=color2).encode()
|
|
||||||
self.js = self.read_file("/main.js").encode('utf-8')
|
self.js = self.read_file("/main.js").encode('utf-8')
|
||||||
self.css = self.read_file("/main.css").encode('utf-8')
|
self.css = self.read_file("/main.css").encode('utf-8')
|
||||||
self.patterns_json = json.dumps(list(self.patterns.patterns.keys()))
|
self.patterns_json = json.dumps(list(self.patterns.patterns.keys()))
|
||||||
|
@ -50,92 +47,88 @@ class LEDServer:
|
||||||
print(f"Error reading file {file_path}: {e}")
|
print(f"Error reading file {file_path}: {e}")
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def save_settings(self):
|
|
||||||
settings = {
|
|
||||||
"num_leds": self.num_leds,
|
|
||||||
"selected_pattern": self.selected_pattern,
|
|
||||||
"color": self.color,
|
|
||||||
"color2": self.color2,
|
|
||||||
"delay": self.delay
|
|
||||||
}
|
|
||||||
print(settings)
|
|
||||||
try:
|
|
||||||
with open(self.SETTINGS_FILE, 'w') as file:
|
|
||||||
json.dump(settings, file)
|
|
||||||
except OSError as e:
|
|
||||||
print(f"Error saving settings: {e}")
|
|
||||||
|
|
||||||
def load_settings(self):
|
|
||||||
if self.file_exists(self.SETTINGS_FILE):
|
|
||||||
try:
|
|
||||||
with open(self.SETTINGS_FILE, 'r') as file:
|
|
||||||
settings = json.load(file)
|
|
||||||
self.num_leds = settings.get("num_leds", self.num_leds)
|
|
||||||
self.selected_pattern = settings.get("selected_pattern", self.selected_pattern)
|
|
||||||
self.color = tuple(settings.get("color", self.color))
|
|
||||||
self.color2 = tuple(settings.get("color2", self.color2))
|
|
||||||
self.delay = settings.get("delay", self.delay)
|
|
||||||
self.patterns.update_num_leds(4, self.num_leds)
|
|
||||||
self.patterns.set_delay(self.delay)
|
|
||||||
self.patterns.selected = self.selected_pattern
|
|
||||||
except (OSError, ValueError) as e:
|
|
||||||
print(f"Error loading settings: {e}")
|
|
||||||
|
|
||||||
def file_exists(self, file_path):
|
|
||||||
try:
|
|
||||||
with open(file_path, 'r'):
|
|
||||||
return True
|
|
||||||
except OSError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def handle_post(self, path, post_data, client_socket):
|
def handle_post(self, path, post_data, client_socket):
|
||||||
print(post_data)
|
paths = {
|
||||||
if path == "/num_leds":
|
"/num_leds" : self.num_leds,
|
||||||
try:
|
"/pattern": self.pattern,
|
||||||
self.num_leds = int(post_data)
|
"/delay": self.delay,
|
||||||
self.patterns.update_num_leds(4, self.num_leds)
|
"/brightness": self.brightness,
|
||||||
self.save_settings()
|
"/color": self.color,
|
||||||
client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
|
"/color2": self.color2
|
||||||
except ValueError:
|
}
|
||||||
client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
|
|
||||||
|
|
||||||
elif path == "/pattern":
|
|
||||||
self.selected_pattern = post_data
|
|
||||||
self.patterns.selected = post_data
|
|
||||||
self.save_settings()
|
|
||||||
client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
|
|
||||||
|
|
||||||
elif path == "/delay":
|
|
||||||
try:
|
|
||||||
self.delay = int(post_data)
|
|
||||||
self.patterns.set_delay(self.delay)
|
|
||||||
self.save_settings()
|
|
||||||
client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
|
|
||||||
except ValueError:
|
|
||||||
client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
|
|
||||||
|
|
||||||
elif path == "/color":
|
|
||||||
# try:
|
|
||||||
self.patterns.set_color1(tuple(int(post_data[i:i+2], 16) for i in (1, 3, 5))) # Convert hex to RGB
|
|
||||||
self.save_settings()
|
|
||||||
client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
|
|
||||||
# except:
|
|
||||||
|
|
||||||
# client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
|
if path in paths:
|
||||||
elif path == "/color2":
|
paths[path](client_socket, post_data)
|
||||||
try:
|
|
||||||
self.patterns.set_color2(tuple(int(post_data[i:i+2], 16) for i in (1, 3, 5))) # Convert hex to RGB
|
|
||||||
self.save_settings()
|
|
||||||
client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
|
|
||||||
except:
|
|
||||||
client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
|
|
||||||
else:
|
else:
|
||||||
client_socket.send(b'HTTP/1.0 404 Not Found\r\nContent-Type: text/plain\r\n\r\n')
|
client_socket.send(b'HTTP/1.0 404 Not Found\r\nContent-Type: text/plain\r\n\r\n')
|
||||||
|
|
||||||
|
def num_leds(self, client_socket, post_data):
|
||||||
|
try:
|
||||||
|
num_leds = int(post_data)
|
||||||
|
self.patterns.update_num_leds(4,num_leds)
|
||||||
|
self.settings["num_leds"] = num_leds
|
||||||
|
self.settings.save()
|
||||||
|
client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
|
||||||
|
except ValueError:
|
||||||
|
client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
|
||||||
|
|
||||||
|
def pattern(self, client_socket, post_data):
|
||||||
|
if self.patterns.select(post_data):
|
||||||
|
self.settings["selected_pattern"] = post_data
|
||||||
|
self.settings.save()
|
||||||
|
client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
|
||||||
|
else:
|
||||||
|
client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
|
||||||
|
|
||||||
|
def delay(self, client_socket, post_data):
|
||||||
|
try:
|
||||||
|
delay = int(post_data)
|
||||||
|
self.patterns.set_delay(delay)
|
||||||
|
self.settings["delay"] = delay
|
||||||
|
self.settings.save()
|
||||||
|
client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
|
||||||
|
except ValueError:
|
||||||
|
client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
|
||||||
|
|
||||||
|
def brightness(self, client_socket, post_data):
|
||||||
|
try:
|
||||||
|
brightness = int(post_data)
|
||||||
|
self.patterns.set_brightness(brightness)
|
||||||
|
self.settings["brightness"] = brightness
|
||||||
|
self.settings.save()
|
||||||
|
client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
|
||||||
|
except ValueError:
|
||||||
|
client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
|
||||||
|
|
||||||
|
def color(self, client_socket, post_data):
|
||||||
|
try:
|
||||||
|
self.patterns.set_color1(tuple(int(post_data[i:i+2], 16) for i in (1, 5, 3))) # Convert hex to RGB
|
||||||
|
self.settings["color1"] = post_data
|
||||||
|
self.settings.save()
|
||||||
|
client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
|
||||||
|
except:
|
||||||
|
client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
|
||||||
|
|
||||||
|
def color2(self, client_socket, post_data):
|
||||||
|
try:
|
||||||
|
self.patterns.set_color2(tuple(int(post_data[i:i+2], 16) for i in (1, 5, 3))) # Convert hex to RGB
|
||||||
|
self.settings["color2"] = post_data
|
||||||
|
self.settings.save()
|
||||||
|
client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
|
||||||
|
except:
|
||||||
|
client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
|
||||||
|
|
||||||
def handle_get(self, path, client_socket):
|
def handle_get(self, path, client_socket):
|
||||||
if path == "/":
|
if path == "/":
|
||||||
client_socket.send(b'HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
|
client_socket.send(b'HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
|
||||||
client_socket.send(self.html)
|
client_socket.send(self.html.format(
|
||||||
|
num_leds=self.settings["num_leds"],
|
||||||
|
delay=self.settings["delay"],
|
||||||
|
brightness=self.settings["brightness"],
|
||||||
|
color=self.settings["color1"],
|
||||||
|
color2=self.settings["color2"],
|
||||||
|
ssid=self.settings["wifi"]["ssid"]).encode())
|
||||||
elif path == "/main.js":
|
elif path == "/main.js":
|
||||||
client_socket.send(b'HTTP/1.0 200 OK\r\nContent-type: application/javascript\r\n\r\n')
|
client_socket.send(b'HTTP/1.0 200 OK\r\nContent-type: application/javascript\r\n\r\n')
|
||||||
client_socket.send(self.js)
|
client_socket.send(self.js)
|
||||||
|
@ -150,6 +143,8 @@ class LEDServer:
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
count = 0
|
count = 0
|
||||||
|
average_time = 0
|
||||||
|
previous_time = utime.ticks_us()
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
count += 1
|
count += 1
|
||||||
|
@ -169,17 +164,18 @@ class LEDServer:
|
||||||
|
|
||||||
if count > 50:
|
if count > 50:
|
||||||
self.led.off()
|
self.led.off()
|
||||||
|
#print(utime.ticks_us() - previous_time)
|
||||||
if count > 100:
|
if count > 100:
|
||||||
self.led.on()
|
self.led.on()
|
||||||
count = 0
|
count = 0
|
||||||
|
# previous_time = utime.ticks_us()
|
||||||
self.patterns.tick()
|
self.patterns.tick()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("Error:", e)
|
print("Error:", e)
|
||||||
|
sys.print_exception(e)
|
||||||
finally:
|
finally:
|
||||||
self.server_socket.close()
|
self.server_socket.close()
|
||||||
self.save_settings()
|
|
||||||
|
|
||||||
# Example of creating and starting the server
|
# Example of creating and starting the server
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
33
patterns.py
33
patterns.py
|
@ -12,6 +12,8 @@ class Patterns:
|
||||||
self.delay = delay
|
self.delay = delay
|
||||||
self.brightness = brightness
|
self.brightness = brightness
|
||||||
self.patterns = {
|
self.patterns = {
|
||||||
|
"off": self.off,
|
||||||
|
"on" : self.on,
|
||||||
"color_wipe": self.color_wipe_step,
|
"color_wipe": self.color_wipe_step,
|
||||||
"rainbow_cycle": self.rainbow_cycle_step,
|
"rainbow_cycle": self.rainbow_cycle_step,
|
||||||
"theater_chase": self.theater_chase_step,
|
"theater_chase": self.theater_chase_step,
|
||||||
|
@ -25,7 +27,7 @@ class Patterns:
|
||||||
self.selected = selected
|
self.selected = selected
|
||||||
self.color1 = color1
|
self.color1 = color1
|
||||||
self.color2 = color2
|
self.color2 = color2
|
||||||
self.transition_duration = 5000 # Duration of color transition in milliseconds
|
self.transition_duration = 50 # Duration of color transition in milliseconds
|
||||||
self.transition_step = 0
|
self.transition_step = 0
|
||||||
|
|
||||||
def tick(self):
|
def tick(self):
|
||||||
|
@ -52,11 +54,30 @@ class Patterns:
|
||||||
def apply_brightness(self, color):
|
def apply_brightness(self, color):
|
||||||
return tuple(int(c * self.brightness / 255) for c in 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 fill(self):
|
def fill(self):
|
||||||
for i in range(self.num_leds):
|
for i in range(self.num_leds):
|
||||||
self.n[i] = self.color1
|
self.n[i] = self.color1
|
||||||
self.n.write()
|
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):
|
def color_wipe_step(self):
|
||||||
color = self.apply_brightness(self.color1)
|
color = self.apply_brightness(self.color1)
|
||||||
current_time = utime.ticks_ms()
|
current_time = utime.ticks_ms()
|
||||||
|
@ -64,7 +85,7 @@ class Patterns:
|
||||||
if self.pattern_step < self.num_leds:
|
if self.pattern_step < self.num_leds:
|
||||||
for i in range(self.num_leds):
|
for i in range(self.num_leds):
|
||||||
self.n[i] = (0, 0, 0)
|
self.n[i] = (0, 0, 0)
|
||||||
self.n[self.pattern_step] = color
|
self.n[self.pattern_step] = self.apply_brightness(color)
|
||||||
self.n.write()
|
self.n.write()
|
||||||
self.pattern_step += 1
|
self.pattern_step += 1
|
||||||
else:
|
else:
|
||||||
|
@ -96,7 +117,7 @@ class Patterns:
|
||||||
if utime.ticks_diff(current_time, self.last_update) >= self.delay:
|
if utime.ticks_diff(current_time, self.last_update) >= self.delay:
|
||||||
for i in range(self.num_leds):
|
for i in range(self.num_leds):
|
||||||
if (i + self.pattern_step) % 3 == 0:
|
if (i + self.pattern_step) % 3 == 0:
|
||||||
self.n[i] = self.color1
|
self.n[i] = self.apply_brightness(self.color1)
|
||||||
else:
|
else:
|
||||||
self.n[i] = (0, 0, 0)
|
self.n[i] = (0, 0, 0)
|
||||||
self.n.write()
|
self.n.write()
|
||||||
|
@ -108,7 +129,7 @@ class Patterns:
|
||||||
if utime.ticks_diff(current_time, self.last_update) >= self.delay:
|
if utime.ticks_diff(current_time, self.last_update) >= self.delay:
|
||||||
if self.pattern_step % 2 == 0:
|
if self.pattern_step % 2 == 0:
|
||||||
for i in range(self.num_leds):
|
for i in range(self.num_leds):
|
||||||
self.n[i] = self.color1
|
self.n[i] = self.apply_brightness(self.color1)
|
||||||
else:
|
else:
|
||||||
for i in range(self.num_leds):
|
for i in range(self.num_leds):
|
||||||
self.n[i] = (0, 0, 0)
|
self.n[i] = (0, 0, 0)
|
||||||
|
@ -209,11 +230,13 @@ if __name__ == "__main__":
|
||||||
p = Patterns(4, 180)
|
p = Patterns(4, 180)
|
||||||
p.set_color1((255,0,0))
|
p.set_color1((255,0,0))
|
||||||
p.set_color2((0,255,0))
|
p.set_color2((0,255,0))
|
||||||
|
#p.set_delay(10)
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
for key in p.patterns:
|
for key in p.patterns:
|
||||||
print(key)
|
print(key)
|
||||||
for _ in range(1000):
|
p.select(key)
|
||||||
|
for _ in range(2000):
|
||||||
p.tick()
|
p.tick()
|
||||||
utime.sleep_ms(1)
|
utime.sleep_ms(1)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import uasyncio as asyncio
|
||||||
|
|
||||||
|
class Settings(dict):
|
||||||
|
SETTINGS_FILE = "/settings.json"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.load() # Load settings from file during initialization
|
||||||
|
|
||||||
|
def set_defaults(self):
|
||||||
|
self["num_leds"] = 50
|
||||||
|
self["selected_pattern"] = "blink"
|
||||||
|
self["color1"] = "#000f00"
|
||||||
|
self["color2"] = "#0f0000"
|
||||||
|
self["delay"] = 100
|
||||||
|
self["brightness"] = 100
|
||||||
|
self["wifi"] = {"ssid": "", "password": ""}
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
try:
|
||||||
|
j = json.dumps(self)
|
||||||
|
with open(self.SETTINGS_FILE, 'w') as file:
|
||||||
|
file.write(j)
|
||||||
|
print("Settings saved successfully.")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error saving settings: {e}")
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
try:
|
||||||
|
with open(self.SETTINGS_FILE, 'r') as file:
|
||||||
|
loaded_settings = json.load(file)
|
||||||
|
self.update(loaded_settings)
|
||||||
|
print("Settings loaded successfully.")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error loading settings: {e}")
|
||||||
|
self.set_defaults()
|
||||||
|
|
||||||
|
# Example usage
|
||||||
|
def main():
|
||||||
|
settings = Settings()
|
||||||
|
print(f"Number of LEDs: {settings['num_leds']}")
|
||||||
|
settings['num_leds'] = 100
|
||||||
|
print(f"Updated number of LEDs: {settings['num_leds']}")
|
||||||
|
settings.save()
|
||||||
|
|
||||||
|
# Create a new Settings object to test loading
|
||||||
|
new_settings = Settings()
|
||||||
|
print(f"Loaded number of LEDs: {new_settings['num_leds']}")
|
||||||
|
print(settings)
|
||||||
|
|
||||||
|
# Run the example
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue