diff --git a/60LED_WS2812B_NTP_Clock.ino b/60LED_WS2812B_NTP_Clock.ino index 374e9db..4cc70bf 100644 --- a/60LED_WS2812B_NTP_Clock.ino +++ b/60LED_WS2812B_NTP_Clock.ino @@ -61,6 +61,12 @@ RgbwColor darkred(HtmlColor(0x800000)); RgbwColor darkgreen(HtmlColor(0x006400)); RgbwColor lightgreen(HtmlColor(0x90ee90)); RgbwColor temp; +RgbwColor secondsColor = white; +RgbwColor minuteColor = darkred; +RgbwColor hourColor = gold; +RgbwColor highnoonColor = white12; +RgbwColor backlightColor = white; +RgbwColor hourMarkingColor = whiter; #else #define MINIMAL_BRIGHTNESS 20 #define LDR_SCALE 16 @@ -82,6 +88,12 @@ RgbColor darkred(HtmlColor(0x800000)); RgbColor darkgreen(HtmlColor(0x006400)); RgbColor lightgreen(HtmlColor(0x90ee90)); RgbColor temp; +RgbColor secondsColor = white; +RgbColor minuteColor = darkred; +RgbColor hourColor = gold; +RgbColor highnoonColor = white12; +RgbColor backlightColor = white; +RgbColor hourMarkingColor = whiter; #endif //NTP handler @@ -100,45 +112,66 @@ volatile int MAX_BRIGHTNESS = 200; // WebPortal const char thingName[] = "NTP-Clock-RGBLED"; const char wifiInitialApPassword[] = "12345678"; -//ToDo add internal LED and check visibility #define STRING_LEN 63 #define NUMBER_LEN 4 +// -- Maximal length the input-range attributes can have. +#define COLOR_ATTR_LENGTH 60 // -- Configuration specific key. The value should be modified if config structure was changed. -#define CONFIG_VERSION "V1.0.0" +#define CONFIG_VERSION "V1.1.2" -// -- Javascript block will be added to the header. 🔒 🔓 const char CUSTOMHTML_SCRIPT_INNER[] PROGMEM = "\n\ -document.addEventListener('DOMContentLoaded', function(event) {\n\ - let elements = document.querySelectorAll('input[type=\"password\"]');\n\ - for (let p of elements) {\n\ - let btn = document.createElement('INPUT'); btn.type = 'button'; btn.value = '🔓'; btn.style.width = 'auto'; p.style.width = '83%'; p.parentNode.insertBefore(btn,p.nextSibling);\n\ - btn.onclick = function() { if (p.type === 'password') { p.type = 'text'; btn.value = '🔒'; } else { p.type = 'password'; btn.value = '🔓'; } }\n\ - };\n\ -});\n"; -//const char CUSTOMHTML_BODY_INNER[] PROGMEM = " "; -DNSServer dnsServer; -WebServer server(80); -#ifdef ESP8266 -ESP8266HTTPUpdateServer httpUpdater; -#elif defined(ESP32) -HTTPUpdateServer httpUpdater; -#endif + function colorCh(id)\n\ + {\n\ + var x=document.getElementById(id);\n\ + var s=document.getElementById(id + 'Val');\n\ + s.innerHTML = x.value;\n\ + }\n\n\ + document.addEventListener('DOMContentLoaded', function(event) {\n\ + let elements = document.querySelectorAll('input[type=\"password\"]');\n\ + for (let p of elements) {\n\ + let btn = document.createElement('INPUT'); btn.type = 'button'; btn.value = '🔓'; btn.style.width = 'auto'; p.style.width = '80%'; p.parentNode.insertBefore(btn,p.nextSibling);\n\ + btn.onclick = function() { if (p.type === 'password') { p.type = 'text'; btn.value = '🔒'; } else { p.type = 'password'; btn.value = '🔓'; } }\n\ + };\n\ + });\n"; +const char IOTWEBCONF_HTML_FORM_COLOR_PARAM[] PROGMEM = + "
({v})" + "" + "
{e}
\n"; -char ntpServerParamValue[STRING_LEN]; -char maxBrightnessParamValue[NUMBER_LEN]; -char singleSecondParamValue[STRING_LEN]; -char allDotsOnParamValue[STRING_LEN]; -char followingHourParamValue[STRING_LEN]; +// -- Our custom class declaration. You should move it to a .h fine in your project. +class ColorWithValueParameter : public iotwebconf::NumberParameter +{ + public: + ColorWithValueParameter( + const char* label, const char* id, char* valueBuffer, int length, + const char* defaultValue + ) : iotwebconf::NumberParameter( + label, id, valueBuffer, length, defaultValue) + { + snprintf( + this->_colorAttr, COLOR_ATTR_LENGTH, + "oninput='colorCh(this.id)'"); -IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION); -IotWebConfParameterGroup timeGroup = IotWebConfParameterGroup("Time", "Time settings"); -IotWebConfTextParameter ntpServerParam = IotWebConfTextParameter("NTP Server", "ntpServer", ntpServerParamValue, STRING_LEN, "pool.ntp.org"); -IotWebConfParameterGroup ledGroup = IotWebConfParameterGroup("LED", "LED settings"); -IotWebConfNumberParameter maxBrightnessParam = IotWebConfNumberParameter("Max BRIGHTNESS", "max brightness", maxBrightnessParamValue, NUMBER_LEN, "200", "20..254", "min='20' max='254' step='1'"); -IotWebConfCheckboxParameter singleSecondParam = IotWebConfCheckboxParameter("Show Seconds", "singleSecond", singleSecondParamValue, STRING_LEN, true); -IotWebConfCheckboxParameter allDotsOnParam = IotWebConfCheckboxParameter("all Dots lighten on", "allDotsOn", allDotsOnParamValue, STRING_LEN, true); -IotWebConfCheckboxParameter followingHourParam = IotWebConfCheckboxParameter("following Hour", "followingHour", followingHourParamValue, STRING_LEN, true); + this->customHtml = this->_colorAttr; + }; + protected: + // Overrides + virtual String renderHtml( + bool dataArrived, bool hasValueFromPost, String valueFromPost) override + { + return TextParameter::renderHtml("color", hasValueFromPost, valueFromPost); + }; + virtual String getHtmlTemplate() + { + return FPSTR(IOTWEBCONF_HTML_FORM_COLOR_PARAM); + }; + private: + char _colorAttr[COLOR_ATTR_LENGTH]; +}; + +// -- We need to create our custom HtmlFormatProvider to add some javasripts. class CustomHtmlFormatProvider : public iotwebconf::HtmlFormatProvider { protected: @@ -157,12 +190,57 @@ class CustomHtmlFormatProvider : public iotwebconf::HtmlFormatProvider } */ }; +// -- Javascript block will be added to the header. +/* + const char CUSTOMHTML_SCRIPT_INNER[] PROGMEM = "\n\ + document.addEventListener('DOMContentLoaded', function(event) {\n\ + let elements = document.querySelectorAll('input[type=\"password\"]');\n\ + for (let p of elements) {\n\ + let btn = document.createElement('INPUT'); btn.type = 'button'; btn.value = '🔓'; btn.style.width = 'auto'; p.style.width = '83%'; p.parentNode.insertBefore(btn,p.nextSibling);\n\ + btn.onclick = function() { if (p.type === 'password') { p.type = 'text'; btn.value = '🔒'; } else { p.type = 'password'; btn.value = '🔓'; } }\n\ + };\n\ + });\n"; +*/ +//const char CUSTOMHTML_BODY_INNER[] PROGMEM = " "; +DNSServer dnsServer; +WebServer server(80); +#ifdef ESP8266 +ESP8266HTTPUpdateServer httpUpdater; +#elif defined(ESP32) +HTTPUpdateServer httpUpdater; +#endif + +char ntpServerParamValue[STRING_LEN]; +char maxBrightnessParamValue[NUMBER_LEN]; +char singleSecondParamValue[STRING_LEN]; +char allDotsOnParamValue[STRING_LEN]; +char followingHourParamValue[STRING_LEN]; +char hourColorParamValue[COLOR_ATTR_LENGTH]; +char minuteColorParamValue[COLOR_ATTR_LENGTH]; +char secondsColorParamValue[COLOR_ATTR_LENGTH]; +char highnoonColorParamValue[COLOR_ATTR_LENGTH]; +char backlightColorParamValue[COLOR_ATTR_LENGTH]; +char hourMarkingColorParamValue[COLOR_ATTR_LENGTH]; + +IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION); +IotWebConfParameterGroup timeGroup = IotWebConfParameterGroup("Time", "Time settings"); +IotWebConfTextParameter ntpServerParam = IotWebConfTextParameter("NTP Server", "ntpServer", ntpServerParamValue, STRING_LEN, "pool.ntp.org"); +IotWebConfParameterGroup ledGroup = IotWebConfParameterGroup("LED", "LED settings"); +IotWebConfNumberParameter maxBrightnessParam = IotWebConfNumberParameter("Max BRIGHTNESS", "max brightness", maxBrightnessParamValue, NUMBER_LEN, "200", "20..254", "min='20' max='254' step='1'"); +IotWebConfCheckboxParameter singleSecondParam = IotWebConfCheckboxParameter("Show Seconds", "singleSecond", singleSecondParamValue, STRING_LEN, true); +IotWebConfCheckboxParameter allDotsOnParam = IotWebConfCheckboxParameter("all Dots lighten on", "allDotsOn", allDotsOnParamValue, STRING_LEN, true); +IotWebConfCheckboxParameter followingHourParam = IotWebConfCheckboxParameter("following Hour", "followingHour", followingHourParamValue, STRING_LEN, true); +ColorWithValueParameter hourColorParam = ColorWithValueParameter("Stundenfarbe", "hourColorParam", hourColorParamValue, COLOR_ATTR_LENGTH, "#FFD700"); +ColorWithValueParameter minuteColorParam = ColorWithValueParameter("Minutenfarbe", "minuteColorParam", minuteColorParamValue, COLOR_ATTR_LENGTH, "#800000"); +ColorWithValueParameter secondsColorParam = ColorWithValueParameter("Sekundenfarbe", "secondsColorParam", secondsColorParamValue, COLOR_ATTR_LENGTH, "#ffffff"); +ColorWithValueParameter highnoonColorParam = ColorWithValueParameter("12Uhr Farbe", "highnoonColorParam", highnoonColorParamValue, COLOR_ATTR_LENGTH, "#1E2823"); +ColorWithValueParameter backlightColorParam = ColorWithValueParameter("Hintergrundfarbe", "backlightColorParam", backlightColorParamValue, COLOR_ATTR_LENGTH, "#1E2823"); +ColorWithValueParameter hourMarkingColorParam = ColorWithValueParameter("Stundenmarkierung", "hourMarkingColorParam", hourMarkingColorParamValue, COLOR_ATTR_LENGTH, "#787878"); + + // -- An instance must be created from the class defined above. CustomHtmlFormatProvider customHtmlFormatProvider; -//ToDo color Picker Second, 12Clock, Minute, Hour - - Task bootAnim(200, TASK_FOREVER, &bootAnimCallback); Task clockTick(1000, TASK_FOREVER, &clockTickCallback); Task ledRefresh(200, TASK_FOREVER, &ledRefreshCallback); @@ -194,7 +272,7 @@ void iotWebConfHandleRoot() { // -- Captive portal request were already served. return; } - + char sTemp[12]; String s = ""; s += ""; //s += CUSTOMHTML_BODY_INNER; @@ -204,7 +282,7 @@ void iotWebConfHandleRoot() { s += ""; s += "
Current Time:"; s += printLocalTime(); - s += "
NTP Server:"; + s += "
NTP Server:"; s += ntpServerParamValue; s += "
Current Brightness value: "; s += String(strip.GetBrightness()); @@ -216,7 +294,37 @@ void iotWebConfHandleRoot() { s += (allDotsOn ? "Yes" : "No"); s += "
Following Hour: "; s += (followingHour ? "Yes" : "No"); - s += "
"; + s += ""; + s += "High noon: "; + s += "Hour color: "; + s += "Minute color: "; + s += "Seconds Color: "; + s += "Backlight: "; + s += "Hour Marking: "; s += "

"; s += "Go to configure page to change values."; s += "\n"; @@ -234,30 +342,23 @@ void iotWebConfConfigSaved() //Serial.println(allDotsOnParam.isChecked() ? "true" : "false"); followingHour = followingHourParam.isChecked() ? true : false; //Serial.println(followingHourParam.isChecked() ? "true" : "false"); + HtmlColor htmlTemp; + htmlTemp.Parse( highnoonColorParamValue ); + highnoonColor = htmlTemp ; + htmlTemp.Parse( hourColorParamValue ); + hourColor = htmlTemp; + htmlTemp.Parse( minuteColorParamValue ); + minuteColor = htmlTemp; + htmlTemp.Parse( secondsColorParamValue ); + secondsColor = htmlTemp; + htmlTemp.Parse( backlightColorParamValue ); + backlightColor = htmlTemp; + htmlTemp.Parse( hourMarkingColorParamValue); + hourMarkingColor = htmlTemp; + Serial.println("Configuration was updated."); } -/* -bool iotWebConfFormValidator(iotwebconf::WebRequestWrapper* webRequestWrapper) -{ - - Serial.println("Validating form."); - boolean valid = true; - - int l = server.arg(ntpServerParam.getId()).length(); - if (l < 3) - { - ntpServerParam.errorMessage = "Please provide at least 3 characters for this test!"; - valid = false; - } - int b = atoi(maxBrightnessParamValue); - if (b < MINIMAL_BRIGHTNESS || b > 254) - { - valid = false; - } - return valid; -} -*/ void iotWebConf_Setup() { @@ -267,6 +368,12 @@ void iotWebConf_Setup() { ledGroup.addItem(&singleSecondParam); ledGroup.addItem(&allDotsOnParam); ledGroup.addItem(&followingHourParam); + ledGroup.addItem(&hourColorParam); + ledGroup.addItem(&minuteColorParam); + ledGroup.addItem(&secondsColorParam); + ledGroup.addItem(&highnoonColorParam); + ledGroup.addItem(&backlightColorParam); + ledGroup.addItem(&hourMarkingColorParam); iotWebConf.addParameterGroup(&timeGroup); iotWebConf.addParameterGroup(&ledGroup); @@ -332,6 +439,7 @@ void setup() { Serial.printf("Lighten up all LEDs: \t%s\n", allDotsOn ? "yes" : "no"); Serial.printf("Following Hour: \t%s\n\n", followingHour ? "yes" : "no"); + strip.Begin(); strip.SetBrightness( MINIMAL_BRIGHTNESS ); strip.ClearTo(white); @@ -359,25 +467,25 @@ void loop() } void ledRefreshCallback() { - temp = allDotsOn ? white : black; + temp = allDotsOn ? backlightColor : black; strip.ClearTo(temp); //1 dot hour marking for (int dot = 0; dot < NUM_LEDS; dot++) { if (MOD(dot, 5) == 0) { - strip.SetPixelColor(dot, whiter); + strip.SetPixelColor(dot, hourMarkingColor); } } //3 dots hour - strip.SetPixelColor(MOD((currentHour * 5 - 1 + hourOffset), NUM_LEDS), gold); - strip.SetPixelColor(MOD((currentHour * 5 + 0 + hourOffset), NUM_LEDS), gold); - strip.SetPixelColor(MOD((currentHour * 5 + 1 + hourOffset), NUM_LEDS), gold); + strip.SetPixelColor(MOD((currentHour * 5 - 1 + hourOffset), NUM_LEDS), hourColor); + strip.SetPixelColor(MOD((currentHour * 5 + 0 + hourOffset), NUM_LEDS), hourColor); + strip.SetPixelColor(MOD((currentHour * 5 + 1 + hourOffset), NUM_LEDS), hourColor); - strip.SetPixelColor(0, white12); //define high noon + strip.SetPixelColor(0, highnoonColor); //define high noon if (singleSecond) { - strip.SetPixelColor(MOD((currentSec + 0), NUM_LEDS), (allDotsOn ? black : white)); + strip.SetPixelColor(MOD((currentSec + 0), NUM_LEDS), (allDotsOn ? black : secondsColor)); } - strip.SetPixelColor(MOD((currentMin + 0), NUM_LEDS), darkred); + strip.SetPixelColor(MOD((currentMin + 0), NUM_LEDS), minuteColor); strip.Show(); } diff --git a/60LED_WS2812B_NTP_Clock.ino.lolin32.v1.1.2.bin b/60LED_WS2812B_NTP_Clock.ino.lolin32.v1.1.2.bin new file mode 100644 index 0000000..755e453 Binary files /dev/null and b/60LED_WS2812B_NTP_Clock.ino.lolin32.v1.1.2.bin differ diff --git a/README.md b/README.md index 6570b99..9402053 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,12 @@ Ab sofort ist die Uhr unter einer neuen IP erreichbar, sodass dort weitere Einst - Anzeige der einzelnen Sekunden - Aufleuchten aller LEDs - Folgende Stunde (wie auf einer analogen Uhr) + - Farbwahl der 12Uhr Markierung + - Farbwahl der aktuelle Stunde (3LED) + - Farbwahl der aktuellen Minute (1LED) + - Farbwahl der aktuellen Sekunde (1LED) + - Farbwahl der übrigen LEDs + - Farbwahl der restlichen Stunden (10 LEDs) Unten auf der Statusseite gibt es einen Link zur Konfigurationsseite, eine Möglichkeit für den Upload einer neuen Firmware sowie die aktuelle Firmwareversion wird angezeigt. @@ -44,13 +50,15 @@ Unten auf der Statusseite gibt es einen Link zur Konfigurationsseite, eine Mögl - Show Seconds - all Dots lighten up - following Hour + - hourColor + - fminuteColor + - fsecondsColor + - fhighnoonColor + - fbacklightColor + - fhourMarkingColor - firmware update link - Firmware config version 'xxxx' ## ausstehende Verbesserungen - - [ ] RGB Auswahl Sekunden - - [ ] RGB Auswahl Minuten - - [ ] RGB Auswahl Stunden - - [ ] RGB Auswahl 12 Uhr - [ ] flüssige Helligkeitsadaptierung