From bbb27dd70b34df81270e5e877d7d2ef4290cb1d7 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 6 Mar 2018 23:47:08 +0100 Subject: [PATCH] Interim commit Added option to send UDP notifications twice to increase reliability Added a C64 color theme Added clock options Added 12 timezones Merged Cronixie and useoverlay build options Removed abbrev char[] from Timezone lib to save memory Added setting to reverse/flip LEDs Added long press random color button function --- wled00/WS2812FX.cpp | 6 ++ wled00/WS2812FX.h | 3 + wled00/data/settings_leds.htm | Bin 8250 -> 8222 bytes wled00/data/settings_sync.htm | Bin 7734 -> 7868 bytes wled00/data/settings_time.htm | Bin 10044 -> 12774 bytes wled00/data/settings_ui.htm | Bin 7470 -> 7454 bytes wled00/htmls00.h | 2 +- wled00/htmls01.h | 21 ++--- wled00/src/dependencies/time/Time.cpp | 10 ++- wled00/src/dependencies/time/TimeLib.h | 1 + wled00/src/dependencies/timezone/Timezone.h | 3 +- wled00/wled00.ino | 87 +++++++------------- wled00/wled01_eeprom.ino | 38 +++++++-- wled00/wled02_xml.ino | 35 +++++++- wled00/wled03_set.ino | 28 ++++--- wled00/wled05_init.ino | 24 +----- wled00/wled07_notify.ino | 9 +- wled00/wled09_button.ino | 37 +++++---- wled00/wled10_ntp.ino | 73 +++++++++++++++- wled00/wled11_ol.ino | 78 +++++++++++------- wled00/wled12_alexa.ino | 4 +- wled00/wled13_cronixie.ino | 24 ++---- wled00/wled14_colors.ino | 29 +++++-- wled00/wled15_hue.ino | 2 +- 24 files changed, 323 insertions(+), 191 deletions(-) diff --git a/wled00/WS2812FX.cpp b/wled00/WS2812FX.cpp index e25a93f3..eb3b0ae7 100644 --- a/wled00/WS2812FX.cpp +++ b/wled00/WS2812FX.cpp @@ -1816,6 +1816,11 @@ void WS2812FX::setFastUpdateMode(bool y) if (_mode_index == 0) _mode_delay = 20; } +void WS2812FX::setReverseMode(bool b) +{ + _reverseMode = b; +} + void WS2812FX::driverModeCronixie(bool b) { _cronixieMode = b; @@ -1940,6 +1945,7 @@ void WS2812FX::setPixelColorRaw(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uin void WS2812FX::setPixelColor(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uint8_t w) { + if (_reverseMode) i = _led_count - 1 -i; if (!_cronixieMode) { #ifdef RGBW diff --git a/wled00/WS2812FX.h b/wled00/WS2812FX.h index fdd997ae..e3a56f4e 100644 --- a/wled00/WS2812FX.h +++ b/wled00/WS2812FX.h @@ -213,6 +213,7 @@ class WS2812FX : public NeoPixelBrightnessBus { _counter_mode_step = 0; _counter_cc_step = 0; _fastStandard = false; + _reverseMode = false; _locked = new boolean[n]; _cronixieDigits = new uint8_t[6]; } @@ -247,6 +248,7 @@ class WS2812FX : public NeoPixelBrightnessBus { setBrightness(uint8_t b), increaseBrightness(uint8_t s), decreaseBrightness(uint8_t s), + setReverseMode(bool b), driverModeCronixie(bool b), setCronixieDigits(uint8_t* d), setCronixieBacklight(bool b), @@ -360,6 +362,7 @@ class WS2812FX : public NeoPixelBrightnessBus { boolean _triggered, _fastStandard, + _reverseMode, _cronixieMode, _cronixieBacklightEnabled, _cc_fs, diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index 14d21096d9e754dbd21144cfa178359bcf91783a..4dd33b0a8fa6d19472ddfd5d4daf890d41a1aa9d 100644 GIT binary patch delta 102 zcmdnxFwbGan$13pT8tBCEZAJelp$>y#E{BR2E;`S#XwSl!H2<>!39X?14UB6;tC8J uKz2Su2}2?fgVY!@STGn&?&lGm94DnSc>@m{a}Yz=ed9WA$F<$Q`{Z`rTUU2yZs@MurCW2qb-!_| z1)sa_z#WgC*R*2j&h>NYy1KWo>nmN=-JX6A{j;7sbpx$yrdEQ^+XHvx`g-d|PmN|x z_fOns*V7ZQuXR;-n{M7c^E~nVm+@82ebJhpIJ(x=f_~qKa!;%0Jnut&9=JE6-V`5j zdM4~ctvu4&E8Sh!-M;^HtveU`)YaWTyDjOXqbu;a+sw)It>+JU8={excTU`XKj!j3 zBzm)#U)8D(3{yQ(zPyYG$@{+;m%4}D2lcYLz?`4yDy;E$p zzQ_J7&0}4xcO<)@%bv8lAX}l&x8AS9-3|9OLM^A=z;)m`_ME`uoM<2D2c0d5uN6IU+S9YS$htLgYtn**BxR5eh05BC30OxZv5L7mmmkz+gP6O6 zF>hTjBQe&MoQajv(Uq31td{PQE%BI|G@Iux(Oebo%4)t?TWLwlYQCzZy_xJVo1}>q zlB;}Pile_MddR5%R$N>vZo7(-x-8mr|I~Hxsk-v)SKTK!_O+JZb>-7Dtt7te3Avj$ zPxX0I6=YkPH_!|GQ9X((1@$9DYf?Slhz_}YD8xA48_LrM%464}{zlKfRepc%Hr%pn zxy4jGv+^*ta?!7AyA{2YWS*MVH6(A0+0u$7_tK+gS01NUE^FN@-D!({cI6PeL_lx+b}=WfAQ5%h(Q7Wb)on(w^wOD{sNC9uXht zE6bQBp!3Xqr?&^5#z6PY{=|Diujcd4tw+R%&Sih&@JJj&32%wl9}16bdFri8e{ftt z-z*W=-kRRR;@5f)4aEEgd!*OH4LQCcPwjfn=!$rE$=l&~DZZ|}{PY&af7(t(T;qlG zM#ytEu6f{}2<28Zk0T0+WzHl)+A7$puhr-ZKb%fZs9laU4fSK8&_7|ZGjV4<)x4fG zQ;I1+d{m@64!Faw5|2#kO&l9fXURAd48+^d@;$gDGVqX?t88Svnz*9jz2e5B zwS<>OOFU@7N9CoSZ-{Q}LFA00j6$tB5qiwqjqD8nVTXYX2g-eBe|)r?TF)-vSa;9F z-;12A33piQ#`}1hx2N;&hxf^%cv-0!FHfIws6KcAUCFOylZVvcL)YP_%N<2g@;6!K zt0JbW-Br);01tKDcYn{=DvrOpd#*KCQG5nu>l4!*A@```$<$&s>T%E}y#Y_z-`Q?> zZaj-vRpy|^UWp$v0Bgb>cH48hPbbA5)!t|CUH6~K7W7iww|q0yRnn)f>e;#ak-B`7 z9p*s)SPQq7-&hT|am`HhHJ5qXA~?qpYgyR=fa^oG*6^^oQ-ZCS%nW8V$T(4)Y$v?-Cs3N{GhoF@`N{- z^U+s^T5Fw^?Hlp;Mg5poL!PDsUUTnc>wWDkKI(T{{Up|kamrI@d43G9DIeMsVs*47 zkJgry`{Ibdv*9g!ytgAf{?3N?+~a)|N@Il8)ZflbGOt9KZOE?p3Sp~o;CMJk2LT8^Z55?ja@mj3MORp!sYD+UAHv*;k@Nq@AUN) zFE~t9uC{*y8uO64?^BpmU+OxkPfVz(LCmR{>SVi#u##S7O^7{JBPO6<^xJf7@2!ce zkg+-US=Q?Ih^AF>yBF3Z&+5wgHr=y1`I`tQwqUwb+EEQ6+Nl+xb7AVhB+z=PFuR|= zmV{32NNAwPT$pV>c&k|dFiTC@lO?FfbX;gYOkk?#9U>*^HL*AHuS*gvf9>a_iSDb@ zv8uD@{rptO%ws$HWT#~HjP0xGh)NX8!h9dEV$RePty}#-w~RdZ=Yyo5PV8@!@}yJv zK@^EL;>k|wP^u9!X2jGvI`(ui~kj0CvYiC~x-}!hYPbBA}dHuyT zw=K%-3I5`(ZS{|AL!M`cY?YL}5Of!K%hL^eN_M!XdUy7H5WH>3f<^R;?A2E0qJ|D- zU8|vW*`8g#?UJhR1=*9erKe6IFGY0Ui7qt({eKdD{F!TJvDsZ|+9Dn8tv-2=s2YE- zb#iuBMnfNHh*|0Vd~8eR@_E4Wuz3-lW1VGjX6;BLc1D%9N?sQoX`?z1oF5kJBJ0tc z(hS{R8NF=IWS=GVZ^b;}uk^My<1WLA<+iGxvNFL_;_O$3lRZU9c{^q6-rbyJ?G*ao zb;UL3TTIpH8_^xLkN(BJ)0FOsJ6gp&mD9tzTi3Mcz5e2@;T<}D=9^@TEY;RMez7g- zWB<=*QQP@vahFQqT0e1Db}q(UE`e)aI34cu61dh`PKUcv0+%_5S?t#L#OW$ktcMpR zaG7;Xi~F(!F7u9QabK0dW%@BK?&}h`RyC%x8{f{DoE@rc_(oAUjxXI>gx|KCey_s6@?SwG- zrvg(w_@)MR=0G)^?{9E&&FN^^eF+Y8g8ho0ReGEzZvA{JzPdZulo~x;=jXelPe@o%z1kXS^S~dr}w2zx9S@ zjr^`VEA_gU@7C*RM-nu(D`2J=^INn}j5|qk(7LR}KCo)96#OU8@uWUFP~LeI%2{1) z_|7qWgJ&9hZb&=qZXQEBTi)~V!d>58ah7_&hrtnhzlY~2tF`?8tudaO#$I+m&zu=P zjux{#hg@*1bEGZh1>12~=X*;MKZUO8-s5uuF(m delta 1578 zcmb_cOHUI~6h32>ih@c?+o?dA0@W6rmbO+NK}#tr5-HHB5Ehyc+DH?jNGZxnjXQ}Z zdQ41=8(kY8VXFzOjB#Q73oclgn5auves^X%fC-5U({$#}d3@(Pue&+(F8yZzo;9WF z*#RlW?~hE`&r_b3XkyJ>x4OsPM?O+X<%r`ruLo+X)0Cw#(kR2%l?GdkqWrVj$w%uK zxW8d9Kd8SVMfrRE$fL$8?spDLCwbL5${|+`Z#svhQyg|_QWxKKX{@+w_^a!T)Wbfv zW{XfKm))8a;g9Zdo|mgwk<;K)l(oY{RHQO3QkX`lK=b@TR;#l#O6Ndhh{H`Cc9o(O zr#Qd%cJM2;(Qaz_j#u5Li`hgXPdxW)Cz0Vaa-79`k&}MMtrTL+33R$j3YG9x#My^) z8mA?^SM;hVu$iL;x`wYg{O6&|Qx2B3bbzYyGYdvW6@{O{z61<`DV__ur$RUI)_EMl zVG*h%YI}h~{Lte#TmbY6WHWHcQJyz~&DE2Xf<8-A+pB*%g+!)x>Uq=t8hivE{LElE zD>;LN6`GTdl#ZK1NiT|SwhjVq1t}I#j9ESTvq-iKi6C1LY4Er&0k1(Yo-(|;GKjUT z=TX8_p#W?}+vZWuO6tO2l((!)#h3+6qzs*<2?NP<4sir?!CxS3MMVwllW6-OUE=4h z310WM1Qo0FnvS~&hJryDc3W{28s$%N5S%q*bp9S3eK_j;sqz0l3at4PQYZS?YRh2E zzXZDYvA<;>&J;l(oA^h-#ozpGx+H2z296n$m?e37tW8Hqw#WIGsf}CO;p2w=DNFLg zlyq5=-=?J7l4JsgSC1)?`DLI@%JApFW$=ku3}wy*g=GXAZ*Z1*-IP=q%G}s4d=u@4 z?-sXv9o{+>z6v^C#Ir0q#BV$Do<4EAKvU8uBa7aNwNfd?z7x)aBk27MCZI^YY*X(z zgk=l-=ODjHr*V$(hS!6oAKOJ2yk$h#KEYzLqL{!O-bsCxZvxNQmSr%Q0fSy^sw#{9 zH$n`&{sDpGp@c1qzT=|WjU#u54mmE0z0$9rF(BtrkrF36!?pp+vf8BX=9@6`+d2CR guF6W~D*ShDgQaKH*TA>Kv%BE?#9pj@?sQ9k0G}&Up#T5? diff --git a/wled00/data/settings_ui.htm b/wled00/data/settings_ui.htm index 851c9ef7856696b386f13b7cff7a7b7dfea8e577..4bf51c1a92a884ee09f2c1ad09bc75a8a0166063 100644 GIT binary patch delta 18 ZcmZ2yHP32;lo+csgBgR#W__{$YydT;1yBG0 delta 16 XcmbPdwa#jTl-T4Xv7pT{Vu#oOHG&1} diff --git a/wled00/htmls00.h b/wled00/htmls00.h index eb783a1a..49877630 100644 --- a/wled00/htmls00.h +++ b/wled00/htmls00.h @@ -7,7 +7,7 @@ const char PAGE_index0[] PROGMEM = R"=====( -WLED 0.5.1 +WLED 0.6.0_dev )====="; diff --git a/wled00/htmls01.h b/wled00/htmls01.h index ad6285f4..5cbada9c 100644 --- a/wled00/htmls01.h +++ b/wled00/htmls01.h @@ -116,7 +116,7 @@ Default Duration: Default Target brightness:
Fade down:

Advanced

-Default overlay ID:
+Reverse LED order (rotate 180):
WARLS offset:
@@ -154,7 +154,7 @@ Color Theme: - + @@ -193,12 +193,13 @@ On/Off button enabled:

WLED Broadcast

UDP Port:
Receive Brightness, Color, and Effects
-Send notifications on direct change:
-Send notifications on button press:
-Send Alexa notifications:
+Send notifications on direct change:
+Send notifications on button press:
+Send Alexa notifications:
Send Philips Hue change notifications: +Send notifications twice:

Alexa Voice Assistant

-Emulate Alexa device:
+Emulate Alexa device:
Alexa invocation name:

Philips Hue

You can find the bridge IP and the light number in the 'About' section of the hue app.
@@ -239,9 +240,9 @@ Get time from NTP server:
Time zone:
Hour/Min offset:
--> Current local time is unknown. @@ -331,7 +332,7 @@ HTTP traffic is not encrypted. An attacker in the same network could intercept f
Enable ArduinoOTA:

About

-WLED version 0.5.1
+WLED version 0.6.0_dev
(c) 2016-2018 Christian Schwinne
Licensed under the MIT license

Uses libraries:
diff --git a/wled00/src/dependencies/time/Time.cpp b/wled00/src/dependencies/time/Time.cpp index 5ca13277..6b1df7c5 100644 --- a/wled00/src/dependencies/time/Time.cpp +++ b/wled00/src/dependencies/time/Time.cpp @@ -281,9 +281,9 @@ void setTime(time_t t) { nextSyncTime = (uint32_t)t + syncInterval; Status = timeSet; prevMillis = millis(); // restart counting from now (thanks to Korman for this fix) -} +} -void setTime(int hr,int min,int sec,int dy, int mnth, int yr){ +time_t getUnixTime(int hr,int min,int sec,int dy, int mnth, int yr){ // year can be given as full four digit year or two digts (2010 or 10 for 2010); //it is converted to years since 1970 if( yr > 99) @@ -296,7 +296,11 @@ void setTime(int hr,int min,int sec,int dy, int mnth, int yr){ tm.Hour = hr; tm.Minute = min; tm.Second = sec; - setTime(makeTime(tm)); + return makeTime(tm); +} + +void setTime(int hr,int min,int sec,int dy, int mnth, int yr){ + setTime(getUnixTime(hr,min,sec,dy,mnth,yr)); } void adjustTime(long adjustment) { diff --git a/wled00/src/dependencies/time/TimeLib.h b/wled00/src/dependencies/time/TimeLib.h index ddb16685..a1f3ce38 100644 --- a/wled00/src/dependencies/time/TimeLib.h +++ b/wled00/src/dependencies/time/TimeLib.h @@ -120,6 +120,7 @@ int year(time_t t); // the year for the given time time_t now(); // return the current time as seconds since Jan 1 1970 void setTime(time_t t); void setTime(int hr,int min,int sec,int day, int month, int yr); +void getUnixTime(int hr,int min,int sec,int day, int month, int yr); //added by Aircoookie to get epoch time void adjustTime(long adjustment); /* date strings */ diff --git a/wled00/src/dependencies/timezone/Timezone.h b/wled00/src/dependencies/timezone/Timezone.h index e0581ee3..c55d0c46 100644 --- a/wled00/src/dependencies/timezone/Timezone.h +++ b/wled00/src/dependencies/timezone/Timezone.h @@ -27,12 +27,11 @@ enum month_t {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec}; //or when standard time begins. struct TimeChangeRule { - char abbrev[6]; //five chars max uint8_t week; //First, Second, Third, Fourth, or Last week of the month uint8_t dow; //day of week, 1=Sun, 2=Mon, ... 7=Sat uint8_t month; //1=Jan, 2=Feb, ... 12=Dec uint8_t hour; //0-23 - int offset; //offset from UTC in minutes + int16_t offset; //offset from UTC in minutes }; class Timezone diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 1350114a..8051d06c 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -3,7 +3,7 @@ */ /* * @title WLED project sketch - * @version 0.5.1 + * @version 0.6.0_dev * @author Christian Schwinne */ @@ -32,8 +32,8 @@ #include "WS2812FX.h" //version in format yymmddb (b = daily build) -#define VERSION 1802273 -const String versionString = "0.5.1"; +#define VERSION 1803061 +const String versionString = "0.6.0_dev"; //AP and OTA default passwords (change them!) String appass = "wled1234"; @@ -42,16 +42,10 @@ String otapass = "wledota"; //If you have an RGBW strip, also uncomment first line in WS2812FX.h! bool useRGBW = false; -//overlays, needed for clocks etc. -#define USEOVERLAYS - -//support for the CRONIXIE clock by Diamex (disable overlays!) -//#define CRONIXIE - //spiffs FS only useful for debug (only ESP8266) //#define USEFS -//to toggle usb serial debug (un)comment following line +//to toggle usb serial debug (un)comment following line(s) //#define DEBUG //Hardware-settings (only changeble via code) @@ -61,39 +55,14 @@ uint8_t auxPin = 15; //use e.g. for external relay uint8_t auxDefaultState = 0; //0: input 1: high 2: low uint8_t auxTriggeredState = 0; //0: input 1: high 2: low -TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; //Central European Summer Time -TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; //Central European Standard Time -Timezone TZ(CEST, CET); -TimeChangeRule *tcr; //pointer to the time change rule, use to get the TZ abbrev -time_t local; - -//cronixie defaults -#ifdef CRONIXIE -#undef LEDCOUNT -#define LEDCOUNT 60 -uint8_t ledcount = 6; -String apssid = "CRONIXIE-AP"; -String alexaInvocationName = "Clock"; -char cronixieDefault[] = "HHMMSS"; -long cronixieRefreshMs = 497; -unsigned long cronixieRefreshedTime; -byte dP[]{0,0,0,0,0,0}; -bool cronixieUseAMPM = false; -bool cronixieBacklight = true; -bool cronixieCountdown = false; -bool ntpEnabled = true; -#endif - //Default CONFIG String serverDescription = versionString; uint8_t currentTheme = 0; String clientssid = "Your_Network_Here"; String clientpass = "Dummy_Pass"; String cmdns = "led"; -#ifndef CRONIXIE -uint8_t ledcount = 100; -String apssid = "WLED-AP"; -#endif +uint8_t ledcount = 10; //lowered to prevent accidental overcurrent +String apssid = ""; //AP off by default (unless setup) uint8_t apchannel = 1; uint8_t aphide = 0; uint8_t apWaitTimeSecs = 32; @@ -114,11 +83,12 @@ uint8_t nightlightTargetBri = 0, bri_nl_t; bool fadeTransition = true; bool sweepTransition = false, sweepDirection = true; uint16_t transitionDelay = 1200; +bool reverseMode = false; bool otaLock = false, wifiLock = false; bool aOtaEnabled = true; bool onlyAP = false; bool buttonEnabled = true; -bool notifyDirect = true, notifyButton = true, notifyDirectDefault = true, alexaNotify = false, macroNotify = false; +bool notifyDirect = true, notifyButton = true, notifyDirectDefault = true, alexaNotify = false, macroNotify = false, notifyTwice = false; bool receiveNotifications = true, receiveNotificationBrightness = true, receiveNotificationColor = true, receiveNotificationEffects = true; uint8_t briMultiplier = 100; uint8_t nightlightDelayMins = 60; @@ -128,9 +98,7 @@ uint8_t effectDefault = 0; uint8_t effectSpeedDefault = 75; uint8_t effectIntensityDefault = 128; //NTP stuff -#ifndef CRONIXIE boolean ntpEnabled = false; -#endif IPAddress ntpServerIP; const char* ntpServerName = "pool.ntp.org"; //custom chase @@ -144,11 +112,10 @@ uint8_t cc_start = 0; //alexa boolean alexaEnabled = true; -#ifndef CRONIXIE String alexaInvocationName = "Light"; -#endif -uint8_t alexaOnMacro = 255, alexaOffMacro = 255; -uint8_t buttonMacro = 255, countdownMacro = 255; +uint8_t alexaOnMacro = 0, alexaOffMacro = 0; +uint8_t buttonMacro = 0, countdownMacro = 0; +uint8_t bootMacro = 0; unsigned long countdownTime = 1514764800L; @@ -191,6 +158,9 @@ byte bri_last = 127; boolean transitionActive = false; boolean buttonPressedBefore = false; long buttonPressedTime = 0; +long notificationSentTime = 0; +uint8_t notificationSentCallMode = 0; +bool notificationTwoRequired = false; boolean nightlightActive = false; boolean nightlightActive_old = false; int nightlightDelayMs; @@ -209,30 +179,34 @@ const int NTP_PACKET_SIZE = 48; byte ntpPacketBuffer[NTP_PACKET_SIZE]; unsigned long ntpLastSyncTime = 999000000L; unsigned long ntpPacketSentTime = 999000000L; -const unsigned long seventyYears = 2208988800UL; +uint8_t currentTimezone = 0; +time_t local; +int utcOffsetSecs = 0; //overlay stuff uint8_t overlayDefault = 0; uint8_t overlayCurrent = 0; -#ifdef USEOVERLAYS int overlayMin = 0, overlayMax = 79; //bb: 35, 46, t: 0, 79 int analogClock12pixel = 25; //bb: 41, t: 25 -bool overlayDimBg = true; boolean analogClockSecondsTrail = false; boolean analogClock5MinuteMarks = false; -boolean nixieClockDisplaySeconds = false; -boolean nixieClock12HourFormat = false; -boolean overlayReverse = true; uint8_t overlaySpeed = 200; long overlayRefreshMs = 200; unsigned long overlayRefreshedTime; int overlayArr[6]; -int overlayDur[6]; -int overlayPauseDur[6]; +uint16_t overlayDur[6]; +uint16_t overlayPauseDur[6]; int nixieClockI = -1; boolean nixiePause; -#endif +uint8_t countdownYear=19, countdownMonth=1, countdownDay=1, countdownHour=0, countdownMin=0, countdownSec=0; //year is actual year -2000 bool countdownOverTriggered = true; +//cronixie +String cronixieDisplay = "HHMMSS"; +byte dP[]{0,0,0,0,0,0}; +bool useAMPM = false; +bool cronixieBacklight = true; +bool overlayCountdown = false; +bool cronixieInit = false; int arlsTimeoutMillis = 2500; boolean arlsTimeout = false; @@ -338,17 +312,12 @@ void loop() { handleButton(); handleNetworkTime(); if (!otaLock && aOtaEnabled) ArduinoOTA.handle(); - #ifdef CRONIXIE - handleCronixie(); - #endif handleAlexa(); + handleOverlays(); if (!arlsTimeout) //block stuff if WARLS is enabled { handleHue(); handleNightlight(); - #ifdef USEOVERLAYS - handleOverlays(); - #endif if (bri_t) strip.service(); //do not update strip if off, prevents flicker on ESP32 } diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index e75c3b2d..fb8b25b5 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -12,7 +12,7 @@ //2 -> 0.4p 1711302 and up //3 -> 0.4 1712121 and up //4 -> 0.5.0 and up -//5 -> 0.5.1 and up +//5 -> 0.6.0_dev and up void clearEEPROM() { @@ -61,7 +61,7 @@ void saveSettingsToEEPROM() EEPROM.write(228, aphide); EEPROM.write(229, ledcount); EEPROM.write(230, notifyButton); - //231 was notifyNightlight + EEPROM.write(231, notifyTwice); EEPROM.write(232, buttonEnabled); //233 reserved for first boot flag EEPROM.write(234, staticip[0]); @@ -82,6 +82,7 @@ void saveSettingsToEEPROM() EEPROM.write(249, bri_s); EEPROM.write(250, receiveNotificationBrightness); EEPROM.write(251, fadeTransition); + EEPROM.write(252, reverseMode); EEPROM.write(253, (transitionDelay >> 0) & 0xFF); EEPROM.write(254, (transitionDelay >> 8) & 0xFF); EEPROM.write(255, briMultiplier); @@ -102,8 +103,8 @@ void saveSettingsToEEPROM() EEPROM.write(325, effectSpeedDefault); EEPROM.write(326, effectIntensityDefault); EEPROM.write(327, ntpEnabled); - //328 reserved for timezone setting - //329 reserved for dst setting + EEPROM.write(328, currentTimezone); + EEPROM.write(329, useAMPM); EEPROM.write(330, useGammaCorrectionBri); EEPROM.write(331, useGammaCorrectionRGB); EEPROM.write(332, overlayDefault); @@ -140,6 +141,9 @@ void saveSettingsToEEPROM() EEPROM.write(391, receiveNotificationColor); EEPROM.write(392, receiveNotificationEffects); EEPROM.write(393, wifiLock); + EEPROM.write(394, (abs(utcOffsetSecs) >> 0) & 0xFF); + EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF); + EEPROM.write(396, (utcOffsetSecs<0)); //is negative for (int k=0;k<6;k++){ int in = 900+k*8; @@ -225,7 +229,7 @@ void loadSettingsFromEEPROM(bool first) if (aphide > 1) aphide = 1; ledcount = EEPROM.read(229); if (ledcount > LEDCOUNT) ledcount = LEDCOUNT; notifyButton = EEPROM.read(230); - //231 was notifyNightlight + notifyTwice = EEPROM.read(231); buttonEnabled = EEPROM.read(232); staticip[0] = EEPROM.read(234); staticip[1] = EEPROM.read(235); @@ -249,6 +253,7 @@ void loadSettingsFromEEPROM(bool first) } receiveNotificationBrightness = EEPROM.read(250); fadeTransition = EEPROM.read(251); + reverseMode = EEPROM.read(252); transitionDelay = ((EEPROM.read(253) << 0) & 0xFF) + ((EEPROM.read(254) << 8) & 0xFF00); briMultiplier = EEPROM.read(255); otapass = ""; @@ -269,6 +274,8 @@ void loadSettingsFromEEPROM(bool first) effectDefault = EEPROM.read(324); effectCurrent = effectDefault; effectSpeedDefault = EEPROM.read(325); effectSpeed = effectSpeedDefault; ntpEnabled = EEPROM.read(327); + currentTimezone = EEPROM.read(328); + useAMPM = EEPROM.read(329); useGammaCorrectionBri = EEPROM.read(330); useGammaCorrectionRGB = EEPROM.read(331); overlayDefault = EEPROM.read(332); @@ -348,6 +355,8 @@ void loadSettingsFromEEPROM(bool first) bootPreset = EEPROM.read(389); wifiLock = EEPROM.read(393); + utcOffsetSecs = ((EEPROM.read(394) << 0) & 0xFF) + ((EEPROM.read(395) << 8) & 0xFF00); + if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative //favorite setting memory (25 slots/ each 20byte) //400 - 899 reserved @@ -442,15 +451,25 @@ void savePreset(uint8_t index) EEPROM.commit(); } -void applyMacro(uint8_t index) +String loadMacro(uint8_t index) { - if (index > 15) return; - String mc="win&"; + index-=1; + String m=""; + if (index > 15) return m; for (int i = 1024+64*index; i < 1088+64*index; i++) { if (EEPROM.read(i) == 0) break; - mc += char(EEPROM.read(i)); + m += char(EEPROM.read(i)); } + return m; +} + +void applyMacro(uint8_t index) +{ + index-=1; + if (index > 15) return; + String mc="win&"; + mc += loadMacro(index+1); mc += "&IN"; //internal, no XML response if (!macroNotify) mc += "&NN"; String forbidden = "&M="; //dont apply if called by the macro itself to prevent loop @@ -465,6 +484,7 @@ void applyMacro(uint8_t index) void saveMacro(uint8_t index, String mc) { + index-=1; if (index > 15) return; int s = 1024+index*64; for (int i = s; i < s+64; i++) diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index e7d5d004..5432495a 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -70,6 +70,7 @@ String getSettings(uint8_t subPage) String v = ".value="; String c = ".checked="; String ih = ".innerHTML="; + String si = ".selectedIndex="; if (subPage == 1) { resp += ds + "CSSID" + v + "\"" + clientssid + "\";"; @@ -164,7 +165,7 @@ String getSettings(uint8_t subPage) resp += ds + "TLBRI" + v + nightlightTargetBri +";"; resp += ds + "TLDUR" + v + nightlightDelayMins +";"; resp += ds + "TLFDE" + c + nightlightFade +";"; - resp += ds + "OLDEF" + v + overlayDefault +";"; + resp += ds + "LEDRV" + c + reverseMode +";"; resp += ds + "WOFFS" + v + arlsOffset +";"; } @@ -172,7 +173,7 @@ String getSettings(uint8_t subPage) { resp += ds + "DESC" + v + "\"" + serverDescription + "\";"; resp += ds + "COLMD" + c + useHSBDefault + ";"; - resp += ds + "THEME.selectedIndex=" + String(currentTheme) + ";"; + resp += ds + "THEME" + si + String(currentTheme) + ";"; for(int i=0;i<6;i++) resp += ds + "CCOL" + i + v + "\"" + cssCol[i] + "\";"; resp += ds + "CFONT" + v + "\"" + cssFont + "\";"; @@ -188,6 +189,7 @@ String getSettings(uint8_t subPage) resp += ds + "NSDIR" + c + notifyDirectDefault +";"; resp += ds + "NSBTN" + c + notifyButton +";"; resp += ds + "NSHUE" + c + notifyHue +";"; + resp += ds + "NS2XS" + c + notifyTwice +";"; resp += ds + "ALEXA" + c + alexaEnabled +";"; resp += ds + "AINVN" + v + "\"" + alexaInvocationName + "\";"; resp += ds + "NSALX" + c + alexaNotify +";"; @@ -207,7 +209,36 @@ String getSettings(uint8_t subPage) if (subPage == 5) { resp += ds + "NTPON" + c + ntpEnabled +";"; + resp += ds + "CL24H" + c + !useAMPM +";"; + resp += ds + "TZONE" + si + String(currentTimezone) + ";"; + resp += ds + "UTCOS" + v + utcOffsetSecs +";"; resp += dg + "(\"times\")[0]" + ih + "\"" + getTimeString() + "\";"; + resp += ds + "OLMDE" + si + String(currentOverlay) + ";"; + resp += ds + "OLIN1" + v + overlayMin +";"; + resp += ds + "OLIN2" + v + overlayMax +";"; + resp += ds + "OLINM" + v + analogClock12pixel +";"; + resp += ds + "OLSTR" + c + analogClockSecondsTrail +";"; + resp += ds + "OL5MI" + c + analogClock5MinuteMarks +";"; + resp += ds + "CRONX" + v + "\"" + cronixieDisplay + "\";"; + resp += ds + "CROBL" + c + cronixieBacklight +";"; + resp += ds + "CLCND" + c + overlayCountdown +";"; + resp += ds + "CDGYR" + v + countdownYear +";"; + resp += ds + "CDGMN" + v + countdownMonth +";"; + resp += ds + "CDGDY" + v + countdownDay +";"; + resp += ds + "CDGHR" + v + countdownHours +";"; + resp += ds + "CDGMI" + v + countdownMin +";"; + resp += ds + "CDGSC" + v + countdownSec +";"; + for (int i=1;i<17;i++) + { + resp += ds + "MC" + String(i) + v + "\"" + loadMacro(i) + "\";"; + } + resp += ds + "MCRBT" + v + macroBoot +";"; + resp += ds + "MCA0I" + v + macroAlexaOn +";"; + resp += ds + "MCA0O" + v + macroAlexaOff +";"; + resp += ds + "MCB0D" + v + macroButton +";"; + resp += ds + "MCB0L" + v + macroLongPress +";"; + resp += ds + "MCNTD" + v + macroCountdown +";"; + resp += ds + "MCLNO" + v + macroNightlight +";"; } if (subPage == 6) diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 56ca9d74..2b5be7f0 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -230,11 +230,7 @@ void handleSettingsSet(uint8_t subPage) if (i > 0) nightlightDelayMins = i; } nightlightFade = server.hasArg("TLFDE"); - if (server.hasArg("OLDEF")) - { - int i = server.arg("OLDEF").toInt(); - if (i >= 0 && i <= 255) overlayDefault = i; - } + reverseMode = server.hasArg("LEDRV"); if (server.hasArg("WOFFS")) { int i = server.arg("WOFFS").toInt(); @@ -278,6 +274,7 @@ void handleSettingsSet(uint8_t subPage) notifyDirectDefault = server.hasArg("NSDIR"); notifyDirect = notifyDirectDefault; notifyButton = server.hasArg("NSBTN"); + notifyTwice = server.hasArg("NS2XS"); alexaEnabled = server.hasArg("ALEXA"); if (server.hasArg("AINVN")) alexaInvocationName = server.arg("AINVN"); alexaNotify = server.hasArg("NSALX"); @@ -319,6 +316,11 @@ void handleSettingsSet(uint8_t subPage) { ntpEnabled = server.hasArg("NTPON"); if (ntpEnabled && WiFi.status() == WL_CONNECTED && !ntpConnected) ntpConnected = ntpUdp.begin(ntpLocalPort); //start if not already connected + if (server.hasArg("OLDEF")) + { + int i = server.arg("OLDEF").toInt(); + if (i >= 0 && i <= 255) overlayDefault = i; + } } //SECURITY @@ -712,17 +714,19 @@ boolean handleSet(String req) applyPreset(req.substring(pos + 3).toInt(), false, false, true); effectUpdated = true; } - #ifdef CRONIXIE + + //cronixie pos = req.indexOf("NX="); //sets digits to code if (pos > 0) { - setCronixie(req.substring(pos + 3, pos + 9).c_str()); + cronixieDisplay = req.substring(pos + 3, pos + 9); + setCronixie(); } pos = req.indexOf("NM="); //mode, 1 countdown if (pos > 0) { - cronixieCountdown = true; + overlayCountdown = true; if (req.indexOf("NM=0") > 0) { - cronixieCountdown = false; + overlayCountdown = false; } } if (req.indexOf("NB=") > 0) //sets backlight @@ -732,10 +736,10 @@ boolean handleSet(String req) { cronixieBacklight = false; } - strip.setCronixieBacklight(cronixieBacklight); - cronixieRefreshedTime = 0; + if (overlayCurrent == 4) strip.setCronixieBacklight(cronixieBacklight); + overlayRefreshedTime = 0; } - #endif + //internal call, does not send XML response pos = req.indexOf("IN"); if (pos < 1) XML_response(); diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 3776ee71..0dd5246d 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -212,16 +212,6 @@ void wledInit() info += "rgbw: false\r\n"; #endif info += "max-leds: " + (String)LEDCOUNT + "\r\n"; - #ifdef USEOVERLAYS - info += "overlays: true\r\n"; - #else - info += "overlays: false\r\n"; - #endif - #ifdef CRONIXIE - info += "cronixie: true\r\n"; - #else - info += "cronixie: false\r\n"; - #endif #ifdef USEFS info += "spiffs: true\r\n"; #else @@ -308,16 +298,13 @@ void wledInit() // Initialize NeoPixel Strip strip.init(); strip.setLedCount(ledcount); + strip.setReverseMode(reverseMode); strip.setColor(0); strip.setBrightness(255); strip.start(); pinMode(buttonPin, INPUT_PULLUP); - #ifdef CRONIXIE - strip.driverModeCronixie(true); - strip.setCronixieBacklight(cronixieBacklight); - setCronixie(cronixieDefault); - #endif + if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true); colorUpdated(0); if(digitalRead(buttonPin) == LOW) buttonEnabled = false; //disable button if it is "pressed" unintentionally @@ -325,11 +312,7 @@ void wledInit() void initAP(){ String save = apssid; - #ifdef CRONIXIE - if (apssid.length() <1) apssid = "CRONIXIE-AP"; - #else - if (apssid.length() <1) apssid = "WLED-AP"; - #endif + if (apssid.length() <1) apssid = "WLED-AP"; WiFi.softAP(apssid.c_str(), appass.c_str(), apchannel, aphide); apssid = save; } @@ -370,6 +353,7 @@ void buildCssColorString() case 8: cs[0]="0ac"; cs[1]="124"; cs[2]="224"; cs[3]="003eff"; cs[4]="003eff"; cs[5]="003eff"; break;//air case 9: cs[0]="f70"; cs[1]="421"; cs[2]="221"; cs[3]="a50"; cs[4]="f70"; cs[5]="f70"; break;//nixie case 10: cs[0]="2d2"; cs[1]="010"; cs[2]="121"; cs[3]="060"; cs[4]="040"; cs[5]="3f3"; break; //terminal + case 11: cs[0]="867ADE"; cs[1]="4033A3"; cs[2]="483AAA"; cs[3]="483AAA"; cs[4]=""; cs[5]="867ADE"; break; //c64 case 14: cs[0]="fc7"; cs[1]="49274a"; cs[2]="94618e"; cs[3]="f4decb"; cs[4]="0008"; cs[5]="f4decb"; break; //end case 15: for (int i=0;i<6;i++)cs[i]=cssCol[i];//custom } diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino index f82a618b..11eb4a76 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled07_notify.ino @@ -4,7 +4,7 @@ #define WLEDPACKETSIZE 24 -void notify(uint8_t callMode) +void notify(uint8_t callMode, bool followUp=false) { if (!udpConnected) return; switch (callMode) @@ -41,10 +41,17 @@ void notify(uint8_t callMode) notifierUdp.beginPacket(broadcastIp, udpPort); notifierUdp.write(udpOut, WLEDPACKETSIZE); notifierUdp.endPacket(); + notificationSentCallMode = callMode; + notificationSentTime = millis(); + notificationTwoRequired = (followUp)? false:notifyTwice; } void handleNotifications() { + if(udpConnected && notificationTwoRequired && millis()-notificationSentTime > 250){ + notify(notificationSentCallMode,true); + } + if(udpConnected && receiveNotifications){ int packetSize = notifierUdp.parsePacket(); if(packetSize && notifierUdp.remoteIP() != WiFi.localIP()) //don't process broadcasts we send ourselves diff --git a/wled00/wled09_button.ino b/wled00/wled09_button.ino index 98b64239..83f21b41 100644 --- a/wled00/wled09_button.ino +++ b/wled00/wled09_button.ino @@ -10,27 +10,34 @@ void handleButton() { buttonPressedTime = millis(); buttonPressedBefore = true; - if (buttonMacro == 255) - { - if (bri == 0) - { - bri = bri_last; - } else - { - bri_last = bri; - bri = 0; - } - colorUpdated(2); - } else { - applyMacro(buttonMacro); - } } else if (digitalRead(buttonPin) == HIGH && buttonPressedBefore) { delay(15); //debounce if (digitalRead(buttonPin) == HIGH) { - if (millis() - buttonPressedTime > 7000) initAP(); + if (millis() - buttonPressedTime > 7000) {initAP();} + else if (millis() - buttonPressedTime > 700) + { + if (buttonLongPressMacro != 0) {applyMacro(buttonLongPressMacro);} + else _setRandomColor(false); + } + else { + if (buttonMacro == 0) + { + if (bri == 0) + { + bri = bri_last; + } else + { + bri_last = bri; + bri = 0; + } + colorUpdated(2); + } else { + applyMacro(buttonMacro); + } + } buttonPressedBefore = false; } } diff --git a/wled00/wled10_ntp.ino b/wled00/wled10_ntp.ino index 4c24e4ad..f1ff30c6 100644 --- a/wled00/wled10_ntp.ino +++ b/wled00/wled10_ntp.ino @@ -2,6 +2,55 @@ * Acquires time from NTP server */ +TimeChangeRule UTCr = {Last, Sun, Mar, 1, 0}; // UTC +Timezone tzUTC(UTCr, UTCr); + +TimeChangeRule BST = {Last, Sun, Mar, 1, 60}; // British Summer Time +TimeChangeRule GMT = {Last, Sun, Oct, 2, 0}; // Standard Time +Timezone tzUK(BST, GMT); + +TimeChangeRule CEST = {Last, Sun, Mar, 2, 120}; //Central European Summer Time +TimeChangeRule CET = {Last, Sun, Oct, 3, 60}; //Central European Standard Time +Timezone tzEUCentral(CEST, CET); + +TimeChangeRule EEST = {Last, Sun, Mar, 3, 180}; //Central European Summer Time +TimeChangeRule EET = {Last, Sun, Oct, 4, 120}; //Central European Standard Time +Timezone tzEUEastern(EEST, EET); + +TimeChangeRule EDT = {Second, Sun, Mar, 2, -240 }; //Daylight time = UTC - 4 hours +TimeChangeRule EST = {First, Sun, Nov, 2, -300 }; //Standard time = UTC - 5 hours +Timezone tzUSEastern(EDT, EST); + +TimeChangeRule CDT = {Second, Sun, Mar, 2, -300 }; //Daylight time = UTC - 5 hours +TimeChangeRule CST = {First, Sun, Nov, 2, -360 }; //Standard time = UTC - 6 hours +Timezone tzUSCentral(CDT, CST); + +TimeChangeRule MDT = {Second, Sun, Mar, 2, -360 }; //Daylight time = UTC - 6 hours +TimeChangeRule MST = {First, Sun, Nov, 2, -420 }; //Standard time = UTC - 7 hours +Timezone tzUSMountain(MDT, MST); + +Timezone tzUSArizona(MST, MST); //Mountain without DST + +TimeChangeRule PDT = {Second, Sun, Mar, 2, -420 }; //Daylight time = UTC - 7 hours +TimeChangeRule PST = {First, Sun, Nov, 2, -480 }; //Standard time = UTC - 8 hours +Timezone tzUSPacific(PDT, PST); + +TimeChangeRule ChST = {Last, Sun, Mar, 1, 480}; // China Standard Time = UTC + 8 hours +Timezone tzChina(ChST, ChST); + +TimeChangeRule JST = {Last, Sun, Mar, 1, 540}; // Japan Standard Time = UTC + 9 hours +Timezone tzJapan(JST, JST); + +TimeChangeRule AEDT = {Second, Sun, Oct, 2, 660 }; //Daylight time = UTC + 11 hours +TimeChangeRule AEST = {First, Sun, Apr, 3, 600 }; //Standard time = UTC + 10 hours +Timezone tzAUEastern(AEDT, AEST); + +TimeChangeRule NZDT = {Second, Sun, Sep, 2, 780 }; //Daylight time = UTC + 13 hours +TimeChangeRule NZST = {First, Sun, Apr, 3, 720 }; //Standard time = UTC + 12 hours +Timezone tzNZ(NZDT, NZST); + +Timezone* timezones[] = { &tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ}; + void handleNetworkTime() { if (ntpEnabled && ntpConnected && millis() - ntpLastSyncTime > 50000000L && WiFi.status() == WL_CONNECTED) @@ -56,7 +105,7 @@ boolean checkNTPResponse() unsigned long secsSince1900 = highWord << 16 | lowWord; DEBUG_PRINT("Unix time = "); - unsigned long epoch = secsSince1900 - seventyYears; + unsigned long epoch = secsSince1900 - 2208988800UL; //subtract 70 years setTime(epoch); DEBUG_PRINTLN(epoch); if (countdownTime - now() > 0) countdownOverTriggered = false; @@ -65,25 +114,41 @@ boolean checkNTPResponse() return false; } +void updateLocalTime() +{ + unsigned long tmc = now()+ (utcOffsetSign)? -utcOffsetSecs:utcOffsetSecs; + local = timezones[currentTimezone]->toLocal(tmc); +} + String getTimeString() { - local = TZ.toLocal(now(), &tcr); + updateLocalTime(); String ret = monthStr(month(local)); ret = ret + " "; ret = ret + day(local); ret = ret + " "; ret = ret + year(local); ret = ret + ", "; - ret = ret + hour(local); + ret += (useAMPM)? hour(local)%12:hour(local); ret = ret + ":"; if (minute(local) < 10) ret = ret + "0"; ret = ret + minute(local); ret = ret + ":"; if (second(local) < 10) ret = ret + "0"; ret = ret + second(local); + if (useAMPM) + { + ret += (hour(local) > 11)? " PM":" AM"; + } return ret; } +void setCountdown() +{ + countdownTime = timezones[currentTimezone]->toUTC(getUnixTime(countdownHour, countdownMin, countdownSec, countdownDay, countdownMonth, countdownYear)); + if (countdownTime - now() > 0) countdownOverTriggered = false; +} + //returns true if countdown just over bool checkCountdown() { @@ -91,7 +156,7 @@ bool checkCountdown() local = abs(diff); if (diff <0 && !countdownOverTriggered) { - applyMacro(countdownMacro); + if (countdownMacro != 0) applyMacro(countdownMacro); countdownOverTriggered = true; return true; } diff --git a/wled00/wled11_ol.ino b/wled00/wled11_ol.ino index da775798..79bdf985 100644 --- a/wled00/wled11_ol.ino +++ b/wled00/wled11_ol.ino @@ -1,7 +1,21 @@ /* - * The Overlay function is over a year old, largely untested and not configurable during runtime. Consider it as deprecated for now, it might get either removed/simplified/reworked. + * Used to draw clock overlays over the strip */ -#ifdef USEOVERLAYS +void initCronixie() +{ + if (overlayCurrent == 7 && !cronixieInit) + { + strip.driverModeCronixie(true); + strip.setCronixieBacklight(cronixieBacklight); + setCronixie(cronixieDefault); + cronixieInit = true; + } else if (cronixieInit && overlayCurrent != 7) + { + strip.driverModeCronixie(false); + cronixieInit = false; + } +} + void _nixieDisplay(int num[], int dur[], int pausedur[], int cnt) { strip.setRange(overlayMin, overlayMax, 0); @@ -84,8 +98,6 @@ void _nixieNumber(int number, int dur) if (overlayArr[i] != -1) { overlayArr[i] = overlayArr[i] + overlayMin; - if (overlayReverse) - overlayArr[i] = overlayMax - overlayArr[i]; } } for (int i = 0; i <6; i++) @@ -106,38 +118,39 @@ void _nixieNumber(int number, int dur) void handleOverlays() { - //properties: range, (color) - //0 no overlay - //1 solid color (NI) - //2 analog clock - //3 digital nixie-style clock one digit - //4 just static hour (NI) - //5 analog countdown - //6 digital one digit countdown + if (overlayCurrent == 0) return; + if (millis() - overlayRefreshedTime > overlayRefreshMs) { - overlayRefreshedTime = millis(); + initCronixie(); + updateLocalTime(); switch (overlayCurrent) { + case 1: _overlaySolid(); break;//solid secondary color case 2: _overlayAnalogClock(); break;//2 analog clock case 3: _overlayNixieClock(); break;//nixie 1-digit - case 5: _overlayAnalogCountdown(); break;//a.countdown - case 6: _overlayNixieCountdown(); break;//d. + case 4: _overlayCronixie();//Diamex cronixie clock kit } + overlayRefreshedTime = millis(); } } +void _overlaySolid() +{ + uint32_t cls = (useGammaCorrectionRGB)? gamma8[white*16777216] + gamma8[col[0]]*65536 + gamma8[col[1]]*256 + gamma8[col[2]]:white*16777216 + col[0]*65536 + col[1]*256 + col[2]; + strip.setRange(overlayMin,overlayMax,cls); + overlayRefreshMs = 1902; +} + void _overlayAnalogClock() { int overlaySize = overlayMax - overlayMin +1; strip.unlockAll(); - if (overlayDimBg) + if (overlayCountdown) { - uint32_t ct = (white>>1)*16777216 + (col[0]>>1)*65536 + (col[1]>>1)*256 + (col[2]>>1); - if (useGammaCorrectionRGB) ct = (gamma8[white]>>1)*16777216 + (gamma8[col[0]]>>1)*65536 + (gamma8[col[1]]>>1)*256 + (gamma8[col[2]]>>1); - strip.setRange(overlayMin, overlayMax, ct); + _overlayAnalogCountdown(); return; } - local = TZ.toLocal(now(), &tcr); + _overlaySolid(); double hourP = ((double)(hour(local)%12))/12; double minuteP = ((double)minute(local))/60; hourP = hourP + minuteP/12; @@ -160,7 +173,14 @@ void _overlayAnalogClock() } if (analogClockSecondsTrail) { - strip.setRange(analogClock12pixel, secondPixel, 0xFF0000); + if (secondPixel < analogClock12pixel) + { + strip.setRange(analogClock12pixel, secondPixel, 0xFF0000); + strip.setRange(secondPixel, overlayMax, 0xFF0000); + } else + { + strip.setRange(analogClock12pixel, secondPixel, 0xFF0000); + } } else { strip.setIndividual(secondPixel, 0xFF0000); @@ -172,14 +192,14 @@ void _overlayAnalogClock() void _overlayNixieClock() { + if (overlayCountdown) + { + _overlayNixieCountdown(); return; + } if (nixieClockI < 0) { - local = TZ.toLocal(now(), &tcr); overlayArr[0] = hour(local); - if (nixieClock12HourFormat && overlayArr[0] > 12) - { - overlayArr[0] = overlayArr[0]%12; - } + if (useAMPM) overlayArr[0] = overlayArr[0]%12; overlayArr[1] = -1; if (overlayArr[0] > 9) { @@ -191,7 +211,7 @@ void _overlayNixieClock() overlayArr[2] = overlayArr[2]/10; overlayArr[4] = -1; overlayArr[5] = -1; - if (nixieClockDisplaySeconds) + if (analogClockSecondsTrail) { overlayArr[4] = second(local); overlayArr[5] = overlayArr[4]%10; @@ -202,8 +222,6 @@ void _overlayNixieClock() if (overlayArr[i] != -1) { overlayArr[i] = overlayArr[i] + overlayMin; - if (overlayReverse) - overlayArr[i] = overlayMax - overlayArr[i]; } } overlayDur[0] = 12 + 12*(255 - overlaySpeed); @@ -331,5 +349,5 @@ void _overlayNixieCountdown() } _nixieNumber(diff, 800); } + overlayRefreshMs = 998; } -#endif diff --git a/wled00/wled12_alexa.ino b/wled00/wled12_alexa.ino index f460ed46..47ec3dfd 100644 --- a/wled00/wled12_alexa.ino +++ b/wled00/wled12_alexa.ino @@ -46,7 +46,7 @@ void handleAlexa() void alexaOn() { - if (alexaOnMacro == 255) + if (alexaOnMacro == 0) { handleSet((alexaNotify)?"win&T=1&IN":"win&T=1&NN&IN"); } else @@ -64,7 +64,7 @@ void alexaOn() void alexaOff() { - if (alexaOffMacro == 255) + if (alexaOffMacro == 0) { handleSet((alexaNotify)?"win&T=0&IN":"win&T=0&NN&IN"); } else diff --git a/wled00/wled13_cronixie.ino b/wled00/wled13_cronixie.ino index f5d7112e..5c79a0d8 100644 --- a/wled00/wled13_cronixie.ino +++ b/wled00/wled13_cronixie.ino @@ -1,7 +1,6 @@ /* * Support for the Cronixie clock */ -#ifdef CRONIXIE uint8_t getSameCodeLength(char code, int index, char const digits[]) { uint8_t counter = 0; @@ -18,8 +17,9 @@ uint8_t getSameCodeLength(char code, int index, char const digits[]) return counter; } -void setCronixie(char const digits[]) +void setCronixie() { + char digits[] = cronixieDisplay.substring(0,6); /* * digit purpose index * 0-9 | 0-9 (incl. random) @@ -86,7 +86,7 @@ void setCronixie(char const digits[]) DEBUG_PRINT("cset "); DEBUG_PRINTLN(digits); - cronixieRefreshMs = 1997; //Only refresh every 2secs if no seconds are displayed + overlayRefreshMs = 1997; //Only refresh every 2secs if no seconds are displayed for (int i = 0; i < 6; i++) { @@ -107,8 +107,8 @@ void setCronixie(char const digits[]) case 'a': dP[i] = 58; i++; break; case 'm': dP[i] = 74 + getSameCodeLength('m',i,digits); i = i+dP[i]-74; break; case 'M': dP[i] = 24 + getSameCodeLength('M',i,digits); i = i+dP[i]-24; break; - case 's': dP[i] = 80 + getSameCodeLength('s',i,digits); i = i+dP[i]-80; cronixieRefreshMs = 497; break; //refresh more often bc. of secs - case 'S': dP[i] = 30 + getSameCodeLength('S',i,digits); i = i+dP[i]-30; cronixieRefreshMs = 497; break; + case 's': dP[i] = 80 + getSameCodeLength('s',i,digits); i = i+dP[i]-80; overlayRefreshMs = 497; break; //refresh more often bc. of secs + case 'S': dP[i] = 30 + getSameCodeLength('S',i,digits); i = i+dP[i]-30; overlayRefreshMs = 497; break; case 'Y': dP[i] = 36 + getSameCodeLength('Y',i,digits); i = i+dP[i]-36; break; case 'y': dP[i] = 86 + getSameCodeLength('y',i,digits); i = i+dP[i]-86; break; case 'I': dP[i] = 39 + getSameCodeLength('I',i,digits); i = i+dP[i]-39; break; //Month. Don't ask me why month and minute both start with M. @@ -139,16 +139,12 @@ void setCronixie(char const digits[]) } DEBUG_PRINTLN((int)dP[5]); - cronixieRefreshedTime = 0; //refresh immediately + _overlayCronixie(); //refresh } -void handleCronixie() +void _overlayCronixie() { - if (millis() - cronixieRefreshedTime > cronixieRefreshMs) - { - cronixieRefreshedTime = millis(); - local = TZ.toLocal(now(), &tcr); - if (cronixieCountdown) checkCountdown(); + if (overlayCountdown) checkCountdown(); uint8_t h = hour(local); uint8_t h0 = h; uint8_t m = minute(local); @@ -159,7 +155,7 @@ void handleCronixie() //this has to be changed in time for 22nd century y -= 2000; if (y<0) y += 30; //makes countdown work - if (cronixieUseAMPM && !cronixieCountdown) + if (useAMPM && !overlayCountdown) { if (h>12) h-=12; else if (h==0) h+=12; @@ -213,6 +209,4 @@ void handleCronixie() } strip.setCronixieDigits(_digitOut); //strip.trigger(); //this has a drawback, no effects slower than RefreshMs. advantage: Quick update, not dependant on effect time - } } -#endif diff --git a/wled00/wled14_colors.ino b/wled00/wled14_colors.ino index eb2d60d9..165053ee 100644 --- a/wled00/wled14_colors.ino +++ b/wled00/wled14_colors.ino @@ -86,16 +86,14 @@ void colorXYtoRGB(float x, float y, uint8_t* rgb) //coordinates to rgb (https:// b = b / r; r = 1.0f; } - } - else if (g > b && g > r) { + } else if (g > b && g > r) { // green is biggest if (g > 1.0f) { r = r / g; b = b / g; g = 1.0f; } - } - else if (b > r && b > g) { + } else if (b > r && b > g) { // blue is biggest if (b > 1.0f) { r = r / b; @@ -117,4 +115,25 @@ void colorRGBtoXY(uint8_t* rgb, float* xy) //rgb to coordinates (https://www.dev xy[1] = Y / (X + Y + Z); } -void colorRGBtoRGBW(uint8_t* rgb, uint8_t* rgbw){} //rgb to rgbw, not imlemented yet +/*//For some reason min and max are not declared here + +float minf (float v, float w) +{ + if (w > v) return v; + return w; +} + +float maxf (float v, float w) +{ + if (w > v) return w; + return v; +} + +void colorRGBtoRGBW(uint8_t* rgb, uint8_t* wht) //rgb to rgbw, untested and currently unused +{ + *wht = (float)minf(rgb[0],minf(rgb[1],rgb[2]))*0.95; + rgb[0]-=wht; + rgb[1]-=wht; + rgb[2]-=wht; +}*/ + diff --git a/wled00/wled15_hue.ino b/wled00/wled15_hue.ino index 1c10faa7..9a6c63c2 100644 --- a/wled00/wled15_hue.ino +++ b/wled00/wled15_hue.ino @@ -45,7 +45,7 @@ bool sendHuePoll(bool sAuth) { bool st; hueClient.setReuse(true); - hueClient.setTimeout(250); + hueClient.setTimeout(450); String hueURL = "http://"; hueURL += hueIP.toString(); hueURL += "/api/";