Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
jimmy | 7028c60ea5 |
|
@ -0,0 +1,321 @@
|
||||||
|
/*
|
||||||
|
WS2812FX Webinterface.
|
||||||
|
|
||||||
|
Harm Aldick - 2016
|
||||||
|
www.aldick.org
|
||||||
|
|
||||||
|
|
||||||
|
FEATURES
|
||||||
|
* Webinterface with mode, color, speed and brightness selectors
|
||||||
|
|
||||||
|
|
||||||
|
LICENSE
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Harm Aldick
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
CHANGELOG
|
||||||
|
2016-11-26 initial version
|
||||||
|
2018-01-06 added custom effects list option and auto-cycle feature
|
||||||
|
|
||||||
|
*/
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <WebServer.h>
|
||||||
|
#define WEB_SERVER WebServer
|
||||||
|
#define ESP_RESET ESP.restart()
|
||||||
|
#else
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESP8266WebServer.h>
|
||||||
|
#define WEB_SERVER ESP8266WebServer
|
||||||
|
#define ESP_RESET ESP.reset()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <WS2812FX.h>
|
||||||
|
#include <ArtnetWifi.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//IPAddress ip(192,168,1,200);
|
||||||
|
//IPAddress gateway(192,168,1,1);
|
||||||
|
//IPAddress subnet(255,255,255,0);
|
||||||
|
|
||||||
|
extern const char index_html[];
|
||||||
|
extern const char main_js[];
|
||||||
|
|
||||||
|
#define WIFI_SSID "XCHC2"
|
||||||
|
#define WIFI_PASSWORD "workspace"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// QUICKFIX...See https://github.com/esp8266/Arduino/issues/263
|
||||||
|
#define min(a,b) ((a)<(b)?(a):(b))
|
||||||
|
#define max(a,b) ((a)>(b)?(a):(b))
|
||||||
|
|
||||||
|
#define LED_PIN 2 // 0 = GPIO0, 2=GPIO2
|
||||||
|
#define LED_COUNT 100
|
||||||
|
|
||||||
|
#define WIFI_TIMEOUT 30000 // checks WiFi every ...ms. Reset after this time, if WiFi cannot reconnect.
|
||||||
|
#define HTTP_PORT 80
|
||||||
|
|
||||||
|
unsigned long auto_last_change = 0;
|
||||||
|
unsigned long last_wifi_check_time = 0;
|
||||||
|
String modes = "";
|
||||||
|
uint8_t myModes[] = {}; // *** optionally create a custom list of effect/mode numbers
|
||||||
|
bool auto_cycle = false;
|
||||||
|
|
||||||
|
WiFiUDP UdpSend;
|
||||||
|
ArtnetWifi artnet;
|
||||||
|
|
||||||
|
WS2812FX ws2812fx = WS2812FX(LED_COUNT, LED_PIN, NEO_BRG + NEO_KHZ800);
|
||||||
|
WEB_SERVER server(HTTP_PORT);
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
Serial.begin(115200);
|
||||||
|
delay(500);
|
||||||
|
Serial.println("\n\nStarting...");
|
||||||
|
|
||||||
|
modes.reserve(5000);
|
||||||
|
modes_setup();
|
||||||
|
|
||||||
|
Serial.println("WS2812FX setup");
|
||||||
|
ws2812fx.init();
|
||||||
|
ws2812fx.setMode(FX_MODE_STATIC);
|
||||||
|
ws2812fx.setColor(0xFF5900);
|
||||||
|
ws2812fx.setSpeed(1000);
|
||||||
|
ws2812fx.setBrightness(128);
|
||||||
|
ws2812fx.start();
|
||||||
|
|
||||||
|
Serial.println("Wifi setup");
|
||||||
|
wifi_setup();
|
||||||
|
|
||||||
|
Serial.println("HTTP server setup");
|
||||||
|
server.on("/", srv_handle_index_html);
|
||||||
|
server.on("/main.js", srv_handle_main_js);
|
||||||
|
server.on("/modes", srv_handle_modes);
|
||||||
|
server.on("/set", srv_handle_set);
|
||||||
|
server.onNotFound(srv_handle_not_found);
|
||||||
|
server.begin();
|
||||||
|
Serial.println("HTTP server started.");
|
||||||
|
|
||||||
|
// this will be called for each packet received
|
||||||
|
artnet.setArtDmxCallback(onDmxFrame);
|
||||||
|
artnet.begin();
|
||||||
|
|
||||||
|
Serial.println("ready!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
unsigned long now = millis();
|
||||||
|
|
||||||
|
server.handleClient();
|
||||||
|
ws2812fx.service();
|
||||||
|
|
||||||
|
// if(now - last_wifi_check_time > WIFI_TIMEOUT) {
|
||||||
|
// Serial.print("Checking WiFi... ");
|
||||||
|
// if(WiFi.status() != WL_CONNECTED) {
|
||||||
|
// Serial.println("WiFi connection lost. Reconnecting...");
|
||||||
|
// wifi_setup();
|
||||||
|
// } else {
|
||||||
|
// Serial.println("OK");
|
||||||
|
// }
|
||||||
|
// last_wifi_check_time = now;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if(auto_cycle && (now - auto_last_change > 10000)) { // cycle effect mode every 10 seconds
|
||||||
|
uint8_t next_mode = (ws2812fx.getMode() + 1) % ws2812fx.getModeCount();
|
||||||
|
if(sizeof(myModes) > 0) { // if custom list of modes exists
|
||||||
|
for(uint8_t i=0; i < sizeof(myModes); i++) {
|
||||||
|
if(myModes[i] == ws2812fx.getMode()) {
|
||||||
|
next_mode = ((i + 1) < sizeof(myModes)) ? myModes[i + 1] : myModes[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ws2812fx.setMode(next_mode);
|
||||||
|
Serial.print("mode is "); Serial.println(ws2812fx.getModeName(ws2812fx.getMode()));
|
||||||
|
auto_last_change = now;
|
||||||
|
}
|
||||||
|
//artnet.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data)
|
||||||
|
{
|
||||||
|
bool tail = false;
|
||||||
|
|
||||||
|
Serial.print("DMX: Univ: ");
|
||||||
|
Serial.print(universe, DEC);
|
||||||
|
Serial.print(", Seq: ");
|
||||||
|
Serial.print(sequence, DEC);
|
||||||
|
Serial.print(", Data (");
|
||||||
|
Serial.print(length, DEC);
|
||||||
|
Serial.print("): ");
|
||||||
|
|
||||||
|
if (length > 16) {
|
||||||
|
length = 16;
|
||||||
|
tail = true;
|
||||||
|
}
|
||||||
|
// send out the buffer
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
Serial.print(data[i], HEX);
|
||||||
|
Serial.print(" ");
|
||||||
|
}
|
||||||
|
if (tail) {
|
||||||
|
Serial.print("...");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connect to WiFi. If no connection is made within WIFI_TIMEOUT, ESP gets resettet.
|
||||||
|
*/
|
||||||
|
void wifi_setup() {
|
||||||
|
char APssid[50] = "LED_";
|
||||||
|
char id[8];
|
||||||
|
itoa(ESP.getChipId(), id, 16);
|
||||||
|
strcat(APssid, id);
|
||||||
|
Serial.println(APssid);
|
||||||
|
const char* APpassword = "1234567890";
|
||||||
|
Serial.println();
|
||||||
|
Serial.print("Connecting to ");
|
||||||
|
Serial.println(WIFI_SSID);
|
||||||
|
|
||||||
|
WiFi.softAP(APssid, APpassword);
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.begin();
|
||||||
|
|
||||||
|
//WiFi.config(ip, gateway, subnet);
|
||||||
|
//
|
||||||
|
// unsigned long connect_start = millis();
|
||||||
|
// while(WiFi.status() != WL_CONNECTED) {
|
||||||
|
// delay(500);
|
||||||
|
// Serial.print(".");
|
||||||
|
//
|
||||||
|
// if(millis() - connect_start > WIFI_TIMEOUT) {
|
||||||
|
// Serial.println();
|
||||||
|
// Serial.print("Tried ");
|
||||||
|
// Serial.print(WIFI_TIMEOUT);
|
||||||
|
// Serial.print("ms. Resetting ESP now.");
|
||||||
|
// ESP_RESET;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
Serial.println("");
|
||||||
|
Serial.println("WiFi connected");
|
||||||
|
Serial.print("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
Serial.println(WiFi.softAPIP());
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build <li> string for all modes.
|
||||||
|
*/
|
||||||
|
void modes_setup() {
|
||||||
|
modes = "";
|
||||||
|
uint8_t num_modes = sizeof(myModes) > 0 ? sizeof(myModes) : ws2812fx.getModeCount();
|
||||||
|
for(uint8_t i=0; i < num_modes; i++) {
|
||||||
|
uint8_t m = sizeof(myModes) > 0 ? myModes[i] : i;
|
||||||
|
modes += "<li><a href='#'>";
|
||||||
|
modes += ws2812fx.getModeName(m);
|
||||||
|
modes += "</a></li>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #####################################################
|
||||||
|
# Webserver Functions
|
||||||
|
##################################################### */
|
||||||
|
|
||||||
|
void srv_handle_not_found() {
|
||||||
|
server.send(404, "text/plain", "File Not Found");
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_handle_index_html() {
|
||||||
|
server.send_P(200,"text/html", index_html);
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_handle_main_js() {
|
||||||
|
server.send_P(200,"application/javascript", main_js);
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_handle_modes() {
|
||||||
|
server.send(200,"text/plain", modes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv_handle_set() {
|
||||||
|
for (uint8_t i=0; i < server.args(); i++){
|
||||||
|
if(server.argName(i) == "c") {
|
||||||
|
uint32_t tmp = (uint32_t) strtol(server.arg(i).c_str(), NULL, 10);
|
||||||
|
if(tmp <= 0xFFFFFF) {
|
||||||
|
ws2812fx.setColor(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(server.argName(i) == "m") {
|
||||||
|
uint8_t tmp = (uint8_t) strtol(server.arg(i).c_str(), NULL, 10);
|
||||||
|
uint8_t new_mode = sizeof(myModes) > 0 ? myModes[tmp % sizeof(myModes)] : tmp % ws2812fx.getModeCount();
|
||||||
|
ws2812fx.setMode(new_mode);
|
||||||
|
auto_cycle = false;
|
||||||
|
Serial.print("mode is "); Serial.println(ws2812fx.getModeName(ws2812fx.getMode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(server.argName(i) == "b") {
|
||||||
|
if(server.arg(i)[0] == '-') {
|
||||||
|
ws2812fx.setBrightness(ws2812fx.getBrightness() * 0.8);
|
||||||
|
} else if(server.arg(i)[0] == ' ') {
|
||||||
|
ws2812fx.setBrightness(min(max(ws2812fx.getBrightness(), 5) * 1.2, 255));
|
||||||
|
} else { // set brightness directly
|
||||||
|
uint8_t tmp = (uint8_t) strtol(server.arg(i).c_str(), NULL, 10);
|
||||||
|
ws2812fx.setBrightness(tmp);
|
||||||
|
}
|
||||||
|
Serial.print("brightness is "); Serial.println(ws2812fx.getBrightness());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(server.argName(i) == "s") {
|
||||||
|
if(server.arg(i)[0] == '-') {
|
||||||
|
ws2812fx.setSpeed(max(ws2812fx.getSpeed(), 5) * 1.2);
|
||||||
|
} else if(server.arg(i)[0] == ' ') {
|
||||||
|
ws2812fx.setSpeed(ws2812fx.getSpeed() * 0.8);
|
||||||
|
} else {
|
||||||
|
uint16_t tmp = (uint16_t) strtol(server.arg(i).c_str(), NULL, 10);
|
||||||
|
ws2812fx.setSpeed(tmp);
|
||||||
|
}
|
||||||
|
Serial.print("speed is "); Serial.println(ws2812fx.getSpeed());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(server.argName(i) == "a") {
|
||||||
|
if(server.arg(i)[0] == '-') {
|
||||||
|
auto_cycle = false;
|
||||||
|
} else {
|
||||||
|
auto_cycle = true;
|
||||||
|
auto_last_change = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server.send(200, "text/plain", "OK");
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
#include <pgmspace.h>
|
||||||
|
char index_html[] PROGMEM = R"=====(
|
||||||
|
<!doctype html>
|
||||||
|
<html lang='en' dir='ltr'>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
|
||||||
|
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
|
||||||
|
<title>WS2812FX Control</title>
|
||||||
|
<script type='text/javascript' src='main.js'></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family:Arial,sans-serif;
|
||||||
|
margin:10px;
|
||||||
|
padding:0;
|
||||||
|
background-color:#202020;
|
||||||
|
color:#909090;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-row {
|
||||||
|
display:flex;
|
||||||
|
flex-direction:row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-row-wrap {
|
||||||
|
display:flex;
|
||||||
|
flex-direction:row;
|
||||||
|
flex-wrap:wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-col {
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
align-items:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='text'] {
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
color:#404040;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li a {
|
||||||
|
display:block;
|
||||||
|
margin:3px;
|
||||||
|
padding:10px;
|
||||||
|
border:2px solid #404040;
|
||||||
|
border-radius:5px;
|
||||||
|
color:#909090;
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#modes li a {
|
||||||
|
min-width:220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.control li a {
|
||||||
|
min-width:60px;
|
||||||
|
min-height:24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.control {
|
||||||
|
display:flex;
|
||||||
|
flex-direction:row;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li a.active {
|
||||||
|
border:2px solid #909090;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>WS2812FX Control</h1>
|
||||||
|
<div class='flex-row'>
|
||||||
|
|
||||||
|
<div class='flex-col'>
|
||||||
|
<div><canvas id='color-canvas' width='360' height='360'></canvas><br/></div>
|
||||||
|
<div><input type='text' id='color-value' oninput='onColor(event, this.value)'/></div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul class='control'>
|
||||||
|
<li>Brightness:</li>
|
||||||
|
<li><a href='#' onclick="onBrightness(event, '-')">☼</a></li>
|
||||||
|
<li><a href='#' onclick="onBrightness(event, '+')">☀</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class='control'>
|
||||||
|
<li>Speed:</li>
|
||||||
|
<li><a href='#' onclick="onSpeed(event, '-')">−</a></li>
|
||||||
|
<li><a href='#' onclick="onSpeed(event, '+')">+</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class='control'>
|
||||||
|
<li>Auto cycle:</li>
|
||||||
|
<li><a href='#' onclick="onAuto(event, '-')">■</a></li>
|
||||||
|
<li><a href='#' onclick="onAuto(event, '+')">►</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul id='modes' class='flex-row-wrap'>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
)=====";
|
|
@ -0,0 +1,110 @@
|
||||||
|
#include <pgmspace.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
The tiny Javascript/canvas based color picker is based on the clever work of the folks
|
||||||
|
at Sparkbox. https://seesparkbox.com/foundry/how_i_built_a_canvas_color_picker
|
||||||
|
*/
|
||||||
|
|
||||||
|
char main_js[] PROGMEM = R"=====(
|
||||||
|
|
||||||
|
var activeButton = null;
|
||||||
|
var colorCanvas = null;
|
||||||
|
|
||||||
|
window.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
// init the canvas color picker
|
||||||
|
colorCanvas = document.getElementById('color-canvas');
|
||||||
|
var colorctx = colorCanvas.getContext('2d');
|
||||||
|
|
||||||
|
// Create color gradient
|
||||||
|
var gradient = colorctx.createLinearGradient(0, 0, colorCanvas.width - 1, 0);
|
||||||
|
gradient.addColorStop(0, "rgb(255, 0, 0)");
|
||||||
|
gradient.addColorStop(0.16, "rgb(255, 0, 255)");
|
||||||
|
gradient.addColorStop(0.33, "rgb(0, 0, 255)");
|
||||||
|
gradient.addColorStop(0.49, "rgb(0, 255, 255)");
|
||||||
|
gradient.addColorStop(0.66, "rgb(0, 255, 0)");
|
||||||
|
gradient.addColorStop(0.82, "rgb(255, 255, 0)");
|
||||||
|
gradient.addColorStop(1, "rgb(255, 0, 0)");
|
||||||
|
|
||||||
|
// Apply gradient to canvas
|
||||||
|
colorctx.fillStyle = gradient;
|
||||||
|
colorctx.fillRect(0, 0, colorCanvas.width - 1, colorCanvas.height - 1);
|
||||||
|
|
||||||
|
// Create semi transparent gradient (white -> transparent -> black)
|
||||||
|
gradient = colorctx.createLinearGradient(0, 0, 0, colorCanvas.height - 1);
|
||||||
|
gradient.addColorStop(0, "rgba(255, 255, 255, 1)");
|
||||||
|
gradient.addColorStop(0.48, "rgba(255, 255, 255, 0)");
|
||||||
|
gradient.addColorStop(0.52, "rgba(0, 0, 0, 0)");
|
||||||
|
gradient.addColorStop(1, "rgba(0, 0, 0, 1)");
|
||||||
|
|
||||||
|
// Apply gradient to canvas
|
||||||
|
colorctx.fillStyle = gradient;
|
||||||
|
colorctx.fillRect(0, 0, colorCanvas.width - 1, colorCanvas.height - 1);
|
||||||
|
|
||||||
|
// setup the canvas click listener
|
||||||
|
colorCanvas.addEventListener('click', (event) => {
|
||||||
|
var imageData = colorCanvas.getContext('2d').getImageData(event.offsetX, event.offsetY, 1, 1);
|
||||||
|
|
||||||
|
var selectedColor = 'rgb(' + imageData.data[0] + ',' + imageData.data[1] + ',' + imageData.data[2] + ')';
|
||||||
|
//console.log('click: ' + event.offsetX + ', ' + event.offsetY + ', ' + selectedColor);
|
||||||
|
document.getElementById('color-value').value = selectedColor;
|
||||||
|
|
||||||
|
selectedColor = imageData.data[0] * 65536 + imageData.data[1] * 256 + imageData.data[2];
|
||||||
|
submitVal('c', selectedColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
// get list of modes from ESP
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.onreadystatechange = function() {
|
||||||
|
if (xhttp.readyState == 4 && xhttp.status == 200) {
|
||||||
|
document.getElementById('modes').innerHTML = xhttp.responseText;
|
||||||
|
modes = document.querySelectorAll('ul#modes li a');
|
||||||
|
modes.forEach(initMode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhttp.open('GET', 'modes', true);
|
||||||
|
xhttp.send();
|
||||||
|
});
|
||||||
|
|
||||||
|
function initMode(mode, index) {
|
||||||
|
mode.addEventListener('click', (event) => onMode(event, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
function onColor(event, color) {
|
||||||
|
event.preventDefault();
|
||||||
|
var match = color.match(/rgb\(([0-9]*),([0-9]*),([0-9]*)\)/);
|
||||||
|
if(match) {
|
||||||
|
var colorValue = Number(match[1]) * 65536 + Number(match[2]) * 256 + Number(match[3]);
|
||||||
|
//console.log('onColor:' + match[1] + "," + match[2] + "," + match[3] + "," + colorValue);
|
||||||
|
submitVal('c', colorValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMode(event, mode) {
|
||||||
|
event.preventDefault();
|
||||||
|
if(activeButton) activeButton.classList.remove('active')
|
||||||
|
activeButton = event.target;
|
||||||
|
activeButton.classList.add('active');
|
||||||
|
submitVal('m', mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBrightness(event, dir) {
|
||||||
|
event.preventDefault();
|
||||||
|
submitVal('b', dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSpeed(event, dir) {
|
||||||
|
event.preventDefault();
|
||||||
|
submitVal('s', dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAuto(event, dir) {
|
||||||
|
event.preventDefault();
|
||||||
|
submitVal('a', dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitVal(name, val) {
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.open('GET', 'set?' + name + '=' + val, true);
|
||||||
|
xhttp.send();
|
||||||
|
}
|
||||||
|
)=====";
|
Loading…
Reference in New Issue