From df43aba37bda2c1080c9973c6abb69f1337b91cc Mon Sep 17 00:00:00 2001 From: bpohvoodoo Date: Sun, 6 Oct 2019 15:38:57 +0200 Subject: [PATCH] 3.1.0.ALPHA3 * further code changes * further integration of multi segments * known problem: as always: AUTOPLAY (as it is not multi segment capable yet) --- Arduino/McLighting/McLighting.ino | 108 +++--- Arduino/McLighting/data/index.htm | 337 ++++++++++-------- Arduino/McLighting/definitions.h | 31 +- Arduino/McLighting/filesystem_functions.h | 22 +- Arduino/McLighting/helper_functions.h | 134 +++---- Arduino/McLighting/json_functions.h | 92 ++--- .../mode_custom_ws2812fx_animations.h | 320 ++++++++--------- Arduino/McLighting/request_handlers.h | 193 +++++----- Arduino/McLighting/rest_api.h | 139 +++++--- 9 files changed, 736 insertions(+), 640 deletions(-) diff --git a/Arduino/McLighting/McLighting.ino b/Arduino/McLighting/McLighting.ino index 644b281..7cb7dac 100644 --- a/Arduino/McLighting/McLighting.ino +++ b/Arduino/McLighting/McLighting.ino @@ -359,27 +359,27 @@ void setup() { (readConfigFS()) ? DBG_OUTPUT_PORT.println("WiFiManager config FS read success!"): DBG_OUTPUT_PORT.println("WiFiManager config FS Read failure!"); delay(250); (readStateFS()) ? DBG_OUTPUT_PORT.println("Strip state config FS read Success!") : DBG_OUTPUT_PORT.println("Strip state config FS read failure!"); - char tmp_strip_size[6], tmp_fxoptions[5], tmp_rgbOrder[5]; //needed tempararily for WiFiManager Settings + char _stripSize[6], _fx_options[5], _rgbOrder[5]; //needed tempararily for WiFiManager Settings WiFiManagerParameter custom_hostname("hostname", "Hostname", HOSTNAME, 64, " maxlength=64"); #if defined(ENABLE_MQTT) - char tmp_mqtt_port[6]; //needed tempararily for WiFiManager Settings + char _mqtt_port[6]; //needed tempararily for WiFiManager Settings WiFiManagerParameter custom_mqtt_host("host", "MQTT hostname", mqtt_host, 64, " maxlength=64"); - sprintf(tmp_mqtt_port, "%d", mqtt_port); - WiFiManagerParameter custom_mqtt_port("port", "MQTT port", tmp_mqtt_port, 5, " maxlength=5 type=\"number\""); + sprintf(_mqtt_port, "%d", mqtt_port); + WiFiManagerParameter custom_mqtt_port("port", "MQTT port", _mqtt_port, 5, " maxlength=5 type=\"number\""); WiFiManagerParameter custom_mqtt_user("user", "MQTT user", mqtt_user, 32, " maxlength=32"); WiFiManagerParameter custom_mqtt_pass("pass", "MQTT pass", mqtt_pass, 32, " maxlength=32 type=\"password\""); #endif - sprintf(tmp_strip_size, "%d", WS2812FXStripSettings.stripSize); - WiFiManagerParameter custom_strip_size("strip_size", "Number of LEDs", tmp_strip_size, 4, " maxlength=4 type=\"number\""); + sprintf(_stripSize, "%d", FXSettings.stripSize); + WiFiManagerParameter custom_strip_size("strip_size", "Number of LEDs", _stripSize, 4, " maxlength=4 type=\"number\""); #if !defined(USE_WS2812FX_DMA) char tmp_led_pin[3]; - sprintf(tmp_led_pin, "%d", WS2812FXStripSettings.pin); + sprintf(tmp_led_pin, "%d", FXSettings.pin); WiFiManagerParameter custom_led_pin("led_pin", "LED GPIO", tmp_led_pin, 2, " maxlength=2 type=\"number\""); #endif - sprintf(tmp_rgbOrder, "%s", WS2812FXStripSettings.RGBOrder); - WiFiManagerParameter custom_rgbOrder("rgbOrder", "RGBOrder", tmp_rgbOrder, 4, " maxlength=4"); - sprintf(tmp_fxoptions, "%d", WS2812FXStripSettings.fxoptions); - WiFiManagerParameter custom_fxoptions("fxoptions", "fxOptions", tmp_fxoptions, 3, " maxlength=3"); + sprintf(_rgbOrder, "%s", FXSettings.RGBOrder); + WiFiManagerParameter custom_rgbOrder("rgbOrder", "RGBOrder", _rgbOrder, 4, " maxlength=4"); + sprintf(_fx_options, "%d", fx_options); + WiFiManagerParameter custom_fxoptions("fxoptions", "fxOptions", _fx_options, 3, " maxlength=3"); #endif @@ -443,14 +443,14 @@ void setup() { strcpy(mqtt_user, custom_mqtt_user.getValue()); strcpy(mqtt_pass, custom_mqtt_pass.getValue()); #endif - strcpy(tmp_strip_size, custom_strip_size.getValue()); - WS2812FXStripSettings.stripSize = constrain(atoi(custom_strip_size.getValue()), 1, MAXLEDS); + strcpy(_stripSize, custom_strip_size.getValue()); + FXSettings.stripSize = constrain(atoi(custom_strip_size.getValue()), 1, MAXLEDS); #if !defined(USE_WS2812FX_DMA) checkPin(atoi(custom_led_pin.getValue())); #endif - strcpy(tmp_rgbOrder, custom_rgbOrder.getValue()); - checkRGBOrder(tmp_rgbOrder); - WS2812FXStripSettings.fxoptions = atoi(custom_fxoptions.getValue()); + strcpy(_rgbOrder, custom_rgbOrder.getValue()); + checkRGBOrder(_rgbOrder); + fx_options = atoi(custom_fxoptions.getValue()); if (updateConfig) { (writeConfigFS(updateConfig)) ? DBG_OUTPUT_PORT.println("WiFiManager config FS Save success!"): DBG_OUTPUT_PORT.println("WiFiManager config FS Save failure!"); } @@ -561,7 +561,7 @@ void setup() { #if defined(ENABLE_REMOTE) irrecv.enableIRIn(); // Start the receiver #endif - ws2812fx_speed_actual = ws2812fx_speed; + fx_speed_actual = fx_speed; brightness_trans = brightness; memcpy(hex_colors, hex_colors_trans, sizeof(hex_colors_trans)); initStrip(); @@ -625,7 +625,7 @@ void loop() { // Simple statemachine that handles the different modes // *************************************************************************** - if ((mode == OFF) && ((strip->getBrightness() == 0) || !transEffect)) { + if ((mode == OFF) && ((strip->getBrightness() == 0) || !FXSettings.transEffect)) { if(strip->isRunning()) { strip->strip_off(); // Workaround: to be shure, delay(10); // that strip is really off. Sometimes strip->stop isn't enought @@ -649,7 +649,7 @@ void loop() { #if defined(ENABLE_MQTT) snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =off", ""); #endif - if (transEffect) { + if (FXSettings.transEffect) { brightness_trans = 0; } } @@ -658,21 +658,21 @@ void loop() { if (mode == SET) { mode = HOLD; // Segment - if (prevsegment != segment) { + if (prevsegment != FXSettings.segment) { #if defined(ENABLE_MQTT) - snprintf(mqtt_buf, sizeof(mqtt_buf), "OK S%i", segment); + snprintf(mqtt_buf, sizeof(mqtt_buf), "OK Ss%i", FXSettings.segment); #endif - prevsegment = segment; + prevsegment = FXSettings.segment; } // Mode - if (ws2812fx_mode != strip->getMode(segment)) { + if (fx_mode != strip->getMode(FXSettings.segment)) { #if defined(ENABLE_MQTT) - snprintf(mqtt_buf, sizeof(mqtt_buf), "OK /%i", ws2812fx_mode); + snprintf(mqtt_buf, sizeof(mqtt_buf), "OK /%i", fx_mode); #endif strip->strip_off(); autoCount = 0; autoDelay = 0; - strip->setMode(segment, ws2812fx_mode); + strip->setMode(FXSettings.segment, fx_mode); } //Color /*if (memcmp(hex_colors_trans, strip->getColors(selected_segment), sizeof(hex_colors_trans)) != 0) { @@ -686,17 +686,17 @@ void loop() { brightness_trans = brightness; } // Speed - if (ws2812fx_speed_actual != ws2812fx_speed) { + if (fx_speed_actual != fx_speed) { #if defined(ENABLE_MQTT) - snprintf(mqtt_buf, sizeof(mqtt_buf), "OK ?%i", ws2812fx_speed); + snprintf(mqtt_buf, sizeof(mqtt_buf), "OK ?%i", fx_speed); #endif } prevmode = SET; strip->trigger(); } - if ((mode == HOLD) || ((mode == OFF) && (strip->getBrightness() > 0) && transEffect)) { - if (ws2812fx_mode == FX_MODE_CUSTOM_0) { + if ((mode == HOLD) || ((mode == OFF) && (strip->getBrightness() > 0) && FXSettings.transEffect)) { + if (fx_mode == FX_MODE_CUSTOM_0) { handleAutoPlay(); } if(!strip->isRunning()) strip->start(); @@ -705,11 +705,11 @@ void loop() { if (prevmode != mode) { convertColors(); - if (memcmp(hex_colors_trans, strip->getColors(segment), sizeof(hex_colors_trans)) != 0) { + if (memcmp(hex_colors_trans, strip->getColors(FXSettings.segment), sizeof(hex_colors_trans)) != 0) { convertColorsFade(); trans_cnt = 1; } - strip->setSpeed(segment, convertSpeed(ws2812fx_speed_actual)); + strip->setSpeed(FXSettings.segment, convertSpeed(fx_speed_actual)); //strip->setBrightness(brightness_actual); #if defined(ENABLE_MQTT) #if ENABLE_MQTT == 0 @@ -731,8 +731,7 @@ void loop() { (writeStateFS(updateState)) ? DBG_OUTPUT_PORT.println("State FS Save Success!") : DBG_OUTPUT_PORT.println("State FS Save failure!"); } if (updateSegState) { - (writeSegmentStateFS(updateSegState, segment)) ? DBG_OUTPUT_PORT.println("Segment State FS Save Success!") : DBG_OUTPUT_PORT.println("Segment State FS Save failure!"); - initStrip(); + (writeSegmentStateFS(updateSegState, FXSettings.segment)) ? DBG_OUTPUT_PORT.println("Segment State FS Save Success!") : DBG_OUTPUT_PORT.println("Segment State FS Save failure!"); } if (updateConfig) { (writeConfigFS(updateConfig)) ? DBG_OUTPUT_PORT.println("Config FS Save success!"): DBG_OUTPUT_PORT.println("Config FS Save failure!"); @@ -740,14 +739,14 @@ void loop() { #endif // Async color transition - if (memcmp(hex_colors_trans, strip->getColors(segment), sizeof(hex_colors_trans)) != 0) { - if (transEffect) { + if (memcmp(hex_colors_trans, strip->getColors(FXSettings.segment), sizeof(hex_colors_trans)) != 0) { + if (FXSettings.transEffect) { if ((trans_cnt > 0) && (trans_cnt < trans_cnt_max)) { if (colorFadeDelay <= millis()) { uint32_t hex_colors_actual[3] = {}; - hex_colors_actual[0] = trans(hex_colors_trans[0], hex_colors[0], trans_cnt); - hex_colors_actual[1] = trans(hex_colors_trans[1], hex_colors[1], trans_cnt); - hex_colors_actual[2] = trans(hex_colors_trans[2], hex_colors[2], trans_cnt); + hex_colors_actual[0] = trans(hex_colors_trans[0], hex_colors[0], trans_cnt, trans_cnt_max); + hex_colors_actual[1] = trans(hex_colors_trans[1], hex_colors[1], trans_cnt, trans_cnt_max); + hex_colors_actual[2] = trans(hex_colors_trans[2], hex_colors[2], trans_cnt, trans_cnt_max); strip->setColors(prevsegment, hex_colors_actual); trans_cnt++; colorFadeDelay = millis() + TRANS_COLOR_DELAY; @@ -768,33 +767,34 @@ void loop() { } } // Async speed transition - if (ws2812fx_speed_actual != ws2812fx_speed) { - if (transEffect) { + if (fx_speed_actual != fx_speed) { + //if (FXSettings.transEffect) { + if (true == false) { if (speedFadeDelay <= millis()) { DBG_OUTPUT_PORT.println("Speed actual: "); - DBG_OUTPUT_PORT.println(ws2812fx_speed_actual); - DBG_OUTPUT_PORT.println(convertSpeed(ws2812fx_speed_actual)); - DBG_OUTPUT_PORT.println(unconvertSpeed(convertSpeed(ws2812fx_speed_actual))); - if (ws2812fx_speed_actual < ws2812fx_speed) { - ws2812fx_speed_actual++; + DBG_OUTPUT_PORT.println(fx_speed_actual); + DBG_OUTPUT_PORT.println(convertSpeed(fx_speed_actual)); + DBG_OUTPUT_PORT.println(unconvertSpeed(convertSpeed(fx_speed_actual))); + if (fx_speed_actual < fx_speed) { + fx_speed_actual++; } - if (ws2812fx_speed_actual > ws2812fx_speed) { - ws2812fx_speed_actual--; + if (fx_speed_actual > fx_speed) { + fx_speed_actual--; } speedFadeDelay = millis() + TRANS_DELAY; - strip->setSpeed(prevsegment, convertSpeed(ws2812fx_speed_actual)); + strip->setSpeed(prevsegment, convertSpeed(fx_speed_actual)); if (mode == HOLD) strip->trigger(); } } else { - ws2812fx_speed_actual = ws2812fx_speed; - strip->setSpeed(prevsegment, convertSpeed(ws2812fx_speed_actual)); + fx_speed_actual = fx_speed; + strip->setSpeed(prevsegment, convertSpeed(fx_speed_actual)); if (mode == HOLD) strip->trigger(); } } // Async brightness transition if (strip->getBrightness() != brightness_trans) { - if (transEffect) { + if (FXSettings.transEffect) { if(brightnessFadeDelay <= millis()) { if (strip->getBrightness() < brightness_trans) { strip->increaseBrightness(1); @@ -814,9 +814,9 @@ void loop() { } /* // Segment change only if color and speed transitions are finished, because they are segment specific - if (prevsegment != segment) { - if ((memcmp(hex_colors_trans, strip->getColors(segment), sizeof(hex_colors_trans)) == 0) && (ws2812fx_speed_actual == ws2812fx_speed)) { - segment = prevsegment; + if (prevsegment != FXSettings.segment) { + if ((memcmp(hex_colors_trans, strip->getColors(FXSettings.segment), sizeof(hex_colors_trans)) == 0) && (fx_speed_actual == fx_speed)) { + FXSettings.segment = prevsegment; } } */ diff --git a/Arduino/McLighting/data/index.htm b/Arduino/McLighting/data/index.htm index 48bc40b..592899e 100644 --- a/Arduino/McLighting/data/index.htm +++ b/Arduino/McLighting/data/index.htm @@ -910,7 +910,7 @@ input[type=number], label{
- +
@@ -979,6 +979,14 @@ input[type=number], label{
+
+

segStart

+ +
+

segStop

+ +
+

selectOPTREV

@@ -993,14 +1001,6 @@ input[type=number], label{
-
-

segStart

- -
-

segStop

- -
-

selectColors

@@ -1048,6 +1048,7 @@ var language = { connectError2: " times. Please use the RECONNECT button to try again.", loadModes: "Loading modes ...", // This language-string is not translated (settings not loaded yet) loadSettings: "Loading settings ...", // This language-string is not translated (settings not loaded yet) + loadConfig: "Loading configuration ...", loadWebsock: "Connecting websockets ...", loadReady: "Ready ...", loadError: "Error loading animation modes, please try again...", // This language-string is not translated (settings not loaded yet) @@ -1108,6 +1109,7 @@ var language = { connectError2: " keer geprobeerd. Gebruik de Verbind opnieuw knop om opnieuw te proberen.", loadModes: "Modes laden...", // This language-string is not translated (settings not loaded yet) loadSettings: "Instellingen laden...", // This language-string is not translated (settings not loaded yet) + loadConfig: "Configuratie laden ...", loadWebsock: "Websockets verbinden...", loadReady: "Klaar...", loadError: "Fout bij laden van animatie modes, probeer opnieuw...", // This language-string is not translated (settings not loaded yet) @@ -1168,6 +1170,7 @@ var language = { connectError2: " mal versucht. Benutze WIEDER VERBINDEN, um es nochmal zu probieren.", loadModes: "Lade Modi ...", // This language-string is not translated (settings not loaded yet) loadSettings: "Lade Einstellungen ...", // This language-string is not translated (settings not loaded yet) + loadConfig: "Lade Konfiguration ...", loadWebsock: "Verbinde Websockets ...", loadReady: "Fertig ...", loadError: "Fehler beim Laden der Animations-Modi, bitte nochmal versuchen...", // This language-string is not translated (settings not loaded yet) @@ -1315,19 +1318,27 @@ var config = { ws_cnt: 0, ws_rgbo: "", ws_pin: 0, - ws_fxopt: 0, - enable_rgbw: false, - transitionEffects: true + ws_trans: false, + enable_rgbw: false }; -var data = { +var state = { + mode: 0, segment: 0, + brightness: 192 +} + +var segstate = { start: 0, stop: 0, - mode: 0, - color: {w:0, r:0, g:0, b:0, hex:"00000000", w2:0, r2:0, g2:0, b2:0, hex2:"00000000", w3:0, r3:0, g3:0, b3:0, hex3:"00000000"}, - brightness: 192, + mode: null, speed: 192, - ws2812fx_mode: null, + color: {w:0, r:0, g:0, b:0, hex:"00000000", w2:0, r2:0, g2:0, b2:0, hex2:"00000000", w3:0, r3:0, g3:0, b3:0, hex3:"00000000"}, + ws_fxopt: 0 +} + + +var data = { + init: true, color_num: 1, modes: [], connection: null, @@ -1335,7 +1346,6 @@ var data = { num_additional_connections: 0, is_connected: false, refresh_interval: 0, - init: true, color_disabled: false }; var sendIt; // Timer to prevent lots of sending @@ -1365,12 +1375,12 @@ function displayColors(all = false) { clearTimeout(sendIt); sendIt = setTimeout(function() { set_color(); }, 50); } else { - document.getElementById("colorSel1").style.backgroundColor = `rgb(${data.color.r}, ${data.color.g}, ${data.color.b})`; - document.getElementById("colorHex1").innerHTML = "#" + data.color.hex; - document.getElementById("colorSel2").style.backgroundColor = `rgb(${data.color.r2}, ${data.color.g2}, ${data.color.b2})`; - document.getElementById("colorHex2").innerHTML = "#" + data.color.hex2; - document.getElementById("colorSel3").style.backgroundColor = `rgb(${data.color.r3}, ${data.color.g3}, ${data.color.b3})`; - document.getElementById("colorHex3").innerHTML = "#" + data.color.hex3; + document.getElementById("colorSel1").style.backgroundColor = `rgb(${segstate.color.r}, ${segstate.color.g}, ${segstate.color.b})`; + document.getElementById("colorHex1").innerHTML = "#" + segstate.color.hex; + document.getElementById("colorSel2").style.backgroundColor = `rgb(${segstate.color.r2}, ${segstate.color.g2}, ${segstate.color.b2})`; + document.getElementById("colorHex2").innerHTML = "#" + segstate.color.hex2; + document.getElementById("colorSel3").style.backgroundColor = `rgb(${segstate.color.r3}, ${segstate.color.g3}, ${segstate.color.b3})`; + document.getElementById("colorHex3").innerHTML = "#" + segstate.color.hex3; } } @@ -1411,44 +1421,44 @@ function initSliderColors(){ function changeRangeNumVal(){ redNumVal.addEventListener('change', ()=>{ // make sure numbers are entered between 0 to 255 - red.value = checkNumVal(redNumVal, red.value); - if (data.color_num === 1) data.color.r = red.value; - if (data.color_num === 2) data.color.r2 = red.value; - if (data.color_num === 3) data.color.r3 = red.value; + red.value = checkNumVal8(redNumVal, red.value); + if (data.color_num === 1) segstate.color.r = red.value; + if (data.color_num === 2) segstate.color.r2 = red.value; + if (data.color_num === 3) segstate.color.r3 = red.value; initSliderColors(); displayColors(); }); greenNumVal.addEventListener('change', ()=>{ // make sure numbers are entered between 0 to 255 - green.value = checkNumVal(greenNumVal, green.value); - if (data.color_num === 1) data.color.g = green.value; - if (data.color_num === 2) data.color.g2 = green.value; - if (data.color_num === 3) data.color.g3 = green.value; + green.value = checkNumVal8(greenNumVal, green.value); + if (data.color_num === 1) segstate.color.g = green.value; + if (data.color_num === 2) segstate.color.g2 = green.value; + if (data.color_num === 3) segstate.color.g3 = green.value; initSliderColors(); displayColors(); }); blueNumVal.addEventListener('change', ()=>{ // make sure numbers are entered between 0 to 255 - blue.value = checkNumVal(blueNumVal, blue.value); - if (data.color_num === 1) data.color.b = blue.value; - if (data.color_num === 2) data.color.b2 = blue.value; - if (data.color_num === 3) data.color.b3 = blue.value; + blue.value = checkNumVal8(blueNumVal, blue.value); + if (data.color_num === 1) segstate.color.b = blue.value; + if (data.color_num === 2) segstate.color.b2 = blue.value; + if (data.color_num === 3) segstate.color.b3 = blue.value; initSliderColors(); displayColors(); }); whiteNumVal.addEventListener('change', ()=>{ // make sure numbers are entered between 0 to 255 - white.value = checkNumVal(whiteNumVal, white.value); - if (data.color_num === 1) data.color.w = white.value; - if (data.color_num === 2) data.color.w2 = white.value; - if (data.color_num === 3) data.color.w3 = white.value; + white.value = checkNumVal8(whiteNumVal, white.value); + if (data.color_num === 1) segstate.color.w = white.value; + if (data.color_num === 2) segstate.color.w2 = white.value; + if (data.color_num === 3) segstate.color.w3 = white.value; initSliderColors(); displayColors(); }); brightNumVal.addEventListener('change', ()=>{ // make sure numbers are entered between 0 to 255 - bright.value = checkNumVal(brightNumVal, bright.value); - data.brightness = bright.value; + bright.value = checkNumVal8(brightNumVal, bright.value); + state.brightness = bright.value; initSliderColors(); // Send Brightness clearTimeout(sendIt); @@ -1456,14 +1466,14 @@ function changeRangeNumVal(){ }); speedNumVal.addEventListener('change', ()=>{ // make sure numbers are entered between 0 to 255 - speed.value = checkNumVal(speedNumVal, speed.value); - data.speed = speed.value; + speed.value = checkNumVal16(speedNumVal, speed.value); + segstate.speed = speed.value; // Send Speed clearTimeout(sendIt); sendIt = setTimeout(function() { set_speed(); }, 50); }); } -function checkNumVal(numVal, curVal) { +function checkNumVal8(numVal, curVal) { if(numVal.value > 255) { alert(language[settings.lang]["not_greater"]); numVal.value = curVal; @@ -1474,6 +1484,17 @@ function checkNumVal(numVal, curVal) { return numVal.value; } +function checkNumVal16(numVal, curVal) { + if(numVal.value > 65535) { + alert(language[settings.lang]["not_greater"]); + numVal.value = curVal; + } else if(numVal.value < 0) { + alert(language[settings.lang]["not_less"]); + numVal.value = curVal; + } + return numVal.value; +} + // Color Sliders controls function initcolorSliders(){ var event = new Event('change'); @@ -1552,8 +1573,11 @@ function xhttp(url, post, callback) { xhr.send(post); } function getModes() { + document.getElementById("percentage").innerHTML = "0%"; + document.getElementById("percentage-done").setAttribute("stroke-dasharray", "0,100"); + document.getElementById("modal-content").innerHTML = language.en.loadModes; xhttp("http://" + host + "/get_modes", false, function(e) { - //console.log("Getting modes list via REST:", e); + console.log("Getting modes list via REST:", e); if (e && e.substring(0,6) !== "ERROR!") { modes = JSON.parse(e); if (typeof modes[0] !== "undefined") { @@ -1572,6 +1596,9 @@ function getModes() { } function getConfig() { + document.getElementById("percentage").innerHTML = "75%"; + document.getElementById("percentage-done").setAttribute("stroke-dasharray", "75,100"); + document.getElementById("modal-content").innerHTML = language.en.loadConfig; xhttp("http://" + host + "/config", false, function(e) { console.log("Getting config via REST:", e); if (e && e.substring(0,6) !== "ERROR!") { @@ -1589,8 +1616,7 @@ function getConfig() { config.enable_rgbw = config.ws_rgbo.includes("W"); } if (typeof res.ws_pin !== "undefined") config.ws_pin = res.ws_pin; - if (typeof res.ws_fxopt !== "undefined") config.ws_fxopt = res.ws_fxopt; - if (typeof res.transEffect !== "undefined") config.transitionEffects = res.transEffect; + if (typeof res.ws_trans !== "undefined") config.ws_trans = res.ws_trans; } } else { console.error(e); @@ -1602,9 +1628,9 @@ function getConfig() { } else { document.getElementById("white").parentNode.className = "hidden"; white.value = 0; - data.color.w = 0; - data.color.w2 = 0; - data.color.w3 = 0; + segstate.color.w = 0; + segstate.color.w2 = 0; + segstate.color.w3 = 0; } }); } @@ -1635,8 +1661,8 @@ function showModes(mode, index) { document.getElementById("modes").appendChild(div); } function readSettings() { - document.getElementById("percentage").innerHTML = "33%"; - document.getElementById("percentage-done").setAttribute("stroke-dasharray", "33,100"); + document.getElementById("percentage").innerHTML = "25%"; + document.getElementById("percentage-done").setAttribute("stroke-dasharray", "25,100"); document.getElementById("modal-content").innerHTML = language.en.loadSettings; xhttp("http://" + host + "/uistate.json", false, function(e) { //console.log("readSettings()", e); @@ -1717,10 +1743,10 @@ function onSelectColNum(colnum) { x = document.getElementById("colorSel" + colnum); x.className = x.className.replace(/\belevation-3\b/g, "elevation-9"); // Set ColorPicker and Sliders to selected color - red.value = data.color["r" + (colnum > 1 ? colnum : "")]; - green.value = data.color["g" + (colnum > 1 ? colnum : "")]; - blue.value = data.color["b" + (colnum > 1 ? colnum : "")]; - white.value = data.color["w" + (colnum > 1 ? colnum : "")]; + red.value = segstate.color["r" + (colnum > 1 ? colnum : "")]; + green.value = segstate.color["g" + (colnum > 1 ? colnum : "")]; + blue.value = segstate.color["b" + (colnum > 1 ? colnum : "")]; + white.value = segstate.color["w" + (colnum > 1 ? colnum : "")]; initSliderColors(); changeRangeNumVal(); colorNumVals(); @@ -1782,10 +1808,10 @@ function initSettings() { option.innerHTML = i; selsegment.appendChild(option); } - selsegment.value = data.segment; + selsegment.value = state.segment; selsegment.addEventListener('change', ()=>{ - data.segment = selsegment.value; - ws_send("Ss" + data.segment); + state.segment = selsegment.value; + ws_send("Ss" + state.segment); }); var num_segments = document.getElementById("selectsegcnt"); num_segments.value = config.ws_seg; @@ -1801,7 +1827,10 @@ function initSettings() { option.innerHTML = i; selsegment.appendChild(option); } - selsegment.value = data.segment; + if (state.segment > config.ws_seg - 1) { + state.segment = config.ws_seg - 1; + } + selsegment.value = state.segment; }); var pin = document.getElementById("selectpin"); pin.value = config.ws_pin; @@ -1823,17 +1852,17 @@ function initSettings() { }); var start = document.getElementById("segstart"); start.setAttribute("max",config.ws_cnt-1); - start.value = data.start; + start.value = segstate.start; start.addEventListener('change', ()=>{ - data.start = start.value; - ws_send("S[" + data.start); + segstate.start = start.value; + ws_send("S[" + segstate.start); }); var stop = document.getElementById("segstop"); stop.setAttribute("max",config.ws_cnt-1); - stop.value = data.stop; + stop.value = segstate.stop; stop.addEventListener('change', ()=>{ - data.stop = stop.value; - ws_send("S]" + data.stop); + segstate.stop = stop.value; + ws_send("S]" + segstate.stop); }); var count = document.getElementById("selectcount"); count.value = config.ws_cnt; @@ -1850,10 +1879,10 @@ function initSettings() { option.innerHTML = selectoptrev[code]; optrev.appendChild(option); } - optrev.value = (config.ws_fxopt & 128); + optrev.value = (segstate.ws_fxopt & 128); optrev.addEventListener('change', ()=>{ - config.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value; - ws_send("Cso" + config.ws_fxopt); + segstate.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value; + ws_send("So" + segstate.ws_fxopt); }); var optfade = document.getElementById("selectoptfade"); for (var code in selectoptfade) { @@ -1862,10 +1891,10 @@ function initSettings() { option.innerHTML = selectoptfade[code]; optfade.appendChild(option); } - optfade.value = (config.ws_fxopt & 112); + optfade.value = (segstate.ws_fxopt & 112); optfade.addEventListener('change', ()=>{ - config.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value; - ws_send("Cso" + config.ws_fxopt); + segstate.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value; + ws_send("So" + segstate.ws_fxopt); }); var optgamma = document.getElementById("selectoptgamma"); for (var code in selectoptgamma) { @@ -1874,10 +1903,10 @@ function initSettings() { option.innerHTML = selectoptgamma[code]; optgamma.appendChild(option); } - optgamma.value = (config.ws_fxopt & 8); + optgamma.value = (segstate.ws_fxopt & 8); optgamma.addEventListener('change', ()=>{ - config.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value; - ws_send("Cso" + config.ws_fxopt); + segstate.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value; + ws_send("So" + segstate.ws_fxopt); }); var optsize = document.getElementById("selectoptsize"); for (var code in selectoptsize) { @@ -1886,10 +1915,10 @@ function initSettings() { option.innerHTML = selectoptsize[code]; optsize.appendChild(option); } - optsize.value = (config.ws_fxopt & 6) + optsize.value = (segstate.ws_fxopt & 6) optsize.addEventListener('change', ()=>{ - config.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value; - ws_send("Cso" + config.ws_fxopt); + segstate.ws_fxopt = optrev.value | optfade.value | optgamma.value | optsize.value; + ws_send("So" + segstate.ws_fxopt); }); slavenodes.value = settings.slave_nodes; lang.addEventListener('change', ()=>{ @@ -2103,8 +2132,8 @@ function ws_reconnect() { function ws_connect() { data.connection = new ReconnectingWebSocket(ws_url, "arduino", ws_options); - document.getElementById("percentage").innerHTML = "67%"; - document.getElementById("percentage-done").setAttribute("stroke-dasharray", "67,100"); + document.getElementById("percentage").innerHTML = "75%"; + document.getElementById("percentage-done").setAttribute("stroke-dasharray", "75,100"); document.getElementById("modal-content").innerHTML = language[settings.lang].loadWebsock; // When the connection is open, send some data to the server @@ -2116,12 +2145,12 @@ function ws_connect() { con.className = "hidden"; con = document.getElementById("connected"); con.className = con.className = ""; - document.getElementById("percentage").innerHTML = "100%"; - document.getElementById("percentage-done").setAttribute("stroke-dasharray", "100,100"); - document.getElementById("modal-content").innerHTML = language[settings.lang].loadReady; //setTimeout(function() { ws_send("$"); }, 2000); //setTimeout(function() { ws_send("C"); }, 3000); //setTimeout(function() { ws_send("~"); }, 4000); + document.getElementById("percentage").innerHTML = "100%"; + document.getElementById("percentage-done").setAttribute("stroke-dasharray", "100,100"); + document.getElementById("modal-content").innerHTML = language[settings.lang].loadReady; }; // When the connection is open, send some data to the server @@ -2154,56 +2183,56 @@ function ws_connect() { // document.getElementById('modal').style.display = "none"; // console.log("res", res); if (res) { - if (typeof res.mode !== "undefined") data.mode = res.mode; + if (typeof res.segment !== "undefined") { state.segment= res.segment; document.getElementById("selectseg").value = state.segment; } + if (typeof res.mode !== "undefined") { state.mode = res.mode; } if (typeof res.brightness !== "undefined") { - data.brightness = res.brightness; + state.brightness = res.brightness; // init ColorSliderVals bright.value = res.brightness; } // Segment Status starts here - if (typeof res.segment !== "undefined") { data.segment= res.segment; document.getElementById("selectseg").value = data.segment; } - if (typeof res.start !== "undefined") { data.start= res.start; document.getElementById("segstart").value = data.start; } - if (typeof res.stop !== "undefined") { data.stop = res.stop; document.getElementById("segstop").value = data.stop; } - if (typeof res.ws2812fx_mode !== "undefined") data.ws2812fx_mode = res.ws2812fx_mode; + if (typeof res.start !== "undefined") { segstate.start= res.start; document.getElementById("segstart").value = segstate.start; } + if (typeof res.stop !== "undefined") { segstate.stop = res.stop; document.getElementById("segstop").value = segstate.stop; } + if (typeof res.fx_mode !== "undefined") { segstate.mode = res.fx_mode; } if (typeof res.speed !== "undefined") { - data.speed = res.speed; + segstate.speed = res.speed; // init SliderVals speed.value = res.speed; } if (typeof res.color !== "undefined") { - data.color.w = res.color[0]; - data.color.r = res.color[1]; - data.color.g = res.color[2]; - data.color.b = res.color[3]; - data.color.hex = rgbToHex([res.color[0], res.color[1], res.color[2], res.color[3]]); - data.color.w2 = res.color[4]; - data.color.r2 = res.color[5]; - data.color.g2 = res.color[6]; - data.color.b2 = res.color[7]; - data.color.hex2 = rgbToHex([res.color[4], res.color[5], res.color[6], res.color[7]]); - data.color.w3 = res.color[8]; - data.color.r3 = res.color[9]; - data.color.g3 = res.color[10]; - data.color.b3 = res.color[11]; - data.color.hex3 = rgbToHex([res.color[8], res.color[9], res.color[10], res.color[11]]); + segstate.color.w = res.color[0]; + segstate.color.r = res.color[1]; + segstate.color.g = res.color[2]; + segstate.color.b = res.color[3]; + segstate.color.hex = rgbToHex([res.color[0], res.color[1], res.color[2], res.color[3]]); + segstate.color.w2 = res.color[4]; + segstate.color.r2 = res.color[5]; + segstate.color.g2 = res.color[6]; + segstate.color.b2 = res.color[7]; + segstate.color.hex2 = rgbToHex([res.color[4], res.color[5], res.color[6], res.color[7]]); + segstate.color.w3 = res.color[8]; + segstate.color.r3 = res.color[9]; + segstate.color.g3 = res.color[10]; + segstate.color.b3 = res.color[11]; + segstate.color.hex3 = rgbToHex([res.color[8], res.color[9], res.color[10], res.color[11]]); // init ColorSliderVals if (data.color_num === 1) { - red.value = data.color.r; - green.value = data.color.g; - blue.value = data.color.b; - white.value = data.color.w; + red.value = segstate.color.r; + green.value = segstate.color.g; + blue.value = segstate.color.b; + white.value = segstate.color.w; } if (data.color_num === 2) { - red.value = data.color.r2; - green.value = data.color.g2; - blue.value = data.color.b2; - white.value = data.color.w2; + red.value = segstate.color.r2; + green.value = segstate.color.g2; + blue.value = segstate.color.b2; + white.value = segstate.color.w2; } if (data.color_num === 3) { - red.value = data.color.r3; - green.value = data.color.g3; - blue.value = data.color.b3; - white.value = data.color.w3; + red.value = segstate.color.r3; + green.value = segstate.color.g3; + blue.value = segstate.color.b3; + white.value = segstate.color.w3; } } // Config starts here @@ -2223,21 +2252,21 @@ function ws_connect() { } else { document.getElementById("white").parentNode.className = "hidden"; white.value = 0; - data.color.w = 0; - data.color.w2 = 0; - data.color.w3 = 0; + segstate.color.w = 0; + segstate.color.w2 = 0; + segstate.color.w3 = 0; } } if (typeof res.ws_pin !== "undefined") { config.ws_pin = res.ws_pin; document.getElementById("selectpin").value = config.ws_pin; } + if (typeof res.ws_trans !== "undefined") { config.ws_trans = res.ws_trans; document.getElementById("set-transitionEffects").value = config.ws_trans; } if (typeof res.ws_fxopt !== "undefined") { - config.ws_fxopt = res.ws_fxopt; - document.getElementById("selectoptrev").value = (config.ws_fxopt & 128); - document.getElementById("selectoptfade").value = (config.ws_fxopt & 112); - document.getElementById("selectoptgamma").value = (config.ws_fxopt & 8); - document.getElementById("selectoptsize").value = (config.ws_fxopt & 6); + segstate.ws_fxopt = res.ws_fxopt; + document.getElementById("selectoptrev").value = (segstate.ws_fxopt & 128); + document.getElementById("selectoptfade").value = (segstate.ws_fxopt & 112); + document.getElementById("selectoptgamma").value = (segstate.ws_fxopt & 8); + document.getElementById("selectoptsize").value = (segstate.ws_fxopt & 6); } - if (typeof res.transEffect !== "undefined") { config.transitionEffects = res.transEffect; document.getElementById("set-transitionEffects").value = config.transitionEffects; } // Modes starts here if (typeof res[0] !== "undefined") { res.forEach(item => { @@ -2254,11 +2283,15 @@ function ws_connect() { // init Colors controls // init display Colors displayColors(true); + console.log("displayColors finished!"); select_active_button(); + console.log("select_active_button finished!"); } - if (data.init === true) { + console.log("data.init: ", data.init); + if (data.init == true) { + console.log("Initializing..."); // Set selected mode button - //document.getElementById(data.ws2812fx_mode).style.backgroundColor = settings.theme_btnsel; + //document.getElementById(segstate.mode).style.backgroundColor = settings.theme_btnsel; // Close Loading Modal setTimeout(() => { document.getElementById('modal').style.display = "none"; @@ -2302,7 +2335,7 @@ function select_active_button() { for (i = 0; i < btns.length; i++) { btns[i].style.backgroundColor = settings.theme_btn; } - if (data.mode != 1 || (data.mode === 1 && data.ws2812fx_mode !== 57)) { // CUSTOM WS MODE + if (state.mode != 1 || (state.mode == 1 && segstate.mode != 57)) { // CUSTOM WS MODE wsmess = document.getElementById("message"); var arr = wsmess.className.split(" "); if (arr.indexOf("hidden") === -1) { @@ -2311,14 +2344,14 @@ function select_active_button() { segments = document.getElementById("segments"); segments.className = segments.className.replace(/\b hidden\b/g, ""); } - if (data.mode >= 1) { - document.getElementById(data.ws2812fx_mode).style.backgroundColor = settings.theme_btnsel; - if (data.ws2812fx_mode === 56) { // AUTOPLAY + if (state.mode >= 1) { + document.getElementById(segstate.mode).style.backgroundColor = settings.theme_btnsel; + if (segstate.mode == 56) { // AUTOPLAY disable_modebuttons(false); disable_color_selection(true); disable_bright_selection(false); disable_speed_selection(true); - } else if (data.ws2812fx_mode === 57) { //CUSTOM_WS + } else if (segstate.mode == 57) { //CUSTOM_WS wsmess = document.getElementById("message"); wsmess.className = wsmess.className.replace(/\b hidden\b/g, ""); sements = document.getElementById("segments"); @@ -2330,17 +2363,17 @@ function select_active_button() { disable_color_selection(true); disable_bright_selection(false); disable_speed_selection(true); - } else if (data.ws2812fx_mode === 58) { //TV + } else if (segstate.mode == 58) { //TV disable_modebuttons(false); disable_color_selection(true); disable_bright_selection(false); disable_speed_selection(false); - } else if (data.ws2812fx_mode === 59) { //E1.31 + } else if (segstate.mode == 59) { //E1.31 disable_modebuttons(false); disable_color_selection(true); disable_bright_selection(false); disable_speed_selection(true); - } else if (data.ws2812fx_mode === 60) { //Fire2012 + } else if (segstate.mode == 60) { //Fire2012 disable_modebuttons(false); disable_color_selection(true); disable_bright_selection(false); @@ -2351,7 +2384,7 @@ function select_active_button() { disable_bright_selection(false); disable_speed_selection(false); } - } else if (data.mode === 0) { + } else if (state.mode == 0) { document.getElementById("off").style.backgroundColor = settings.theme_btnsel; disable_modebuttons(false); disable_color_selection(true); @@ -2379,32 +2412,32 @@ function disable_modebuttons(status) { function set_mode(mode_id) { if (Number.isInteger(mode_id)) { - data.mode = 1; - data.ws2812fx_mode = mode_id; + state.mode = 1; + segstate.mode = mode_id; } else { // For named modes if (mode_id == "off") { - data.mode = 0; + state.mode = 0; } } select_active_button(); ws_send("/" + mode_id); } function set_speed() { - ws_send("?" + data.speed); + ws_send("?" + segstate.speed); } function set_brightness() { - ws_send("%" + data.brightness); + ws_send("%" + state.brightness); } function set_color() { if (data.color_num === 1) { - ws_send("#" + rgbToHex([data.color.w, data.color.r, data.color.g, data.color.b])); + ws_send("#" + rgbToHex([segstate.color.w, segstate.color.r, segstate.color.g, segstate.color.b])); } if (data.color_num === 2) { - ws_send("##" + rgbToHex([data.color.w2, data.color.r2, data.color.g2, data.color.b2])); + ws_send("##" + rgbToHex([segstate.color.w2, segstate.color.r2, segstate.color.g2, segstate.color.b2])); } if (data.color_num === 3) { - ws_send("###" + rgbToHex([data.color.w3, data.color.r3, data.color.g3, data.color.b3])); + ws_send("###" + rgbToHex([segstate.color.w3, segstate.color.r3, segstate.color.g3, segstate.color.b3])); } } @@ -2442,11 +2475,11 @@ function onSelectColor(event) { var color = context.getImageData(pos.x, pos.y, 1, 1).data; var hex_color = rgbToHex(color); var colnum = (data.color_num === 1) ? "" : data.color_num; - data.color["hex" + colnum] = hex_color; - data.color["r" + colnum] = color[0]; - data.color["g" + colnum] = color[1]; - data.color["b" + colnum] = color[2]; - data.color["w" + colnum] = 0; + segstate.color["hex" + colnum] = hex_color; + segstate.color["r" + colnum] = color[0]; + segstate.color["g" + colnum] = color[1]; + segstate.color["b" + colnum] = color[2]; + segstate.color["w" + colnum] = 0; red.value = color[0]; green.value = color[1]; blue.value = color[2]; @@ -2623,12 +2656,10 @@ document.addEventListener("DOMContentLoaded", function(event) { readSettings(); ws_connect(); ws_send("$"); - document.getElementById("modal-content").innerHTML = language.en.loadModes; //ws_send("C"); getConfig(); canvas.width = 400; canvas.height = 400; - redrawColorPicker(); }); diff --git a/Arduino/McLighting/definitions.h b/Arduino/McLighting/definitions.h index 74f66a0..6f6f463 100644 --- a/Arduino/McLighting/definitions.h +++ b/Arduino/McLighting/definitions.h @@ -31,12 +31,12 @@ char HOSTNAME[65] = "McLightingRGBW"; // Friedly hostname is configurable just #define ENABLE_STATE_SAVE // If defined, load saved state on reboot and save state on SPIFFS #define CUSTOM_WS2812FX_ANIMATIONS // uncomment and put animations in "custom_ws2812fx_animations.h" -#define USE_HTML_MIN_GZ // uncomment for using index.htm & edit.htm from PROGMEM instead of SPIFFS +//#define USE_HTML_MIN_GZ // uncomment for using index.htm & edit.htm from PROGMEM instead of SPIFFS #define TRANS_COLOR_DELAY 5 // Delay for color transition #define TRANS_DELAY 10 // Delay for brightness and speed transition -bool transEffect = false; // Experimental: Enable transitions of color, brightness and speed. It does not work properly for all effects. + // Experimental: Enable transitions of color, brightness and speed. It does not work properly for all effects. bool transEffectOverride = false; uint8_t trans_cnt = 0; int trans_cnt_max = 0; @@ -51,9 +51,6 @@ unsigned long speedFadeDelay = 0; #endif uint8_t num_segments = 1; -uint8_t segment = 0; -uint16_t seg_start = 0; -uint16_t seg_stop = NUMLEDS - 1; uint8_t prevsegment = 0; #if defined(ENABLE_REMOTE) @@ -153,13 +150,18 @@ MODE prevmode = HOLD; // Do not change uint8_t autoCount = 0; // Global variable for storing the counter for automated playback long autoDelay = 0; // Global variable for storing the time to next auto effect -uint8_t ws2812fx_speed = 196; // Global variable for storing the speed for effects --> smaller == slower -uint8_t ws2812fx_speed_actual = 196; // Global variable for storing the speed for effects while fading --> smaller == slower -uint8_t brightness = 196; // Global variable for storing the brightness (255 == 100%) -uint8_t brightness_trans = 0; // Global variable for storing the brightness before change -uint8_t ws2812fx_mode = 0; // Global variable for storing the WS2812FX mode to set -uint32_t hex_colors[3] = {}; // Color array for setting colors of WS2812FX + uint16_t seg_start = 0; + uint16_t seg_stop = NUMLEDS - 1; + uint16_t fx_speed = 1000; // Global variable for storing the speed for effects --> smaller == slower + uint8_t brightness = 196; // Global variable for storing the brightness (255 == 100%) + uint8_t fx_mode = 0; // Global variable for storing the WS2812FX mode to set + uint32_t hex_colors[3] = {}; // Color array for setting colors of WS2812FX + uint8_t fx_options = FX_OPTIONS; + + +uint16_t fx_speed_actual = 1000; // Global variable for storing the speed for effects while fading --> smaller == slower +uint8_t brightness_trans = 0; // Global variable for storing the brightness before change uint32_t hex_colors_trans[3] = {}; // Color array of colors of WS2812FX before fading struct ledstate // Data structure to store a state of a single led { @@ -202,8 +204,9 @@ bool updateConfig = false; // For WiFiManger custom config and config #endif struct { + uint8_t segment = 0; uint16_t stripSize = NUMLEDS; - char RGBOrder[5] = RGBORDER; + char RGBOrder[5] = RGBORDER; #if defined(USE_WS2812FX_DMA) #if USE_WS2812FX_DMA == 0 uint8_t pin = 3; @@ -217,5 +220,5 @@ struct { #else uint8_t pin = LED_PIN; #endif - uint8_t fxoptions = FX_OPTIONS; -} WS2812FXStripSettings; + bool transEffect = false; +} FXSettings; diff --git a/Arduino/McLighting/filesystem_functions.h b/Arduino/McLighting/filesystem_functions.h index 6128a09..9cadb35 100644 --- a/Arduino/McLighting/filesystem_functions.h +++ b/Arduino/McLighting/filesystem_functions.h @@ -78,14 +78,13 @@ strcpy(mqtt_pass, root["mqtt_pass"]); #endif num_segments = constrain(root["ws_seg"].as(), 1, MAX_NUM_SEGMENTS - 1); - WS2812FXStripSettings.stripSize = constrain(root["ws_cnt"].as(), 1, MAXLEDS); - char tmp_rgbOrder[5]; - strcpy(tmp_rgbOrder, root["ws_rgbo"]); - checkRGBOrder(tmp_rgbOrder); + FXSettings.stripSize = constrain(root["ws_cnt"].as(), 1, MAXLEDS); + char _rgbOrder[5]; + strcpy(_rgbOrder, root["ws_rgbo"]); + checkRGBOrder(_rgbOrder); uint8_t temp_pin; checkPin((uint8_t) root["ws_pin"]); - WS2812FXStripSettings.fxoptions = constrain(root["ws_fxopt"].as(), 0, 255) & 0xFE; - transEffect = root["transEffect"].as(); + FXSettings.transEffect = root["ws_trans"].as(); jsonBuffer.clear(); return true; } else { @@ -152,7 +151,7 @@ JsonObject root = jsonBuffer.as(); serializeJson(root, DBG_OUTPUT_PORT); DBG_OUTPUT_PORT.println(""); - segment = root["segment"]; + FXSettings.segment = root["segment"]; mode = static_cast(root["mode"].as()); brightness = root["brightness"]; jsonBuffer.clear(); @@ -225,10 +224,10 @@ JsonObject root = jsonBuffer.as(); serializeJson(root, DBG_OUTPUT_PORT); DBG_OUTPUT_PORT.println(""); - seg_start = root["start"].as(); - seg_stop = root["stop"].as(); - ws2812fx_mode = root["ws2812fx_mode"].as(); - ws2812fx_speed = root["speed"].as(); + seg_start = constrain(root["start"].as(), 0, FXSettings.stripSize - 1) ; + seg_stop = constrain(root["stop"].as(), 0, FXSettings.stripSize - 1); + fx_mode = root["fx_mode"].as(); + fx_speed = root["speed"].as(); main_color.white = root["color"][0].as(); main_color.red = root["color"][1].as(); main_color.green = root["color"][2].as(); @@ -241,6 +240,7 @@ xtra_color.red = root["color"][9].as(); xtra_color.green = root["color"][10].as(); xtra_color.blue = root["color"][11].as(); + fx_options = constrain(root["ws_fxopt"].as(), 0, 255) & 0xFE; convertColors(); jsonBuffer.clear(); return true; diff --git a/Arduino/McLighting/helper_functions.h b/Arduino/McLighting/helper_functions.h index 4562368..2642786 100644 --- a/Arduino/McLighting/helper_functions.h +++ b/Arduino/McLighting/helper_functions.h @@ -2,11 +2,12 @@ bool readSegmentStateFS(uint8_t seg); // End Prototypes -uint16_t convertSpeed(uint8_t mcl_speed) { - uint16_t ws2812_speed = 61760 * (exp(0.0002336 * mcl_speed) - exp(-0.03181 * mcl_speed)); - ws2812_speed = SPEED_MAX - ws2812_speed; - ws2812_speed = constrain(ws2812_speed, SPEED_MIN, SPEED_MAX); - return ws2812_speed; +uint16_t convertSpeed(uint16_t _mcl_speed) { + uint16_t _fx_speed = 61760 * (exp(0.0002336 * _mcl_speed) - exp(-0.03181 * _mcl_speed)); + _fx_speed = SPEED_MAX - _fx_speed; + _fx_speed = constrain(_fx_speed, SPEED_MIN, SPEED_MAX); + //return _fx_speed; + return _mcl_speed; } uint8_t unconvertSpeed(uint16_t ws2812_speed) { @@ -31,8 +32,8 @@ bool checkPin(uint8_t pin) { pin = 2; #endif #endif - if (((pin >= 0 && pin <= 5) || (pin >= 12 && pin <= 16)) && (pin != WS2812FXStripSettings.pin)) { - WS2812FXStripSettings.pin = pin; + if (((pin >= 0 && pin <= 5) || (pin >= 12 && pin <= 16)) && (pin != FXSettings.pin)) { + FXSettings.pin = pin; return true; } return false; @@ -104,22 +105,22 @@ neoPixelType checkRGBOrder(char rgbOrder[5]) { returnOrder = NEO_BGRW; } else { DBG_OUTPUT_PORT.print("invalid input!"); - uint16_t check = checkRGBOrder(WS2812FXStripSettings.RGBOrder); + uint16_t check = checkRGBOrder(FXSettings.RGBOrder); if (check != 0) { returnOrder = static_cast(check); - strcpy(rgbOrder, WS2812FXStripSettings.RGBOrder); + strcpy(rgbOrder, FXSettings.RGBOrder); } else { returnOrder = static_cast(checkRGBOrder(RGBORDER)); strcpy(rgbOrder, RGBORDER); } } DBG_OUTPUT_PORT.println("success!"); - strcpy(WS2812FXStripSettings.RGBOrder, rgbOrder); + strcpy(FXSettings.RGBOrder, rgbOrder); return returnOrder; } // function to Initialize the strip -void initStrip(uint16_t stripSize = WS2812FXStripSettings.stripSize, char RGBOrder[5] = WS2812FXStripSettings.RGBOrder, uint8_t pin = WS2812FXStripSettings.pin, uint8_t fxoptions = WS2812FXStripSettings.fxoptions ){ +void initStrip(uint16_t _stripSize = FXSettings.stripSize, char _RGBOrder[5] = FXSettings.RGBOrder, uint8_t _pin = FXSettings.pin){ DBG_OUTPUT_PORT.println("Initializing strip!"); /*#if defined(USE_WS2812FX_DMA) if (dma != NULL) { @@ -133,21 +134,20 @@ void initStrip(uint16_t stripSize = WS2812FXStripSettings.stripSize, char RGBOrd strip->resetSegments(); strip->resetSegmentRuntimes(); delete(strip); - WS2812FXStripSettings.stripSize = stripSize; - strcpy(WS2812FXStripSettings.RGBOrder, RGBOrder); - WS2812FXStripSettings.pin = pin; - WS2812FXStripSettings.fxoptions = fxoptions; + FXSettings.stripSize = _stripSize; + strcpy(FXSettings.RGBOrder, _RGBOrder); + FXSettings.pin = _pin; } if (ledstates != NULL) { delete(ledstates); } - ledstates = new uint8_t [WS2812FXStripSettings.stripSize]; + ledstates = new uint8_t [FXSettings.stripSize]; #if !defined(LED_TYPE_WS2811) - strip = new WS2812FX(stripSize, pin, checkRGBOrder(RGBOrder) + NEO_KHZ800); + strip = new WS2812FX(_stripSize, _pin, checkRGBOrder(_RGBOrder) + NEO_KHZ800); #else - strip = new WS2812FX(stripSize, pin, checkRGBOrder(RGBOrder) + NEO_KHZ400); + strip = new WS2812FX(_stripSize, _pin, checkRGBOrder(_RGBOrder) + NEO_KHZ400); #endif // Parameter 1 = number of pixels in strip // Parameter 2 = Arduino pin number (most are valid) @@ -163,39 +163,39 @@ void initStrip(uint16_t stripSize = WS2812FXStripSettings.stripSize, char RGBOrd // on a live circuit...if you must, connect GND first. strip->init(); #if defined(USE_WS2812FX_DMA) - initDMA(stripSize); + initDMA(_stripSize); strip->setCustomShow(DMA_Show); #endif //parameters: index, start, stop, mode, color, speed, options for (uint8_t seg=0; seg < num_segments; seg++) { - if (seg != segment) { // Read actual segment last + if (seg != FXSettings.segment) { // Read actual segment last (readSegmentStateFS(seg)) ? DBG_OUTPUT_PORT.println("Segment state config FS read Success!") : DBG_OUTPUT_PORT.println("Segment state config FS read failure!"); - strip->setSegment(seg, seg_start, seg_stop , ws2812fx_mode, hex_colors_trans, convertSpeed(ws2812fx_speed), fxoptions); + strip->setSegment(seg, seg_start, seg_stop, fx_mode, hex_colors_trans, convertSpeed(fx_speed), fx_options); } } //read actual segment last to set all vars correctly - (readSegmentStateFS(segment)) ? DBG_OUTPUT_PORT.println("Segment state config FS read Success!") : DBG_OUTPUT_PORT.println("Segment state config FS read failure!"); - strip->setSegment(segment, seg_start, seg_stop , ws2812fx_mode, hex_colors_trans, convertSpeed(ws2812fx_speed), fxoptions); - - strip->setCustomMode(0, F("Autoplay"), myCustomEffect0); - strip->setCustomMode(1, F("Custom WS"), myCustomEffect1); + (readSegmentStateFS(FXSettings.segment)) ? DBG_OUTPUT_PORT.println("Segment state config FS read Success!") : DBG_OUTPUT_PORT.println("Segment state config FS read failure!"); + strip->setSegment(FXSettings.segment, seg_start, seg_stop , 0, hex_colors_trans, convertSpeed(fx_speed), fx_options); + strip->setMode(FXSettings.segment, fx_mode); + fx_speed_actual = fx_speed; + strip->setCustomMode(0, F("Autoplay"), handleAuto); + strip->setCustomMode(1, F("Custom WS"), handleCustomWS); #if defined(CUSTOM_WS2812FX_ANIMATIONS) - strip->setCustomMode(2, F("TV"), myCustomEffect2); - strip->setCustomMode(3, F("E1.31"), myCustomEffect3); - strip->setCustomMode(4, F("Fire 2012"), myCustomEffect4); - strip->setCustomMode(5, F("Gradient"), myCustomEffect5); - gReverseDirection = (WS2812FXStripSettings.fxoptions & 128); + strip->setCustomMode(2, F("TV"), handleTV); + strip->setCustomMode(3, F("E1.31"), handleE131); + strip->setCustomMode(4, F("Fire 2012"), handleFire2012); + strip->setCustomMode(5, F("Gradient"), handleGradient); DBG_OUTPUT_PORT.print("Number of Segments: "); DBG_OUTPUT_PORT.println(strip->getNumSegments()); if (e131 != NULL) { delete(e131); } e131 = new ESPAsyncE131(END_UNIVERSE - START_UNIVERSE + 1); float universe_leds = 170.0; // a universe has only 512 (0..511) channels: 3*170 or 4*128 <= 512 - if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) { + if (strstr(FXSettings.RGBOrder, "W") != NULL) { //universe_leds = 128.0; } - float float_enduni = stripSize/universe_leds; - uint8_t END_UNIVERSE = stripSize/universe_leds; + float float_enduni = _stripSize/universe_leds; + uint8_t END_UNIVERSE = _stripSize/universe_leds; if (float_enduni > END_UNIVERSE) { END_UNIVERSE = END_UNIVERSE +1; } @@ -225,22 +225,33 @@ uint32_t* convertColors2(uint8_t w, uint8_t r, uint8_t g, uint8_t b, uint8_t w2, return hexcolors; } -void getSegmentParams(uint8_t seg) { - seg_start = strip->getSegment(seg)->start;; - seg_stop = strip->getSegment(seg)->stop;; - ws2812fx_mode = strip->getMode(seg); - main_color.white = ((strip->getColors(seg)[0] >> 24) & 0xFF); - main_color.red = ((strip->getColors(seg)[0] >> 16) & 0xFF); - main_color.green = ((strip->getColors(seg)[0] >> 8) & 0xFF); - main_color.blue = ((strip->getColors(seg)[0]) & 0xFF); - back_color.white = ((strip->getColors(seg)[1] >> 24) & 0xFF); - back_color.red = ((strip->getColors(seg)[1] >> 16) & 0xFF); - back_color.green = ((strip->getColors(seg)[1] >> 8) & 0xFF); - back_color.blue = ((strip->getColors(seg)[1]) & 0xFF); - xtra_color.white = ((strip->getColors(seg)[2] >> 24) & 0xFF); - xtra_color.red = ((strip->getColors(seg)[2] >> 16) & 0xFF); - xtra_color.green = ((strip->getColors(seg)[2] >> 8) & 0xFF); - xtra_color.blue = ((strip->getColors(seg)[2] >> 0) & 0xFF); +void getSegmentParams(uint8_t _seg) { + seg_start = strip->getSegment(_seg)->start;; + seg_stop = strip->getSegment(_seg)->stop;; + fx_mode = strip->getMode(_seg); + fx_speed = strip->getSpeed(_seg); + fx_speed_actual = fx_speed; + main_color.white = ((strip->getColors(_seg)[0] >> 24) & 0xFF); + main_color.red = ((strip->getColors(_seg)[0] >> 16) & 0xFF); + main_color.green = ((strip->getColors(_seg)[0] >> 8) & 0xFF); + main_color.blue = ((strip->getColors(_seg)[0]) & 0xFF); + back_color.white = ((strip->getColors(_seg)[1] >> 24) & 0xFF); + back_color.red = ((strip->getColors(_seg)[1] >> 16) & 0xFF); + back_color.green = ((strip->getColors(_seg)[1] >> 8) & 0xFF); + back_color.blue = ((strip->getColors(_seg)[1]) & 0xFF); + xtra_color.white = ((strip->getColors(_seg)[2] >> 24) & 0xFF); + xtra_color.red = ((strip->getColors(_seg)[2] >> 16) & 0xFF); + xtra_color.green = ((strip->getColors(_seg)[2] >> 8) & 0xFF); + xtra_color.blue = ((strip->getColors(_seg)[2] >> 0) & 0xFF); + fx_options = strip->getOptions(_seg); +} + +void setSegmentSize() { + strip->strip_off(); + delay(10); + if(strip->isRunning()) strip->stop(); + strip->resetSegmentRuntimes(); + strip->setSegment(FXSettings.segment, seg_start, seg_stop , fx_mode, hex_colors_trans, convertSpeed(fx_speed), fx_options); } void calculateColorTransitionSteps() { @@ -257,9 +268,9 @@ void calculateColorTransitionSteps() { } void convertColorsFade() { - if (transEffect) { + if (FXSettings.transEffect) { if (trans_cnt > 1) { - memcpy(hex_colors, strip->getColors(segment), sizeof(hex_colors)); + memcpy(hex_colors, strip->getColors(FXSettings.segment), sizeof(hex_colors)); DBG_OUTPUT_PORT.println("Color transistion aborted. Restarting...!"); trans_cnt = 1; } @@ -268,16 +279,17 @@ void convertColorsFade() { } uint32_t scale_wrgb(uint32_t wrgb, uint8_t level) { - uint8_t w = ((wrgb >> 24) & 0xFF) * level / 255; - uint8_t r = ((wrgb >> 16) & 0xFF) * level / 255; - uint8_t g = ((wrgb >> 8) & 0xFF) * level / 255; - uint8_t b = ((wrgb) & 0xFF) * level / 255; + uint8_t w = (uint16_t)(((wrgb >> 24) & 0xFF) * level / 255); + uint8_t r = (uint16_t)(((wrgb >> 16) & 0xFF) * level / 255); + uint8_t g = (uint16_t)(((wrgb >> 8) & 0xFF) * level / 255); + uint8_t b = (uint16_t)(((wrgb) & 0xFF) * level / 255); return (w << 24) | (r << 16) | (g << 8) | b; } -uint32_t trans(uint32_t newcolor, uint32_t oldcolor, uint8_t level) { - level = (level * (255/trans_cnt_max)); - newcolor = scale_wrgb(newcolor, level); - oldcolor = scale_wrgb(oldcolor, 255-level); - return newcolor + oldcolor; +uint32_t trans(uint32_t _newcolor, uint32_t _oldcolor, uint8_t _level, uint8_t _steps) { + if (_steps == 0) { _steps = 1; }; + _level = (uint16_t)(_level * 255 / _steps); + _newcolor = scale_wrgb(_newcolor, _level); + _oldcolor = scale_wrgb(_oldcolor, 255-_level); + return _newcolor + _oldcolor; } diff --git a/Arduino/McLighting/json_functions.h b/Arduino/McLighting/json_functions.h index cbd5a46..15e7fda 100644 --- a/Arduino/McLighting/json_functions.h +++ b/Arduino/McLighting/json_functions.h @@ -7,17 +7,16 @@ #endif char * listStateJSONfull() { - const size_t bufferSize = JSON_ARRAY_SIZE(12) + JSON_OBJECT_SIZE(20) + 250; + const size_t bufferSize = JSON_ARRAY_SIZE(12) + JSON_OBJECT_SIZE(19) + 250; DynamicJsonDocument jsonBuffer(bufferSize); JsonObject root = jsonBuffer.to(); - root["segment"] = segment; + root["segment"] = FXSettings.segment; root["start"] = seg_start; root["stop"] = seg_stop; root["mode"] = (uint8_t) mode; //getSegmentParams(segment); - root["ws2812fx_mode"] = ws2812fx_mode; - root["ws2812fx_mode_name"] = strip->getModeName(ws2812fx_mode); - root["speed"] = ws2812fx_speed; + root["fx_mode"] = fx_mode; + root["speed"] = fx_speed; root["brightness"] = brightness; JsonArray color = root.createNestedArray("color"); color.add(main_color.white); @@ -32,6 +31,7 @@ char * listStateJSONfull() { color.add(xtra_color.red); color.add(xtra_color.green); color.add(xtra_color.blue); + root["ws_fxopt"] = fx_options; root["hostname"] = HOSTNAME; #if defined(ENABLE_MQTT) root["mqtt_host"] = mqtt_host; @@ -40,11 +40,10 @@ char * listStateJSONfull() { root["mqtt_pass"] = mqtt_pass; #endif root["ws_seg"] = num_segments; - root["ws_cnt"] = WS2812FXStripSettings.stripSize; - root["ws_rgbo"] = WS2812FXStripSettings.RGBOrder; - root["ws_pin"] = WS2812FXStripSettings.pin; - root["ws_fxopt"] = WS2812FXStripSettings.fxoptions; - root["transEffect"] = transEffect; + root["ws_cnt"] = FXSettings.stripSize; + root["ws_rgbo"] = FXSettings.RGBOrder; + root["ws_pin"] = FXSettings.pin; + root["ws_trans"] = FXSettings.transEffect; uint16_t msg_len = measureJson(root) + 1; char * buffer = (char *) malloc(msg_len); serializeJson(root, buffer, msg_len); @@ -56,7 +55,7 @@ char * listStateJSON() { const size_t bufferSize = JSON_OBJECT_SIZE(3) + 25; DynamicJsonDocument jsonBuffer(bufferSize); JsonObject root = jsonBuffer.to(); - root["segment"] = segment; + root["segment"] = FXSettings.segment; root["mode"] = (uint8_t) mode; root["brightness"] = brightness; uint16_t msg_len = measureJson(root) + 1; @@ -67,11 +66,10 @@ char * listStateJSON() { } char * listSegmentStateJSON(uint8_t seg) { - const size_t bufferSize = JSON_ARRAY_SIZE(12) + JSON_OBJECT_SIZE(7) + 100; + const size_t bufferSize = JSON_ARRAY_SIZE(12) + JSON_OBJECT_SIZE(6) + 100; DynamicJsonDocument jsonBuffer(bufferSize); JsonObject root = jsonBuffer.to(); - root["segment"] = seg; - if (seg == segment) { + if (seg == FXSettings.segment) { root["start"] = seg_start; root["stop"] = seg_stop; } else { @@ -79,22 +77,37 @@ char * listSegmentStateJSON(uint8_t seg) { root["stop"] = strip->getSegment(seg)->stop; } //getSegmentParams(seg); - root["ws2812fx_mode"] = strip->getMode(seg); - root["ws2812fx_mode_name"] = strip->getModeName(strip->getMode(seg)); - root["speed"] = ws2812fx_speed; + root["fx_mode"] = strip->getMode(seg); + root["speed"] = fx_speed; JsonArray color = root.createNestedArray("color"); - color.add((strip->getColors(seg)[0] >> 24) & 0xFF); - color.add((strip->getColors(seg)[0] >> 16) & 0xFF); - color.add((strip->getColors(seg)[0] >> 8) & 0xFF); - color.add((strip->getColors(seg)[0]) & 0xFF); - color.add((strip->getColors(seg)[1] >> 24) & 0xFF); - color.add((strip->getColors(seg)[1] >> 16) & 0xFF); - color.add((strip->getColors(seg)[1] >> 8) & 0xFF); - color.add((strip->getColors(seg)[1]) & 0xFF); - color.add((strip->getColors(seg)[2] >> 24) & 0xFF); - color.add((strip->getColors(seg)[2] >> 16) & 0xFF); - color.add((strip->getColors(seg)[2] >> 8) & 0xFF); - color.add((strip->getColors(seg)[2]) & 0xFF); + if (seg == FXSettings.segment) { + color.add(main_color.white); + color.add(main_color.red); + color.add(main_color.green); + color.add(main_color.blue); + color.add(back_color.white); + color.add(back_color.red); + color.add(back_color.green); + color.add(back_color.blue); + color.add(xtra_color.white); + color.add(xtra_color.red); + color.add(xtra_color.green); + color.add(xtra_color.blue); + } else { + color.add((strip->getColors(seg)[0] >> 24) & 0xFF); + color.add((strip->getColors(seg)[0] >> 16) & 0xFF); + color.add((strip->getColors(seg)[0] >> 8) & 0xFF); + color.add((strip->getColors(seg)[0]) & 0xFF); + color.add((strip->getColors(seg)[1] >> 24) & 0xFF); + color.add((strip->getColors(seg)[1] >> 16) & 0xFF); + color.add((strip->getColors(seg)[1] >> 8) & 0xFF); + color.add((strip->getColors(seg)[1]) & 0xFF); + color.add((strip->getColors(seg)[2] >> 24) & 0xFF); + color.add((strip->getColors(seg)[2] >> 16) & 0xFF); + color.add((strip->getColors(seg)[2] >> 8) & 0xFF); + color.add((strip->getColors(seg)[2]) & 0xFF); + } + root["ws_fxopt"] = fx_options; uint16_t msg_len = measureJson(root) + 1; char * buffer = (char *) malloc(msg_len); serializeJson(root, buffer, msg_len); @@ -111,9 +124,9 @@ void getStateJSON() { char * listConfigJSON() { #if defined(ENABLE_MQTT) - const size_t bufferSize = JSON_OBJECT_SIZE(11) + 150; + const size_t bufferSize = JSON_OBJECT_SIZE(10) + 150; #else - const size_t bufferSize = JSON_OBJECT_SIZE(7) + 100; + const size_t bufferSize = JSON_OBJECT_SIZE(6) + 100; #endif DynamicJsonDocument jsonBuffer(bufferSize); JsonObject root = jsonBuffer.to(); @@ -125,11 +138,10 @@ char * listConfigJSON() { root["mqtt_pass"] = mqtt_pass; #endif root["ws_seg"] = num_segments; - root["ws_cnt"] = WS2812FXStripSettings.stripSize; - root["ws_rgbo"] = WS2812FXStripSettings.RGBOrder; - root["ws_pin"] = WS2812FXStripSettings.pin; - root["ws_fxopt"] = WS2812FXStripSettings.fxoptions; - root["transEffect"] = transEffect; + root["ws_cnt"] = FXSettings.stripSize; + root["ws_rgbo"] = FXSettings.RGBOrder; + root["ws_pin"] = FXSettings.pin; + root["ws_trans"] = FXSettings.transEffect; uint16_t msg_len = measureJson(root) + 1; char * buffer = (char *) malloc(msg_len); serializeJson(root, buffer, msg_len); @@ -199,10 +211,10 @@ char * listESPStateJSON() { #else root["animation_lib"] = "WS2812FX"; #endif - root["ws2812_pin"] = WS2812FXStripSettings.pin; - root["led_count"] = WS2812FXStripSettings.stripSize; - root["rgb_order"] = WS2812FXStripSettings.RGBOrder; - if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) { + root["ws2812_pin"] = FXSettings.pin; + root["led_count"] = FXSettings.stripSize; + root["rgb_order"] = FXSettings.RGBOrder; + if (strstr(FXSettings.RGBOrder, "W") != NULL) { root["rgbw_mode"] = "ON"; } else { root["rgbw_mode"] = "OFF"; diff --git a/Arduino/McLighting/mode_custom_ws2812fx_animations.h b/Arduino/McLighting/mode_custom_ws2812fx_animations.h index eab6ee2..ba6c6bd 100644 --- a/Arduino/McLighting/mode_custom_ws2812fx_animations.h +++ b/Arduino/McLighting/mode_custom_ws2812fx_animations.h @@ -1,14 +1,12 @@ // Prototypes -uint16_t convertSpeed(uint8_t mcl_speed); -uint32_t trans(uint32_t newcolor, uint32_t oldcolor, uint8_t level); +uint16_t convertSpeed(uint16_t _mcl_speed); +uint32_t trans(uint32_t _newcolor, uint32_t _oldcolor, uint8_t _level, uint8_t _steps); // End Prototypes /* - Example of adding the example: https://github.com/kitesurfer1404/WS2812FX/blob/master/examples/ws2812fx_custom_FastLED/ws2812fx_custom_FastLED.ino as a custom effect More info on how to create custom aniamtions for WS2812FX: https://github.com/kitesurfer1404/WS2812FX/blob/master/extras/WS2812FX%20Users%20Guide.md#custom-effects - */ // *************************************************************************** @@ -16,85 +14,123 @@ More info on how to create custom aniamtions for WS2812FX: https://github.com/ki // *************************************************************************** void handleAutoPlay() { - if (autoDelay <= millis()) { - hex_colors[0] = autoParams[autoCount][0]; - hex_colors[1] = autoParams[autoCount][1]; - hex_colors[2] = autoParams[autoCount][2]; - strip->setColors(segment, hex_colors); - strip->setSpeed(segment, convertSpeed((uint8_t)autoParams[autoCount][3])); - strip->setMode(segment, (uint8_t)autoParams[autoCount][4]); + WS2812FX::Segment* _seg = strip->getSegment(); + if (autoDelay <= millis()) { + hex_colors_trans[0] = autoParams[autoCount][0]; + hex_colors_trans[1] = autoParams[autoCount][1]; + hex_colors_trans[2] = autoParams[autoCount][2]; + strip->setColors(FXSettings.segment, hex_colors_trans); + strip->setSpeed(FXSettings.segment, convertSpeed((uint16_t)autoParams[autoCount][3])); + strip->setMode(FXSettings.segment, (uint8_t)autoParams[autoCount][4]); strip->trigger(); autoDelay = millis() + (uint32_t)autoParams[autoCount][5]; DBG_OUTPUT_PORT.print("autoTick "); DBG_OUTPUT_PORT.printf("autoTick[%d]: {0x%08x, 0x%08x, 0x%08x, %d, %d, %d}\r\n", autoCount, hex_colors[0], hex_colors[1], hex_colors[2], autoParams[autoCount][3], autoParams[autoCount][4], autoParams[autoCount][5]); - autoCount++; if (autoCount >= (sizeof(autoParams) / sizeof(autoParams[0]))) autoCount = 0; } } -void handleAuto() { - // Dummy function -} - -void handleCustomWS() { - // Dummy function -} - #if defined(CUSTOM_WS2812FX_ANIMATIONS) -// *************************************************************************** -// TV mode -// *************************************************************************** - -uint8_t dipInterval = 10; -uint16_t darkTime = 250; -unsigned long currentDipTime; -unsigned long dipStartTime; -unsigned long currentMillis; -uint8_t ledState = LOW; -long previousMillis = 0; -uint16_t led = 5; -uint16_t interv = 2000; -uint8_t twitch = 50; -uint8_t dipCount = 0; -boolean timeToDip = false; - - -void hsb2rgbAN1(uint16_t index, uint8_t sat, uint8_t bright, uint16_t led) { - // Source: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ - uint8_t temp[5], n = (index >> 8) % 3; - temp[0] = temp[3] = (uint8_t)(( (sat ^ 255) * bright) / 255); - temp[1] = temp[4] = (uint8_t)((((( (index & 255) * sat) / 255) + (sat ^ 255)) * bright) / 255); - temp[2] = (uint8_t)(((((((index & 255) ^ 255) * sat) / 255) + (sat ^ 255)) * bright) / 255); - strip->setPixelColor(led, temp[n + 2], temp[n + 1], temp[n], 0); -} - - -void updateLed (uint16_t led, uint8_t brightness) { - ledstates[led] = brightness; - for (uint16_t i=seg_start; i<=seg_stop; i++) { - uint16_t index = (i%3 == 0) ? 400 : random(0,767); - hsb2rgbAN1(index, 200, ledstates[i], i); + // *************************************************************************** + // TV mode + // *************************************************************************** + uint8_t dipInterval = 10; + uint16_t darkTime = 250; + unsigned long currentDipTime; + unsigned long dipStartTime; + unsigned long currentMillis; + uint8_t ledState = LOW; + long previousMillis = 0; + uint16_t interv = 2000; + uint8_t twitch = 50; + uint8_t dipCount = 0; + boolean timeToDip = false; + + + void hsb2rgbAN1(uint16_t index, uint8_t sat, uint8_t bright, uint16_t led) { + // Source: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/ + uint8_t temp[5], n = (index >> 8) % 3; + temp[0] = temp[3] = (uint8_t)(( (sat ^ 255) * bright) / 255); + temp[1] = temp[4] = (uint8_t)((((( (index & 255) * sat) / 255) + (sat ^ 255)) * bright) / 255); + temp[2] = (uint8_t)(((((((index & 255) ^ 255) * sat) / 255) + (sat ^ 255)) * bright) / 255); + strip->setPixelColor(led, temp[n + 2], temp[n + 1], temp[n], 0); } - //strip->show(); + + /* + * paste in the Fire2012 code with a small edit at the end which uses the + * setPixelColor() function to copy the color data to the ws2812fx instance. + */ + #include //https://github.com/FastLED/FastLED + // Fire2012 by Mark Kriegsman, July 2012 + // as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY + //// + // This basic one-dimensional 'fire' simulation works roughly as follows: + // There's a underlying array of 'heat' cells, that model the temperature + // at each point along the line. Every cycle through the simulation, + // four steps are performed: + // 1) All cells cool down a little bit, losing heat to the air + // 2) The heat from each cell drifts 'up' and diffuses a little + // 3) Sometimes randomly new 'sparks' of heat are added at the bottom + // 4) The heat from each cell is rendered as a color into the leds array + // The heat-to-color mapping uses a black-body radiation approximation. + // + // Temperature is in arbitrary units from 0 (cold black) to 255 (white hot). + // + // This simulation scales it self a bit depending on NUM_LEDS; it should look + // "OK" on anywhere from 20 to 100 LEDs without too much tweaking. + // + // I recommend running this simulation at anywhere from 30-100 frames per second, + // meaning an interframe delay of about 10-35 milliseconds. + // + // Looks best on a high-density LED setup (60+ pixels/meter). + // + // + // There are two main parameters you can play with to control the look and + // feel of your fire: COOLING (used in step 1 above), and SPARKING (used + // in step 3 above). + // + // COOLING: How much does the air cool as it rises? + // Less cooling = taller flames. More cooling = shorter flames. + // Default 50, suggested range 20-100 + #define COOLING 70 + + // SPARKING: What chance (out of 255) is there that a new spark will be lit? + // Higher chance = more roaring fire. Lower chance = more flickery fire. + // Default 120, suggested range 50-200. + #define SPARKING 120 + +#endif + +uint16_t handleAuto() { + WS2812FX::Segment* _seg = strip->getSegment(); + return _seg->speed; } - -// See: http://forum.mysensors.org/topic/85/phoneytv-for-vera-is-here/13 -void handleTV() { +uint16_t handleCustomWS(void) { + WS2812FX::Segment* _seg = strip->getSegment(); + return _seg->speed; +} +#if defined(CUSTOM_WS2812FX_ANIMATIONS) +uint16_t handleTV(void) { + WS2812FX::Segment* _seg = strip->getSegment(); if (timeToDip == false) { currentMillis = millis(); if(currentMillis-previousMillis > interv) { previousMillis = currentMillis; //interv = random(750,4001);//Adjusts the interval for more/less frequent random light changes - interv = random(1000-(ws2812fx_speed*2),5001-(ws2812fx_speed*8)); + interv = random(1000-(fx_speed*2),5001-(fx_speed*8)); twitch = random(40,100);// Twitch provides motion effect but can be a bit much if too high dipCount = dipCount++; } if(currentMillis-previousMillisstart, _seg->stop); + ledState = ledState == LOW ? HIGH : LOW; // if the LED is off turn it on and vice-versa: + ledstates[led] = ((ledState) ? 255 : 0); + for (uint16_t j=_seg->start; j<=_seg->stop; j++) { + uint16_t index = (j%3 == 0) ? 400 : random(0,767); + hsb2rgbAN1(index, 200, ledstates[j], j); + } if (dipCount > dipInterval) { DBG_OUTPUT_PORT.println("dip"); timeToDip = true; @@ -108,25 +144,30 @@ void handleTV() { DBG_OUTPUT_PORT.println("Dip Time"); currentDipTime = millis(); if (currentDipTime - dipStartTime < darkTime) { - for (uint16_t i=3; istart + 3); i<= _seg->stop; i++) { + ledstates[i] = brightness; + for (uint16_t j=_seg->start; j<=_seg->stop; j++) { + uint16_t index = (j%3 == 0) ? 400 : random(0,767); + hsb2rgbAN1(index, 200, ledstates[j], j); + } } } else { timeToDip = false; } } + return _seg->speed; } -void handleE131(){ - if (!e131->isEmpty()) - { +uint16_t handleE131(void) { + WS2812FX::Segment* _seg = strip->getSegment(); + if (!e131->isEmpty()) { e131_packet_t packet; e131->pull(&packet); // Pull packet from ring buffer uint16_t universe = htons(packet.universe); uint8_t *data = packet.property_values + 1; - if (universe < START_UNIVERSE || universe > END_UNIVERSE) return; //async will take care about filling the buffer + if (universe < START_UNIVERSE || universe > END_UNIVERSE) return _seg->speed; //async will take care about filling the buffer // Serial.printf("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH1: %u\n", // htons(packet.universe), // The Universe for this packet @@ -137,143 +178,72 @@ void handleE131(){ /* #if defined(RGBW) uint16_t multipacketOffset = (universe - START_UNIVERSE) * 128; //if more than 128 LEDs * 4 colors = 512 channels, client will send in next higher universe if (NUMLEDS <= multipacketOffset) return; - uint16_t len = (128 + multipacketOffset > WS2812FXStripSettings.stripSize) ? (WS2812FXStripSettings.stripSize - multipacketOffset) : 128; + uint16_t len = (128 + multipacketOffset > FXSettings.stripSize) ? (FXSettings.stripSize - multipacketOffset) : 128; #else*/ uint16_t multipacketOffset = (universe - START_UNIVERSE) * 170; //if more than 170 LEDs * 3 colors = 510 channels, client will send in next higher universe - if (WS2812FXStripSettings.stripSize <= multipacketOffset) return; - uint16_t len = (170 + multipacketOffset > WS2812FXStripSettings.stripSize) ? (WS2812FXStripSettings.stripSize - multipacketOffset) : 170; + if (FXSettings.stripSize <= multipacketOffset) return _seg->speed; + uint16_t len = (170 + multipacketOffset > FXSettings.stripSize) ? (FXSettings.stripSize - multipacketOffset) : 170; /* #endif */ for (uint16_t i = 0; i < len; i++){ - uint16_t j = i * 3; -/* #if defined(RGBW) - strip->setPixelColor(i + multipacketOffset, data[j], data[j + 1], data[j + 2], data[j + 3]); - #else */ - strip->setPixelColor(i + multipacketOffset, data[j], data[j + 1], data[j + 2], 0); -/* #endif */ + if ((i >= _seg->start) && (i <= _seg->stop)) { + uint16_t j = i * 3; + /* #if defined(RGBW) + strip->setPixelColor(i + multipacketOffset, data[j], data[j + 1], data[j + 2], data[j + 3]); + #else */ + strip->setPixelColor(i + multipacketOffset, data[j], data[j + 1], data[j + 2], 0); + /* #endif */ + } } } + return _seg->speed; } -#include //https://github.com/FastLED/FastLED -/* - * paste in the Fire2012 code with a small edit at the end which uses the - * setPixelColor() function to copy the color data to the ws2812fx instance. -*/ - - // Fire2012 by Mark Kriegsman, July 2012 -// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY -//// -// This basic one-dimensional 'fire' simulation works roughly as follows: -// There's a underlying array of 'heat' cells, that model the temperature -// at each point along the line. Every cycle through the simulation, -// four steps are performed: -// 1) All cells cool down a little bit, losing heat to the air -// 2) The heat from each cell drifts 'up' and diffuses a little -// 3) Sometimes randomly new 'sparks' of heat are added at the bottom -// 4) The heat from each cell is rendered as a color into the leds array -// The heat-to-color mapping uses a black-body radiation approximation. -// -// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot). -// -// This simulation scales it self a bit depending on NUM_LEDS; it should look -// "OK" on anywhere from 20 to 100 LEDs without too much tweaking. -// -// I recommend running this simulation at anywhere from 30-100 frames per second, -// meaning an interframe delay of about 10-35 milliseconds. -// -// Looks best on a high-density LED setup (60+ pixels/meter). -// -// -// There are two main parameters you can play with to control the look and -// feel of your fire: COOLING (used in step 1 above), and SPARKING (used -// in step 3 above). -// -// COOLING: How much does the air cool as it rises? -// Less cooling = taller flames. More cooling = shorter flames. -// Default 50, suggested range 20-100 -#define COOLING 70 - -// SPARKING: What chance (out of 255) is there that a new spark will be lit? -// Higher chance = more roaring fire. Lower chance = more flickery fire. -// Default 120, suggested range 50-200. -#define SPARKING 120 - -bool gReverseDirection = false; - -void Fire2012() { +uint16_t handleFire2012(void) { // Array of temperature readings at each simulation cell - + WS2812FX::Segment* _seg = strip->getSegment(); + // Step 1. Cool down every cell a little - for( uint16_t i = seg_start; i <= seg_stop; i++) { - ledstates[i] = qsub8( ledstates[i], random8(0, ((COOLING * 10) / WS2812FXStripSettings.stripSize) + 2)); + for( uint16_t i = _seg->start; i <= _seg->stop; i++) { + ledstates[i] = qsub8(ledstates[i], random8(0, ((COOLING * 10) / (_seg->stop - _seg->start)+1) + 2)); } // Step 2. Heat from each cell drifts 'up' and diffuses a little - for( uint16_t k= seg_stop-seg_start - 1; k >= 2; k--) { + for( uint16_t k= _seg->stop; k >= (_seg->start + 2); k--) { ledstates[k] = (ledstates[k - 1] + ledstates[k - 2] + ledstates[k - 2]) / 3; } // Step 3. Randomly ignite new 'sparks' of heat near the bottom if( random8() < SPARKING ) { - uint8_t y = random8(7); + uint8_t y = random8(7) + _seg->start; ledstates[y] = qadd8(ledstates[y], random8(160,255) ); } // Step 4. Map from heat cells to LED colors - for( uint16_t j = seg_start; j <= seg_stop; j++) { - CRGB color = HeatColor( ledstates[j]); - uint16_t pixelnumber; - if( gReverseDirection ) { - pixelnumber = seg_stop - j; + for( uint16_t j = _seg->start; j <= _seg->stop; j++) { + CRGB color = HeatColor(ledstates[j]); + uint16_t pixel; + if ((_seg->options & 128) > 0) { + pixel = _seg->stop - j; } else { - pixelnumber = j; + pixel = j; } - strip->setPixelColor(pixelnumber, color.red, color.green, color.blue, 0); + strip->setPixelColor(pixel, color.red, color.green, color.blue, 0); } + return _seg->speed; } -void Gradient() { - for( uint16_t j = seg_start; j <= seg_stop; j++) { - uint16_t pixelnumber; - uint32_t color; - if( gReverseDirection ) { - pixelnumber = seg_stop - j; +uint16_t handleGradient() { + WS2812FX::Segment* _seg = strip->getSegment(); + for(uint16_t j = 0; j <= (_seg->stop - _seg->start); j++) { + uint16_t pixel; + if ((_seg->options & 128) > 0) { + pixel = _seg->stop - j; } else { - pixelnumber = j; + pixel = _seg->start + j; } - color = trans(strip->getColors(segment)[1], strip->getColors(segment)[0], (j*255)/(seg_stop - seg_start)); - strip->setPixelColor(pixelnumber, ((color >> 16) & 0xFF), ((color >> 8) & 0xFF), ((color >> 0) & 0xFF), ((color >> 24) & 0xFF)); + uint32_t color = trans(_seg->colors[1], _seg->colors[0], j, (_seg->stop - _seg->start)); + strip->setPixelColor(pixel, ((color >> 16) & 0xFF), ((color >> 8) & 0xFF), ((color >> 0) & 0xFF), ((color >> 24) & 0xFF)); } -} -#endif - -uint16_t myCustomEffect0() { - handleAuto(); - return (strip->getSpeed(segment) / WS2812FXStripSettings.stripSize); -} - -uint16_t myCustomEffect1() { - handleCustomWS(); - return (strip->getSpeed(segment) / WS2812FXStripSettings.stripSize); -} -#if defined(CUSTOM_WS2812FX_ANIMATIONS) -uint16_t myCustomEffect2() { - handleTV(); - return (strip->getSpeed(segment) / WS2812FXStripSettings.stripSize); -} - -uint16_t myCustomEffect3() { - handleE131(); - return (strip->getSpeed(segment) / WS2812FXStripSettings.stripSize); -} - -uint16_t myCustomEffect4() { - Fire2012(); - return (strip->getSpeed(segment) / WS2812FXStripSettings.stripSize); -} - -uint16_t myCustomEffect5() { - Gradient(); - return (strip->getSpeed(segment) / WS2812FXStripSettings.stripSize); + return _seg->speed; } #endif diff --git a/Arduino/McLighting/request_handlers.h b/Arduino/McLighting/request_handlers.h index f636a02..b719ba0 100644 --- a/Arduino/McLighting/request_handlers.h +++ b/Arduino/McLighting/request_handlers.h @@ -7,7 +7,7 @@ bool handleSetMainColor(uint8_t * mypayload) { // decode rgb data uint32_t rgb = (uint32_t) strtoul((const char *) &mypayload[1], NULL, 16); - if (rgb != strip->getColors(segment)[0]) { + if (rgb != strip->getColors(FXSettings.segment)[0]) { main_color.white = ((rgb >> 24) & 0xFF); main_color.red = ((rgb >> 16) & 0xFF); main_color.green = ((rgb >> 8) & 0xFF); @@ -20,7 +20,7 @@ bool handleSetMainColor(uint8_t * mypayload) { bool handleSetBackColor(uint8_t * mypayload) { // decode rgb data uint32_t rgb = (uint32_t) strtoul((const char *) &mypayload[2], NULL, 16); - if (rgb != strip->getColors(segment)[1]) { + if (rgb != strip->getColors(FXSettings.segment)[1]) { back_color.white = ((rgb >> 24) & 0xFF); back_color.red = ((rgb >> 16) & 0xFF); back_color.green = ((rgb >> 8) & 0xFF); @@ -32,7 +32,7 @@ bool handleSetBackColor(uint8_t * mypayload) { bool handleSetXtraColor(uint8_t * mypayload) { // decode rgb data uint32_t rgb = (uint32_t) strtoul((const char *) &mypayload[3], NULL, 16); - if (rgb != strip->getColors(segment)[2]) { + if (rgb != strip->getColors(FXSettings.segment)[2]) { xtra_color.white = ((rgb >> 24) & 0xFF); xtra_color.red = ((rgb >> 16) & 0xFF); xtra_color.green = ((rgb >> 8) & 0xFF); @@ -45,13 +45,13 @@ bool handleSetXtraColor(uint8_t * mypayload) { bool handleSetAllMode(uint8_t * mypayload) { // decode rgb data uint32_t rgb = (uint32_t) strtoul((const char *) &mypayload[1], NULL, 16); - if ((mode = OFF) || (ws2812fx_mode != strip->getMode(segment)) || (rgb != strip->getColors(segment)[0])) { + if ((mode = OFF) || (fx_mode != strip->getMode(FXSettings.segment)) || (rgb != strip->getColors(FXSettings.segment)[0])) { main_color.white = ((rgb >> 24) & 0xFF); main_color.red = ((rgb >> 16) & 0xFF); main_color.green = ((rgb >> 8) & 0xFF); main_color.blue = ((rgb >> 0) & 0xFF); DBG_OUTPUT_PORT.printf("WS: Set all leds to main color: R: [%u] G: [%u] B: [%u] W: [%u]\r\n", main_color.red, main_color.green, main_color.blue, main_color.white); - ws2812fx_mode = FX_MODE_STATIC; + fx_mode = FX_MODE_STATIC; mode = SET; return true; } @@ -65,8 +65,8 @@ void handleSetSingleLED(uint8_t * mypayload, uint8_t firstChar = 0) { templed[4] = 0x00; uint8_t led = atoi(templed); - DBG_OUTPUT_PORT.printf("led value: [%i]. Entry threshold: <= [%i] (=> %s)\r\n", led, WS2812FXStripSettings.stripSize, mypayload ); - if (led <= WS2812FXStripSettings.stripSize) { + DBG_OUTPUT_PORT.printf("led value: [%i]. Entry threshold: <= [%i] (=> %s)\r\n", led, FXSettings.stripSize, mypayload ); + if (led <= FXSettings.stripSize) { char redhex[3]; char greenhex[3]; char bluehex[3]; @@ -101,7 +101,7 @@ void handleSetSingleLED(uint8_t * mypayload, uint8_t firstChar = 0) { strip->show(); } mode = HOLD; - ws2812fx_mode= FX_MODE_CUSTOM_1; + fx_mode= FX_MODE_CUSTOM_1; } void handleSetDifferentColors(uint8_t * mypayload) { @@ -152,10 +152,10 @@ bool setModeByStateString(String saved_state_string) { DBG_OUTPUT_PORT.printf("Parsed state: %s\r\n", saved_state_string.c_str()); String str_mode = getValue(saved_state_string, '|', 1); mode = static_cast(str_mode.toInt()); - String str_ws2812fx_mode = getValue(saved_state_string, '|', 2); - ws2812fx_mode = str_ws2812fx_mode.toInt(); - String str_ws2812fx_speed = getValue(saved_state_string, '|', 3); - ws2812fx_speed = str_ws2812fx_speed.toInt(); + String str_fx_mode = getValue(saved_state_string, '|', 2); + fx_mode = str_fx_mode.toInt(); + String str_fx_speed = getValue(saved_state_string, '|', 3); + fx_speed = str_fx_speed.toInt(); String str_brightness = getValue(saved_state_string, '|', 4); brightness = str_brightness.toInt(); String str_red = getValue(saved_state_string, '|', 5); @@ -196,12 +196,12 @@ bool setModeByStateString(String saved_state_string) { void handleSetWS2812FXMode(uint8_t * mypayload) { if (isDigit(mypayload[1])) { - ws2812fx_mode = (uint8_t) strtol((const char *) &mypayload[1], NULL, 10); - ws2812fx_mode = constrain(ws2812fx_mode, 0, strip->getModeCount() - 1); + fx_mode = (uint8_t) strtol((const char *) &mypayload[1], NULL, 10); + fx_mode = constrain(fx_mode, 0, strip->getModeCount() - 1); mode = SET; } else { if (strcmp((char *) &mypayload[1], "off") == 0) { - mode = OFF; + if (mode == OFF) { mode = SET; } else { mode = OFF; }; } if (strcmp((char *) &mypayload[1], "on") == 0) { mode = SET; @@ -268,36 +268,57 @@ void checkpayload(uint8_t * _payload, bool mqtt = false, uint8_t num = 0) { if (_payload[0] == 'S') { if (_payload[1] == 's') { uint8_t seg = (uint8_t) strtol((const char *) &_payload[2], NULL, 10); - segment = constrain(seg, 0, MAX_NUM_SEGMENTS); - if (prevsegment != segment) { - prevsegment = segment; - getSegmentParams(segment); + FXSettings.segment = constrain(seg, 0, num_segments - 1); + if (prevsegment != FXSettings.segment) { + prevsegment = FXSettings.segment; + getSegmentParams(FXSettings.segment); + //convertColors(); + //memcpy(hex_colors, hex_colors_trans, sizeof(hex_colors_trans)); memcpy(hex_colors_trans, hex_colors, sizeof(hex_colors_trans)); - mode = SET; _updateState = true; Dbg_Prefix(mqtt, num); - DBG_OUTPUT_PORT.printf("Set segment to: [%u]\r\n", segment); + DBG_OUTPUT_PORT.printf("Set segment to: [%u]\r\n", FXSettings.segment); } } // / ==> Set segment first LED if (_payload[1] == '[') { - uint16_t segstart = (uint8_t) strtol((const char *) &_payload[2], NULL, 10); - getSegmentParams(segment); - seg_start = constrain(segstart, 0, WS2812FXStripSettings.stripSize); - _updateSegState = true; - Dbg_Prefix(mqtt, num); - DBG_OUTPUT_PORT.printf("Set segment start to: [%u]\r\n", segstart); + uint16_t _seg_start = (uint16_t) strtol((const char *) &_payload[2], NULL, 10); + //getSegmentParams(FXSettings.segment); + _seg_start = constrain(_seg_start, 0, FXSettings.stripSize - 1); + if (_seg_start != seg_start) { + seg_start = _seg_start; + _updateSegState = true; + setSegmentSize(); + Dbg_Prefix(mqtt, num); + DBG_OUTPUT_PORT.printf("Set segment start to: [%u]\r\n", _seg_start); + } } // / ==> Set segment last LED if (_payload[1] == ']') { - uint16_t segstop = (uint8_t) strtol((const char *) &_payload[2], NULL, 10); - getSegmentParams(segment); - seg_stop = constrain(segstop, 0, WS2812FXStripSettings.stripSize - 1); - _updateSegState = true; - Dbg_Prefix(mqtt, num); - DBG_OUTPUT_PORT.printf("Set segment stop to: [%u]\r\n", segstop); - } - char * buffer = listSegmentStateJSON(segment); + uint16_t _seg_stop = (uint16_t) strtol((const char *) &_payload[2], NULL, 10); + //getSegmentParams(FXSettings.segment); + _seg_stop = constrain(_seg_stop, seg_start, FXSettings.stripSize - 1); + if (_seg_stop != seg_stop) { + seg_stop = _seg_stop; + _updateSegState = true; + setSegmentSize(); + Dbg_Prefix(mqtt, num); + DBG_OUTPUT_PORT.printf("Set segment stop to: [%u]\r\n", _seg_stop); + } + } + if (_payload[1] == 'o') { + char _fx_options[4]; + snprintf(_fx_options, sizeof(_fx_options), "%s", &_payload[2]); + _fx_options[3] = 0x00; + if (((constrain(atoi(_fx_options), 0, 255)>>1)<<1) != fx_options) { + fx_options = ((constrain(atoi(_fx_options), 0, 255)>>1)<<1); + _updateSegState = true; + strip->setOptions(FXSettings.segment, fx_options); + Dbg_Prefix(mqtt, num); + DBG_OUTPUT_PORT.printf("Set segment options to: [%u]\r\n", fx_options); + } + } + char * buffer = listSegmentStateJSON(FXSettings.segment); if (mqtt == true) { DBG_OUTPUT_PORT.print("MQTT: "); #if defined(ENABLE_MQTT) @@ -317,7 +338,7 @@ void checkpayload(uint8_t * _payload, bool mqtt = false, uint8_t num = 0) { // / ==> Set WS2812 mode. if (_payload[0] == '/') { handleSetWS2812FXMode(_payload); - if (ws2812fx_mode != strip->getMode(segment)) { + if (fx_mode != strip->getMode(FXSettings.segment)) { _updateSegState = true; Dbg_Prefix(mqtt, num); DBG_OUTPUT_PORT.printf("Set WS2812 mode: [%s]\r\n", _payload); @@ -354,12 +375,12 @@ void checkpayload(uint8_t * _payload, bool mqtt = false, uint8_t num = 0) { // ? ==> Set speed if (_payload[0] == '?') { - uint8_t d = (uint8_t) strtol((const char *) &_payload[1], NULL, 10); - ws2812fx_speed = constrain(d, 0, 255); + uint16_t _fx_speed = (uint16_t) strtol((const char *) &_payload[1], NULL, 10); + fx_speed = constrain(_fx_speed, SPEED_MIN, SPEED_MAX ); mode = SET; _updateSegState = true; Dbg_Prefix(mqtt, num); - DBG_OUTPUT_PORT.printf("Set speed to: [%u]\r\n", ws2812fx_speed); + DBG_OUTPUT_PORT.printf("Set speed to: [%u]\r\n", fx_speed); } // % ==> Set brightness @@ -430,26 +451,31 @@ void checkpayload(uint8_t * _payload, bool mqtt = false, uint8_t num = 0) { if (_payload[0] == 'C') { bool _updateStrip = false; bool _updateConfig = false; + bool _updateSegState = false; if (_payload[1] == 's') { if (_payload[2] == 's') { - char tmp_segments[3]; - snprintf(tmp_segments, sizeof(tmp_segments), "%s", &_payload[3]); - tmp_segments[2] = 0x00; - num_segments = constrain(atoi(tmp_segments), 1, MAX_NUM_SEGMENTS - 1); + char _num_segments[3]; + snprintf(_num_segments, sizeof(_num_segments), "%s", &_payload[3]); + _num_segments[2] = 0x00; + num_segments = constrain(atoi(_num_segments), 1, MAX_NUM_SEGMENTS - 1); + if (FXSettings.segment >= num_segments) { + FXSettings.segment = num_segments - 1; + } _updateStrip = true; + _updateSegState = true; } if (_payload[2] == 'c') { char tmp_count[6]; snprintf(tmp_count, sizeof(tmp_count), "%s", &_payload[3]); tmp_count[5] = 0x00; - WS2812FXStripSettings.stripSize = constrain(atoi(tmp_count), 1, MAXLEDS); + FXSettings.stripSize = constrain(atoi(tmp_count), 1, MAXLEDS); _updateStrip = true; } if (_payload[2] == 'r') { - char tmp_rgbOrder[5]; - snprintf(tmp_rgbOrder, sizeof(tmp_rgbOrder), "%s", &_payload[3]); - tmp_rgbOrder[4] = 0x00; - checkRGBOrder(tmp_rgbOrder); + char _rgbOrder[5]; + snprintf(_rgbOrder, sizeof(_rgbOrder), "%s", &_payload[3]); + _rgbOrder[4] = 0x00; + checkRGBOrder(_rgbOrder); _updateStrip=true; } #if !defined(USE_WS2812FX_DMA) @@ -460,14 +486,7 @@ void checkpayload(uint8_t * _payload, bool mqtt = false, uint8_t num = 0) { checkPin(atoi(tmp_pin)); _updateStrip = true; } - #endif - if (_payload[2] == 'o') { - char tmp_fxoptions[4]; - snprintf(tmp_fxoptions, sizeof(tmp_fxoptions), "%s", &_payload[3]); - tmp_fxoptions[3] = 0x00; - WS2812FXStripSettings.fxoptions = ((constrain(atoi(tmp_fxoptions), 0, 255)>>1)<<1); - _updateStrip = true; - } + #endif } if (_updateStrip){ initStrip(); @@ -507,10 +526,10 @@ void checkpayload(uint8_t * _payload, bool mqtt = false, uint8_t num = 0) { } #endif if (_payload[1] == 'e') { - char tmp_transEffect[2]; - snprintf(tmp_transEffect, sizeof(tmp_transEffect), "%s", &_payload[2]); - tmp_transEffect[sizeof(tmp_transEffect) - 1] = 0x00; - transEffect = atoi(tmp_transEffect); + char _transEffect[2]; + snprintf(_transEffect, sizeof(_transEffect), "%s", &_payload[2]); + _transEffect[sizeof(_transEffect) - 1] = 0x00; + FXSettings.transEffect = atoi(_transEffect); _updateConfig = true; } @@ -535,9 +554,15 @@ void checkpayload(uint8_t * _payload, bool mqtt = false, uint8_t num = 0) { DBG_OUTPUT_PORT.println("Saving config.json!"); if(!save_conf.active()) save_conf.once(3, tickerSaveConfig); } + if (_updateSegState) { + DBG_OUTPUT_PORT.println("Saving stripstate_segment.json!"); + if(!save_seg_state.active()) save_seg_state.once(3, tickerSaveSegmentState); + + } #endif _updateStrip = false; _updateConfig = false; + _updateSegState = false; DBG_OUTPUT_PORT.printf("Get status info: %s\r\n", buffer); free (buffer); } @@ -705,12 +730,12 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght color["g3"] = xtra_color.green; color["b3"] = xtra_color.blue; color["w3"] = xtra_color.white; - if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) { + if (strstr(FXSettings.RGBOrder, "W") != NULL) { root["white_value"]= main_color.white; } root["brightness"] = brightness; root["color_temp"] = color_temp; - root["speed"] = ws2812fx_speed; + root["speed"] = fx_speed; //char modeName[30]; //strncpy_P(modeName, (PGM_P)strip->getModeName(strip->getMode()), sizeof(modeName)); // copy from progmem #if defined(ENABLE_HOMEASSISTANT) @@ -787,9 +812,9 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght } if (root.containsKey("speed")) { - uint8_t json_speed = constrain((uint8_t) root["speed"], 0, 255); - if (json_speed != ws2812fx_speed) { - ws2812fx_speed = json_speed; + uint16_t _fx_speed = constrain((uint8_t) root["speed"], SPEED_MIN, SPEED_MAX); + if (_fx_speed != fx_speed) { + fx_speed = _fx_speed; mode = SET; } } @@ -820,7 +845,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght for (uint8_t i = 0; i < strip->getModeCount(); i++) { if(String(strip->getModeName(i)) == effectString) { mode = SET; - ws2812fx_mode = i; + fx_mode = i; break; } } @@ -900,7 +925,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght #endif root["brightness"] = "true"; root["rgb"] = "true"; - if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) { + if (strstr(FXSettings.RGBOrder, "W") != NULL) { root["white_value"]= "true"; } root["optimistic"] = "false"; @@ -1005,7 +1030,7 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght #endif root["brightness"] = "true"; root["rgb"] = "true"; - if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) { + if (strstr(FXSettings.RGBOrder, "W") != NULL) { root["white_value"]= "true"; } root["optimistic"] = "false"; @@ -1203,23 +1228,23 @@ void handleRemote() { mode = SET; } } - if ((ws2812fx_mode < 56) || (ws2812fx_mode > 57)) { + if ((fx_mode < 56) || (fx_mode > 57)) { if (results.value == rmt_commands[SPEED_UP]) { //Speed Up last_remote_cmd = results.value; - if (ws2812fx_speed + chng <= 255) { - ws2812fx_speed = ws2812fx_speed + chng; + if (fx_speed + chng <= 65535) { + fx_speed = fx_speed + (chng * 5); mode = SET; } } if (results.value == rmt_commands[SPEED_DOWN]) { //Speed down last_remote_cmd = results.value; - if (ws2812fx_speed - chng >= 0) { - ws2812fx_speed = ws2812fx_speed - chng; + if (fx_speed - chng >= 0) { + fx_speed = fx_speed - (chng * 5); mode = SET; } } } - if ((ws2812fx_mode < 56) || (ws2812fx_mode > 60)) { + if ((fx_mode < 56) || (fx_mode > 60)) { if (results.value == rmt_commands[RED_UP]) { //Red Up last_remote_cmd = results.value; if (selected_color == 1) { @@ -1404,48 +1429,48 @@ void handleRemote() { } // end of if HOLD if (results.value == rmt_commands[MODE_UP]) { //Mode Up last_remote_cmd = results.value; - if ((ws2812fx_mode < strip->getModeCount()-1) && (mode == HOLD)) { - ws2812fx_mode = ws2812fx_mode + 1; + if ((fx_mode < strip->getModeCount()-1) && (mode == HOLD)) { + fx_mode = fx_mode + 1; } mode = SET; } if (results.value == rmt_commands[MODE_DOWN]) { //Mode down last_remote_cmd = results.value; - if ((ws2812fx_mode > 0) && (mode == HOLD)) { - ws2812fx_mode = ws2812fx_mode - 1; + if ((fx_mode > 0) && (mode == HOLD)) { + fx_mode = fx_mode - 1; } mode = SET; } if (results.value == rmt_commands[AUTOMODE]) { // Toggle Automode last_remote_cmd = 0; - ws2812fx_mode = 56; + fx_mode = 56; mode = SET; } #if defined(CUSTOM_WS2812FX_ANIMATIONS) if (results.value == rmt_commands[CUST_1]) { // Select TV Mode last_remote_cmd = 0; - ws2812fx_mode = 57; + fx_mode = 57; mode = SET; } #endif if (results.value == rmt_commands[CUST_2]) { // Select Custom Mode 2 last_remote_cmd = 0; - ws2812fx_mode = 12; + fx_mode = 12; mode = SET; } if (results.value == rmt_commands[CUST_3]) { // Select Custom Mode 3 last_remote_cmd = 0; - ws2812fx_mode = 48; + fx_mode = 48; mode = SET; } if (results.value == rmt_commands[CUST_4]) { // Select Custom Mode 4 last_remote_cmd = 0; - ws2812fx_mode = 21; + fx_mode = 21; mode = SET; } if (results.value == rmt_commands[CUST_5]) { // Select Custom Mode 5 last_remote_cmd = 0; - ws2812fx_mode = 46; + fx_mode = 46; mode = SET; } irrecv.resume(); // Receive the next value diff --git a/Arduino/McLighting/rest_api.h b/Arduino/McLighting/rest_api.h index 6fbbc8c..fd33fe4 100644 --- a/Arduino/McLighting/rest_api.h +++ b/Arduino/McLighting/rest_api.h @@ -92,12 +92,12 @@ server.on("/get_brightness", []() { }); server.on("/get_speed", []() { - char str_speed[4]; - snprintf(str_speed, sizeof(str_speed), "%i", ws2812fx_speed); + char str_speed[6]; + snprintf(str_speed, sizeof(str_speed), "%i", fx_speed); str_speed[sizeof(str_speed) - 1] = 0x00; server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", str_speed ); - DBG_OUTPUT_PORT.printf("/get_speed: %i\r\n", ws2812fx_speed); + DBG_OUTPUT_PORT.printf("/get_speed: %i\r\n", fx_speed); }); server.on("/get_switch", []() { @@ -161,23 +161,29 @@ server.on("/config", []() { // ToDo do not save if no change bool _updateStrip = false; bool _updateConfig = false; - if(server.hasArg("ws_seg")){ - uint8_t wsseg = server.arg("ws_seg").toInt(); - num_segments = constrain(wsseg, 1, MAX_NUM_SEGMENTS - 1); - _updateStrip = true; + if(server.hasArg("seg")){ + uint8_t _ws_seg = server.arg("seg").toInt(); + _ws_seg = constrain(_ws_seg, 1, MAX_NUM_SEGMENTS - 1); + if (_ws_seg != num_segments){ + num_segments = _ws_seg; + _updateStrip = true; + } } if(server.hasArg("ws_cnt")){ - uint16_t pixelCt = server.arg("ws_cnt").toInt(); - if (pixelCt > 0) { - WS2812FXStripSettings.stripSize = constrain(pixelCt, 1, MAXLEDS); - _updateStrip = true; + uint16_t _stripSize = server.arg("ws_cnt").toInt(); + if (_stripSize > 0) { + _stripSize = constrain(_stripSize, 1, MAXLEDS); + if (_stripSize != FXSettings.stripSize) { + FXSettings.stripSize = _stripSize; + _updateStrip = true; + } } } if(server.hasArg("ws_rgbo")){ - char tmp_rgbOrder[5]; - snprintf(tmp_rgbOrder, sizeof(tmp_rgbOrder), "%s", server.arg("ws_rgbo").c_str()); - tmp_rgbOrder[sizeof(tmp_rgbOrder) - 1] = 0x00; - checkRGBOrder(tmp_rgbOrder); + char _ws_rgbo[5]; + snprintf(_ws_rgbo, sizeof(_ws_rgbo), "%s", server.arg("ws_rgbo").c_str()); + _ws_rgbo[sizeof(_ws_rgbo) - 1] = 0x00; + checkRGBOrder(_ws_rgbo); _updateStrip = true; } @@ -186,49 +192,61 @@ server.on("/config", []() { if (checkPin(server.arg("ws_pin").toInt())) { _updateStrip = true; DBG_OUTPUT_PORT.print("Pin was set to: "); - DBG_OUTPUT_PORT.println(WS2812FXStripSettings.pin); + DBG_OUTPUT_PORT.println(FXSettings.pin); } else { - DBG_OUTPUT_PORT.println("invalid input!"); + DBG_OUTPUT_PORT.println("invalid input or same value!"); } } #endif - if(server.hasArg("ws_fxopt")){ - WS2812FXStripSettings.fxoptions = ((constrain(server.arg("ws_fxopt").toInt(), 0, 255)>>1)<<1); - _updateStrip = true; - } - if(_updateStrip) { initStrip(); } if(server.hasArg("hostname")){ - snprintf(HOSTNAME, sizeof(HOSTNAME), "%s", server.arg("hostname").c_str()); - HOSTNAME[sizeof(HOSTNAME) - 1] = 0x00; - _updateConfig = true; + char _hostname[sizeof(HOSTNAME)]; + snprintf(_hostname, sizeof(_hostname), "%s", server.arg("hostname").c_str()); + _hostname[sizeof(_hostname) - 1] = 0x00; + if (strcmp(HOSTNAME, _hostname) != 0) { + strcpy(HOSTNAME, _hostname); + _updateConfig = true; + } } #if defined(ENABLE_MQTT) if(server.hasArg("mqtt_host")){ - snprintf(mqtt_host, sizeof(mqtt_host), "%s", server.arg("mqtt_host").c_str()); - mqtt_host[sizeof(mqtt_host) - 1] = 0x00; - _updateConfig = true; + char _mqtt_host[sizeof(mqtt_host)]; + snprintf(_mqtt_host, sizeof(_mqtt_host), "%s", server.arg("mqtt_host").c_str()); + _mqtt_host[sizeof(_mqtt_host) - 1] = 0x00; + if (strcmp(mqtt_host, _mqtt_host) != 0) { + strcpy(mqtt_host, _mqtt_host); + _updateConfig = true; + } } if(server.hasArg("mqtt_port")){ - if ((server.arg("mqtt_port").toInt() >= 0) && (server.arg("mqtt_port").toInt() <=65535)) { - mqtt_port = server.arg("mqttport").toInt(); + uint16_t _mqtt_port = constrain(server.arg("mqtt_port").toInt(), 1, 65535); + if (_mqtt_port != mqtt_port) { + mqtt_port = _mqtt_port; _updateConfig = true; } } if(server.hasArg("mqtt_user")){ - snprintf(mqtt_user, sizeof(mqtt_user), "%s", server.arg("mqtt_user").c_str()); - mqtt_user[sizeof(mqtt_user) - 1] = 0x00; - _updateConfig = true; + char _mqtt_user[sizeof(mqtt_user)]; + snprintf(_mqtt_user, sizeof(_mqtt_user), "%s", server.arg("mqtt_user").c_str()); + _mqtt_user[sizeof(mqtt_user) - 1] = 0x00; + if (strcmp(mqtt_user, _mqtt_user) != 0) { + strcpy(mqtt_user, _mqtt_user); + _updateConfig = true; + } } if(server.hasArg("mqtt_pass")){ - snprintf(mqtt_pass, sizeof(mqtt_pass), "%s", server.arg("mqtt_pass").c_str()); - mqtt_pass[sizeof(mqtt_pass) - 1] = 0x00; - _updateConfig = true; + char _mqtt_pass[sizeof(mqtt_pass)]; + snprintf(_mqtt_pass, sizeof(_mqtt_pass), "%s", server.arg("mqtt_pass").c_str()); + _mqtt_pass[sizeof(_mqtt_pass) - 1] = 0x00; + if (strcmp(mqtt_pass, _mqtt_pass) != 0) { + strcpy(mqtt_pass, _mqtt_pass); + _updateConfig = true; + } } if (_updateConfig) { initMqtt(); @@ -236,7 +254,7 @@ server.on("/config", []() { #endif if(server.hasArg("trans_effect")){ - transEffect = server.arg("trans_effect").toInt(); + FXSettings.transEffect = server.arg("trans_effect").toInt(); _updateConfig = true; } @@ -272,20 +290,47 @@ server.on("/on", []() { server.on("/set", []() { prevmode = HOLD; - ws2812fx_mode = FX_MODE_STATIC; + fx_mode = FX_MODE_STATIC; boolean _updateState = false; boolean _updateSegState = false; // Segment if ((server.arg("seg") != "") && (server.arg("seg").toInt() >= 0) && (server.arg("seg").toInt() <= MAX_NUM_SEGMENTS)) { - segment = server.arg("seg").toInt(); - if (prevsegment != segment) { - prevsegment = segment; - getSegmentParams(segment); + FXSettings.segment = server.arg("seg").toInt(); + if (prevsegment != FXSettings.segment) { + prevsegment = FXSettings.segment; + getSegmentParams(FXSettings.segment); memcpy(hex_colors_trans, hex_colors, sizeof(hex_colors_trans)); mode = SET; _updateState = true; + } + } + if ((server.arg("start") != "") && (server.arg("start").toInt() >= 0) && (server.arg("start").toInt() <= MAX_NUM_SEGMENTS)) { + uint16_t _seg_start = server.arg("start").toInt(); + _seg_start = constrain(seg_start, 0, FXSettings.stripSize -1); + if (_seg_start != seg_start) { + seg_start = _seg_start; + setSegmentSize(); + _updateSegState = true; } } + if ((server.arg("stop") != "") && (server.arg("stop").toInt() >= 0) && (server.arg("stop").toInt() <= MAX_NUM_SEGMENTS)) { + uint16_t _seg_stop = server.arg("stop").toInt(); + _seg_stop = constrain(_seg_stop, seg_start, FXSettings.stripSize - 1); + if (_seg_stop != seg_stop) { + seg_stop = _seg_stop; + setSegmentSize(); + _updateSegState = true; + } + } + + if(server.hasArg("fxopt")){ + uint8_t _ws_fxopt = ((constrain(server.arg("fxopt").toInt(), 0, 255)>>1)<<1); + if (_ws_fxopt != fx_options) { + fx_options = _ws_fxopt; + strip->setOptions(FXSettings.segment, fx_options); + _updateSegState = true; + } + } //color wrgb if (server.arg("rgb") != "") { uint32_t rgb = (uint32_t) strtoul(server.arg("rgb").c_str(), NULL, 16); @@ -362,15 +407,15 @@ server.on("/set", []() { // Speed - if ((server.arg("s") != "") && (server.arg("s").toInt() >= 0) && (server.arg("s").toInt() <= 255)) { - ws2812fx_speed = constrain(server.arg("s").toInt(), 0, 255); + if ((server.arg("s") != "") && (server.arg("s").toInt() >= 0) && (server.arg("s").toInt() <= 65535)) { + fx_speed = constrain(server.arg("s").toInt(), SPEED_MIN, SPEED_MAX); mode = SET; _updateSegState = true; } //Mode if ((server.arg("m") != "") && (server.arg("m").toInt() >= 0) && (server.arg("m").toInt() <= strip->getModeCount())) { - ws2812fx_mode = constrain(server.arg("m").toInt(), 0, strip->getModeCount() - 1); - if (ws2812fx_mode != strip->getMode(segment)) { + fx_mode = constrain(server.arg("m").toInt(), 0, strip->getModeCount() - 1); + if (fx_mode != strip->getMode(FXSettings.segment)) { mode = SET; _updateSegState = true; } @@ -402,5 +447,3 @@ server.on("/set", []() { _updateState = false; _updateSegState = false; }); - -