From a12e1315dd7b138898319d7e657b1d8e6ae170fe Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Fri, 18 Jul 2025 09:19:59 +0200 Subject: [PATCH 01/13] Update usermod_v2_word_clock.cpp zu 11x11 Grid --- .../usermod_v2_word_clock.cpp | 77 +++++++++++++++---- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp index 5100da180d..cef0c9566f 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp @@ -24,13 +24,16 @@ class WordClockUsermod : public Usermod int ledOffset = 100; bool meander = false; bool nord = false; + bool eleven = false; // defines for mask sizes - #define maskSizeLeds 114 + #define maskSizeLeds 121 #define maskSizeMinutes 12 #define maskSizeMinutesMea 12 + #define maskSizeMinutes11 12 #define maskSizeHours 6 #define maskSizeHoursMea 6 + #define maskSizeHours11 6 #define maskSizeItIs 5 #define maskSizeMinuteDots 4 @@ -39,10 +42,10 @@ class WordClockUsermod : public Usermod const int maskMinutes[14][maskSizeMinutes] = { {107, 108, 109, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 0 - 00 - { 7, 8, 9, 10, 40, 41, 42, 43, -1, -1, -1, -1}, // 1 - 05 fünf nach + { 7, 8, 9, 10, 38, 39, 42, 43, -1, -1, -1, -1}, // 1 - 05 fünf nach { 11, 12, 13, 14, 40, 41, 42, 43, -1, -1, -1, -1}, // 2 - 10 zehn nach { 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1}, // 3 - 15 viertel - { 15, 16, 17, 18, 19, 20, 21, 40, 41, 42, 43, -1}, // 4 - 20 zwanzig nach + { 11, 12, 13, 14, 15, 16, 17, 40, 41, 42, 43, -1}, // 4 - 20 zwanzig nach { 7, 8, 9, 10, 33, 34, 35, 44, 45, 46, 47, -1}, // 5 - 25 fünf vor halb { 44, 45, 46, 47, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - 30 halb { 7, 8, 9, 10, 40, 41, 42, 43, 44, 45, 46, 47}, // 7 - 35 fünf nach halb @@ -72,6 +75,24 @@ class WordClockUsermod : public Usermod { 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, -1}, // 12 - 15 alternative viertel nach { 26, 27, 28, 29, 30, 31, 32, 41, 42, 43, -1, -1} // 13 - 45 alternative viertel vor }; + // 11x11 meander wiring + const int maskMinutes11[14][maskSizeMinutes11] = + { + { 99, 100, 101, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 0 - 00 + { 7, 8, 9, 10, 38, 39, 40, 41, -1, -1, -1, -1}, // 1 - 05 fünf nach + { 18, 19, 20, 21, 38, 39, 40, 41, -1, -1, -1, -1}, // 2 - 10 zehn nach + { 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1}, // 3 - 15 viertel + { 11, 12, 13, 14, 15, 16, 17, 38, 39, 40, 41, -1}, // 4 - 20 zwanzig nach + { 7, 8, 9, 10, 35, 36, 37, 44, 45, 46, 47, -1}, // 5 - 25 fünf vor halb + { 44, 45, 46, 47, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - 30 halb + { 7, 8, 9, 10, 38, 39, 40, 41, 44, 45, 46, 47}, // 7 - 35 fünf nach halb + { 11, 12, 13, 14, 15, 16, 17, 35, 36, 37, -1, -1}, // 8 - 40 zwanzig vor + { 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1}, // 9 - 45 dreiviertel + { 18, 19, 20, 21, 35, 36, 37, -1, -1, -1, -1, -1}, // 10 - 50 zehn vor + { 7, 8, 9, 10, 35, 36, 37, -1, -1, -1, -1, -1}, // 11 - 55 fünf vor + { 26, 27, 28, 29, 30, 31, 32, 38, 39, 40, 41, -1}, // 12 - 15 alternative viertel nach + { 26, 27, 28, 29, 30, 31, 32, 35, 36, 37, -1, -1} // 13 - 45 alternative viertel vor + }; // hour masks @@ -92,7 +113,8 @@ class WordClockUsermod : public Usermod { 49, 50, 51, -1, -1, -1}, // 11: elf { 94, 95, 96, 97, 98, -1} // 12: zwölf and 00: null }; - // Meander wiring + + // Meander wiring const int maskHoursMea[13][maskSizeHoursMea] = { { 63, 64, 65, -1, -1, -1}, // 01: ein @@ -109,12 +131,29 @@ class WordClockUsermod : public Usermod { 49, 50, 51, -1, -1, -1}, // 11: elf { 94, 95, 96, 97, 98, -1} // 12: zwölf and 00: null }; + // 11x11 Meander wiring + const int maskHours11[13][maskSizeHours11] = + { + { 61, 62, 63, -1, -1, -1}, // 01: ein + { 61, 62, 63, 64, -1, -1}, // 01: eins + { 62, 63, 64, 65, -1, -1}, // 02: zwei + { 67, 68, 69, 70, -1, -1}, // 03: drei + { 77, 78, 79, 80, -1, -1}, // 04: vier + { 73, 74, 75, 76, -1, -1}, // 05: fünf + {104, 105, 106, 107, 108, -1}, // 06: sechs + { 55, 56, 57, 58, 59, 60}, // 07: sieben + { 89, 90, 91, 92, -1, -1}, // 08: acht + { 81, 82, 83, 84, -1, -1}, // 09: neun + { 93, 94, 95, 96, -1, -1}, // 10: zehn + { 85, 86, 87, -1, -1, -1}, // 11: elf + { 49, 50, 51, 52, 53, -1} // 12: zwölf and 00: null + }; // mask "it is" const int maskItIs[maskSizeItIs] = {0, 1, 3, 4, 5}; // mask minute dots - const int maskMinuteDots[maskSizeMinuteDots] = {110, 111, 112, 113}; + const int maskMinuteDots[maskSizeMinuteDots] = {112, 114, 116, 118}; // overall mask to define which LEDs are on int maskLedsOn[maskSizeLeds] = @@ -129,7 +168,7 @@ class WordClockUsermod : public Usermod 0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0 + 0,0,0,0,0,0,0,0,0,0,0 }; // update led mask @@ -171,21 +210,25 @@ class WordClockUsermod : public Usermod } // update led mask - if (meander) - { - updateLedMask(maskHoursMea[index], maskSizeHoursMea); + if (meander) { + updateLedMask(maskHoursMea[index], maskSizeHoursMea); + } else if (eleven) { + updateLedMask(maskHours11[index], maskSizeHours11); } else { updateLedMask(maskHours[index], maskSizeHours); } + + } // set minutes void setMinutes(int index) { // update led mask - if (meander) - { - updateLedMask(maskMinutesMea[index], maskSizeMinutesMea); + if (meander) { + updateLedMask(maskMinutesMea[index], maskSizeMinutesMea); + } else if (eleven) { + updateLedMask(maskMinutes11[index], maskSizeMinutes11); } else { updateLedMask(maskMinutes[index], maskSizeMinutes); } @@ -212,7 +255,7 @@ class WordClockUsermod : public Usermod // update the display void updateDisplay(uint8_t hours, uint8_t minutes) { - // disable complete matrix at the bigging + // disable complete matrix at the beginning for (int x = 0; x < maskSizeLeds; x++) { maskLedsOn[x] = 0; @@ -425,7 +468,8 @@ class WordClockUsermod : public Usermod top[F("active")] = usermodActive; top[F("displayItIs")] = displayItIs; top[F("ledOffset")] = ledOffset; - top[F("Meander wiring?")] = meander; + top[F("meanderWiring")] = meander; + top[F("wiring11x11")] = eleven; top[F("Norddeutsch")] = nord; } @@ -462,7 +506,8 @@ class WordClockUsermod : public Usermod configComplete &= getJsonValue(top[F("active")], usermodActive); configComplete &= getJsonValue(top[F("displayItIs")], displayItIs); configComplete &= getJsonValue(top[F("ledOffset")], ledOffset); - configComplete &= getJsonValue(top[F("Meander wiring?")], meander); + configComplete &= getJsonValue(top[F("meanderWiring")], meander); + configComplete &= getJsonValue(top[F("wiring11x11")], eleven); configComplete &= getJsonValue(top[F("Norddeutsch")], nord); return configComplete; @@ -505,4 +550,4 @@ class WordClockUsermod : public Usermod }; static WordClockUsermod usermod_v2_word_clock; -REGISTER_USERMOD(usermod_v2_word_clock); \ No newline at end of file +REGISTER_USERMOD(usermod_v2_word_clock); From 2fb1ede432fdbf797acbcf5e8e64779c5ed8e5e0 Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Fri, 18 Jul 2025 09:22:27 +0200 Subject: [PATCH 02/13] Update readme.md to 11x11 --- usermods/usermod_v2_word_clock/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usermods/usermod_v2_word_clock/readme.md b/usermods/usermod_v2_word_clock/readme.md index b81cebcea9..7928aed398 100644 --- a/usermods/usermod_v2_word_clock/readme.md +++ b/usermods/usermod_v2_word_clock/readme.md @@ -1,6 +1,6 @@ # Word Clock Usermod V2 -This usermod drives an 11x10 pixel matrix wordclock with WLED. There are 4 additional dots for the minutes. +This usermod drives an 11x10 or a 11x11 pixel matrix wordclock with WLED. There are 4 additional dots for the minutes. The visualisation is described by 4 masks with LED numbers (single dots for minutes, minutes, hours and "clock"). The index of the LEDs in the masks always starts at 0, even if the ledOffset is not 0. There are 3 parameters that control behavior: @@ -16,7 +16,7 @@ The original used a long wire to connect DO to DI, from one line to the next lin I wired my clock in meander style. So the first LED in the second line is on the right. With this method, every other line was inverted and showed the wrong letter. -I added a switch in usermod called "meander wiring?" to enable/disable the alternate wiring pattern. +I added a switch in usermod called "meanderwiring" to enable/disable the alternate wiring pattern and a switch for the 11x11 grid. ## Installation From e06c271c66038b9c2443b37d02a1219dad873659 Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Fri, 18 Jul 2025 09:23:24 +0200 Subject: [PATCH 03/13] SVG with Covergrid --- usermods/usermod_v2_word_clock/de_DE_s1.svg | 137 ++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 usermods/usermod_v2_word_clock/de_DE_s1.svg diff --git a/usermods/usermod_v2_word_clock/de_DE_s1.svg b/usermods/usermod_v2_word_clock/de_DE_s1.svg new file mode 100644 index 0000000000..d87b970ef5 --- /dev/null +++ b/usermods/usermod_v2_word_clock/de_DE_s1.svg @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From fa2286a4370cb5e1ea2d7288bb3945aa15e3e136 Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Sun, 20 Jul 2025 12:05:43 +0200 Subject: [PATCH 04/13] Update readme.md Added a Link to the source of the SVG --- usermods/usermod_v2_word_clock/readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/usermods/usermod_v2_word_clock/readme.md b/usermods/usermod_v2_word_clock/readme.md index 7928aed398..042b3b7a77 100644 --- a/usermods/usermod_v2_word_clock/readme.md +++ b/usermods/usermod_v2_word_clock/readme.md @@ -18,6 +18,9 @@ With this method, every other line was inverted and showed the wrong letter. I added a switch in usermod called "meanderwiring" to enable/disable the alternate wiring pattern and a switch for the 11x11 grid. +## 11x11 Grid +I integreated the Grafics from https://github.com/panbachi/wordclock/blob/master/graphics/plate/de_DE_s1.svg + ## Installation Copy and update the example `platformio_override.ini.sample` From 0aa68a39b5692cfd2c593f80240dc123bd299997 Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Thu, 24 Jul 2025 12:38:57 +0200 Subject: [PATCH 05/13] Update usermod_v2_word_clock.cpp Mapping wrong at 11x11 ---> eins --- usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp index cef0c9566f..50074a6880 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp @@ -135,7 +135,7 @@ class WordClockUsermod : public Usermod const int maskHours11[13][maskSizeHours11] = { { 61, 62, 63, -1, -1, -1}, // 01: ein - { 61, 62, 63, 64, -1, -1}, // 01: eins + { 60, 61, 62, 63, -1, -1}, // 01: eins { 62, 63, 64, 65, -1, -1}, // 02: zwei { 67, 68, 69, 70, -1, -1}, // 03: drei { 77, 78, 79, 80, -1, -1}, // 04: vier From ea2bafc51a30bc4134d653003abadcc226f08f38 Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Mon, 4 Aug 2025 11:58:34 +0200 Subject: [PATCH 06/13] Update usermod_v2_word_clock.cpp Added map for a 2d Matrix in Meanderwiring --- .../usermod_v2_word_clock.cpp | 75 ++++--------------- 1 file changed, 15 insertions(+), 60 deletions(-) diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp index 50074a6880..519224ef12 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp @@ -24,16 +24,13 @@ class WordClockUsermod : public Usermod int ledOffset = 100; bool meander = false; bool nord = false; - bool eleven = false; // defines for mask sizes #define maskSizeLeds 121 #define maskSizeMinutes 12 #define maskSizeMinutesMea 12 - #define maskSizeMinutes11 12 #define maskSizeHours 6 #define maskSizeHoursMea 6 - #define maskSizeHours11 6 #define maskSizeItIs 5 #define maskSizeMinuteDots 4 @@ -60,25 +57,7 @@ class WordClockUsermod : public Usermod // Meander wiring const int maskMinutesMea[14][maskSizeMinutesMea] = { - { 99, 100, 101, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 0 - 00 - { 7, 8, 9, 10, 33, 34, 35, 36, -1, -1, -1, -1}, // 1 - 05 fünf nach - { 18, 19, 20, 21, 33, 34, 35, 36, -1, -1, -1, -1}, // 2 - 10 zehn nach - { 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1}, // 3 - 15 viertel - { 11, 12, 13, 14, 15, 16, 17, 33, 34, 35, 36, -1}, // 4 - 20 zwanzig nach - { 7, 8, 9, 10, 41, 42, 43, 44, 45, 46, 47, -1}, // 5 - 25 fünf vor halb - { 44, 45, 46, 47, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - 30 halb - { 7, 8, 9, 10, 33, 34, 35, 36, 44, 45, 46, 47}, // 7 - 35 fünf nach halb - { 11, 12, 13, 14, 15, 16, 17, 41, 42, 43, -1, -1}, // 8 - 40 zwanzig vor - { 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1}, // 9 - 45 dreiviertel - { 18, 19, 20, 21, 41, 42, 43, -1, -1, -1, -1, -1}, // 10 - 50 zehn vor - { 7, 8, 9, 10, 41, 42, 43, -1, -1, -1, -1, -1}, // 11 - 55 fünf vor - { 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, -1}, // 12 - 15 alternative viertel nach - { 26, 27, 28, 29, 30, 31, 32, 41, 42, 43, -1, -1} // 13 - 45 alternative viertel vor - }; - // 11x11 meander wiring - const int maskMinutes11[14][maskSizeMinutes11] = - { - { 99, 100, 101, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 0 - 00 + {112, 114, 116, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 0 - 00 { 7, 8, 9, 10, 38, 39, 40, 41, -1, -1, -1, -1}, // 1 - 05 fünf nach { 18, 19, 20, 21, 38, 39, 40, 41, -1, -1, -1, -1}, // 2 - 10 zehn nach { 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1}, // 3 - 15 viertel @@ -86,10 +65,10 @@ class WordClockUsermod : public Usermod { 7, 8, 9, 10, 35, 36, 37, 44, 45, 46, 47, -1}, // 5 - 25 fünf vor halb { 44, 45, 46, 47, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - 30 halb { 7, 8, 9, 10, 38, 39, 40, 41, 44, 45, 46, 47}, // 7 - 35 fünf nach halb - { 11, 12, 13, 14, 15, 16, 17, 35, 36, 37, -1, -1}, // 8 - 40 zwanzig vor + { 11, 12, 13, 14, 15, 16, 17, 35, 36, 37, -1, -1}, // 8 - 40 zwanzig vor { 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1}, // 9 - 45 dreiviertel - { 18, 19, 20, 21, 35, 36, 37, -1, -1, -1, -1, -1}, // 10 - 50 zehn vor - { 7, 8, 9, 10, 35, 36, 37, -1, -1, -1, -1, -1}, // 11 - 55 fünf vor + { 18, 19, 20, 21, 35, 36, 37, -1, -1, -1, -1, -1}, // 10 - 50 zehn vor + { 7, 8, 9, 10, 35, 36, 37, -1, -1, -1, -1, -1}, // 11 - 55 fünf vor { 26, 27, 28, 29, 30, 31, 32, 38, 39, 40, 41, -1}, // 12 - 15 alternative viertel nach { 26, 27, 28, 29, 30, 31, 32, 35, 36, 37, -1, -1} // 13 - 45 alternative viertel vor }; @@ -113,29 +92,11 @@ class WordClockUsermod : public Usermod { 49, 50, 51, -1, -1, -1}, // 11: elf { 94, 95, 96, 97, 98, -1} // 12: zwölf and 00: null }; - - // Meander wiring + // Meander wiring const int maskHoursMea[13][maskSizeHoursMea] = - { - { 63, 64, 65, -1, -1, -1}, // 01: ein - { 62, 63, 64, 65, -1, -1}, // 01: eins - { 55, 56, 57, 58, -1, -1}, // 02: zwei - { 66, 67, 68, 69, -1, -1}, // 03: drei - { 73, 74, 75, 76, -1, -1}, // 04: vier - { 51, 52, 53, 54, -1, -1}, // 05: fünf - { 83, 84, 85, 86, 87, -1}, // 06: sechs - { 88, 89, 90, 91, 92, 93}, // 07: sieben - { 77, 78, 79, 80, -1, -1}, // 08: acht - {103, 104, 105, 106, -1, -1}, // 09: neun - {106, 107, 108, 109, -1, -1}, // 10: zehn - { 49, 50, 51, -1, -1, -1}, // 11: elf - { 94, 95, 96, 97, 98, -1} // 12: zwölf and 00: null - }; - // 11x11 Meander wiring - const int maskHours11[13][maskSizeHours11] = { { 61, 62, 63, -1, -1, -1}, // 01: ein - { 60, 61, 62, 63, -1, -1}, // 01: eins + { 61, 62, 63, 64, -1, -1}, // 01: eins { 62, 63, 64, 65, -1, -1}, // 02: zwei { 67, 68, 69, 70, -1, -1}, // 03: drei { 77, 78, 79, 80, -1, -1}, // 04: vier @@ -210,25 +171,21 @@ class WordClockUsermod : public Usermod } // update led mask - if (meander) { - updateLedMask(maskHoursMea[index], maskSizeHoursMea); - } else if (eleven) { - updateLedMask(maskHours11[index], maskSizeHours11); + if (meander) + { + updateLedMask(maskHoursMea[index], maskSizeHoursMea); } else { updateLedMask(maskHours[index], maskSizeHours); } - - } // set minutes void setMinutes(int index) { // update led mask - if (meander) { - updateLedMask(maskMinutesMea[index], maskSizeMinutesMea); - } else if (eleven) { - updateLedMask(maskMinutes11[index], maskSizeMinutes11); + if (meander) + { + updateLedMask(maskMinutesMea[index], maskSizeMinutesMea); } else { updateLedMask(maskMinutes[index], maskSizeMinutes); } @@ -255,7 +212,7 @@ class WordClockUsermod : public Usermod // update the display void updateDisplay(uint8_t hours, uint8_t minutes) { - // disable complete matrix at the beginning + // disable complete matrix at the bigging for (int x = 0; x < maskSizeLeds; x++) { maskLedsOn[x] = 0; @@ -468,8 +425,7 @@ class WordClockUsermod : public Usermod top[F("active")] = usermodActive; top[F("displayItIs")] = displayItIs; top[F("ledOffset")] = ledOffset; - top[F("meanderWiring")] = meander; - top[F("wiring11x11")] = eleven; + top[F("Meander wiring?")] = meander; top[F("Norddeutsch")] = nord; } @@ -506,8 +462,7 @@ class WordClockUsermod : public Usermod configComplete &= getJsonValue(top[F("active")], usermodActive); configComplete &= getJsonValue(top[F("displayItIs")], displayItIs); configComplete &= getJsonValue(top[F("ledOffset")], ledOffset); - configComplete &= getJsonValue(top[F("meanderWiring")], meander); - configComplete &= getJsonValue(top[F("wiring11x11")], eleven); + configComplete &= getJsonValue(top[F("Meander wiring?")], meander); configComplete &= getJsonValue(top[F("Norddeutsch")], nord); return configComplete; From 9b865fbb485fc030576b01433987f87c52687d6f Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Mon, 4 Aug 2025 12:00:11 +0200 Subject: [PATCH 07/13] Update usermod_v2_word_clock.cpp Added meander wiring for a 2d Matrix 11x11 --- .../usermod_v2_word_clock.cpp | 118 +++++++++++++++--- 1 file changed, 101 insertions(+), 17 deletions(-) diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp index 519224ef12..01b3d187f7 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp @@ -24,13 +24,18 @@ class WordClockUsermod : public Usermod int ledOffset = 100; bool meander = false; bool nord = false; + bool eleven = false; // defines for mask sizes #define maskSizeLeds 121 #define maskSizeMinutes 12 #define maskSizeMinutesMea 12 + #define maskSizeMinutes11 12 + #define maskSizeMinutes11Mea 12 #define maskSizeHours 6 #define maskSizeHoursMea 6 + #define maskSizeHours11 6 + #define maskSizeHours11Mea 6 #define maskSizeItIs 5 #define maskSizeMinuteDots 4 @@ -57,7 +62,25 @@ class WordClockUsermod : public Usermod // Meander wiring const int maskMinutesMea[14][maskSizeMinutesMea] = { - {112, 114, 116, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 0 - 00 + { 99, 100, 101, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 0 - 00 + { 7, 8, 9, 10, 33, 34, 35, 36, -1, -1, -1, -1}, // 1 - 05 fünf nach + { 18, 19, 20, 21, 33, 34, 35, 36, -1, -1, -1, -1}, // 2 - 10 zehn nach + { 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1}, // 3 - 15 viertel + { 11, 12, 13, 14, 15, 16, 17, 33, 34, 35, 36, -1}, // 4 - 20 zwanzig nach + { 7, 8, 9, 10, 41, 42, 43, 44, 45, 46, 47, -1}, // 5 - 25 fünf vor halb + { 44, 45, 46, 47, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - 30 halb + { 7, 8, 9, 10, 33, 34, 35, 36, 44, 45, 46, 47}, // 7 - 35 fünf nach halb + { 11, 12, 13, 14, 15, 16, 17, 41, 42, 43, -1, -1}, // 8 - 40 zwanzig vor + { 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1}, // 9 - 45 dreiviertel + { 18, 19, 20, 21, 41, 42, 43, -1, -1, -1, -1, -1}, // 10 - 50 zehn vor + { 7, 8, 9, 10, 41, 42, 43, -1, -1, -1, -1, -1}, // 11 - 55 fünf vor + { 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, -1}, // 12 - 15 alternative viertel nach + { 26, 27, 28, 29, 30, 31, 32, 41, 42, 43, -1, -1} // 13 - 45 alternative viertel vor + }; + // 11x11 wiring + const int maskMinutes11[14][maskSizeMinutes11] = + { + { 99, 100, 101, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 0 - 00 { 7, 8, 9, 10, 38, 39, 40, 41, -1, -1, -1, -1}, // 1 - 05 fünf nach { 18, 19, 20, 21, 38, 39, 40, 41, -1, -1, -1, -1}, // 2 - 10 zehn nach { 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1}, // 3 - 15 viertel @@ -65,14 +88,31 @@ class WordClockUsermod : public Usermod { 7, 8, 9, 10, 35, 36, 37, 44, 45, 46, 47, -1}, // 5 - 25 fünf vor halb { 44, 45, 46, 47, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - 30 halb { 7, 8, 9, 10, 38, 39, 40, 41, 44, 45, 46, 47}, // 7 - 35 fünf nach halb - { 11, 12, 13, 14, 15, 16, 17, 35, 36, 37, -1, -1}, // 8 - 40 zwanzig vor + { 11, 12, 13, 14, 15, 16, 17, 35, 36, 37, -1, -1}, // 8 - 40 zwanzig vor { 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1}, // 9 - 45 dreiviertel - { 18, 19, 20, 21, 35, 36, 37, -1, -1, -1, -1, -1}, // 10 - 50 zehn vor - { 7, 8, 9, 10, 35, 36, 37, -1, -1, -1, -1, -1}, // 11 - 55 fünf vor + { 18, 19, 20, 21, 35, 36, 37, -1, -1, -1, -1, -1}, // 10 - 50 zehn vor + { 7, 8, 9, 10, 35, 36, 37, -1, -1, -1, -1, -1}, // 11 - 55 fünf vor { 26, 27, 28, 29, 30, 31, 32, 38, 39, 40, 41, -1}, // 12 - 15 alternative viertel nach { 26, 27, 28, 29, 30, 31, 32, 35, 36, 37, -1, -1} // 13 - 45 alternative viertel vor }; - +// 11x11 meander wiring ANPASSUNG HIER + const int maskMinutes11Mea[14][maskSizeMinutes11Mea] = + { + {107, 108, 109, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 0 - 00 + { 7, 8, 9, 10, 35, 36, 37, 38, -1, -1, -1, -1}, // 1 - 05 fünf nach + { 11, 12, 13, 14, 35, 36, 37, 38, -1, -1, -1, -1}, // 2 - 10 zehn nach + { 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1}, // 3 - 15 viertel + { 15, 16, 17, 18, 19, 20, 21, 35, 36, 37, 38, -1}, // 4 - 20 zwanzig nach + { 7, 8, 9, 10, 39, 40, 41, 44, 45, 46, 47, -1}, // 5 - 25 fünf vor halb + { 44, 45, 46, 47, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - 30 halb + { 7, 8, 9, 10, 35, 36, 37, 38, 44, 45, 46, 47}, // 7 - 35 fünf nach halb + { 15, 16, 17, 18, 19, 20, 21, 39, 40, 41, -1, -1}, // 8 - 40 zwanzig vor + { 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1}, // 9 - 45 dreiviertel + { 11, 12, 13, 14, 39, 40, 41, -1, -1, -1, -1, -1}, // 10 - 50 zehn vor + { 7, 8, 9, 10, 39, 40, 41, -1, -1, -1, -1, -1}, // 11 - 55 fünf vor + { 26, 27, 28, 29, 30, 31, 32, 35, 36, 37, 38, -1}, // 12 - 15 alternative viertel nach + { 26, 27, 28, 29, 30, 31, 32, 39, 40, 41, -1, -1} // 13 - 45 alternative viertel vor + }; // hour masks // Normal wiring @@ -92,11 +132,29 @@ class WordClockUsermod : public Usermod { 49, 50, 51, -1, -1, -1}, // 11: elf { 94, 95, 96, 97, 98, -1} // 12: zwölf and 00: null }; - // Meander wiring + + // Meander wiring const int maskHoursMea[13][maskSizeHoursMea] = + { + { 63, 64, 65, -1, -1, -1}, // 01: ein + { 62, 63, 64, 65, -1, -1}, // 01: eins + { 55, 56, 57, 58, -1, -1}, // 02: zwei + { 66, 67, 68, 69, -1, -1}, // 03: drei + { 73, 74, 75, 76, -1, -1}, // 04: vier + { 51, 52, 53, 54, -1, -1}, // 05: fünf + { 83, 84, 85, 86, 87, -1}, // 06: sechs + { 88, 89, 90, 91, 92, 93}, // 07: sieben + { 77, 78, 79, 80, -1, -1}, // 08: acht + {103, 104, 105, 106, -1, -1}, // 09: neun + {106, 107, 108, 109, -1, -1}, // 10: zehn + { 49, 50, 51, -1, -1, -1}, // 11: elf + { 94, 95, 96, 97, 98, -1} // 12: zwölf and 00: null + }; + // 11x11 + const int maskHours11[13][maskSizeHours11] = { { 61, 62, 63, -1, -1, -1}, // 01: ein - { 61, 62, 63, 64, -1, -1}, // 01: eins + { 60, 61, 62, 63, -1, -1}, // 01: eins { 62, 63, 64, 65, -1, -1}, // 02: zwei { 67, 68, 69, 70, -1, -1}, // 03: drei { 77, 78, 79, 80, -1, -1}, // 04: vier @@ -109,7 +167,23 @@ class WordClockUsermod : public Usermod { 85, 86, 87, -1, -1, -1}, // 11: elf { 49, 50, 51, 52, 53, -1} // 12: zwölf and 00: null }; - + // 11x11 Meander wiring + const int maskHours11Mea[13][maskSizeHours11Mea] = + { + { 57, 58, 59, -1, -1, -1}, // 01: ein + { 57, 58, 59, 60, -1, -1}, // 01: eins + { 62, 63, 64, 65, -1, -1}, // 02: zwei + { 67, 68, 69, 70, -1, -1}, // 03: drei + { 84, 85, 86, 87, -1, -1}, // 04: vier + { 73, 74, 75, 76, -1, -1}, // 05: fünf + {100, 101, 102, 103, 104, -1}, // 06: sechs + { 60, 61, 62, 63, 64, 65}, // 07: sieben + { 89, 90, 91, 92, -1, -1}, // 08: acht + { 80, 81, 82, 83, -1, -1}, // 09: neun + { 93, 94, 95, 96, -1, -1}, // 10: zehn + { 77, 78, 79, -1, -1, -1}, // 11: elf + { 49, 50, 51, 52, 53, -1} // 12: zwölf and 00: null + }; // mask "it is" const int maskItIs[maskSizeItIs] = {0, 1, 3, 4, 5}; @@ -171,21 +245,29 @@ class WordClockUsermod : public Usermod } // update led mask - if (meander) - { + if (meander && !eleven) { updateLedMask(maskHoursMea[index], maskSizeHoursMea); + } else if (eleven && !meander) { + updateLedMask(maskHours11[index], maskSizeHours11); + } else if (eleven && meander) { + updateLedMask(maskHours11Mea[index], maskSizeHours11Mea); } else { - updateLedMask(maskHours[index], maskSizeHours); + updateLedMask(maskHours[index], maskSizeHours); } + + } // set minutes void setMinutes(int index) { // update led mask - if (meander) - { - updateLedMask(maskMinutesMea[index], maskSizeMinutesMea); + if (meander && !eleven) { + updateLedMask(maskMinutesMea[index], maskSizeMinutesMea); + } else if (eleven && !meander) { + updateLedMask(maskMinutes11[index], maskSizeMinutes11); + } else if (eleven && meander) { + updateLedMask(maskMinutes11Mea[index], maskSizeMinutes11Mea); } else { updateLedMask(maskMinutes[index], maskSizeMinutes); } @@ -212,7 +294,7 @@ class WordClockUsermod : public Usermod // update the display void updateDisplay(uint8_t hours, uint8_t minutes) { - // disable complete matrix at the bigging + // disable complete matrix at the beginning for (int x = 0; x < maskSizeLeds; x++) { maskLedsOn[x] = 0; @@ -425,7 +507,8 @@ class WordClockUsermod : public Usermod top[F("active")] = usermodActive; top[F("displayItIs")] = displayItIs; top[F("ledOffset")] = ledOffset; - top[F("Meander wiring?")] = meander; + top[F("meanderWiring")] = meander; + top[F("wiring11x11")] = eleven; top[F("Norddeutsch")] = nord; } @@ -462,7 +545,8 @@ class WordClockUsermod : public Usermod configComplete &= getJsonValue(top[F("active")], usermodActive); configComplete &= getJsonValue(top[F("displayItIs")], displayItIs); configComplete &= getJsonValue(top[F("ledOffset")], ledOffset); - configComplete &= getJsonValue(top[F("Meander wiring?")], meander); + configComplete &= getJsonValue(top[F("meanderWiring")], meander); + configComplete &= getJsonValue(top[F("wiring11x11")], eleven); configComplete &= getJsonValue(top[F("Norddeutsch")], nord); return configComplete; From 0dade6de2fd040b8c239b154303b1280c552783d Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Tue, 5 Aug 2025 11:42:22 +0200 Subject: [PATCH 08/13] Update usermod_v2_word_clock.cpp Add the Status of the usermod in JSON, so that you can switch off and on the Usermod remotely for Example with Home Assistant --- .../usermod_v2_word_clock/usermod_v2_word_clock.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp index 01b3d187f7..fe7c9cb65c 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp @@ -456,6 +456,10 @@ class WordClockUsermod : public Usermod */ void addToJsonState(JsonObject& root) { + // Create a nested object for the usermod + JsonObject usermodJson = root.createNestedObject("WordClockUsermod"); + // Add the current state of the 'usermodActive' variable + usermodJson["active"] = usermodActive; } /* @@ -464,6 +468,13 @@ class WordClockUsermod : public Usermod */ void readFromJsonState(JsonObject& root) { + JsonObject usermodJson = root["WordClockUsermod"]; + if (!usermodJson.isNull()) { + // Check if the 'active' key is present and update the variable + if (usermodJson.containsKey("active")) { + usermodActive = usermodJson["active"].as(); + } + } } /* From 46eb6b2eb1a85ad82ff61af0e3ba294eb286fac3 Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Tue, 5 Aug 2025 11:45:21 +0200 Subject: [PATCH 09/13] Update readme.md Added the integration into Homeassist --- usermods/usermod_v2_word_clock/readme.md | 69 ++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/usermods/usermod_v2_word_clock/readme.md b/usermods/usermod_v2_word_clock/readme.md index 042b3b7a77..54cdb09b76 100644 --- a/usermods/usermod_v2_word_clock/readme.md +++ b/usermods/usermod_v2_word_clock/readme.md @@ -40,3 +40,72 @@ No special requirements. 2022/08/18 added meander wiring pattern. 2022/03/30 initial commit + +## Home Assistant Configuration +Now, we will create the necessary entities in Home Assistant to display the switch and send commands to WLED. + +Step 2.1: Edit configuration.yaml + +Add the following complete code block to your configuration.yaml file. + +YAML + +# configuration.yaml + +# 1. REST command to send on/off commands to the WLED usermod +rest_command: + wled_wordclock_set: + # REPLACE: Enter the IP address of your WLED device here + url: "http://YOUR_WLED_IP_ADDRESS/json/state" + method: "POST" + headers: + Content-Type: "application/json" + # Forces 'true'/'false' to be lowercase to generate valid JSON + payload: '{"WordClockUsermod":{"active":{{ active | string | lower }}}}' + +# 2. REST sensor to read the current state of the usermod +rest: + - resource: "http://YOUR_WLED_IP_ADDRESS/json/state" + scan_interval: 30 + sensor: + - name: "WLED Wordclock Status" + unique_id: wled_wordclock_status_sensor + # Reads the value from the JSON; the path is without ".um" because the value is in the root object + value_template: "{{ value_json.WordClockUsermod.active }}" + +# 3. Template switch that combines the commands and the sensor into a UI element +template: + - switch: + - name: "WLED Word Clock Active" + unique_id: wled_wordclock_active_switch + # Action on turning on + turn_on: + service: rest_command.wled_wordclock_set + data: + active: true + # Action on turning off + turn_off: + service: rest_command.wled_wordclock_set + data: + active: false + # Uses the state of the sensor to display the switch state (on/off) + state: > + {{ is_state('sensor.wled_wordclock_status', 'True') }} + # Changes the icon depending on the state + icon: >- + {% if this.state == 'on' %} + mdi:clock-digital + {% else %} + mdi:clock-outline + {% endif %} +Step 2.2: Adjust the IP Address + +In the YAML code, replace the placeholder YOUR_WLED_IP_ADDRESS in both places with the actual IP address of your WLED controller. + +Step 2.3: Restart Home Assistant + +Save the configuration.yaml file. + +Check the configuration under Settings > System > Restart > Check Configuration. + +If the configuration is valid, restart Home Assistant. From 4007a5331e3f4146f0092bf478055e02e8fec3e6 Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Tue, 5 Aug 2025 12:01:28 +0200 Subject: [PATCH 10/13] Update readme.md Added HA Configuration --- usermods/usermod_v2_word_clock/readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usermods/usermod_v2_word_clock/readme.md b/usermods/usermod_v2_word_clock/readme.md index 54cdb09b76..cfaf4522a9 100644 --- a/usermods/usermod_v2_word_clock/readme.md +++ b/usermods/usermod_v2_word_clock/readme.md @@ -50,8 +50,8 @@ Add the following complete code block to your configuration.yaml file. YAML -# configuration.yaml - +`configuration.yaml` +``` # 1. REST command to send on/off commands to the WLED usermod rest_command: wled_wordclock_set: @@ -70,7 +70,6 @@ rest: sensor: - name: "WLED Wordclock Status" unique_id: wled_wordclock_status_sensor - # Reads the value from the JSON; the path is without ".um" because the value is in the root object value_template: "{{ value_json.WordClockUsermod.active }}" # 3. Template switch that combines the commands and the sensor into a UI element @@ -98,13 +97,14 @@ template: {% else %} mdi:clock-outline {% endif %} +``` Step 2.2: Adjust the IP Address In the YAML code, replace the placeholder YOUR_WLED_IP_ADDRESS in both places with the actual IP address of your WLED controller. Step 2.3: Restart Home Assistant -Save the configuration.yaml file. +Save the `configuration.yaml` file. Check the configuration under Settings > System > Restart > Check Configuration. From 6dc9beeb488718b18dd2ce92671870909cb45dcc Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Sat, 9 May 2026 23:10:19 +0200 Subject: [PATCH 11/13] Add meander wiring option to readme Added a new configuration option for meander wiring and updated documentation to reflect changes. --- usermods/usermod_v2_word_clock/readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/usermods/usermod_v2_word_clock/readme.md b/usermods/usermod_v2_word_clock/readme.md index cfaf4522a9..8eeea4252f 100644 --- a/usermods/usermod_v2_word_clock/readme.md +++ b/usermods/usermod_v2_word_clock/readme.md @@ -7,6 +7,7 @@ There are 3 parameters that control behavior: active: enable/disable usermod diplayItIs: enable/disable display of "Es ist" on the clock ledOffset: number of LEDs before the wordclock LEDs +meanderwiring: on/off ## Update for alternative wiring pattern From fb2ca04f684d68ed1a9a06b2ad10f5b6eee6f688 Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Sat, 9 May 2026 23:39:47 +0200 Subject: [PATCH 12/13] Fix typos in usermod_v2_word_clock readme Corrected typos and improved clarity in readme. --- usermods/usermod_v2_word_clock/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usermods/usermod_v2_word_clock/readme.md b/usermods/usermod_v2_word_clock/readme.md index 8eeea4252f..4693043e8b 100644 --- a/usermods/usermod_v2_word_clock/readme.md +++ b/usermods/usermod_v2_word_clock/readme.md @@ -5,7 +5,7 @@ The visualisation is described by 4 masks with LED numbers (single dots for minu There are 3 parameters that control behavior: active: enable/disable usermod -diplayItIs: enable/disable display of "Es ist" on the clock +displayItIs: enable/disable display of "Es ist" on the clock ledOffset: number of LEDs before the wordclock LEDs meanderwiring: on/off @@ -20,7 +20,7 @@ With this method, every other line was inverted and showed the wrong letter. I added a switch in usermod called "meanderwiring" to enable/disable the alternate wiring pattern and a switch for the 11x11 grid. ## 11x11 Grid -I integreated the Grafics from https://github.com/panbachi/wordclock/blob/master/graphics/plate/de_DE_s1.svg +I integrated the grafics from https://github.com/panbachi/wordclock/blob/master/graphics/plate/de_DE_s1.svg ## Installation From f7146b1eb349e3cbeef2986c402b2aa2fcb06717 Mon Sep 17 00:00:00 2001 From: Zippochonda Date: Sat, 9 May 2026 23:43:07 +0200 Subject: [PATCH 13/13] Implement backward compatibility for meander wiring Added backward compatibility for meander wiring configuration. --- usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp index fe7c9cb65c..418a8cbd86 100644 --- a/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp +++ b/usermods/usermod_v2_word_clock/usermod_v2_word_clock.cpp @@ -556,7 +556,10 @@ class WordClockUsermod : public Usermod configComplete &= getJsonValue(top[F("active")], usermodActive); configComplete &= getJsonValue(top[F("displayItIs")], displayItIs); configComplete &= getJsonValue(top[F("ledOffset")], ledOffset); - configComplete &= getJsonValue(top[F("meanderWiring")], meander); + if (!getJsonValue(top[F("meanderWiring")], meander)) { + getJsonValue(top[F("meander")], meander); // backward compatibility + configComplete = false; + } configComplete &= getJsonValue(top[F("wiring11x11")], eleven); configComplete &= getJsonValue(top[F("Norddeutsch")], nord);