From 8048bb85fb265c38f3c19226e1d5c68f1fed20cd Mon Sep 17 00:00:00 2001 From: Serhan Date: Tue, 14 Jan 2020 15:58:14 +0100 Subject: [PATCH 001/509] Update NpbWrapper.h Fixes the WS2801 Color Order --- wled00/NpbWrapper.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 7648350cb..77d4e1e4f 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -86,7 +86,10 @@ #define PIXELFEATURE4 DotStarLbgrFeature #elif defined(USE_LPD8806) #define PIXELFEATURE3 Lpd8806GrbFeature - #define PIXELFEATURE4 Lpd8806GrbFeature + #define PIXELFEATURE4 Lpd8806GrbFeature +#elif defined(USE_WS2801) + #define PIXELFEATURE3 NeoRbgFeature + #define PIXELFEATURE4 NeoRbgFeature #else #define PIXELFEATURE3 NeoGrbFeature #define PIXELFEATURE4 NeoGrbwFeature @@ -235,7 +238,7 @@ public: } break; case NeoPixelType_Grbw: { - #ifdef USE_LPD8806 + #if defined(USE_LPD8806) || defined(USE_WS2801) _pGrbw->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); #else _pGrbw->SetPixelColor(indexPixel, color); From 593c1d6b057ffd5c0c36b5ae0603c0b69f3f6dfb Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:01:31 -0500 Subject: [PATCH 002/509] Create Enclosure_with_OLED_temp_ESP07 --- usermods/Enclosure_with_OLED_temp_ESP07 | 1 + 1 file changed, 1 insertion(+) create mode 100644 usermods/Enclosure_with_OLED_temp_ESP07 diff --git a/usermods/Enclosure_with_OLED_temp_ESP07 b/usermods/Enclosure_with_OLED_temp_ESP07 new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/usermods/Enclosure_with_OLED_temp_ESP07 @@ -0,0 +1 @@ + From 7bf92db4c976e83263cb1b88fa8770c643cda015 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:05:49 -0500 Subject: [PATCH 003/509] Delete Enclosure_with_OLED_temp_ESP07 --- usermods/Enclosure_with_OLED_temp_ESP07 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 usermods/Enclosure_with_OLED_temp_ESP07 diff --git a/usermods/Enclosure_with_OLED_temp_ESP07 b/usermods/Enclosure_with_OLED_temp_ESP07 deleted file mode 100644 index 8b1378917..000000000 --- a/usermods/Enclosure_with_OLED_temp_ESP07 +++ /dev/null @@ -1 +0,0 @@ - From 5d947cc8e1f0373a1ad836e4ca7d6e10301cbdc8 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:06:26 -0500 Subject: [PATCH 004/509] Create readme.md --- .../Enclosure_with_OLED_temp_ESP07/readme.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 usermods/Enclosure_with_OLED_temp_ESP07/readme.md diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md new file mode 100644 index 000000000..2541e6955 --- /dev/null +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -0,0 +1,34 @@ +# Almost universal controller board for outdoor applications +This usermod is using ideas from @mrVanboy and @400killer +## Features +- SSD1306 128x32 and 128x64 I2C OLED display (optional) +- Dallas temperature sensor (optional) + +## Hardware +![Hardware connection](assets/controller.jpg) + +## Requirements +Functionality checked with: +- ESP-07S +- PlatformIO +- SSD1306 128x32 I2C OLED display +- DS18B20 (temperature sensor) +- KY-022 (infrared receiver) +- Push button (N.O. momentary switch) + +### Platformio +Uncomment `U8g2@~2.27.3`,`DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`: +```ini +# platformio.ini +... +[common] +... +lib_deps_external = + ... + #For use SSD1306 0.91" OLED display uncomment following + U8g2@~2.27.3 + #For Dallas sensor uncomment following 2 lines + DallasTemperature@~3.8.0 + OneWire@~2.3.5 +... +``` From 5d8bfc293088554987640e46bbe40cb9b091d999 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:07:27 -0500 Subject: [PATCH 005/509] Create readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md new file mode 100644 index 000000000..4466821bc --- /dev/null +++ b/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md @@ -0,0 +1,9 @@ +# Enclosure and PCB + +## IP67 rated enclosure +![Enclosure](assets/controller.jpg) + +## PCB +![PCB](assets/controller.jpg) +``` +``` From 551afe0cd79fba4b087eeeb02d1f8121fff2fba9 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:08:14 -0500 Subject: [PATCH 006/509] Add files via upload --- .../wled06_usermod.ino | 212 ++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino b/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino new file mode 100644 index 000000000..b3f1c5db5 --- /dev/null +++ b/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino @@ -0,0 +1,212 @@ +#include // from https://github.com/olikraus/u8g2/ +#include //Dallastemperature sensor +//The SCL and SDA pins are defined here. +//Lolin32 boards use SCL=5 SDA=4 +#define U8X8_PIN_SCL 5 +#define U8X8_PIN_SDA 4 +// Dallas sensor +OneWire oneWire(12); +DallasTemperature sensor(&oneWire); +long temptimer = millis(); +long lastMeasure = 0; +#define Celsius // Show temperature mesaurement in Celcius otherwise is in Fahrenheit + +// If display does not work or looks corrupted check the +// constructor reference: +// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp +// or check the gallery: +// https://github.com/olikraus/u8g2/wiki/gallery +// --> First choise of cheap I2C OLED 128X32 +<<<<<<< HEAD +U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA +// --> Second choise of cheap I2C OLED 128X64 +//U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA +======= +//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA +// --> Second choise of cheap I2C OLED 128X64 +U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA +>>>>>>> 1680c014057bb993974950f37b14369b398ca647 +// gets called once at boot. Do all initialization that doesn't depend on +// network here +void userSetup() { + sensor.begin(); //Start Dallas temperature sensor + u8x8.begin(); + u8x8.setPowerSave(0); + u8x8.setContrast(10); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255 + u8x8.setFont(u8x8_font_chroma48medium8_r); + u8x8.drawString(0, 0, "Loading..."); +} + +// gets called every time WiFi is (re-)connected. Initialize own network +// interfaces here +void userConnected() {} + +// needRedraw marks if redraw is required to prevent often redrawing. +bool needRedraw = true; + +// Next variables hold the previous known values to determine if redraw is +// required. +String knownSsid = ""; +IPAddress knownIp; +uint8_t knownBrightness = 0; +uint8_t knownMode = 0; +uint8_t knownPalette = 0; + +long lastUpdate = 0; +long lastRedraw = 0; +bool displayTurnedOff = false; +// How often we are redrawing screen +#define USER_LOOP_REFRESH_RATE_MS 5000 + +void userLoop() { + +//----> Dallas temperature sensor MQTT publishing + temptimer = millis(); +// Timer to publishe new temperature every 60 seconds + if (temptimer - lastMeasure > 60000) + { + lastMeasure = temptimer; +//Check if MQTT Connected, otherwise it will crash the 8266 + if (mqtt != nullptr) + { + sensor.requestTemperatures(); +//Gets prefered temperature scale based on selection in definitions section + #ifdef Celsius + float board_temperature = sensor.getTempCByIndex(0); + #else + float board_temperature = sensor.getTempFByIndex(0); + #endif +//Create character string populated with user defined device topic from the UI, and the read temperature. Then publish to MQTT server. + char subuf[38]; + strcpy(subuf, mqttDeviceTopic); + strcat(subuf, "/temperature"); + mqtt->publish(subuf, 0, true, String(board_temperature).c_str()); + } + } + + // Check if we time interval for redrawing passes. + if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) { + return; + } + lastUpdate = millis(); + + // Turn off display after 3 minutes with no change. + if(!displayTurnedOff && millis() - lastRedraw > 3*60*1000) { + u8x8.setPowerSave(1); + displayTurnedOff = true; + } + + // Check if values which are shown on display changed from the last time. + if (((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid) { + needRedraw = true; + } else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) { + needRedraw = true; + } else if (knownBrightness != bri) { + needRedraw = true; + } else if (knownMode != strip.getMode()) { + needRedraw = true; + } else if (knownPalette != strip.getSegment(0).palette) { + needRedraw = true; + } + + if (!needRedraw) { + return; + } + needRedraw = false; + + if (displayTurnedOff) + { + u8x8.setPowerSave(0); + displayTurnedOff = false; + } + lastRedraw = millis(); + + // Update last known values. + #if defined(ESP8266) + knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID(); + #else + knownSsid = WiFi.SSID(); + #endif + knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP(); + knownBrightness = bri; + knownMode = strip.getMode(); + knownPalette = strip.getSegment(0).palette; + u8x8.clear(); + u8x8.setFont(u8x8_font_chroma48medium8_r); + + // First row with Wifi name + u8x8.setCursor(1, 0); + u8x8.print(knownSsid.substring(0, u8x8.getCols() > 1 ? u8x8.getCols() - 2 : 0)); + // Print `~` char to indicate that SSID is longer, than owr dicplay + if (knownSsid.length() > u8x8.getCols()) + u8x8.print("~"); + + // Second row with IP or Psssword + u8x8.setCursor(1, 1); + // Print password in AP mode and if led is OFF. + if (apActive && bri == 0) + u8x8.print(apPass); + else + u8x8.print(knownIp); + + // Third row with mode name + u8x8.setCursor(2, 2); + uint8_t qComma = 0; + bool insideQuotes = false; + uint8_t printedChars = 0; + char singleJsonSymbol; + + // Find the mode name in JSON + for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) { + singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i); + switch (singleJsonSymbol) { + case '"': + insideQuotes = !insideQuotes; + break; + case '[': + case ']': + break; + case ',': + qComma++; + default: + if (!insideQuotes || (qComma != knownMode)) + break; + u8x8.print(singleJsonSymbol); + printedChars++; + } + if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2)) + break; + } + // Fourth row with palette name + u8x8.setCursor(2, 3); + qComma = 0; + insideQuotes = false; + printedChars = 0; + // Looking for palette name in JSON. + for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) { + singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i); + switch (singleJsonSymbol) { + case '"': + insideQuotes = !insideQuotes; + break; + case '[': + case ']': + break; + case ',': + qComma++; + default: + if (!insideQuotes || (qComma != knownPalette)) + break; + u8x8.print(singleJsonSymbol); + printedChars++; + } + if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2)) + break; + } + + u8x8.setFont(u8x8_font_open_iconic_embedded_1x1); + u8x8.drawGlyph(0, 0, 80); // wifi icon + u8x8.drawGlyph(0, 1, 68); // home icon + u8x8.setFont(u8x8_font_open_iconic_weather_2x2); + u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon +} From b7d84c002d7f9838dfee706501cb401b985b03c1 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:08:49 -0500 Subject: [PATCH 007/509] Add files via upload --- .../assets/controller.jpg | Bin 0 -> 153419 bytes .../assets/pcb.png | Bin 0 -> 240670 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 usermods/Enclosure_with_OLED_temp_ESP07/assets/controller.jpg create mode 100644 usermods/Enclosure_with_OLED_temp_ESP07/assets/pcb.png diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/assets/controller.jpg b/usermods/Enclosure_with_OLED_temp_ESP07/assets/controller.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d518ca3e310870f82eda70d8ae65c4313045aacf GIT binary patch literal 153419 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

{5^`$)Z`0Xr}DRJOdm-B+-y*hgTU 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 z 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 literal 0 HcmV?d00001 diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/assets/pcb.png b/usermods/Enclosure_with_OLED_temp_ESP07/assets/pcb.png new file mode 100644 index 0000000000000000000000000000000000000000..cf146918ac4f0071330ca928b4ab27e1dce1f98c GIT binary patch literal 240670 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%0AGS7EI}nJ0_y6 z-6kGCt`z;$z7XJ)r^9ZS=U;n6E`8)h8Je9T6|MXN_mzjf zet-y&=>kk27oUXLf;6=Kaw;~C#s-fY!9_DImh{JQ*JYdvglq{ep!SV7@{Yg&?oRl@ zLNvew0ZKAfIZJYKHu5mKEy@`NsT~X%gP1##kr1n<2bmE<@xZSyQwDX4l}h;CeqU0- z(<;TrCStIhF4fh$;qDRcfG_Dmp@;p1AZ&yk7JMHU`S5qgBsjBqJywS^!(Z8uiy~gi znKH$>Va}Z3#R45uvd;B@5C|;=D?qx(@116Ix*~jy^^G>0-Kk8k2T(25l?EDjr^HlA zNf{u8yMMswCka!14St%OF;)1`Yp>nX2ac2X`+UnbO`A5$i;+|pF!QxguKq;-B07Gf ze5>1CgXyl$l93Tmu$Z^v?)@Vw)aWsl8B(8`+8uR6fKg8s!X>zDFk&G_jUD^Wc|V#p z>z14Re&~w_0Y-oZcUbSRRDeX;7||b<=}x@UEkd`yKt^5P6h zPGCq3u51MjBrF&l{rlkH0UYU*!vz<0@Cp3u6&Fi-3M{NU%Eg+K8E6k3-v)lQB@lnr zz%kguX3d>52V*nkcf=7*>yy`k!7D<-I4_0F&BX8NH8r-C7hafGKVwE-qRr+zAB*Mw z1v%uzYB{(dFsy@5S)ICe?H>dw7^kK|Dxl1`A&=J-6d{J28!P%;Qc;Bsq#=Lk*GFZV zjAqh93s{#fLuAR4H=tle9z=Rr4C4DixeG&^^KxJrz#xd|gLSAPyTh^gdSv*LQmzbN zEXZY@LIr_PQm`yCf4(PW()p1VfBh9|??LbcrUz9crKx{^Q*eL9>8b$(#>>tR7NhOc zVIDh@V^tvHI9aef_i|XYV880Obmq){Fx~ivaLWdmq){B5;_3PYKcVVkIqJwWuwiY4 z@>Aky>OfMc(PPriI7Jbt(|`fT%NJk%8!>3QqJCZ|S3V`wqN2j@#B%Ce5szjmo^b-p z!LVEbk9u790|XnUUEw&4MF7N@Ser@J8SjkN0|u3BEob;PReUU73p~`}^q9nT;CE9i z#ewqhU|D5ug##UO@3|53@R+HXHicC`2(Jz#>DQSx5QcCF+how7)8Rspi1VI+6${i*iN;OoP-+(C7t8;> zG()nxWXi*{KakXJX;QBO*5U@-8m#Q}>^WS~Q(s?!yclBPV9*o525pb~A2KRvBLbiX zmm9d_V0>{2q|ah^3{0Cm?Y#WCGhfO1_FKmW`0yW$%yk|I2Z7L0u*QwEQNglW8-4=^ zzAn&!sQx?D>Ol(21574!lNnRfI?K=@xw7#47u0q+&?~59VYzOt@~?uk_8|IJA;2cj zVMAjJ{IoFXk5yk}?40aL(yR9nrCj}3W(hTV6r2zMT++3qPd=!8Tiroa8A`3l_oZA)(z*4dSfjt zc$zC(7bQibt@0ss#g*8S2a7JO{NoEy2|00!oEuK7m%`F?Y6}4qG4(>4ezbk3i6Z4f zWK^__9(|U4{P9D=#V1w^S9W`$WYN6jv%@Oh69crK6#JExHIy-Y8BnfVkU9Bq&lrqB z+}J$}0u3D2(a&)}N`l<<+Iz54mPzK&Y>7kUc*oPkL}Kx0>NSI1K4T{2~LP8LBZYAC0?>LyX!EFN`>~Jig5(BploTHTSLB{Nml+=NE?mWdq^!IEbXT0D%yh22QkXrD; zh^#aT%g&S%xE^rjZu4f(%`;~vJ!xs(WbD{0uyOOV;4drOMq*fO6Ft~9j1M)@!?LTY zcEYVPGChd?4-PCDWvb&!%pXLk?w>K&XudD_{#=FWVzALw1#v`{NRi2gcc2sBHu zLq-B7=yG$NjD3|ldD;o+!v}iZjb4oQ?OciaV+0*Vra8K0|6&S)p~J>YTwDq^4SgE| zHeWF;qVYn9b2`biZmbmafzLf|2xoh&3?KGe88C1R`$;7rc#mRco;ctHqL4a@9wYYy zBg(7`g&!@2uJXet%WjE4i)tLoJdcPG?zcj$qog55QgbxMWs^E zX^^a3xfhj# zxTAY0tIUS=J0u4Y&o>|rkmQ$Oo0$yR4MRZr&U{QqVsAg>*)1nS!Z8I&-;^KIT1iVs zC(=b$TCr)DNKAwbO-_)-JBt8lgA72OmhLVS*C!u`ll-u5yGTK$+8{b> zP*4Kd9PB0xV;jSawAz=B8@p|QVTyU zuGHOuEppfzOzR}v&CVC+E;37)LdV?Np zIt?14U`3lM0|$;%eMf706j7}|P-q8QvdBVcro_X4NBYSpzm0yhR$h;oejj=T z3yooAp0PR&kx6c+P$Pplu=>hWXbuz|Cq}`1)=cUc`BD&5AxKN_CR?|xlASx(z#Ltm zwoTwxFX66uiA1P@wA3C#XUdq^IM9OUln;@qT$#BZ=y%7^V^X1}pHS!KuExC5{imh5 zMnHjYl%s~$$|p-JLz$X$*A21((fqHu=zi=+_z$(J^whuHEjOHZqMUL31c{4{kq;JpAy+>; zQ(petAlX?^DAzpt3>=s-{e;1R^5;XI(pWFspj`C{^T|aMQY5QO5;R?#?AY}w z_&Y*QoHQIg5<4V|7psY};L8w!<93(Jm)~#qJ-(#Qnq|Sl3p|7Aajj&v(`1xyET;3? zPkZvd!Pj0`q%vj7iC4(BZELYv@=7T$-z9bRrP2uhELT{ZL`Nm4)q+`B{Uj+lO%-9v zr#;G3i;)c3&Z$DSbJf<_kMNH&5xfNfx5uMgIZdlna!Q7raN?Cs^l<^hqvZiq@(Q@x5Q;r3yaxjML`NfV z$Q3NpF%OP<*J98x)QdH|P!?dnQqkASX*fl^S+Fv9a;6+#LxFM?*=dhi@9A;alOi z5QPm}Ve$@Cmb3@LJ1AU?8X0v}xhm|;v+aL}8a?e(+VTqBtJc)`*&3JN1TpWLW=hhq_r0NxM(H4mm*--Z{g=T0N39cUs zYBTYk4pg$jFeUCo9IngJkG=(m_Ycfjp*D%pCx12s4y}TPoxtgsmpb{Zt`@)dAKVs) z$$@C=?9lh8;hIRXvvad!!ie_L6DO)@zGMbv*)eZYngNx2BT+fw%0T|Ll}x5Gu8~Qb z6X_$va*83A*0#VUGC0lC^cPXgjth|GFfS{&f+j`{%Bkt_$IxRsmLEBEkjT5As#P<@ zf`hg;6KN*VNE8ymbyUJjxr`c58cJ0JgiLFEm^q(q-F%D=iFqm$eL$cYxwZ2dYV@>2 zX6w_0unw}ndxX{3Gc(dwhhT;9dphHSbMN?!_x|_4d0!w%?YD?p9pUp?e3)ub4bQ;X z2c;f9Sdlgv(=9?C|DjR_#@eL{ia;EEwZ1Pdm(zN7Rm#T_NXzkY}INgSst~5iu*k>U3cgG@~7XOEk{8K6GYmt!g(8rg)L2850wwn6Ngx7 zQd%nuzWz>5o-{!oeEK#u_?h$OJJP8~hElHHd~dFte$sUy+bQpU_<)iLldrs97JRWn z1`h8b(HIQTKZ{+d4O4>KYP~Wg-HxyToiI4SbRYPT?VX(^`&r=c!S+}7hWf_cHk*6$ zv}t!@URC797yrI7AtBwf9)V!lJwl^$i%=gmH9pAj%bqW{2LW zMmv5PhS4yY@4LlI{-3??fUo)b-+$kco4pg6vJrbzl-jGR3)O1T-RjUim2~ex7uwS5 zptjPQRW)nXUWq*tLK3pqz4!k-=iX1;L_$cY@Bim`$-Vb8&OYz+ocENU=Pr=YKz}8_ zr-)En6nuwVE?YU;(zKnF_>A@(pGiBDC7y`X?ure8PZFN2*s(_fLIdOsPSCp#K~IL> z%BiZvy8wCO?;#DsAZ|q9-0wH+5SKUJ7k8Y(dGe;yLoW|^VU1IrstZEDM)53EN?IzT0GSY6c?;N-7)@`_Q%_c(`KDfHZ3NZ3}|j zENo)vNA_j^8+%AtNU*HizFPq*X5@odfo)s10MinBDR^0X--Nl9ar%seK&*%ftH1}9 z-mkW#tvCtuku_VkOCJEN`|jumQBl6kSiVMTdm*Yg)`r^9I@DIxXJ7DI0M<^;hBo~x zD)>{}s3sXR1sl*8!1e4Q!q)P$bKGi%#hS6GC~w>Cx4)AzYgU5Kt+ytewpel&78RK? zy?s2qM1R5pJvi_guch*Opb+{_JlLJ>Q+prdg9l4YXYurQmruq|5FbxZMf1u&tL4k_ zEKT#c7C4`wNUu$5?P2>TpNFqP*|KM!NXHn-a(QTa}yf1jl@<-5sK6}ZaG%9gjk{!X=v`a1+Q~f;@tM=u^9Iixv;h!mT23u&zUAHKEx#Xq@6+m5ed3U@WnXNESFQG;ZV2 zGN~zuIcfx9C)YDM^^}Z%>m&K?%a0JW)~LWOfmhOjgHjKoz+!ODn3x|^29$iMho$nt zCU_NMD^*YaDZpVP9E$A|)@_l;;e<6JEL3*vNtA^XSIS*a^iXs_t*Pa6@N|SYzh>hC z&pCKZis!Bu-#a^~jg?L3l2%;+#kk}%W+gs#hGMjK&o*({D|#cN72x?+)2AoI16=K9 zU7*0+ANq4%X=zzR2#7v<_6^>@mTWyhy3F~xVepAQ;WtA<2@-qTu;m&!|*Tpukn(lZ}$@aZ76qBgK>aG#}y zkJLrHOB+X3%i!Ek_Tgm#SvYqi5VQq=@CodzD>g0|KTX?b&#lF^D_5ci{u_V=(I8ov zkv(n;!BQPZ(1Q&^2Zu|_vFOEuD|Qs;I8U=N9&WPnWQJV-)CgJg`MYx8o&Ckz^AG7a z;#29=yp9wA%oO9)R4UHEV54Unfl7$ZAQoDx59wv>`C zGSKRv2u2wi!%f!&@Um=EqD-GRUv9s#CxR{K$`fyXAd{A^mzH%SB^{?rC7yGvjQzW! z187?iVl2kO7Za1MJbvR{Cautm|E<-Xn|(HjFx#Z%V#~Yq->a=YrE7QoU!=Q;A1-?f zExH|tax4*{UOIOV=bsT`=p(=#I$|9L?u#By6gkp8)M%;8X=ED@JF# z2>QKe9+PmmfmpWsA1LPKig(Q*a5c*Z+$z)m=nu!9)|U}z>*{6OWG4EJ#e@_~abAKeYoG&57Z;N!V&W}EG>6YHJdq}o;i1ganX+m-EEhcx z`cx0nSkbQiANASQQfy@oz&!BQgAN>N*5ybXnrs|&Ik&lPG^$lmSyibIIr$8KW29Ak zNlBc+EY-#gAkEE1UGf36Dl=^^6Ubs`!)Vg12j%@CsC)kn*k=z&^M{;d<9ORi3=dpO zSFQ)HJiwv}>5d(0JrwEm-y@!qFHm$@kAj` z`eqC8umV>(xo|CjPBVU!Te^3aec8FP=kPK0jE|Qmbeh)63txXPe$l}y zUn{s<0vpXQ8po@mRJJ}P&oQI2 zuW8rppS*2>wX3r;{wrNE-YA`TMbW&nd6j;w)Gzj9Sxy%BCDl*Jup;g=_XXCOXiBLE zl*(0%I8YRVi{%P)Wr#_nr2? z#LTn#&a};9R6%^*q&7k;FmZy@^m_|@^1OOeXL;+nCuQBH&C>dT7o~BX2nDdH*RmY| ztb0hH%pd!SB*SdHCQjhC6e-fH4ZxN`It2%)`^QsLC9L`FBFP8jp;sP}ac_^5r2Pk^ zcE3lYDL7Azmqh|W8nI_T^lsB~phE+Z2#CK*WV3HOC6i~pg*Nn&ELaUb25|M`>MhbX z4sq@Xt}0rQ_F7&0sNNpXh-x7?EeBF_q=~Q9+^D7-{9w^5G<<{W=`_(OM^7A)=N^8B z*JR9hqcJahWm*y(U_uGKuAc`PHl=7hIW4Z3JKIlZVZNk8^x&;5MExNSp=*c}Co&`| zBtQ;g%mv^oHrQWMaX84re1x(gcD5`Dfs(i{4lESIRm9P(-rl&h+}KuU97v7;@MooA zy+S1K3vL|O@vakSJAf+KwqO^UBocaAhYp=k{l-&JI7BiOLu-d6)_~;049nmXupZ0> zH=#F{x}TR$o`quko}@kU%WqSllNq9Pi0~{!LeVPGy7o|kE~(IHh;+dkG&u`Z6%>#t zuUUA9apvGnOC6Z_9P=Tw(gJ-Q9x4IMa9!J(Xn zs5y>(ArBn0EFAjj#hw&|y0-*f_C78I^TK2)D*6`sSP!ZP`uEpg^YUI!hhD}@SCoT= zh~Lh8=YO9c)?+{?m`0Dbz^NQ*lM5E#r6{(S*Dsu0oM@*&uv__h$-4A2((1{VW&P*x z$sITMk@~x8frC(}PP&|mJiWR&yU4cPdt~6apCsNBTqn+8CVYUVsHFHY_RF>_yl)dF z(pu3QoP(cc%vRQmiSR@8;o=pNhrBfwIZxKL+SQShMX{0!r*~A?rGFps^-w2qrE`ON z?>Lh!6P|lOS~YH{L?k3?{LgwqVOknMnVn|qk3nhv$2D7}ZLJ7JSe(E$`M;d1i{M>M zA8JIGx>9le&XQDMHf-Jw&LF(pD};dYbaQi-+(nD!)3?5b;Lswoe?pA3-h(8>!wE(Y zCd9hn%ql&x2#Dx~y&)_Ijeg$B^#B87Q(>1WBr+HljJ)q5dS6do;A@IPBm*N7ZsY`UX##3Y?w9=?(8LQaLsD-fWr+%$wJgM#|@Rr z?G}i0{EBlW3Vr{_ag4|8zK&0E90Hzot0AN)BPB#ATCW&%ESx~Na zJ0B+<^)-Wjn888YpNWGR9KfnwjYH!F*8^}=YF1|b7iR^n8g!NXA-$nk)p1sGeHDXd z(Rz^gE0fqIe3F!D^R@#bdym<#IOdE?RZ1)Y^C3J~g6r2*TqLdBDrH;dW!9MOCb(p( zD#&7fJQ&bbi5FBhOwipr4T;3|qp2c0@jnX(31NSgm%<=o!O5XPki-ReOE3(nNE_(A zo^*lwgIHHiRty&WV?7YsqkmEI!fC@4xVmOpSYC%-wrf`mVA;Uc{DQDvcU%XV_EMWa z6mv1++!-&2*JQG5Ph!Hg^7oc?(8=ol%xg05{gDcwkXUF$g5ZcJPDWrC`AM;|3DC+- zWiKNiR}f=@B~K_854!DU^%})FFHM;zekfbBW+GZkf^sc9Mv4){fR=dNaDk%KCkYw? zMX38NVFg(~zP7S_WZn2Kic)nxc`8j_{%DN+xMZ!gZ4e{JAeuDNw@fK=SZ?kAzrLuf zebA@>1<)d~qz+XLIQDe)rITBQy_I_e4}@P?BOxHnI9)3%*IE*esdglrzySnSjqbTa z!>L9fk#EBi%6gDsg#Q^LhC5dt$|UF@=aa-5eoa+Ie2;*g*I76A2|urf#CEX_tP#N= z>&3Oo`ZHpcqiC5rExgXg@(sG1pl%iEL(#^Evr#vnf|U#rT42A$$$RY&$^^Qa2Qvdv^$C@XSp2|TxE!Qa--LkMR8Zf&bz z>C?EjG{3!vga!pFokT~*1IwoM=HX+>s=XVaCNOWsR*}RN$f-7h$k&njIB;=3BgnN5 zj(m-nuSL)udlVo`u7Rwwqj~v%UlD+%fvfO7{lhH9mfxVsF5q4j;^YsjLFZBnxjLIn zpmYMDrbU2{Y=F3>)3c+bDMWS!n52qOaKvvTI_c$kL0ZZV-wlY!aUz z&?CF@l`l8Ffvb9-Y|CsVx!G7X1T1tMd!;}Y!4(y*k7S#rOOUQOKFrN(gbfb{9#zl-KkDUl)(o4KJe&` zh&`y2-xCp7+YFJCzCbM4AhaG}J2If#YG+V?XbNb*m(&*-Yfq0p^?z2~ecEWWCTC?A-s|hHK<2zMeClwXQHrl}z*AF*wXY@IOw4Mb(CGTpr(Jt^elh!KRZ~ou^ctt=-+VEje4@%mhXUQFI+x* ze2{c)*9I29!Acc`T&bn2{*leFrd_^!pKLscHL(iw9ZCde`<5-hd}gHk0N0H$cDcD%cRBI$Nm;pWy*%>mud;dOA0i#E*R>AxH6~}}!p)oM(VD&b%aQqZ zap5(^cl77wO_vp5m4K_x}4$HxoYE}ZggV8$wS=!6t?E-$gXeB{N`(B(*M z4LJxT4F7^tCV6N#Hbb8FeQO3vjK8naZ=+a}8xO(2rX$c9@N|`iI5}nk7?5ja0&(8B z4`3D{Vd?_hvd-kZFkfE~-t7?E3ffGt$kQh8T^gyg^#XnKP;^7FYaYNZLZ4iIkcGBz z<2?dy$dfJI&Fx!78GWGl$9CY*2wlG-3%U~B8GAMsVYlWGzZ6TW`ln^)@)TK`RxEJ_ zfFN>m(MROy>;V^{Z2%PEUwQ(Yh=;6Lw^1G&`L&FF>oMuv?mAh!X^Y%5dZI+bTK2$- zM42{j1m?6=27LL0+F25Mb(CAWby9w`$X#8uVwF6GIDXA)1}kT?wjR53e>rE#k=la5 z)Ds^cEY~5H;9-RS88Z4?8CW}7o`3gM1&p8n{2NIEr#X2;k_;c*Tl)9xA|L~^hggIy z(O2B4&W%O5a>HTESDW(@i?C2Rk)<*x?v5j_zR-ENPn5|$+OaLLGZ{8w)MXq>E__J^*)&E1UPq7|hXoE{AW$T~)l1*^j5aN)4=nhS?Zn*fz~ z>+%?EK;S*kVsr1FOoyxTn&zQHg|=%sL-rGdGb{Dn{d-m1d#a>j1nRXlpg|f=~#s5 z^1w!P{DK1f;dH7%aSSg* zS5zuX0{}V2Z2E)lu)#h{W)RO^Ag+Vei`%X1M(=^s@566<*dIq zi4iAuice@z&@et;-h1u|S@+lrasr^k4+k9{j!I$?!m?^`H^*3nhrglvmNKM6s;ALCT! zLel6P0j6dtx%1EM%!H>t+vd;SMpJLmv|)>7DbX{kJr#lGPG8lZV=LF;7Qei{48Q*u++PD-S? zboE+!Z`xeh@#`v)7Ew|c_*l#6dY^U zumEw73I^?Ltn@WUPhKda-+T>orH6d`E|I|lpVLW;+Qz04K}DyE z^^b=1?59szF#QpNt830kFKz5A^VVenSma#6!C4t_RS0ke;EsjClZ-}uDpSe-@)>RE zMPak!e=YgrBt81Gnc~!K`yrt(N`-SK;2D zW=b7|R-oc87tMd&CnS3Q7@vQV4$BBATE71D<4Rnh)p^Z|KnXm$SSnQ(jqFSZFOb79q!(u?vHOyyfO-XPJJWSmIq^eFhVM zMh1w4=wrqAYh?M54bmSz+=jk8R%XBZylO`DT@T5|FF%kzT|0{WJPYneLRDKSrVPMl zag=qkr)|4-%i1kFnBHUx2UCBh?tStZFR^el8EVn|Gv3%`%aGQ!% z2p}F@GGMGR{Qkl6VBZeP=N0RxJce^@;ksc7M2jC!{8_rRZYJ$oGy^BgM?7JDm4q?& zhsG6m9-0KIScGAh9*eLQViC?sI$@d72_^slKmbWZK~y!kyTDg$X)psFc!7SrfnqeP z)et{)=uns5y+6-KcqCh=8_Z3dObApA@*ay*lcgbCacaK#ZQOCSAAY{`o!yS$dj80~(NCg)e%q1`u z3(={LRdsy-eBZUa`K|$nYZuTU4*;OG>-R{fw)N$!Rd1+6#Owu2WXRV)!re}?IJJqB z_Cq@>ns*v&_b8Oz*#;hP**5;?7<({88#tc~gw5H=IY=&+)_-{bn4yr$oPzkVb<;TP zN41qv*8_Jy3n@!2`Re)mrQc1xZW}?!`S$i_Qkm_ZV&r)zrC)PQGW;a z>f=IjAw$#^F+_m)VJd1J@c=XqHh-`YYr#NmjE5H5#eyzV>|Kk zw7cw|4RG-mD(g<9mE5PbAp!u)sx8~(tHo<13OX}fNMt2n%EGSfAYaUL)QbXgP#ige zm5kG;;YoY11p50)?bsN3Y1o6Z7vi0tckNgDGNEuKK;>=5zWe_EJ7nnNA4;Fw+5#B# zRK8;u?TG&FNh@i z!`~aC^1>|418fi^oFt;8py7;t2|XB$fexZs&K+*nCyuAfv6SO#EO1dmo7^JX{`y`K zaHY=#{j8(#$wqL}v(pW7W7p17Cptpz21siaA1N6CS^q`Ca4GR+D1CXM-L3$`6gxAq zKi2NtqrS&S)By>OxGaxFPCo z{J{?73vce4^{y({UWVct&x<29e?2d(`|g zDr(qpgh$H${`;5PnGD8v@}X0B{A8{Uii+640g#}^M8)R9&Bx@UcV3aGn&I%WzZQzw zE;h~%+Gm@|_6f|gI8njzqiYw^9EyqWy7ea6wf~@eykxaBf{rJ-992#Ed9ZfG8ey^> ze5>Z@xm117gpzd5cN=ij#-`-Ci}^z2$pj#y^ex$o$j}WUSa0Yo(t?zalr95m1GvDk z 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

-
-
- - - - - - -
-
-

Brightness

-
- -
- -
-
-
-
- -
+
+
+ + + + + + +
+
+

Brightness

+
+ +
+ +
+
+
+
+ +
-
-
-
-

White channel

-
- -
-
-
-
-
-
-
-
-
-

-
-
-
-
-
R
-
-
- - - -
-

Color palette

-
- - -
-
+
+
+
+

White channel

+
+ +
+
+
+
+
+
+
+
+
+

+
+
+
+
+
R
+
+
+ + + +
+

Color palette

+
+ + +
+
-
-

Effect speed

-
- -
- -
-
-
-

Effect intensity

-
- -
- -
-
-
-

Effect mode

-
- -
-
-Loading... -
-
-
+
+

Effect speed

+
+ +
+ +
+
+
+

Effect intensity

+
+ +
+ +
+
+
+

Effect mode

+
+ +
+
+ Loading... +
+
+
+ +
+
+ Loading... +
+
+ +
+
-
-
-Loading... -
-
- -
-
- -
-

Load from slot

- - - -
- - - -
- - - -
- - - -
-
-Slot 16 can save all segments.

-
-First preset:
-Last preset:
-Time per preset: s
-Transition: s -
+
+

Load from slot

+ + + +
+ + + +
+ + + +
+ + + +
+
+ Slot 16 can save all segments.

+
+ First preset:
+ Last preset:
+ Time per preset: s
+ Transition: s +
- - - - + + + +
@@ -817,16 +817,16 @@ Transition: /*! -* iro.js v4.4.0 -* 2016-2019 James Daniel -* Licensed under MPL 2.0 -* github.com/jaames/iro.js -*/ + * iro.js v4.4.0 + * 2016-2019 James Daniel + * Licensed under MPL 2.0 + * github.com/jaames/iro.js + */ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.iro=e()}(this,function(){"use strict";var c=function(){},i={},h=[],u=[];function p(t,e){var o,n,r,i,s=arguments,a=u;for(i=arguments.length;2t){var n=function(e){var t="".concat(e).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return t?Math.max(0,(t[1]?t[1].length:0)-(t[2]?+t[2]:0)):0}(t);return parseFloat(e.toFixed(n))}return Math.round(e/t)*t}return function(){function n(e,r){(function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")})(this,n),l.element(e)?this.element=e:l.string(e)&&(this.element=document.querySelector(e)),l.element(this.element)&&l.empty(this.element.rangeTouch)&&(this.config=Object.assign({},t,r),this.init())}return r=n,i=[{key:"setup",value:function(e){var r=1(t=100/c.width*(u.clientX-c.left))?t=0:100t?t-=(100-2*t)*f:50 3000) { -requestJson({}, true); -} + if (!document.hidden && new Date () - lastUpdate > 3000) { + requestJson({}, true); + } } function onLoad() { -size(); - -var cd = d.getElementById('csl').children; -for (i = 0; i < cd.length; i++) { -cd[i].style.backgroundColor = "rgb(0, 0, 0)"; -} -selectSlot(0); -updateTablinks(0); -resetUtil(); -cpick.on("input:end", function() { -setColor(true); -}); -setTimeout(requestJson, 25); -d.addEventListener("visibilitychange", handleVisibilityChange, false); - -d.getElementById("cv").style.opacity=0; + size(); + + var cd = d.getElementById('csl').children; + for (i = 0; i < cd.length; i++) { + cd[i].style.backgroundColor = "rgb(0, 0, 0)"; + } + selectSlot(0); + updateTablinks(0); + resetUtil(); + cpick.on("input:end", function() { + setColor(true); + }); + setTimeout(requestJson, 25); + d.addEventListener("visibilitychange", handleVisibilityChange, false); + + d.getElementById("cv").style.opacity=0; } function updateTablinks(tabI) { -tablinks = d.getElementsByClassName("tablinks"); -for (i = 0; i < tablinks.length; i++) { -tablinks[i].className = tablinks[i].className.replace(" active", ""); -} -if (pcMode) return; -tablinks[tabI].className += " active"; + tablinks = d.getElementsByClassName("tablinks"); + for (i = 0; i < tablinks.length; i++) { + tablinks[i].className = tablinks[i].className.replace(" active", ""); + } + if (pcMode) return; + tablinks[tabI].className += " active"; } function openTab(tabI) { -if (pcMode) return; -var i, tabcontent, tablinks; -iSlide = tabI; -_C.classList.toggle('smooth', false); -_C.style.setProperty('--i', iSlide); -updateTablinks(tabI); + if (pcMode) return; + var i, tabcontent, tablinks; + iSlide = tabI; + _C.classList.toggle('smooth', false); + _C.style.setProperty('--i', iSlide); + updateTablinks(tabI); } var timeout; function showToast(text, error = false) { -var x = d.getElementById("toast"); -x.innerHTML = text; -x.className = error ? "error":"show"; -clearTimeout(timeout); -x.style.animation = 'none'; -x.offsetHeight; -x.style.animation = null; -timeout = setTimeout(function(){ x.className = x.className.replace("show", ""); }, 2900); + var x = d.getElementById("toast"); + x.innerHTML = text; + x.className = error ? "error":"show"; + clearTimeout(timeout); + x.style.animation = 'none'; + x.offsetHeight; + x.style.animation = null; + timeout = setTimeout(function(){ x.className = x.className.replace("show", ""); }, 2900); } function showErrorToast() { -showToast('Connection to light failed. Please refresh the page. If the issue persists, reboot your ESP.', true); + showToast('Connection to light failed. Please refresh the page. If the issue persists, reboot your ESP.', true); } function clearErrorToast() { -d.getElementById("toast").className = d.getElementById("toast").className.replace("error", ""); + d.getElementById("toast").className = d.getElementById("toast").className.replace("error", ""); } function populateSegments(s) { -var cn = ""; -segCount = 0, lowestUnused = 0; + var cn = ""; + segCount = 0, lowestUnused = 0; + + for (y in s.seg) + { + segCount++; + + var inst=s.seg[y]; + var i = parseInt(inst.id); + if (i == lowestUnused) lowestUnused = i+1; + + cn += `
+ + +
+ + + + + + + + + +
Start LEDStop LED
+ + + + + + + + + +
GroupingSpacing
+
${inst.stop - inst.start} LED${inst.stop - inst.start > 1 ? "s":""} (${Math.ceil((inst.stop - inst.start)/(inst.grp + inst.spc))} virtual)
+ + + +
+

`; + } -for (y in s.seg) -{ -segCount++; - -var inst=s.seg[y]; -var i = parseInt(inst.id); -if (i == lowestUnused) lowestUnused = i+1; - -cn += `
- - -
- - - - - - - - - -
Start LEDStop LED
- - - - - - - - - -
GroupingSpacing
-
${inst.stop - inst.start} LED${inst.stop - inst.start > 1 ? "s":""} (${Math.ceil((inst.stop - inst.start)/(inst.grp + inst.spc))} virtual)
- - - -
-

`; -} - -d.getElementById('segcont').innerHTML = cn; -if (lowestUnused >= maxSeg) { -d.getElementById('segutil').innerHTML = 'Maximum number of segments reached.'; -noNewSegs = true; -} else if (noNewSegs) { -resetUtil(); -noNewSegs = false; -} + d.getElementById('segcont').innerHTML = cn; + if (lowestUnused >= maxSeg) { + d.getElementById('segutil').innerHTML = 'Maximum number of segments reached.'; + noNewSegs = true; + } else if (noNewSegs) { + resetUtil(); + noNewSegs = false; + } } function updateTrail(e) { -var progress = e.value *100 /255; -progress = parseInt(progress); -var val = `linear-gradient(90deg, white ${progress}%, #444 ${progress}%)`; -e.parentNode.getElementsByClassName('sliderdisplay')[0].style.background = val; + var progress = e.value *100 /255; + progress = parseInt(progress); + var val = `linear-gradient(90deg, white ${progress}%, #444 ${progress}%)`; + e.parentNode.getElementsByClassName('sliderdisplay')[0].style.background = val; } function updateLen(s) { -var start = parseInt(d.getElementById(`seg${s}s`).value); -var stop = parseInt(d.getElementById(`seg${s}e`).value); -var len = stop - start; -var out = "(delete)" -if (len > 1) { -out = `${len} LEDs`; -} else if (len == 1) { -out = "1 LED" -} - -if (d.getElementById(`seg${s}grp`) != null) -{ -var grp = parseInt(d.getElementById(`seg${s}grp`).value); -var spc = parseInt(d.getElementById(`seg${s}spc`).value); -if (grp == 0) grp = 1; -var virt = Math.ceil(len/(grp + spc)); -if (!isNaN(virt) && (grp > 1 || spc > 0)) out += ` (${virt} virtual)`; -} - -d.getElementById(`seg${s}len`).innerHTML = out; + var start = parseInt(d.getElementById(`seg${s}s`).value); + var stop = parseInt(d.getElementById(`seg${s}e`).value); + var len = stop - start; + var out = "(delete)" + if (len > 1) { + out = `${len} LEDs`; + } else if (len == 1) { + out = "1 LED" + } + + if (d.getElementById(`seg${s}grp`) != null) + { + var grp = parseInt(d.getElementById(`seg${s}grp`).value); + var spc = parseInt(d.getElementById(`seg${s}spc`).value); + if (grp == 0) grp = 1; + var virt = Math.ceil(len/(grp + spc)); + if (!isNaN(virt) && (grp > 1 || spc > 0)) out += ` (${virt} virtual)`; + } + + d.getElementById(`seg${s}len`).innerHTML = out; } function updateUI() { -d.getElementById('buttonPower').className = (isOn) ? "active":""; -d.getElementById('buttonNl').className = (nlA) ? "active":""; -d.getElementById('buttonSync').className = (syncSend) ? "active":""; + d.getElementById('buttonPower').className = (isOn) ? "active":""; + d.getElementById('buttonNl').className = (nlA) ? "active":""; + d.getElementById('buttonSync').className = (syncSend) ? "active":""; -d.getElementById('fxb' + selectedFx).style.backgroundColor = "#666"; -updateTrail(d.getElementById('sliderBri')); -updateTrail(d.getElementById('sliderSpeed')); -updateTrail(d.getElementById('sliderIntensity')); -updateTrail(d.getElementById('sliderW')); -if (isRgbw) d.getElementById('wwrap').style.display = "block"; + d.getElementById('fxb' + selectedFx).style.backgroundColor = "#666"; + updateTrail(d.getElementById('sliderBri')); + updateTrail(d.getElementById('sliderSpeed')); + updateTrail(d.getElementById('sliderIntensity')); + updateTrail(d.getElementById('sliderW')); + if (isRgbw) d.getElementById('wwrap').style.display = "block"; + + var btns = document.getElementsByClassName("psts"); + for (i = 0; i < btns.length; i++) { + btns[i].className = btns[i].className.replace(" active", ""); + if ((savedPresets >> i) & 0x01) btns[i].className += " stored"; + } + if (currentPreset > 0 && currentPreset <= btns.length) btns[currentPreset -1].className += " active"; -var btns = document.getElementsByClassName("psts"); -for (i = 0; i < btns.length; i++) { -btns[i].className = btns[i].className.replace(" active", ""); -if ((savedPresets >> i) & 0x01) btns[i].className += " stored"; -} -if (currentPreset > 0 && currentPreset <= btns.length) btns[currentPreset -1].className += " active"; - -spal = d.getElementById("selectPalette"); -spal.style.backgroundColor = (spal.selectedIndex > 0) ? "#666":"#333"; + spal = d.getElementById("selectPalette"); + spal.style.backgroundColor = (spal.selectedIndex > 0) ? "#666":"#333"; } function compare(a, b) { -if (a.name < b.name){ -return -1; -} -return 1; + if (a.name < b.name){ + return -1; + } + return 1; } var jsonTimeout; function requestJson(command, verbose = true) { -lastUpdate = new Date(); -if (!jsonTimeout) jsonTimeout = setTimeout(showErrorToast, 3000); -var req = null; -e1 = d.getElementById('fxlist'); -e2 = d.getElementById('selectPalette'); + lastUpdate = new Date(); + if (!jsonTimeout) jsonTimeout = setTimeout(showErrorToast, 3000); + var req = null; + e1 = d.getElementById('fxlist'); + e2 = d.getElementById('selectPalette'); -url = command ? '/json/state':'/json'; + url = command ? '/json/state':'/json'; + + type = command ? 'post':'get'; + if (command) + { + command.v = verbose; + req = JSON.stringify(command); + } + fetch + (url, { + method: type, + headers: { + "Content-type": "application/json; charset=UTF-8" + }, + body: req + }) + .then(res => { + if (!res.ok) { + showErrorToast(); + } + return res.json(); + }) + .then(json => { + clearTimeout(jsonTimeout); + jsonTimeout = null; + clearErrorToast(); + if (!json) showToast('Empty response', true); + if (json.success) return; + var s = json; + if (!command) { + var x='',y=''; + json.effects.shift(); //remove solid + for (i in json.effects) json.effects[i] = {"id": parseInt(i)+1, "name":json.effects[i]}; + json.effects.sort(compare); + for (i in json.effects) { + x += '
'; + } -type = command ? 'post':'get'; -if (command) -{ -command.v = verbose; -req = JSON.stringify(command); -} -fetch -(url, { -method: type, -headers: { -"Content-type": "application/json; charset=UTF-8" -}, -body: req -}) -.then(res => { -if (!res.ok) { -showErrorToast(); -} -return res.json(); -}) -.then(json => { -clearTimeout(jsonTimeout); -jsonTimeout = null; -clearErrorToast(); -if (!json) showToast('Empty response', true); -if (json.success) return; -var s = json; -if (!command) { -var x='',y=''; -json.effects.shift(); //remove solid -for (i in json.effects) json.effects[i] = {"id": parseInt(i)+1, "name":json.effects[i]}; -json.effects.sort(compare); -for (i in json.effects) { -x += '
'; -} + json.palettes.shift(); //remove default + for (i in json.palettes) json.palettes[i] = {"id": parseInt(i)+1, "name":json.palettes[i]}; + json.palettes.sort(compare); + for (i in json.palettes) { + y += ''; + } + e1.innerHTML=x; e2.innerHTML=y; + var info = json.info; + var name = info.name; + d.getElementById('namelabel').innerHTML = name; + if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)"; + if (info.live) name = "(Live) " + name; + d.title = name; + isRgbw = info.leds.wv; + ledCount = info.leds.count; + syncTglRecv = info.str; + maxSeg = info.leds.maxseg; + s = json.state; + } + isOn = s.on; + d.getElementById('sliderBri').value= s.bri; + nlA = s.nl.on; + nlDur = s.nl.dur; + syncSend = s.udpn.send; + savedPresets = s.pss; + currentPreset = s.ps; + d.getElementById('cyToggle').checked = (s.pl < 0) ? false : true; + d.getElementById('cycs').value = s.ccnf.min; + d.getElementById('cyce').value = s.ccnf.max; + d.getElementById('cyct').value = s.ccnf.time /10; + d.getElementById('cyctt').value = s.transition /10; + + var selc=0; var ind=0; + populateSegments(s); + for (i in s.seg) + { + if(s.seg[i].sel) {selc = ind; break;} ind++; + } + var i=s.seg[selc]; + if (!i) { + showToast('No Segments!', true); + updateUI(); + return; + } + var cd = d.getElementById('csl').children; + for (e = 2; e >= 0; e--) + { + cd[e].style.backgroundColor = "rgb(" + i.col[e][0] + "," + i.col[e][1] + "," + i.col[e][2] + ")"; + if (isRgbw) whites[e] = i.col[e][3]; + selectSlot(csel); + } + d.getElementById('sliderSpeed').value = whites[csel]; -json.palettes.shift(); //remove default -for (i in json.palettes) json.palettes[i] = {"id": parseInt(i)+1, "name":json.palettes[i]}; -json.palettes.sort(compare); -for (i in json.palettes) { -y += ''; -} -e1.innerHTML=x; e2.innerHTML=y; -var info = json.info; -var name = info.name; -d.getElementById('namelabel').innerHTML = name; -if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)"; -if (info.live) name = "(Live) " + name; -d.title = name; -isRgbw = info.leds.wv; -ledCount = info.leds.count; -syncTglRecv = info.str; -maxSeg = info.leds.maxseg; -s = json.state; -} -isOn = s.on; -d.getElementById('sliderBri').value= s.bri; -nlA = s.nl.on; -nlDur = s.nl.dur; -syncSend = s.udpn.send; -savedPresets = s.pss; -currentPreset = s.ps; -d.getElementById('cyToggle').checked = (s.pl < 0) ? false : true; -d.getElementById('cycs').value = s.ccnf.min; -d.getElementById('cyce').value = s.ccnf.max; -d.getElementById('cyct').value = s.ccnf.time /10; -d.getElementById('cyctt').value = s.transition /10; + d.getElementById('sliderSpeed').value = i.sx; + d.getElementById('sliderIntensity').value = i.ix; -var selc=0; var ind=0; -populateSegments(s); -for (i in s.seg) -{ -if(s.seg[i].sel) {selc = ind; break;} ind++; -} -var i=s.seg[selc]; -if (!i) { -showToast('No Segments!', true); -updateUI(); -return; -} -var cd = d.getElementById('csl').children; -for (e = 2; e >= 0; e--) -{ -cd[e].style.backgroundColor = "rgb(" + i.col[e][0] + "," + i.col[e][1] + "," + i.col[e][2] + ")"; -if (isRgbw) whites[e] = i.col[e][3]; -selectSlot(csel); -} -d.getElementById('sliderSpeed').value = whites[csel]; + d.getElementById('fxb' + selectedFx).style.backgroundColor = "#333"; + selectedFx = i.fx; + e2.value = i.pal; + if (!command) d.getElementById('Effects').scrollTop = d.getElementById('fxb' + selectedFx).offsetTop - d.getElementById('Effects').clientHeight/1.8; -d.getElementById('sliderSpeed').value = i.sx; -d.getElementById('sliderIntensity').value = i.ix; - -d.getElementById('fxb' + selectedFx).style.backgroundColor = "#333"; -selectedFx = i.fx; -e2.value = i.pal; -if (!command) d.getElementById('Effects').scrollTop = d.getElementById('fxb' + selectedFx).offsetTop - d.getElementById('Effects').clientHeight/1.8; - -if (s.error) showToast('WLED error ' + s.error, true); -updateUI(); -}) -.catch(function (error) { -showToast(error, true); -}) + if (s.error) showToast('WLED error ' + s.error, true); + updateUI(); + }) + .catch(function (error) { + showToast(error, true); + }) } function togglePower() { -isOn = !isOn; -var obj = {"on": isOn}; -obj.transition = parseInt(d.getElementById('cyctt').value*10); -requestJson(obj); + isOn = !isOn; + var obj = {"on": isOn}; + obj.transition = parseInt(d.getElementById('cyctt').value*10); + requestJson(obj); } function toggleNl() { -nlA = !nlA; -if (nlA) -{ -showToast('Nightlight active. Your light will turn off after ' + nlDur + ' minutes.'); -} else { -showToast('Nightlight deactivated.'); -} -var obj = {"nl": {"on": nlA}}; -requestJson(obj); + nlA = !nlA; + if (nlA) + { + showToast('Nightlight active. Your light will turn off after ' + nlDur + ' minutes.'); + } else { + showToast('Nightlight deactivated.'); + } + var obj = {"nl": {"on": nlA}}; + requestJson(obj); } function toggleSync() { -syncSend = !syncSend; -if (syncSend) -{ -showToast('Other lights in the network will now sync to this one.'); -} else { -showToast('This light and other lights in the network will no longer sync.'); -} -var obj = {"udpn": {"send": syncSend}}; -if (syncTglRecv) obj.udpn.recv = syncSend; -requestJson(obj); + syncSend = !syncSend; + if (syncSend) + { + showToast('Other lights in the network will now sync to this one.'); + } else { + showToast('This light and other lights in the network will no longer sync.'); + } + var obj = {"udpn": {"send": syncSend}}; + if (syncTglRecv) obj.udpn.recv = syncSend; + requestJson(obj); } function toggleLiveview() { -isLv = !isLv; -d.getElementById('liveview').style.display = (isLv) ? "block":"none"; -d.getElementById('liveview').src = (isLv) ? "/liveview":"about:blank"; -d.getElementById('buttonSr').className = (isLv) ? "active":""; + isLv = !isLv; + d.getElementById('liveview').style.display = (isLv) ? "block":"none"; + d.getElementById('liveview').src = (isLv) ? "/liveview":"about:blank"; + d.getElementById('buttonSr').className = (isLv) ? "active":""; } function makeSeg() { -var ns = 0; -if (lowestUnused > 0) { -var pend = d.getElementById(`seg${lowestUnused -1}e`).value; -if (pend < ledCount) ns = pend; -} -var cn = `
- -
- - - - - - - - - -
Start LEDStop LED
-
${ledCount - ns} LEDs
- -
-
`; -d.getElementById('segutil').innerHTML = cn; + var ns = 0; + if (lowestUnused > 0) { + var pend = d.getElementById(`seg${lowestUnused -1}e`).value; + if (pend < ledCount) ns = pend; + } + var cn = `
+ +
+ + + + + + + + + +
Start LEDStop LED
+
${ledCount - ns} LEDs
+ +
+
`; + d.getElementById('segutil').innerHTML = cn; } function resetUtil() { -var cn = `
`; -d.getElementById('segutil').innerHTML = cn; + var cn = `
`; + d.getElementById('segutil').innerHTML = cn; } function selSeg(s){ -var sel = d.getElementById(`seg${s}sel`).checked; -var obj = {"seg": {"id": s, "sel": sel}}; -requestJson(obj); + var sel = d.getElementById(`seg${s}sel`).checked; + var obj = {"seg": {"id": s, "sel": sel}}; + requestJson(obj); } function setSeg(s){ -var start = parseInt(d.getElementById(`seg${s}s`).value); -var stop = parseInt(d.getElementById(`seg${s}e`).value); -if (stop <= start) {delSeg(s); return;}; -var obj = {"seg": {"id": s, "start": start, "stop": stop}}; -if (d.getElementById(`seg${s}grp`)) -{ -var grp = parseInt(d.getElementById(`seg${s}grp`).value); -var spc = parseInt(d.getElementById(`seg${s}spc`).value); -obj.seg.grp = grp; -obj.seg.spc = spc; -} -requestJson(obj); + var start = parseInt(d.getElementById(`seg${s}s`).value); + var stop = parseInt(d.getElementById(`seg${s}e`).value); + if (stop <= start) {delSeg(s); return;}; + var obj = {"seg": {"id": s, "start": start, "stop": stop}}; + if (d.getElementById(`seg${s}grp`)) + { + var grp = parseInt(d.getElementById(`seg${s}grp`).value); + var spc = parseInt(d.getElementById(`seg${s}spc`).value); + obj.seg.grp = grp; + obj.seg.spc = spc; + } + requestJson(obj); } function delSeg(s){ -if (segCount < 2) { -showToast("You need to have multiple segments in order to delete one."); -return; -} -expanded[s] = false; -segCount--; -var obj = {"seg": {"id": s, "stop": 0}}; -requestJson(obj); + if (segCount < 2) { + showToast("You need to have multiple segments in order to delete one."); + return; + } + expanded[s] = false; + segCount--; + var obj = {"seg": {"id": s, "stop": 0}}; + requestJson(obj); } function setRev(s){ -var rev = d.getElementById(`seg${s}rev`).checked; -var obj = {"seg": {"id": s, "rev": rev}}; -requestJson(obj); + var rev = d.getElementById(`seg${s}rev`).checked; + var obj = {"seg": {"id": s, "rev": rev}}; + requestJson(obj); } function setX(ind) { -var obj = {"seg": {"fx": parseInt(ind)}}; -requestJson(obj); + var obj = {"seg": {"fx": parseInt(ind)}}; + requestJson(obj); } function setPalette() { -var obj = {"seg": {"pal": parseInt(d.getElementById('selectPalette').value)}}; -requestJson(obj); + var obj = {"seg": {"pal": parseInt(d.getElementById('selectPalette').value)}}; + requestJson(obj); } function setBri() { -var obj = {"bri": parseInt(d.getElementById('sliderBri').value)}; -obj.transition = parseInt(d.getElementById('cyctt').value*10); -requestJson(obj); + var obj = {"bri": parseInt(d.getElementById('sliderBri').value)}; + obj.transition = parseInt(d.getElementById('cyctt').value*10); + requestJson(obj); } function setSpeed() { -var obj = {"seg": {"sx": parseInt(d.getElementById('sliderSpeed').value)}}; -requestJson(obj); + var obj = {"seg": {"sx": parseInt(d.getElementById('sliderSpeed').value)}}; + requestJson(obj); } function setIntensity() { -var obj = {"seg": {"ix": parseInt(d.getElementById('sliderIntensity').value)}}; -requestJson(obj); + var obj = {"seg": {"ix": parseInt(d.getElementById('sliderIntensity').value)}}; + requestJson(obj); } function toggleCY() { -var obj = {"pl" : -1}; -if (d.getElementById('cyToggle').checked) -{ -obj = {"pl": 0, "ccnf": {"min": parseInt(d.getElementById('cycs').value), "max": parseInt(d.getElementById('cyce').value), "time": parseInt(d.getElementById('cyct').value*10)}}; -obj.transition = parseInt(d.getElementById('cyctt').value*10); -} - -requestJson(obj); + var obj = {"pl" : -1}; + if (d.getElementById('cyToggle').checked) + { + obj = {"pl": 0, "ccnf": {"min": parseInt(d.getElementById('cycs').value), "max": parseInt(d.getElementById('cyce').value), "time": parseInt(d.getElementById('cyct').value*10)}}; + obj.transition = parseInt(d.getElementById('cyctt').value*10); + } + + requestJson(obj); } function togglePS() { -ps = !ps; - -var btns = document.getElementsByClassName("psts"); -for (i = 0; i < btns.length; i++) { -if (ps) { -btns[i].className += " saving"; -} else { -btns[i].className = btns[i].className.replace(" saving", ""); -} -} - -d.getElementById("psLabel").innerHTML = (ps) ? "Save to slot":"Load from slot"; + ps = !ps; + + var btns = document.getElementsByClassName("psts"); + for (i = 0; i < btns.length; i++) { + if (ps) { + btns[i].className += " saving"; + } else { + btns[i].className = btns[i].className.replace(" saving", ""); + } + } + + d.getElementById("psLabel").innerHTML = (ps) ? "Save to slot":"Load from slot"; } function setPreset(i) { -var obj = {"ps": i} -if ((savedPresets >> (i-1)) & 0x01) { -showToast("Loading config from slot " + i +"."); -} else { -showToast("Slot " + i +" is empty! Use saving mode to save the current config to it."); -} -if (ps) { -obj = {"psave": i}; -showToast("Saving config to slot " + i +"."); -} -requestJson(obj); + var obj = {"ps": i} + if ((savedPresets >> (i-1)) & 0x01) { + showToast("Loading config from slot " + i +"."); + } else { + showToast("Slot " + i +" is empty! Use saving mode to save the current config to it."); + } + if (ps) { + obj = {"psave": i}; + showToast("Saving config to slot " + i +"."); + } + requestJson(obj); } function selectSlot(b) { -csel = b; -var cd = d.getElementById('csl').children; -for (i = 0; i < cd.length; i++) { -cd[i].style.border="2px solid white"; -cd[i].style.margin="5px"; -cd[i].style.width="42px"; -} -cd[csel].style.border="5px solid white"; -cd[csel].style.margin="2px"; -cd[csel].style.width="50px"; -if (cpick.color.rgbString !== cd[csel].style.backgroundColor) { -cpick.color.set(cd[csel].style.backgroundColor); -} -d.getElementById('sliderW').value = whites[csel]; -updateTrail(d.getElementById('sliderW')); + csel = b; + var cd = d.getElementById('csl').children; + for (i = 0; i < cd.length; i++) { + cd[i].style.border="2px solid white"; + cd[i].style.margin="5px"; + cd[i].style.width="42px"; + } + cd[csel].style.border="5px solid white"; + cd[csel].style.margin="2px"; + cd[csel].style.width="50px"; + if (cpick.color.rgbString !== cd[csel].style.backgroundColor) { + cpick.color.set(cd[csel].style.backgroundColor); + } + d.getElementById('sliderW').value = whites[csel]; + updateTrail(d.getElementById('sliderW')); } var lasth = 0; function pC(col) { -if (col == "rnd") -{ -col = {h: 0, s: 0, v: 100}; -col.s = Math.floor((Math.random() * 50) + 50); -do { -col.h = Math.floor(Math.random() * 360); -} while (Math.abs(col.h - lasth) < 50); -lasth = col.h; -} -cpick.color.set(col); -setColor(false); + if (col == "rnd") + { + col = {h: 0, s: 0, v: 100}; + col.s = Math.floor((Math.random() * 50) + 50); + do { + col.h = Math.floor(Math.random() * 360); + } while (Math.abs(col.h - lasth) < 50); + lasth = col.h; + } + cpick.color.set(col); + setColor(false); } function setColor(fromPicker) { -var cd = d.getElementById('csl').children; -if (fromPicker && cd[csel].style.backgroundColor == 'rgb(0, 0, 0)') cpick.color.setChannel('hsv', 'v', 100); -cd[csel].style.backgroundColor = cpick.color.rgbString; -whites[csel] = d.getElementById('sliderW').value; -var col = cpick.color.rgb; -var obj = {"seg": {"col": [[col.r, col.g, col.b, whites[csel]],[],[]]}}; -if (csel == 1) { -obj = {"seg": {"col": [[],[col.r, col.g, col.b, whites[csel]],[]]}}; -} else if (csel == 2) { -obj = {"seg": {"col": [[],[],[col.r, col.g, col.b, whites[csel]]]}}; -} -obj.transition = parseInt(d.getElementById('cyctt').value*10); -if (d.getElementById('selectPalette').value > 5) { -d.getElementById('selectPalette').value = 0; -obj.seg.pal = 0; -} -requestJson(obj); + var cd = d.getElementById('csl').children; + if (fromPicker && cd[csel].style.backgroundColor == 'rgb(0, 0, 0)') cpick.color.setChannel('hsv', 'v', 100); + cd[csel].style.backgroundColor = cpick.color.rgbString; + whites[csel] = d.getElementById('sliderW').value; + var col = cpick.color.rgb; + var obj = {"seg": {"col": [[col.r, col.g, col.b, whites[csel]],[],[]]}}; + if (csel == 1) { + obj = {"seg": {"col": [[],[col.r, col.g, col.b, whites[csel]],[]]}}; + } else if (csel == 2) { + obj = {"seg": {"col": [[],[],[col.r, col.g, col.b, whites[csel]]]}}; + } + obj.transition = parseInt(d.getElementById('cyctt').value*10); + if (d.getElementById('selectPalette').value > 5) { + d.getElementById('selectPalette').value = 0; + obj.seg.pal = 0; + } + requestJson(obj); } function expand(i) { -expanded[i] = !expanded[i]; -d.getElementById('seg' +i).style.display = (expanded[i]) ? "block":"none"; -d.getElementById('sege' +i).style.transform = (expanded[i]) ? "rotate(180deg)":"rotate(0deg)" + expanded[i] = !expanded[i]; + d.getElementById('seg' +i).style.display = (expanded[i]) ? "block":"none"; + d.getElementById('sege' +i).style.transform = (expanded[i]) ? "rotate(180deg)":"rotate(0deg)" } function unfocusSliders() { -d.getElementById("sliderBri").blur(); -d.getElementById("sliderSpeed").blur(); -d.getElementById("sliderIntensity").blur(); + d.getElementById("sliderBri").blur(); + d.getElementById("sliderSpeed").blur(); + d.getElementById("sliderIntensity").blur(); } //sliding UI @@ -1404,67 +1404,67 @@ let iSlide = 0, x0 = null, y0 = null, scrollS = 0, locked = false, w; function unify(e) { return e.changedTouches ? e.changedTouches[0] : e } function lock(e) { -if (pcMode) return; -var l = e.target.classList; -if (l.contains('noslide') || l.contains('iro__wheel__saturation') || l.contains('iro__slider__value') || l.contains('iro__slider')) return; -x0 = unify(e).clientX; -y0 = unify(e).clientY; -scrollS = d.getElementsByClassName("tabcontent")[iSlide].scrollTop; + if (pcMode) return; + var l = e.target.classList; + if (l.contains('noslide') || l.contains('iro__wheel__saturation') || l.contains('iro__slider__value') || l.contains('iro__slider')) return; + x0 = unify(e).clientX; + y0 = unify(e).clientY; + scrollS = d.getElementsByClassName("tabcontent")[iSlide].scrollTop; -_C.classList.toggle('smooth', !(locked = true)) + _C.classList.toggle('smooth', !(locked = true)) } function drag(e) { -if (!locked || pcMode) return; -if (d.getElementsByClassName("tabcontent")[iSlide].scrollTop != scrollS) { -move(e); return; -} - -//if (Math.abs(unify(e).clientX - x0) > Math.abs(unify(e).clientY - y0)) { -//if (e.cancelable) e.preventDefault(); -//} - -_C.style.setProperty('--tx', `${Math.round(unify(e).clientX - x0)}px`) + if (!locked || pcMode) return; + if (d.getElementsByClassName("tabcontent")[iSlide].scrollTop != scrollS) { + move(e); return; + } + + //if (Math.abs(unify(e).clientX - x0) > Math.abs(unify(e).clientY - y0)) { + //if (e.cancelable) e.preventDefault(); + //} + + _C.style.setProperty('--tx', `${Math.round(unify(e).clientX - x0)}px`) } function move(e) { -if(!locked || pcMode) return; -var dx = unify(e).clientX - x0, s = Math.sign(dx), -f = +(s*dx/w).toFixed(2); + if(!locked || pcMode) return; + var dx = unify(e).clientX - x0, s = Math.sign(dx), + f = +(s*dx/w).toFixed(2); -if((iSlide > 0 || s < 0) && (iSlide < N - 1 || s > 0) && f > .12) { -_C.style.setProperty('--i', iSlide -= s); -f = 1 - f; -updateTablinks(iSlide); -} - -_C.style.setProperty('--tx', '0px'); -_C.style.setProperty('--f', f); -_C.classList.toggle('smooth', !(locked = false)); -x0 = null + if((iSlide > 0 || s < 0) && (iSlide < N - 1 || s > 0) && f > .12) { + _C.style.setProperty('--i', iSlide -= s); + f = 1 - f; + updateTablinks(iSlide); + } + + _C.style.setProperty('--tx', '0px'); + _C.style.setProperty('--f', f); + _C.classList.toggle('smooth', !(locked = false)); + x0 = null } function size() { -w = window.innerWidth; -_C.style.setProperty('--tp', d.getElementById('top').clientHeight + "px"); -_C.style.setProperty('--bt', d.getElementById('bot').clientHeight + "px"); -if (w < 1250) togglePcMode(); + w = window.innerWidth; + _C.style.setProperty('--tp', d.getElementById('top').clientHeight + "px"); + _C.style.setProperty('--bt', d.getElementById('bot').clientHeight + "px"); + if (w < 1250) togglePcMode(); } function togglePcMode() { -if (w < 1250 && !pcMode) return; -openTab(0); -pcMode = !pcMode; -if (w < 1250) pcMode = false; -updateTablinks(0); -d.getElementById('buttonPcm').className = (pcMode) ? "active":""; -if (pcMode) -{ -_C.style.width = '100%'; -} else { -_C.style.width = '400%'; -} + if (w < 1250 && !pcMode) return; + openTab(0); + pcMode = !pcMode; + if (w < 1250) pcMode = false; + updateTablinks(0); + d.getElementById('buttonPcm').className = (pcMode) ? "active":""; + if (pcMode) + { + _C.style.width = '100%'; + } else { + _C.style.width = '400%'; + } } size(); diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 5fe0e919e..07e49ceab 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -118,7 +118,15 @@ LED voltage (Max. current for a single LED):

LEDs are 4-channel type (RGBW):
-Auto-calculate white channel from RGB:
+Auto-calculate white channel from RGB:
+ +
Color order:
-AP IP: Not active
+AP IP: Not active
+

Experimental

+Disable WiFi sleep:
+Can help with connectivity issues.
+Do not enable if WiFi is working correctly, increases power consumption.
+
diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 0a38a37ac..746f98d0b 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -38,6 +38,9 @@ #include #include #include + extern "C" { + #include + } #else #include #include "esp_wifi.h" @@ -120,6 +123,8 @@ byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no conne IPAddress staticIP(0, 0, 0, 0); //static IP of ESP IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks +bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues + //LED CONFIG uint16_t ledCount = 30; //overcurrent prevented by ABL diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index bc19bd1d6..40b01ae50 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -6,7 +6,7 @@ #define EEPSIZE 2560 //eeprom Version code, enables default settings instead of 0 init on update -#define EEPVER 15 +#define EEPVER 16 //0 -> old version, default //1 -> 0.4p 1711272 and up //2 -> 0.4p 1711302 and up @@ -23,6 +23,7 @@ //13-> 0.9.0-dev //14-> 0.9.0-b1 //15-> 0.9.0-b3 +//16-> 0.9.1 void commit() { @@ -131,6 +132,8 @@ void saveSettingsToEEPROM() EEPROM.write(368, abs(arlsOffset)); EEPROM.write(369, turnOnAtBoot); + EEPROM.write(370, noWifiSleep); + EEPROM.write(372, useRGBW); EEPROM.write(374, strip.paletteFade); EEPROM.write(375, strip.milliampsPerLed); //was apWaitTimeSecs up to 0.8.5 @@ -484,6 +487,11 @@ void loadSettingsFromEEPROM(bool first) DMXMode = DMX_MODE_MULTIPLE_RGB; } + //if (lastEEPROMversion > 15) + //{ + noWifiSleep = EEPROM.read(370); + //} + receiveDirect = !EEPROM.read(2200); notifyMacro = EEPROM.read(2201); diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index 731d71ac7..3a7e12ba9 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -194,6 +194,8 @@ void getSettingsJS(byte subPage, char* dest) sappends('s',"AP",fapass); sappend('v',"AC",apChannel); + sappend('c',"WS",noWifiSleep); + if (WiFi.localIP()[0] != 0) //is connected { diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 8ee395c3e..6655dafd5 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -46,6 +46,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) if (passlen == 0 || (passlen > 7 && !isAsterisksOnly(request->arg("AP").c_str(), 65))) strlcpy(apPass, request->arg("AP").c_str(), 65); int t = request->arg("AC").toInt(); if (t > 0 && t < 14) apChannel = t; + noWifiSleep = request->hasArg("WS"); + char k[3]; k[2] = 0; for (int i = 0; i<4; i++) { diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index b26358cb3..8d41756b4 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -190,9 +190,14 @@ void initConnection() #ifdef ESP8266 WiFi.hostname(serverDescription); #endif + WiFi.begin(clientSSID, clientPass); + #ifdef ARDUINO_ARCH_ESP32 + if (noWifiSleep) WiFi.setSleep(false); WiFi.setHostname(serverDescription); + #else + if (noWifiSleep) wifi_set_sleep_type(NONE_SLEEP_T); #endif } diff --git a/wled00/wled17_mqtt.ino b/wled00/wled17_mqtt.ino index efc308a9c..aa72b9e1c 100644 --- a/wled00/wled17_mqtt.ino +++ b/wled00/wled17_mqtt.ino @@ -129,6 +129,7 @@ bool initMqtt() strcpy(mqttStatusTopic, mqttDeviceTopic); strcat(mqttStatusTopic, "/status"); mqtt->setWill(mqttStatusTopic, 0, true, "offline"); + mqtt->setKeepAlive(60); mqtt->connect(); return true; } From 3e3f46a683c45a612104dcb2657b49d152e5510d Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Thu, 20 Feb 2020 20:46:00 -0500 Subject: [PATCH 038/509] Added new mod --- .../readme.md | 25 ++ .../wled06_usermod.ino | 213 ++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md create mode 100644 usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md new file mode 100644 index 000000000..7a489f03f --- /dev/null +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -0,0 +1,25 @@ +# Wemos D1 mini and Wemos32 mini shield +## Project repository +- [Original repository](https://github.com/srg74/WLED-wemos-shield) - WLED Wemos shield repository +## Features +* SSD1306 128x32 or 128x64 I2C OLED display +* On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) +* Auto display shutoff for saving display lifetime +* Dallas temperature sensor +* Reporting temperature to MQTT broker +* Relay for energy saving + +## Hardware +![Shield](https://github.com/srg74/WLED-wemos-shield/blob/master/resources/Images/Assembly_8.jpg) + +## Wiki +![Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) + +## Functionality checked with +* Wemos D1 mini original v3.1 and clones +* Wemos32 mini +* PlatformIO +* SSD1306 128x32 I2C OLED display +* DS18B20 (temperature sensor) +* Push button (N.O. momentary switch) + diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino new file mode 100644 index 000000000..0e1b1e66b --- /dev/null +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino @@ -0,0 +1,213 @@ +#include // from https://github.com/olikraus/u8g2/ +#include //Dallastemperature sensor + +//The SCL and SDA pins are defined here. +//ESP8266 Wemos D1 mini boards use SCL=5 SDA=4 +#define U8X8_PIN_SCL 5 +#define U8X8_PIN_SDA 4 +//ESP32 Wemos32 mini boards use SCL=22 SDA=21 +//#define U8X8_PIN_SCL 22 +//#define U8X8_PIN_SDA 21 + +// Dallas sensor +OneWire oneWire(13); //ESP8266 boards +//OneWire oneWire(23); //ESP32 boards +DallasTemperature sensor(&oneWire); +long temptimer = millis(); +long lastMeasure = 0; +#define Celsius // Show temperature mesaurement in Celcius otherwise is in Fahrenheit + +// If display does not work or looks corrupted check the +// constructor reference: +// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp +// or check the gallery: +// https://github.com/olikraus/u8g2/wiki/gallery +// --> First choise of cheap I2C OLED 128X32 0.91" +U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA +// --> Second choise of cheap I2C OLED 128X64 0.96" or 1.3" +//U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA +// gets called once at boot. Do all initialization that doesn't depend on +// network here +void userSetup() { + sensor.begin(); //Start Dallas temperature sensor + u8x8.begin(); + u8x8.setPowerSave(0); + u8x8.setFlipMode(1); + u8x8.setContrast(10); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255 + u8x8.setFont(u8x8_font_chroma48medium8_r); + u8x8.drawString(0, 0, "Loading..."); +} + +// gets called every time WiFi is (re-)connected. Initialize own network +// interfaces here +void userConnected() {} + +// needRedraw marks if redraw is required to prevent often redrawing. +bool needRedraw = true; + +// Next variables hold the previous known values to determine if redraw is +// required. +String knownSsid = ""; +IPAddress knownIp; +uint8_t knownBrightness = 0; +uint8_t knownMode = 0; +uint8_t knownPalette = 0; + +long lastUpdate = 0; +long lastRedraw = 0; +bool displayTurnedOff = false; +// How often we are redrawing screen +#define USER_LOOP_REFRESH_RATE_MS 5000 + +void userLoop() { + +//----> Dallas temperature sensor MQTT publishing + temptimer = millis(); +// Timer to publishe new temperature every 60 seconds + if (temptimer - lastMeasure > 60000) + { + lastMeasure = temptimer; +//Check if MQTT Connected, otherwise it will crash the 8266 + if (mqtt != nullptr) + { + sensor.requestTemperatures(); +//Gets prefered temperature scale based on selection in definitions section + #ifdef Celsius + float board_temperature = sensor.getTempCByIndex(0); + #else + float board_temperature = sensor.getTempFByIndex(0); + #endif +//Create character string populated with user defined device topic from the UI, and the read temperature. Then publish to MQTT server. + char subuf[38]; + strcpy(subuf, mqttDeviceTopic); + strcat(subuf, "/temperature"); + mqtt->publish(subuf, 0, true, String(board_temperature).c_str()); + } + } + + // Check if we time interval for redrawing passes. + if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) { + return; + } + lastUpdate = millis(); + + // Turn off display after 3 minutes with no change. + if(!displayTurnedOff && millis() - lastRedraw > 3*60*1000) { + u8x8.setPowerSave(1); + displayTurnedOff = true; + } + + // Check if values which are shown on display changed from the last time. + if (((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid) { + needRedraw = true; + } else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) { + needRedraw = true; + } else if (knownBrightness != bri) { + needRedraw = true; + } else if (knownMode != strip.getMode()) { + needRedraw = true; + } else if (knownPalette != strip.getSegment(0).palette) { + needRedraw = true; + } + + if (!needRedraw) { + return; + } + needRedraw = false; + + if (displayTurnedOff) + { + u8x8.setPowerSave(0); + displayTurnedOff = false; + } + lastRedraw = millis(); + + // Update last known values. + #if defined(ESP8266) + knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID(); + #else + knownSsid = WiFi.SSID(); + #endif + knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP(); + knownBrightness = bri; + knownMode = strip.getMode(); + knownPalette = strip.getSegment(0).palette; + u8x8.clear(); + u8x8.setFont(u8x8_font_chroma48medium8_r); + + // First row with Wifi name + u8x8.setCursor(1, 0); + u8x8.print(knownSsid.substring(0, u8x8.getCols() > 1 ? u8x8.getCols() - 2 : 0)); + // Print `~` char to indicate that SSID is longer, than owr dicplay + if (knownSsid.length() > u8x8.getCols()) + u8x8.print("~"); + + // Second row with IP or Psssword + u8x8.setCursor(1, 1); + // Print password in AP mode and if led is OFF. + if (apActive && bri == 0) + u8x8.print(apPass); + else + u8x8.print(knownIp); + + // Third row with mode name + u8x8.setCursor(2, 2); + uint8_t qComma = 0; + bool insideQuotes = false; + uint8_t printedChars = 0; + char singleJsonSymbol; + + // Find the mode name in JSON + for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) { + singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i); + switch (singleJsonSymbol) { + case '"': + insideQuotes = !insideQuotes; + break; + case '[': + case ']': + break; + case ',': + qComma++; + default: + if (!insideQuotes || (qComma != knownMode)) + break; + u8x8.print(singleJsonSymbol); + printedChars++; + } + if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2)) + break; + } + // Fourth row with palette name + u8x8.setCursor(2, 3); + qComma = 0; + insideQuotes = false; + printedChars = 0; + // Looking for palette name in JSON. + for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) { + singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i); + switch (singleJsonSymbol) { + case '"': + insideQuotes = !insideQuotes; + break; + case '[': + case ']': + break; + case ',': + qComma++; + default: + if (!insideQuotes || (qComma != knownPalette)) + break; + u8x8.print(singleJsonSymbol); + printedChars++; + } + if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2)) + break; + } + + u8x8.setFont(u8x8_font_open_iconic_embedded_1x1); + u8x8.drawGlyph(0, 0, 80); // wifi icon + u8x8.drawGlyph(0, 1, 68); // home icon + u8x8.setFont(u8x8_font_open_iconic_weather_2x2); + u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon +} \ No newline at end of file From 451a6841c9a4fc7686e2392c11230d020d65adf0 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Thu, 20 Feb 2020 20:48:25 -0500 Subject: [PATCH 039/509] Update readme.md --- usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md index 7a489f03f..a92c0a47f 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -12,8 +12,7 @@ ## Hardware ![Shield](https://github.com/srg74/WLED-wemos-shield/blob/master/resources/Images/Assembly_8.jpg) -## Wiki -![Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) +- [Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) ## Functionality checked with * Wemos D1 mini original v3.1 and clones From 5ca1e9268c21ced2b7a5104af55e91ea9239053e Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Thu, 20 Feb 2020 20:49:33 -0500 Subject: [PATCH 040/509] Update readme.md --- usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md index a92c0a47f..a16beb297 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -12,7 +12,7 @@ ## Hardware ![Shield](https://github.com/srg74/WLED-wemos-shield/blob/master/resources/Images/Assembly_8.jpg) -- [Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) +- [Wemos shield project Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) ## Functionality checked with * Wemos D1 mini original v3.1 and clones From 6451522f89de23c7fbd45a8c332d7be457537ca1 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Thu, 20 Feb 2020 20:50:38 -0500 Subject: [PATCH 041/509] Update readme.md --- usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md index a16beb297..fa0e4324a 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -1,6 +1,7 @@ # Wemos D1 mini and Wemos32 mini shield ## Project repository - [Original repository](https://github.com/srg74/WLED-wemos-shield) - WLED Wemos shield repository +- [Wemos shield project Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) ## Features * SSD1306 128x32 or 128x64 I2C OLED display * On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) @@ -12,8 +13,6 @@ ## Hardware ![Shield](https://github.com/srg74/WLED-wemos-shield/blob/master/resources/Images/Assembly_8.jpg) -- [Wemos shield project Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) - ## Functionality checked with * Wemos D1 mini original v3.1 and clones * Wemos32 mini From bdc44a4070f8d168b3b9ca911164e5d309b9f9a3 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Thu, 20 Feb 2020 20:53:17 -0500 Subject: [PATCH 042/509] Update readme.md --- usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md index fa0e4324a..2584c919c 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -2,6 +2,7 @@ ## Project repository - [Original repository](https://github.com/srg74/WLED-wemos-shield) - WLED Wemos shield repository - [Wemos shield project Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) +- [Precompiled WLED firmware](https://github.com/srg74/WLED-wemos-shield/tree/master/resources/Firmware) ## Features * SSD1306 128x32 or 128x64 I2C OLED display * On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) From 863498f76219f2fc1dca1bb4e155d69182600bca Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Thu, 20 Feb 2020 22:43:59 -0500 Subject: [PATCH 043/509] Update readme.md --- .../readme.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md index 2584c919c..8a1d7ecab 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -4,21 +4,21 @@ - [Wemos shield project Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) - [Precompiled WLED firmware](https://github.com/srg74/WLED-wemos-shield/tree/master/resources/Firmware) ## Features -* SSD1306 128x32 or 128x64 I2C OLED display -* On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) -* Auto display shutoff for saving display lifetime -* Dallas temperature sensor -* Reporting temperature to MQTT broker -* Relay for energy saving +- SSD1306 128x32 or 128x64 I2C OLED display +- On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) +- Auto display shutoff for saving display lifetime +- Dallas temperature sensor +- Reporting temperature to MQTT broker +- Relay for energy saving ## Hardware ![Shield](https://github.com/srg74/WLED-wemos-shield/blob/master/resources/Images/Assembly_8.jpg) ## Functionality checked with -* Wemos D1 mini original v3.1 and clones -* Wemos32 mini -* PlatformIO -* SSD1306 128x32 I2C OLED display -* DS18B20 (temperature sensor) -* Push button (N.O. momentary switch) +- Wemos D1 mini original v3.1 and clones +- Wemos32 mini +- PlatformIO +- SSD1306 128x32 I2C OLED display +- DS18B20 (temperature sensor) +- Push button (N.O. momentary switch) From b1961033b36a4c8c062f162e59f4788c912af330 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Thu, 20 Feb 2020 22:48:20 -0500 Subject: [PATCH 044/509] Update readme.md --- usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md | 1 - 1 file changed, 1 deletion(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md index 8a1d7ecab..be97d4b8c 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -21,4 +21,3 @@ - SSD1306 128x32 I2C OLED display - DS18B20 (temperature sensor) - Push button (N.O. momentary switch) - From fb59f1f0a0e6d710f7e5b0402184334ed48c73ab Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Fri, 21 Feb 2020 16:55:58 -0500 Subject: [PATCH 045/509] Update wled06_usermod.ino --- .../wled06_usermod.ino | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino index 0e1b1e66b..9e6e0b793 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino @@ -1,17 +1,20 @@ #include // from https://github.com/olikraus/u8g2/ #include //Dallastemperature sensor - +#ifdef ARDUINO_ARCH_ESP32 //ESP32 boards +uint8_t SCL_PIN = 22; +uint8_t SDA_PIN = 21; +OneWire oneWire(23); +#else //ESP8266 boards +uint8_t SCL_PIN = 5; +uint8_t SDA_PIN = 4; +OneWire oneWire(13); +#endif //The SCL and SDA pins are defined here. -//ESP8266 Wemos D1 mini boards use SCL=5 SDA=4 -#define U8X8_PIN_SCL 5 -#define U8X8_PIN_SDA 4 -//ESP32 Wemos32 mini boards use SCL=22 SDA=21 -//#define U8X8_PIN_SCL 22 -//#define U8X8_PIN_SDA 21 +//ESP8266 Wemos D1 mini board use SCL=5 SDA=4 while ESP32 Wemos32 mini board use SCL=22 SDA=21 +#define U8X8_PIN_SCL SCL_PIN +#define U8X8_PIN_SDA SDA_PIN // Dallas sensor -OneWire oneWire(13); //ESP8266 boards -//OneWire oneWire(23); //ESP32 boards DallasTemperature sensor(&oneWire); long temptimer = millis(); long lastMeasure = 0; @@ -210,4 +213,4 @@ void userLoop() { u8x8.drawGlyph(0, 1, 68); // home icon u8x8.setFont(u8x8_font_open_iconic_weather_2x2); u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon -} \ No newline at end of file +} From 1a4061fdb5b49270303b036d50dd1e791a1e17cc Mon Sep 17 00:00:00 2001 From: Def3nder Date: Sat, 22 Feb 2020 16:17:32 +0100 Subject: [PATCH 046/509] Refactor callMode (#702) --- .../wled06_usermod.ino | 2 +- .../stairway_wipe_basic/wled06_usermod.ino | 8 +- wled00/const.h | 13 +++ wled00/wled00.ino | 4 +- wled00/wled03_set.ino | 2 +- wled00/wled05_init.ino | 2 +- wled00/wled07_notify.ino | 26 +++--- wled00/wled08_led.ino | 38 +++++--- wled00/wled09_button.ino | 2 +- wled00/wled12_alexa.ino | 8 +- wled00/wled15_hue.ino | 2 +- wled00/wled16_blynk.ino | 14 +-- wled00/wled17_mqtt.ino | 4 +- wled00/wled19_json.ino | 2 +- wled00/wled20_ir.ino | 93 ++++++++----------- 15 files changed, 114 insertions(+), 106 deletions(-) diff --git a/usermods/rotary_encoder_change_effect/wled06_usermod.ino b/usermods/rotary_encoder_change_effect/wled06_usermod.ino index dbde9560a..f004ba2f4 100644 --- a/usermods/rotary_encoder_change_effect/wled06_usermod.ino +++ b/usermods/rotary_encoder_change_effect/wled06_usermod.ino @@ -39,7 +39,7 @@ void userLoop() { //call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification) // 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa - colorUpdated(6); + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); lastTime = millis(); } } diff --git a/usermods/stairway_wipe_basic/wled06_usermod.ino b/usermods/stairway_wipe_basic/wled06_usermod.ino index ab61c5afe..3d493cc1d 100644 --- a/usermods/stairway_wipe_basic/wled06_usermod.ino +++ b/usermods/stairway_wipe_basic/wled06_usermod.ino @@ -47,7 +47,7 @@ void userLoop() if (millis() + strip.timebase > (cycleTime - 25)) { //wipe complete effectCurrent = FX_MODE_STATIC; timeStaticStart = millis(); - colorUpdated(3); + colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); wipeState = 2; } } else if (wipeState == 2) { //static @@ -59,7 +59,7 @@ void userLoop() #ifdef STAIRCASE_WIPE_OFF effectCurrent = FX_MODE_COLOR_WIPE; strip.timebase = 360 + (255 - effectSpeed)*75 - millis(); //make sure wipe starts fully lit - colorUpdated(3); + colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); wipeState = 4; #else turnOff(); @@ -93,7 +93,7 @@ void startWipe() bool doReverse = (userVar0 == 2); seg.setOption(1, doReverse); - colorUpdated(3); + colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); } void turnOff() @@ -104,7 +104,7 @@ void turnOff() transitionDelayTemp = 4000; //fade out slowly #endif bri = 0; - colorUpdated(3); + colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); wipeState = 0; userVar0 = 0; previousUserVar0 = 0; diff --git a/wled00/const.h b/wled00/const.h index 1308bf5fe..4d2875723 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -7,6 +7,19 @@ #define AP_BEHAVIOR_ALWAYS 2 //Always open #define AP_BEHAVIOR_BUTTON_ONLY 3 //Only when button pressed for 6 sec +//Notifier callMode +#define NOTIFIER_CALL_MODE_INIT 0 // no updates on init, can be used to disable updates +#define NOTIFIER_CALL_MODE_DIRECT_CHANGE 1 +#define NOTIFIER_CALL_MODE_BUTTON 2 +#define NOTIFIER_CALL_MODE_NOTIFICATION 3 +#define NOTIFIER_CALL_MODE_NIGHTLIGHT 4 +#define NOTIFIER_CALL_MODE_NO_NOTIFY 5 +#define NOTIFIER_CALL_MODE_FX_CHANGED 6 +#define NOTIFIER_CALL_MODE_HUE 7 +#define NOTIFIER_CALL_MODE_PRESET_CYCLE 8 +#define NOTIFIER_CALL_MODE_BLYNK 9 +#define NOTIFIER_CALL_MODE_ALEXA 10 + //RGB to RGBW conversion mode #define RGBW_MODE_MANUAL_ONLY 0 //No automatic white channel calculation. Manual white channel slider #define RGBW_MODE_AUTO_BRIGHTER 1 //New algorithm. Adds as much white as the darkest RGBW channel diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 746f98d0b..c04258f06 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -301,7 +301,7 @@ unsigned long buttonWaitTime = 0; bool notifyDirectDefault = notifyDirect; bool receiveNotifications = true; unsigned long notificationSentTime = 0; -byte notificationSentCallMode = 0; +byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; bool notificationTwoRequired = false; //effects @@ -369,7 +369,7 @@ unsigned long realtimeTimeout = 0; //mqtt long lastMqttReconnectAttempt = 0; long lastInterfaceUpdate = 0; -byte interfaceUpdateCallMode = 0; +byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; char mqttStatusTopic[40] = ""; //this must be global because of async handlers #if AUXPIN >= 0 diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 6655dafd5..f7485917d 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -651,7 +651,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) if (pos < 1) XML_response(request); pos = req.indexOf("&NN"); //do not send UDP notifications this time - colorUpdated((pos > 0) ? 5:1); + colorUpdated((pos > 0) ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE); return true; } diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 8d41756b4..820670c82 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -99,7 +99,7 @@ void beginStrip() #endif if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true); - colorUpdated(0); + colorUpdated(NOTIFIER_CALL_MODE_INIT); //init relay pin #if RLYPIN >= 0 diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino index ab55df28d..6af7416bc 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled07_notify.ino @@ -11,15 +11,15 @@ void notify(byte callMode, bool followUp=false) if (!udpConnected) return; switch (callMode) { - case 0: return; - case 1: if (!notifyDirect) return; break; - case 2: if (!notifyButton) return; break; - case 4: if (!notifyDirect) return; break; - case 6: if (!notifyDirect) return; break; //fx change - case 7: if (!notifyHue) return; break; - case 8: if (!notifyDirect) return; break; - case 9: if (!notifyDirect) return; break; - case 10: if (!notifyAlexa) return; break; + case NOTIFIER_CALL_MODE_INIT: return; + case NOTIFIER_CALL_MODE_DIRECT_CHANGE: if (!notifyDirect) return; break; + case NOTIFIER_CALL_MODE_BUTTON: if (!notifyButton) return; break; + case NOTIFIER_CALL_MODE_NIGHTLIGHT: if (!notifyDirect) return; break; + case NOTIFIER_CALL_MODE_FX_CHANGED: if (!notifyDirect) return; break; //fx change + case NOTIFIER_CALL_MODE_HUE: if (!notifyHue) return; break; + case NOTIFIER_CALL_MODE_PRESET_CYCLE: if (!notifyDirect) return; break; + case NOTIFIER_CALL_MODE_BLYNK: if (!notifyDirect) return; break; + case NOTIFIER_CALL_MODE_ALEXA: if (!notifyAlexa) return; break; default: return; } byte udpOut[WLEDPACKETSIZE]; @@ -157,9 +157,9 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ col[3] = p->property_values[DMXAddress+11]; //white colSec[3] = p->property_values[DMXAddress+12]; } - transitionDelayTemp = 0; // act fast - colorUpdated(3); // don't send UDP - return; // don't activate realtime live mode + transitionDelayTemp = 0; // act fast + colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); // don't send UDP + return; // don't activate realtime live mode break; case DMX_MODE_MULTIPLE_RGB: @@ -329,7 +329,7 @@ void handleNotifications() if (nightlightActive) nightlightDelayMins = udpIn[7]; if (receiveNotificationBrightness || !someSel) bri = udpIn[2]; - colorUpdated(3); + colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); } else if (udpIn[0] > 0 && udpIn[0] < 5 && receiveDirect) //1 warls //2 drgb //3 drgbw { diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index fb0e8a7e8..124e43bd6 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -79,6 +79,7 @@ bool colorChanged() { if (col[i] != colIT[i]) return true; if (colSec[i] != colSecIT[i]) return true; + if (col[i] != colNlT[i]) return true; } if (bri != briIT) return true; return false; @@ -89,18 +90,24 @@ void colorUpdated(int callMode) { //call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification) // 6: fx changed 7: hue 8: preset cycle 9: blynk 10: alexa - if (callMode != 0 && callMode != 1 && callMode != 5) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments + if (callMode != NOTIFIER_CALL_MODE_INIT && + callMode != NOTIFIER_CALL_MODE_DIRECT_CHANGE && + callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette); if (!colorChanged()) { - if (nightlightActive && !nightlightActiveOld && callMode != 3 && callMode != 5) + if (nightlightActive && !nightlightActiveOld && + callMode != NOTIFIER_CALL_MODE_NOTIFICATION && + callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) { - notify(4); interfaceUpdateCallMode = 4; return; + notify(NOTIFIER_CALL_MODE_NIGHTLIGHT); + interfaceUpdateCallMode = NOTIFIER_CALL_MODE_NIGHTLIGHT; + return; } else if (fxChanged) { - notify(6); - if (callMode != 8) interfaceUpdateCallMode = 6; + notify(NOTIFIER_CALL_MODE_FX_CHANGED); + if (callMode != NOTIFIER_CALL_MODE_PRESET_CYCLE) interfaceUpdateCallMode = NOTIFIER_CALL_MODE_FX_CHANGED; if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0; if (isPreset) {isPreset = false;} else {currentPreset = -1;} @@ -110,7 +117,7 @@ void colorUpdated(int callMode) if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0; if (isPreset) {isPreset = false;} else {currentPreset = -1;} - if (callMode != 5 && nightlightActive && nightlightFade) + if (callMode != NOTIFIER_CALL_MODE_NO_NOTIFY && nightlightActive && nightlightFade) { briNlT = bri; nightlightDelayMs -= (millis() - nightlightStartTime); @@ -123,8 +130,8 @@ void colorUpdated(int callMode) } if (briT == 0) { - setLedsStandard(true); //do not color transition if starting from off - if (callMode != 3) resetTimebase(); //effect start from beginning + setLedsStandard(true); //do not color transition if starting from off + if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION) resetTimebase(); //effect start from beginning } briIT = bri; @@ -135,7 +142,7 @@ void colorUpdated(int callMode) if (fadeTransition) { //set correct delay if not using notification delay - if (callMode != 3 && !jsonTransitionOnce) transitionDelayTemp = transitionDelay; + if (callMode != NOTIFIER_CALL_MODE_NOTIFICATION && !jsonTransitionOnce) transitionDelayTemp = transitionDelay; jsonTransitionOnce = false; if (transitionDelayTemp == 0) {setLedsStandard(); strip.trigger(); return;} @@ -158,7 +165,7 @@ void colorUpdated(int callMode) strip.trigger(); } - if (callMode == 8) return; + if (callMode == NOTIFIER_CALL_MODE_PRESET_CYCLE) return; //set flag to update blynk and mqtt interfaceUpdateCallMode = callMode; } @@ -167,12 +174,13 @@ void colorUpdated(int callMode) void updateInterfaces(uint8_t callMode) { #ifndef WLED_DISABLE_ALEXA - if (espalexaDevice != nullptr && callMode != 10) { + if (espalexaDevice != nullptr && callMode != NOTIFIER_CALL_MODE_ALEXA) { espalexaDevice->setValue(bri); espalexaDevice->setColor(col[0], col[1], col[2]); } #endif - if (callMode != 9 && callMode != 5) updateBlynk(); + if (callMode != NOTIFIER_CALL_MODE_BLYNK && + callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) updateBlynk(); doPublishMqtt = true; lastInterfaceUpdate = millis(); } @@ -233,7 +241,7 @@ void handleNightlight() { for (byte i=0; i<4; i++) col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color } - colorUpdated(5); + colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); } if (nper >= 1) { @@ -241,7 +249,7 @@ void handleNightlight() if (!nightlightFade) { bri = nightlightTargetBri; - colorUpdated(5); + colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); } updateBlynk(); if (bri == 0) briLast = briNlT; @@ -257,7 +265,7 @@ void handleNightlight() applyPreset(presetCycCurr,presetApplyBri,presetApplyCol,presetApplyFx); presetCycCurr++; if (presetCycCurr > presetCycleMax) presetCycCurr = presetCycleMin; if (presetCycCurr > 25) presetCycCurr = 1; - colorUpdated(8); + colorUpdated(NOTIFIER_CALL_MODE_PRESET_CYCLE); presetCycledTime = millis(); } } diff --git a/wled00/wled09_button.ino b/wled00/wled09_button.ino index 86227dc3f..1cd868bec 100644 --- a/wled00/wled09_button.ino +++ b/wled00/wled09_button.ino @@ -7,7 +7,7 @@ void shortPressAction() if (!macroButton) { toggleOnOff(); - colorUpdated(2); + colorUpdated(NOTIFIER_CALL_MODE_BUTTON); } else { applyMacro(macroButton); } diff --git a/wled00/wled12_alexa.ino b/wled00/wled12_alexa.ino index c3bc01ab0..9c27041b7 100644 --- a/wled00/wled12_alexa.ino +++ b/wled00/wled12_alexa.ino @@ -41,7 +41,7 @@ void onAlexaChange(EspalexaDevice* dev) if (bri == 0) { bri = briLast; - colorUpdated(10); + colorUpdated(NOTIFIER_CALL_MODE_ALEXA); } } else applyMacro(macroAlexaOn); } else if (m == EspalexaDeviceProperty::off) @@ -52,13 +52,13 @@ void onAlexaChange(EspalexaDevice* dev) { briLast = bri; bri = 0; - colorUpdated(10); + colorUpdated(NOTIFIER_CALL_MODE_ALEXA); } } else applyMacro(macroAlexaOff); } else if (m == EspalexaDeviceProperty::bri) { bri = espalexaDevice->getValue(); - colorUpdated(10); + colorUpdated(NOTIFIER_CALL_MODE_ALEXA); } else //color { uint32_t color = espalexaDevice->getRGB(); @@ -67,7 +67,7 @@ void onAlexaChange(EspalexaDevice* dev) col[1] = ((color >> 8) & 0xFF); col[2] = (color & 0xFF); if (useRGBW && col[3] == 0) colorRGBtoRGBW(col); // do not touch white value if EspalexaDevice.cpp did set the white channel - colorUpdated(10); + colorUpdated(NOTIFIER_CALL_MODE_ALEXA); } } diff --git a/wled00/wled15_hue.ino b/wled00/wled15_hue.ino index da400f5e8..77e6622c6 100644 --- a/wled00/wled15_hue.ino +++ b/wled00/wled15_hue.ino @@ -6,7 +6,7 @@ void handleHue() { if (hueReceived) { - colorUpdated(7); hueReceived = false; + colorUpdated(NOTIFIER_CALL_MODE_HUE); hueReceived = false; if (hueStoreAllowed && hueNewKey) { saveSettingsToEEPROM(); //save api key diff --git a/wled00/wled16_blynk.ino b/wled00/wled16_blynk.ino index c09d0c185..ea4d68771 100644 --- a/wled00/wled16_blynk.ino +++ b/wled00/wled16_blynk.ino @@ -41,45 +41,45 @@ void updateBlynk() BLYNK_WRITE(V0) { bri = param.asInt();//bri - colorUpdated(9); + colorUpdated(NOTIFIER_CALL_MODE_BLYNK); } BLYNK_WRITE(V1) { blHue = param.asInt();//hue colorHStoRGB(blHue*10,blSat,(false)? colSec:col); - colorUpdated(9); + colorUpdated(NOTIFIER_CALL_MODE_BLYNK); } BLYNK_WRITE(V2) { blSat = param.asInt();//sat colorHStoRGB(blHue*10,blSat,(false)? colSec:col); - colorUpdated(9); + colorUpdated(NOTIFIER_CALL_MODE_BLYNK); } BLYNK_WRITE(V3) { bool on = (param.asInt()>0); - if (!on != !bri) {toggleOnOff(); colorUpdated(9);} + if (!on != !bri) {toggleOnOff(); colorUpdated(NOTIFIER_CALL_MODE_BLYNK);} } BLYNK_WRITE(V4) { effectCurrent = param.asInt()-1;//fx - colorUpdated(9); + colorUpdated(NOTIFIER_CALL_MODE_BLYNK); } BLYNK_WRITE(V5) { effectSpeed = param.asInt();//sx - colorUpdated(9); + colorUpdated(NOTIFIER_CALL_MODE_BLYNK); } BLYNK_WRITE(V6) { effectIntensity = param.asInt();//ix - colorUpdated(9); + colorUpdated(NOTIFIER_CALL_MODE_BLYNK); } BLYNK_WRITE(V7) diff --git a/wled00/wled17_mqtt.ino b/wled00/wled17_mqtt.ino index aa72b9e1c..db34a742b 100644 --- a/wled00/wled17_mqtt.ino +++ b/wled00/wled17_mqtt.ino @@ -12,7 +12,7 @@ void parseMQTTBriPayload(char* payload) uint8_t in = strtoul(payload, NULL, 10); if (in == 0 && bri > 0) briLast = bri; bri = in; - colorUpdated(1); + colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); } } @@ -60,7 +60,7 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties if (strstr(topic, "/col")) { colorFromDecOrHexString(col, (char*)payload); - colorUpdated(1); + colorUpdated(NOTIFIER_CALL_MODE_DIRECT_CHANGE); } else if (strstr(topic, "/api")) { String apireq = "win&"; diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index 219ef8bc1..852dfdacf 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -154,7 +154,7 @@ bool deserializeState(JsonObject root) } } - colorUpdated(noNotification ? 5:1); + colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE); ps = root["psave"] | -1; if (ps >= 0) savePreset(ps); diff --git a/wled00/wled20_ir.ino b/wled00/wled20_ir.ino index 113b19b53..617518c31 100644 --- a/wled00/wled20_ir.ino +++ b/wled00/wled20_ir.ino @@ -29,7 +29,7 @@ bool decodeIRCustom(uint32_t code) default: return false; } - if (code != IRCUSTOM_MACRO1) colorUpdated(2); //don't update color again if we apply macro, it already does it + if (code != IRCUSTOM_MACRO1) colorUpdated(NOTIFIER_CALL_MODE_BUTTON); //don't update color again if we apply macro, it already does it return true; } @@ -51,25 +51,25 @@ void decodeIR(uint32_t code) irTimesRepeated++; if (lastValidCode == IR24_BRIGHTER || lastValidCode == IR40_BPLUS ) { - relativeChange(&bri, 10); colorUpdated(2); + relativeChange(&bri, 10); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); } else if (lastValidCode == IR24_DARKER || lastValidCode == IR40_BMINUS ) { - relativeChange(&bri, -10, 5); colorUpdated(2); + relativeChange(&bri, -10, 5); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); } if (lastValidCode == IR40_WPLUS) { - relativeChangeWhite(10); colorUpdated(2); + relativeChangeWhite(10); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); } else if (lastValidCode == IR40_WMINUS) { - relativeChangeWhite(-10, 5); colorUpdated(2); + relativeChangeWhite(-10, 5); colorUpdated(NOTIFIER_CALL_MODE_BUTTON); } else if ((lastValidCode == IR24_ON || lastValidCode == IR40_ON) && irTimesRepeated > 7 ) { nightlightActive = true; nightlightStartTime = millis(); - colorUpdated(2); + colorUpdated(NOTIFIER_CALL_MODE_BUTTON); } return; } @@ -85,11 +85,12 @@ void decodeIR(uint32_t code) case 3: decodeIR40(code); break; // blue 40-key remote with 25%, 50%, 75% and 100% keys case 4: decodeIR44(code); break; // white 44-key remote with color-up/down keys and DIY1 to 6 keys case 5: decodeIR21(code); break; // white 21-key remote - case 6: decodeIR6(code); break; // black 6-key learning remote defaults: "CH" controls brightness, + case 6: decodeIR6(code); break; // black 6-key learning remote defaults: "CH" controls brightness, // "VOL +" controls effect, "VOL -" controls colour/palette, "MUTE" // sets bright plain white default: return; } + colorUpdated(NOTIFIER_CALL_MODE_BUTTON); //for notifier, IR is considered a button input } //code <= 0xF70000 also invalid } @@ -125,7 +126,6 @@ void decodeIR24(uint32_t code) default: return; } lastValidCode = code; - colorUpdated(2); //for notifier, IR is considered a button input } void decodeIR24OLD(uint32_t code) @@ -158,7 +158,6 @@ void decodeIR24OLD(uint32_t code) default: return; } lastValidCode = code; - colorUpdated(2); //for notifier, IR is considered a button input } @@ -194,7 +193,6 @@ void decodeIR24CT(uint32_t code) default: return; } lastValidCode = code; - colorUpdated(2); //for notifier, IR is considered a button input } @@ -253,7 +251,6 @@ void decodeIR40(uint32_t code) case IR40_FLASH : if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break; } lastValidCode = code; - colorUpdated(2); //for notifier, IR is considered a button input } void decodeIR44(uint32_t code) @@ -317,12 +314,11 @@ void decodeIR44(uint32_t code) case IR44_FADE7 : bri = 255; break; } lastValidCode = code; - colorUpdated(2); //for notifier, IR is considered a button input } void decodeIR21(uint32_t code) { - switch (code) { + switch (code) { case IR21_BRIGHTER: relativeChange(&bri, 10); break; case IR21_DARKER: relativeChange(&bri, -10, 5); break; case IR21_OFF: briLast = bri; bri = 0; break; @@ -345,51 +341,42 @@ void decodeIR21(uint32_t code) case IR21_FADE: if (!applyPreset(3)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; case IR21_SMOOTH: if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break; default: return; - } - lastValidCode = code; - colorUpdated(2); //for notifier, IR is considered a button input + } + lastValidCode = code; } void decodeIR6(uint32_t code) { - - switch (code) { - case IR6_POWER: toggleOnOff(); break; - case IR6_CHANNEL_UP: relativeChange(&bri, 10); break; - case IR6_CHANNEL_DOWN: relativeChange(&bri, -10, 5); break; - case IR6_VOLUME_UP: /* next effect */ relativeChange(&effectCurrent, 1); break; - case IR6_VOLUME_DOWN: - /* next palette */ - - relativeChange(&effectPalette, 1); - - switch(lastIR6ColourIdx) - { - case 0: colorFromUint32(COLOR_RED); break; - case 1: colorFromUint32(COLOR_REDDISH); break; - case 2:colorFromUint32(COLOR_ORANGE); break; - case 3:colorFromUint32(COLOR_YELLOWISH); break; - case 4:colorFromUint32(COLOR_GREEN); break; - case 5:colorFromUint32(COLOR_GREENISH); break; - case 6:colorFromUint32(COLOR_TURQUOISE); break; - case 7: colorFromUint32(COLOR_CYAN); break; - case 8:colorFromUint32(COLOR_BLUE); break; - case 9:colorFromUint32(COLOR_DEEPBLUE); break; - case 10:colorFromUint32(COLOR_PURPLE); break; - case 11:colorFromUint32(COLOR_PINK); break; - case 12:colorFromUint32(COLOR_WHITE); break; - default:break; - - } - - lastIR6ColourIdx++; - if(lastIR6ColourIdx > 12) lastIR6ColourIdx = 0; - + switch (code) { + case IR6_POWER: toggleOnOff(); break; + case IR6_CHANNEL_UP: relativeChange(&bri, 10); break; + case IR6_CHANNEL_DOWN: relativeChange(&bri, -10, 5); break; + case IR6_VOLUME_UP: /* next effect */ relativeChange(&effectCurrent, 1); break; + case IR6_VOLUME_DOWN: + /* next palette */ + relativeChange(&effectPalette, 1); + switch(lastIR6ColourIdx) { + case 0: colorFromUint32(COLOR_RED); break; + case 1: colorFromUint32(COLOR_REDDISH); break; + case 2:colorFromUint32(COLOR_ORANGE); break; + case 3:colorFromUint32(COLOR_YELLOWISH); break; + case 4:colorFromUint32(COLOR_GREEN); break; + case 5:colorFromUint32(COLOR_GREENISH); break; + case 6:colorFromUint32(COLOR_TURQUOISE); break; + case 7: colorFromUint32(COLOR_CYAN); break; + case 8:colorFromUint32(COLOR_BLUE); break; + case 9:colorFromUint32(COLOR_DEEPBLUE); break; + case 10:colorFromUint32(COLOR_PURPLE); break; + case 11:colorFromUint32(COLOR_PINK); break; + case 12:colorFromUint32(COLOR_WHITE); break; + default:break; + } + lastIR6ColourIdx++; + if(lastIR6ColourIdx > 12) lastIR6ColourIdx = 0; break; - case IR6_MUTE: effectCurrent = 0; effectPalette = 0; colorFromUint32(COLOR_WHITE); bri=255; break; - } - lastValidCode = code; - colorUpdated(2); //for notifier, IR is considered a button input + case IR6_MUTE: effectCurrent = 0; effectPalette = 0; colorFromUint32(COLOR_WHITE); bri=255; break; + } + lastValidCode = code; } From a0b208cca0dff3147e82472797963816b02aa2ad Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 22 Feb 2020 10:18:18 -0500 Subject: [PATCH 047/509] Added new user mod for Wemos shield (#701) --- .../readme.md | 23 ++ .../wled06_usermod.ino | 216 ++++++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md create mode 100644 usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md new file mode 100644 index 000000000..be97d4b8c --- /dev/null +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -0,0 +1,23 @@ +# Wemos D1 mini and Wemos32 mini shield +## Project repository +- [Original repository](https://github.com/srg74/WLED-wemos-shield) - WLED Wemos shield repository +- [Wemos shield project Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) +- [Precompiled WLED firmware](https://github.com/srg74/WLED-wemos-shield/tree/master/resources/Firmware) +## Features +- SSD1306 128x32 or 128x64 I2C OLED display +- On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) +- Auto display shutoff for saving display lifetime +- Dallas temperature sensor +- Reporting temperature to MQTT broker +- Relay for energy saving + +## Hardware +![Shield](https://github.com/srg74/WLED-wemos-shield/blob/master/resources/Images/Assembly_8.jpg) + +## Functionality checked with +- Wemos D1 mini original v3.1 and clones +- Wemos32 mini +- PlatformIO +- SSD1306 128x32 I2C OLED display +- DS18B20 (temperature sensor) +- Push button (N.O. momentary switch) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino new file mode 100644 index 000000000..9e6e0b793 --- /dev/null +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino @@ -0,0 +1,216 @@ +#include // from https://github.com/olikraus/u8g2/ +#include //Dallastemperature sensor +#ifdef ARDUINO_ARCH_ESP32 //ESP32 boards +uint8_t SCL_PIN = 22; +uint8_t SDA_PIN = 21; +OneWire oneWire(23); +#else //ESP8266 boards +uint8_t SCL_PIN = 5; +uint8_t SDA_PIN = 4; +OneWire oneWire(13); +#endif +//The SCL and SDA pins are defined here. +//ESP8266 Wemos D1 mini board use SCL=5 SDA=4 while ESP32 Wemos32 mini board use SCL=22 SDA=21 +#define U8X8_PIN_SCL SCL_PIN +#define U8X8_PIN_SDA SDA_PIN + +// Dallas sensor +DallasTemperature sensor(&oneWire); +long temptimer = millis(); +long lastMeasure = 0; +#define Celsius // Show temperature mesaurement in Celcius otherwise is in Fahrenheit + +// If display does not work or looks corrupted check the +// constructor reference: +// https://github.com/olikraus/u8g2/wiki/u8x8setupcpp +// or check the gallery: +// https://github.com/olikraus/u8g2/wiki/gallery +// --> First choise of cheap I2C OLED 128X32 0.91" +U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA +// --> Second choise of cheap I2C OLED 128X64 0.96" or 1.3" +//U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA +// gets called once at boot. Do all initialization that doesn't depend on +// network here +void userSetup() { + sensor.begin(); //Start Dallas temperature sensor + u8x8.begin(); + u8x8.setPowerSave(0); + u8x8.setFlipMode(1); + u8x8.setContrast(10); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255 + u8x8.setFont(u8x8_font_chroma48medium8_r); + u8x8.drawString(0, 0, "Loading..."); +} + +// gets called every time WiFi is (re-)connected. Initialize own network +// interfaces here +void userConnected() {} + +// needRedraw marks if redraw is required to prevent often redrawing. +bool needRedraw = true; + +// Next variables hold the previous known values to determine if redraw is +// required. +String knownSsid = ""; +IPAddress knownIp; +uint8_t knownBrightness = 0; +uint8_t knownMode = 0; +uint8_t knownPalette = 0; + +long lastUpdate = 0; +long lastRedraw = 0; +bool displayTurnedOff = false; +// How often we are redrawing screen +#define USER_LOOP_REFRESH_RATE_MS 5000 + +void userLoop() { + +//----> Dallas temperature sensor MQTT publishing + temptimer = millis(); +// Timer to publishe new temperature every 60 seconds + if (temptimer - lastMeasure > 60000) + { + lastMeasure = temptimer; +//Check if MQTT Connected, otherwise it will crash the 8266 + if (mqtt != nullptr) + { + sensor.requestTemperatures(); +//Gets prefered temperature scale based on selection in definitions section + #ifdef Celsius + float board_temperature = sensor.getTempCByIndex(0); + #else + float board_temperature = sensor.getTempFByIndex(0); + #endif +//Create character string populated with user defined device topic from the UI, and the read temperature. Then publish to MQTT server. + char subuf[38]; + strcpy(subuf, mqttDeviceTopic); + strcat(subuf, "/temperature"); + mqtt->publish(subuf, 0, true, String(board_temperature).c_str()); + } + } + + // Check if we time interval for redrawing passes. + if (millis() - lastUpdate < USER_LOOP_REFRESH_RATE_MS) { + return; + } + lastUpdate = millis(); + + // Turn off display after 3 minutes with no change. + if(!displayTurnedOff && millis() - lastRedraw > 3*60*1000) { + u8x8.setPowerSave(1); + displayTurnedOff = true; + } + + // Check if values which are shown on display changed from the last time. + if (((apActive) ? String(apSSID) : WiFi.SSID()) != knownSsid) { + needRedraw = true; + } else if (knownIp != (apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP())) { + needRedraw = true; + } else if (knownBrightness != bri) { + needRedraw = true; + } else if (knownMode != strip.getMode()) { + needRedraw = true; + } else if (knownPalette != strip.getSegment(0).palette) { + needRedraw = true; + } + + if (!needRedraw) { + return; + } + needRedraw = false; + + if (displayTurnedOff) + { + u8x8.setPowerSave(0); + displayTurnedOff = false; + } + lastRedraw = millis(); + + // Update last known values. + #if defined(ESP8266) + knownSsid = apActive ? WiFi.softAPSSID() : WiFi.SSID(); + #else + knownSsid = WiFi.SSID(); + #endif + knownIp = apActive ? IPAddress(4, 3, 2, 1) : WiFi.localIP(); + knownBrightness = bri; + knownMode = strip.getMode(); + knownPalette = strip.getSegment(0).palette; + u8x8.clear(); + u8x8.setFont(u8x8_font_chroma48medium8_r); + + // First row with Wifi name + u8x8.setCursor(1, 0); + u8x8.print(knownSsid.substring(0, u8x8.getCols() > 1 ? u8x8.getCols() - 2 : 0)); + // Print `~` char to indicate that SSID is longer, than owr dicplay + if (knownSsid.length() > u8x8.getCols()) + u8x8.print("~"); + + // Second row with IP or Psssword + u8x8.setCursor(1, 1); + // Print password in AP mode and if led is OFF. + if (apActive && bri == 0) + u8x8.print(apPass); + else + u8x8.print(knownIp); + + // Third row with mode name + u8x8.setCursor(2, 2); + uint8_t qComma = 0; + bool insideQuotes = false; + uint8_t printedChars = 0; + char singleJsonSymbol; + + // Find the mode name in JSON + for (size_t i = 0; i < strlen_P(JSON_mode_names); i++) { + singleJsonSymbol = pgm_read_byte_near(JSON_mode_names + i); + switch (singleJsonSymbol) { + case '"': + insideQuotes = !insideQuotes; + break; + case '[': + case ']': + break; + case ',': + qComma++; + default: + if (!insideQuotes || (qComma != knownMode)) + break; + u8x8.print(singleJsonSymbol); + printedChars++; + } + if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2)) + break; + } + // Fourth row with palette name + u8x8.setCursor(2, 3); + qComma = 0; + insideQuotes = false; + printedChars = 0; + // Looking for palette name in JSON. + for (size_t i = 0; i < strlen_P(JSON_palette_names); i++) { + singleJsonSymbol = pgm_read_byte_near(JSON_palette_names + i); + switch (singleJsonSymbol) { + case '"': + insideQuotes = !insideQuotes; + break; + case '[': + case ']': + break; + case ',': + qComma++; + default: + if (!insideQuotes || (qComma != knownPalette)) + break; + u8x8.print(singleJsonSymbol); + printedChars++; + } + if ((qComma > knownMode) || (printedChars > u8x8.getCols() - 2)) + break; + } + + u8x8.setFont(u8x8_font_open_iconic_embedded_1x1); + u8x8.drawGlyph(0, 0, 80); // wifi icon + u8x8.drawGlyph(0, 1, 68); // home icon + u8x8.setFont(u8x8_font_open_iconic_weather_2x2); + u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon +} From 447594b5ea2f1c6d323cb983bf97f83bdad91bbd Mon Sep 17 00:00:00 2001 From: Debashish Sahu Date: Sat, 22 Feb 2020 10:19:05 -0500 Subject: [PATCH 048/509] PIO cleanup and ESP8266/32 core bump (#699) * Try to fix TravisCI * Bump ESP8266/ESP32 core version Co-authored-by: Aircoookie --- platformio.ini | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/platformio.ini b/platformio.ini index 154406606..dd5f7a73c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -77,12 +77,14 @@ arduino_core_2_5_0 = espressif8266@2.0.4 arduino_core_2_5_2 = espressif8266@2.2.3 arduino_core_2_6_1 = espressif8266@2.3.0 arduino_core_2_6_2 = espressif8266@2.3.1 +arduino_core_2_6_3 = espressif8266@2.3.3 arduino_core_stage = https://github.com/platformio/platform-espressif8266.git#feature/stage -platform = ${common:esp8266.arduino_core_2_6_2} +platform = ${common:esp8266.arduino_core_2_6_3} build_flags = -D ESP8266 -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH -Wl,-Teagle.flash.4m1m.ld ;;;; Required for core > v2.5.0 or staging version 4MB Flash 3MB SPIFFs +lib_ignore = AsyncTCP [common:esp8266_1M] platform = espressif8266@1.8.0 @@ -96,6 +98,7 @@ build_flags = -D WLED_DISABLE_CRONIXIE ; -D WLED_DISABLE_HUESYNC ; -D WLED_DISABLE_INFRARED +lib_ignore = ${common:esp8266.lib_ignore} [common:esp8266_512k] platform = espressif8266@1.8.0 @@ -109,12 +112,16 @@ build_flags = -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC ; -D WLED_DISABLE_INFRARED +lib_ignore = ${common:esp8266.lib_ignore} [common:esp32] -platform = espressif32@1.11.1 +platform = espressif32@1.11.2 build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH -D ARDUINO_ARCH_ESP32 +lib_ignore = + ESPAsyncTCP + ESPAsyncUDP # see: http://docs.platformio.org/en/latest/platforms/espressif8266.html [env:nodemcuv2] @@ -129,7 +136,7 @@ build_flags = lib_deps = ${common.lib_deps_external} lib_compat_mode = strict -lib_ignore = AsyncTCP +lib_ignore = ${common:esp8266.lib_ignore} [env:d1_mini] board = d1_mini @@ -143,7 +150,7 @@ build_flags = lib_deps = ${common.lib_deps_external} lib_compat_mode = strict -lib_ignore = AsyncTCP +lib_ignore = ${common:esp8266.lib_ignore} [env:esp01_1m] board = esp01_1m @@ -159,7 +166,7 @@ build_flags = lib_deps = ${common.lib_deps_external} lib_compat_mode = strict -lib_ignore = AsyncTCP +lib_ignore = ${common:esp8266.lib_ignore} [env:esp01] board = esp01 @@ -174,7 +181,7 @@ build_flags = lib_deps = ${common.lib_deps_external} lib_compat_mode = strict -lib_ignore = AsyncTCP +lib_ignore = ${common:esp8266.lib_ignore} [env:esp07] board = esp07 @@ -188,7 +195,7 @@ build_flags = lib_deps = ${common.lib_deps_external} lib_compat_mode = strict -lib_ignore = AsyncTCP +lib_ignore = ${common:esp8266.lib_ignore} # see: http://docs.platformio.org/en/latest/platforms/espressif32.html [env:esp32dev] @@ -202,8 +209,7 @@ build_flags = ${common:esp32.build_flags} lib_deps = ${common.lib_deps_external} -lib_ignore = - ESPAsyncUDP +lib_ignore = ${common:esp32.lib_ignore} lib_compat_mode = strict [env:esp8285_4CH_MagicHome] @@ -220,7 +226,7 @@ build_flags = lib_deps = ${common.lib_deps_external} lib_compat_mode = strict -lib_ignore = AsyncTCP +lib_ignore = ${common:esp8266.lib_ignore} [env:esp8285_4CH_H801] board = esp8285 @@ -237,7 +243,7 @@ build_flags = lib_deps = ${common.lib_deps_external} lib_compat_mode = strict -lib_ignore = AsyncTCP +lib_ignore = ${common:esp8266.lib_ignore} [env:esp8285_5CH_H801] board = esp8285 @@ -255,5 +261,4 @@ build_flags = lib_deps = ${common.lib_deps_external} lib_compat_mode = strict -lib_ignore = AsyncTCP - +lib_ignore = ${common:esp8266.lib_ignore} From e621fdec0ca722f247c60a1895439d1926b12287 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Sat, 22 Feb 2020 17:20:34 +0100 Subject: [PATCH 049/509] Remove analog flicker (#678) * remove analog LED flicker run SetRgbwPwm from main loop and with GetPixelColor(0) to get all effects using fade_out() working. * correct unintended bitwise AND to logical AND * Update analogLastShow * new Arduino Core WaveForm library included * new Arduino Core only for 8266 * correct formating + define for MQTT_KEEP_ALIVE * fix for ESP32 * reduce scope of variable "done" * call analogWrite only if Color or Bri did change * Remove duplicate wifi sleep code Co-authored-by: Aircoookie --- wled00/FX.h | 9 +- wled00/FX_fcn.cpp | 34 ++ wled00/NpbWrapper.h | 39 +-- .../arduino/core_esp8266_waveform.cpp | 312 ++++++++++++++++++ .../arduino/core_esp8266_waveform.h | 71 ++++ wled00/wled00.ino | 16 + wled00/wled01_eeprom.ino | 2 +- wled00/wled05_init.ino | 4 +- wled00/wled17_mqtt.ino | 3 +- wled00/wled19_json.ino | 11 + 10 files changed, 464 insertions(+), 37 deletions(-) create mode 100644 wled00/src/dependencies/arduino/core_esp8266_waveform.cpp create mode 100644 wled00/src/dependencies/arduino/core_esp8266_waveform.h diff --git a/wled00/FX.h b/wled00/FX.h index 9f1fda411..eec42990e 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -415,7 +415,8 @@ class WS2812FX { resetSegments(), setPixelColor(uint16_t n, uint32_t c), setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), - show(void); + show(void), + setRgbwPwm(void); bool reverseMode = false, @@ -627,6 +628,12 @@ class WS2812FX { uint32_t _lastPaletteChange = 0; uint32_t _lastShow = 0; + #ifdef WLED_USE_ANALOG_LEDS + uint32_t _analogLastShow = 0; + uint32_t _analogLastColor = 0; + uint8_t _analogLastBri = 0; + #endif + uint8_t _segment_index = 0; uint8_t _segment_index_palette_last = 99; segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 24 bytes per element diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 73ddbf794..0707392d2 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -829,6 +829,40 @@ bool WS2812FX::segmentsAreIdentical(Segment* a, Segment* b) return true; } +#ifdef WLED_USE_ANALOG_LEDS +void WS2812FX::setRgbwPwm(void) { + uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days + if (nowUp - _analogLastShow < MIN_SHOW_DELAY) return; + + _analogLastShow = nowUp; + + RgbwColor color = bus->GetPixelColorRgbw(0); + byte b = getBrightness(); + if (color == _analogLastColor && b == _analogLastBri) return; + + // check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp + #ifdef WLED_USE_5CH_LEDS + if (color.R == 255 && color.G == 255 && color.B == 255 && color.W == 255) { + bus->SetRgbwPwm(0, 0, 0, 0, color.W * b / 255); + } else if (color.R == 127 && color.G == 127 && color.B == 127 && color.W == 255) { + bus->SetRgbwPwm(0, 0, 0, color.W * b / 512, color.W * b / 255); + } else if (color.R == 0 && color.G == 0 && color.B == 0 && color.W == 255) { + bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); + } else if (color.R == 130 && color.G == 90 && color.B == 0 && color.W == 255) { + bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, color.W * b / 512); + } else if (color.R == 255 && color.G == 153 && color.B == 0 && color.W == 255) { + bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); + } else { // not only white colors + bus->SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255); + } + #else + bus->SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255); + #endif +} +#else +void WS2812FX::setRgbwPwm() {} +#endif + //gamma 2.4 lookup table used for color correction const byte gammaT[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 54d21ac18..a9fbd7c2e 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -3,7 +3,9 @@ #define NpbWrapper_h //PIN CONFIGURATION +#ifndef LEDPIN #define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) +#endif //#define USE_APA102 // Uncomment for using APA102 LEDs. //#define USE_WS2801 // Uncomment for using WS2801 LEDs (make sure you have NeoPixelBus v2.5.6 or newer) //#define USE_LPD8806 // Uncomment for using LPD8806 @@ -164,7 +166,7 @@ public: #endif } #else // ESP8266 - //init PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller + //init PWM pins pinMode(RPIN, OUTPUT); pinMode(GPIN, OUTPUT); pinMode(BPIN, OUTPUT); @@ -185,9 +187,9 @@ public: void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t w2=0) { #ifdef ARDUINO_ARCH_ESP32 - ledcWrite(0, r); //RPIN - ledcWrite(1, g); //GPIN - ledcWrite(2, b); //BPIN + ledcWrite(0, r); + ledcWrite(1, g); + ledcWrite(2, b); switch (_type) { case NeoPixelType_Grb: break; #ifdef WLED_USE_5CH_LEDS @@ -196,7 +198,7 @@ public: case NeoPixelType_Grbw: ledcWrite(3, w); break; #endif } - #else + #else // ESP8266 analogWrite(RPIN, r); analogWrite(GPIN, g); analogWrite(BPIN, b); @@ -227,11 +229,6 @@ public: switch (_type) { case NeoPixelType_Grb: { _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); - #ifdef WLED_USE_ANALOG_LEDS - if (indexPixel != 0) return; //set analog LEDs from first pixel - byte b = _pGrb->GetBrightness(); - SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, 0); - #endif } break; case NeoPixelType_Grbw: { @@ -240,28 +237,6 @@ public: #else _pGrbw->SetPixelColor(indexPixel, color); #endif - #ifdef WLED_USE_ANALOG_LEDS - if (indexPixel != 0) return; //set analog LEDs from first pixel - byte b = _pGrbw->GetBrightness(); - // check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp - #ifdef WLED_USE_5CH_LEDS - if (color.R == 255 & color.G == 255 && color.B == 255 && color.W == 255) { - SetRgbwPwm(0, 0, 0, 0, color.W * b / 255); - } else if (color.R == 127 & color.G == 127 && color.B == 127 && color.W == 255) { - SetRgbwPwm(0, 0, 0, color.W * b / 512, color.W * b / 255); - } else if (color.R == 0 & color.G == 0 && color.B == 0 && color.W == 255) { - SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); - } else if (color.R == 130 & color.G == 90 && color.B == 0 && color.W == 255) { - SetRgbwPwm(0, 0, 0, color.W * b / 255, color.W * b / 512); - } else if (color.R == 255 & color.G == 153 && color.B == 0 && color.W == 255) { - SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); - } else { // not only white colors - SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255); - } - #else - SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255); - #endif - #endif } break; } diff --git a/wled00/src/dependencies/arduino/core_esp8266_waveform.cpp b/wled00/src/dependencies/arduino/core_esp8266_waveform.cpp new file mode 100644 index 000000000..6a52b1b3a --- /dev/null +++ b/wled00/src/dependencies/arduino/core_esp8266_waveform.cpp @@ -0,0 +1,312 @@ +/* + esp8266_waveform - General purpose waveform generation and control, + supporting outputs on all pins in parallel. + + Copyright (c) 2018 Earle F. Philhower, III. All rights reserved. + + The core idea is to have a programmable waveform generator with a unique + high and low period (defined in microseconds). TIMER1 is set to 1-shot + mode and is always loaded with the time until the next edge of any live + waveforms. + + Up to one waveform generator per pin supported. + + Each waveform generator is synchronized to the ESP cycle counter, not the + timer. This allows for removing interrupt jitter and delay as the counter + always increments once per 80MHz clock. Changes to a waveform are + contiguous and only take effect on the next waveform transition, + allowing for smooth transitions. + + This replaces older tone(), analogWrite(), and the Servo classes. + + Everywhere in the code where "cycles" is used, it means ESP.getCycleTime() + cycles, not TIMER1 cycles (which may be 2 CPU clocks @ 160MHz). + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifdef ESP8266 +#include +#include "ets_sys.h" +#include "core_esp8266_waveform.h" + +extern "C" { + +// Maximum delay between IRQs +#define MAXIRQUS (10000) + +// Set/clear GPIO 0-15 by bitmask +#define SetGPIO(a) do { GPOS = a; } while (0) +#define ClearGPIO(a) do { GPOC = a; } while (0) + +// Waveform generator can create tones, PWM, and servos +typedef struct { + uint32_t nextServiceCycle; // ESP cycle timer when a transition required + uint32_t expiryCycle; // For time-limited waveform, the cycle when this waveform must stop + uint32_t nextTimeHighCycles; // Copy over low->high to keep smooth waveform + uint32_t nextTimeLowCycles; // Copy over high->low to keep smooth waveform +} Waveform; + +static Waveform waveform[17]; // State of all possible pins +static volatile uint32_t waveformState = 0; // Is the pin high or low, updated in NMI so no access outside the NMI code +static volatile uint32_t waveformEnabled = 0; // Is it actively running, updated in NMI so no access outside the NMI code + +// Enable lock-free by only allowing updates to waveformState and waveformEnabled from IRQ service routine +static volatile uint32_t waveformToEnable = 0; // Message to the NMI handler to start a waveform on a inactive pin +static volatile uint32_t waveformToDisable = 0; // Message to the NMI handler to disable a pin from waveform generation + +static uint32_t (*timer1CB)() = NULL; + + +// Non-speed critical bits +#pragma GCC optimize ("Os") + +static inline ICACHE_RAM_ATTR uint32_t GetCycleCount() { + uint32_t ccount; + __asm__ __volatile__("esync; rsr %0,ccount":"=a"(ccount)); + return ccount; +} + +// Interrupt on/off control +static ICACHE_RAM_ATTR void timer1Interrupt(); +static bool timerRunning = false; + +static void initTimer() { + timer1_disable(); + ETS_FRC_TIMER1_INTR_ATTACH(NULL, NULL); + ETS_FRC_TIMER1_NMI_INTR_ATTACH(timer1Interrupt); + timer1_enable(TIM_DIV1, TIM_EDGE, TIM_SINGLE); + timerRunning = true; +} + +static void ICACHE_RAM_ATTR deinitTimer() { + ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL); + timer1_disable(); + timer1_isr_init(); + timerRunning = false; +} + +// Set a callback. Pass in NULL to stop it +void setTimer1Callback(uint32_t (*fn)()) { + timer1CB = fn; + if (!timerRunning && fn) { + initTimer(); + timer1_write(microsecondsToClockCycles(1)); // Cause an interrupt post-haste + } else if (timerRunning && !fn && !waveformEnabled) { + deinitTimer(); + } +} + +// Start up a waveform on a pin, or change the current one. Will change to the new +// waveform smoothly on next low->high transition. For immediate change, stopWaveform() +// first, then it will immediately begin. +int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS) { + if ((pin > 16) || isFlashInterfacePin(pin)) { + return false; + } + Waveform *wave = &waveform[pin]; + // Adjust to shave off some of the IRQ time, approximately + wave->nextTimeHighCycles = microsecondsToClockCycles(timeHighUS); + wave->nextTimeLowCycles = microsecondsToClockCycles(timeLowUS); + wave->expiryCycle = runTimeUS ? GetCycleCount() + microsecondsToClockCycles(runTimeUS) : 0; + if (runTimeUS && !wave->expiryCycle) { + wave->expiryCycle = 1; // expiryCycle==0 means no timeout, so avoid setting it + } + + uint32_t mask = 1<nextServiceCycle = GetCycleCount() + microsecondsToClockCycles(1); + waveformToEnable |= mask; + if (!timerRunning) { + initTimer(); + timer1_write(microsecondsToClockCycles(10)); + } else { + // Ensure timely service.... + if (T1L > microsecondsToClockCycles(10)) { + timer1_write(microsecondsToClockCycles(10)); + } + } + while (waveformToEnable) { + delay(0); // Wait for waveform to update + } + } + + return true; +} + +// Speed critical bits +#pragma GCC optimize ("O2") +// Normally would not want two copies like this, but due to different +// optimization levels the inline attribute gets lost if we try the +// other version. + +static inline ICACHE_RAM_ATTR uint32_t GetCycleCountIRQ() { + uint32_t ccount; + __asm__ __volatile__("rsr %0,ccount":"=a"(ccount)); + return ccount; +} + +static inline ICACHE_RAM_ATTR uint32_t min_u32(uint32_t a, uint32_t b) { + if (a < b) { + return a; + } + return b; +} + +// Stops a waveform on a pin +int ICACHE_RAM_ATTR stopWaveform(uint8_t pin) { + // Can't possibly need to stop anything if there is no timer active + if (!timerRunning) { + return false; + } + // If user sends in a pin >16 but <32, this will always point to a 0 bit + // If they send >=32, then the shift will result in 0 and it will also return false + uint32_t mask = 1< microsecondsToClockCycles(10)) { + timer1_write(microsecondsToClockCycles(10)); + } + while (waveformToDisable) { + /* no-op */ // Can't delay() since stopWaveform may be called from an IRQ + } + if (!waveformEnabled && !timer1CB) { + deinitTimer(); + } + return true; +} + +// The SDK and hardware take some time to actually get to our NMI code, so +// decrement the next IRQ's timer value by a bit so we can actually catch the +// real CPU cycle counter we want for the waveforms. +#if F_CPU == 80000000 + #define DELTAIRQ (microsecondsToClockCycles(3)) +#else + #define DELTAIRQ (microsecondsToClockCycles(2)) +#endif + + +static ICACHE_RAM_ATTR void timer1Interrupt() { + // Optimize the NMI inner loop by keeping track of the min and max GPIO that we + // are generating. In the common case (1 PWM) these may be the same pin and + // we can avoid looking at the other pins. + static int startPin = 0; + static int endPin = 0; + + uint32_t nextEventCycles = microsecondsToClockCycles(MAXIRQUS); + uint32_t timeoutCycle = GetCycleCountIRQ() + microsecondsToClockCycles(14); + + if (waveformToEnable || waveformToDisable) { + // Handle enable/disable requests from main app. + waveformEnabled = (waveformEnabled & ~waveformToDisable) | waveformToEnable; // Set the requested waveforms on/off + waveformState &= ~waveformToEnable; // And clear the state of any just started + waveformToEnable = 0; + waveformToDisable = 0; + // Find the first GPIO being generated by checking GCC's find-first-set (returns 1 + the bit of the first 1 in an int32_t) + startPin = __builtin_ffs(waveformEnabled) - 1; + // Find the last bit by subtracting off GCC's count-leading-zeros (no offset in this one) + endPin = 32 - __builtin_clz(waveformEnabled); + } + + if (waveformEnabled) { + bool done = false; + do { + nextEventCycles = microsecondsToClockCycles(MAXIRQUS); + for (int i = startPin; i <= endPin; i++) { + uint32_t mask = 1<expiryCycle) { + int32_t expiryToGo = wave->expiryCycle - now; + if (expiryToGo < 0) { + // Done, remove! + waveformEnabled &= ~mask; + if (i == 16) { + GP16O &= ~1; + } else { + ClearGPIO(mask); + } + continue; + } + } + + // Check for toggles + int32_t cyclesToGo = wave->nextServiceCycle - now; + if (cyclesToGo < 0) { + cyclesToGo = -((-cyclesToGo) % (wave->nextTimeHighCycles + wave->nextTimeLowCycles)); + waveformState ^= mask; + if (waveformState & mask) { + if (i == 16) { + GP16O |= 1; // GPIO16 write slow as it's RMW + } else { + SetGPIO(mask); + } + wave->nextServiceCycle = now + wave->nextTimeHighCycles + cyclesToGo; + nextEventCycles = min_u32(nextEventCycles, min_u32(wave->nextTimeHighCycles + cyclesToGo, 1)); + } else { + if (i == 16) { + GP16O &= ~1; // GPIO16 write slow as it's RMW + } else { + ClearGPIO(mask); + } + wave->nextServiceCycle = now + wave->nextTimeLowCycles + cyclesToGo; + nextEventCycles = min_u32(nextEventCycles, min_u32(wave->nextTimeLowCycles + cyclesToGo, 1)); + } + } else { + uint32_t deltaCycles = wave->nextServiceCycle - now; + nextEventCycles = min_u32(nextEventCycles, deltaCycles); + } + } + + // Exit the loop if we've hit the fixed runtime limit or the next event is known to be after that timeout would occur + uint32_t now = GetCycleCountIRQ(); + int32_t cycleDeltaNextEvent = timeoutCycle - (now + nextEventCycles); + int32_t cyclesLeftTimeout = timeoutCycle - now; + done = (cycleDeltaNextEvent < 0) || (cyclesLeftTimeout < 0); + } while (!done); + } // if (waveformEnabled) + + if (timer1CB) { + nextEventCycles = min_u32(nextEventCycles, timer1CB()); + } + + if (nextEventCycles < microsecondsToClockCycles(10)) { + nextEventCycles = microsecondsToClockCycles(10); + } + nextEventCycles -= DELTAIRQ; + + // Do it here instead of global function to save time and because we know it's edge-IRQ +#if F_CPU == 160000000 + T1L = nextEventCycles >> 1; // Already know we're in range by MAXIRQUS +#else + T1L = nextEventCycles; // Already know we're in range by MAXIRQUS +#endif + TEIE |= TEIE1; // Edge int enable +} + +}; +#endif \ No newline at end of file diff --git a/wled00/src/dependencies/arduino/core_esp8266_waveform.h b/wled00/src/dependencies/arduino/core_esp8266_waveform.h new file mode 100644 index 000000000..24ce91fb3 --- /dev/null +++ b/wled00/src/dependencies/arduino/core_esp8266_waveform.h @@ -0,0 +1,71 @@ +/* + esp8266_waveform - General purpose waveform generation and control, + supporting outputs on all pins in parallel. + + Copyright (c) 2018 Earle F. Philhower, III. All rights reserved. + + The core idea is to have a programmable waveform generator with a unique + high and low period (defined in microseconds). TIMER1 is set to 1-shot + mode and is always loaded with the time until the next edge of any live + waveforms. + + Up to one waveform generator per pin supported. + + Each waveform generator is synchronized to the ESP cycle counter, not the + timer. This allows for removing interrupt jitter and delay as the counter + always increments once per 80MHz clock. Changes to a waveform are + contiguous and only take effect on the next waveform transition, + allowing for smooth transitions. + + This replaces older tone(), analogWrite(), and the Servo classes. + + Everywhere in the code where "cycles" is used, it means ESP.getCycleTime() + cycles, not TIMER1 cycles (which may be 2 CPU clocks @ 160MHz). + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#ifndef __ESP8266_WAVEFORM_H +#define __ESP8266_WAVEFORM_H + +#ifdef __cplusplus +extern "C" { +#endif + +// Start or change a waveform of the specified high and low times on specific pin. +// If runtimeUS > 0 then automatically stop it after that many usecs. +// Returns true or false on success or failure. +int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS); +// Stop a waveform, if any, on the specified pin. +// Returns true or false on success or failure. +int stopWaveform(uint8_t pin); + +// Add a callback function to be called on *EVERY* timer1 trigger. The +// callback returns the number of microseconds until the next desired call. +// However, since it is called every timer1 interrupt, it may be called +// again before this period. It should therefore use the ESP Cycle Counter +// to determine whether or not to perform an operation. +// Pass in NULL to disable the callback and, if no other waveforms being +// generated, stop the timer as well. +// Make sure the CB function has the ICACHE_RAM_ATTR decorator. +void setTimer1Callback(uint32_t (*fn)()); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wled00/wled00.ino b/wled00/wled00.ino index c04258f06..ee97c85f5 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -93,6 +93,18 @@ #include #endif +// remove flicker because PWM signal of RGB channels can become out of phase +#if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266) + #include "src/dependencies/arduino/core_esp8266_waveform.h" +#endif + +// enable additional debug output +#ifdef WLED_DEBUG + #ifndef ESP8266 + #include + #endif +#endif + //version code in format yymmddb (b = daily build) #define VERSION 2002192 @@ -526,6 +538,10 @@ void loop() { handleOverlays(); yield(); + #ifdef WLED_USE_ANALOG_LEDS + strip.setRgbwPwm(); + #endif + if (doReboot) reset(); if (!realtimeMode) //block stuff if WARLS/Adalight is enabled diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index 40b01ae50..84e865292 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -3,7 +3,7 @@ * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map */ -#define EEPSIZE 2560 +#define EEPSIZE 2560 //Maximum is 4096 //eeprom Version code, enables default settings instead of 0 init on update #define EEPVER 16 diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 820670c82..c4f0b45bd 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -194,10 +194,10 @@ void initConnection() WiFi.begin(clientSSID, clientPass); #ifdef ARDUINO_ARCH_ESP32 - if (noWifiSleep) WiFi.setSleep(false); + WiFi.setSleep(!noWifiSleep); WiFi.setHostname(serverDescription); #else - if (noWifiSleep) wifi_set_sleep_type(NONE_SLEEP_T); + wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); #endif } diff --git a/wled00/wled17_mqtt.ino b/wled00/wled17_mqtt.ino index db34a742b..741c807f8 100644 --- a/wled00/wled17_mqtt.ino +++ b/wled00/wled17_mqtt.ino @@ -3,6 +3,7 @@ */ #ifdef WLED_ENABLE_MQTT +#define MQTT_KEEP_ALIVE_TIME 60 // contact the MQTT broker every 60 seconds void parseMQTTBriPayload(char* payload) { @@ -129,7 +130,7 @@ bool initMqtt() strcpy(mqttStatusTopic, mqttDeviceTopic); strcat(mqttStatusTopic, "/status"); mqtt->setWill(mqttStatusTopic, 0, true, "offline"); - mqtt->setKeepAlive(60); + mqtt->setKeepAlive(MQTT_KEEP_ALIVE_TIME); mqtt->connect(); return true; } diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index 852dfdacf..6bf9aafda 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -267,14 +267,25 @@ void serializeInfo(JsonObject root) wifi_info["channel"] = WiFi.channel(); #ifdef ARDUINO_ARCH_ESP32 + #ifdef WLED_DEBUG + wifi_info["txPower"] = (int) WiFi.getTxPower(); + wifi_info["sleep"] = (bool) WiFi.getSleep(); + #endif root["arch"] = "esp32"; root["core"] = ESP.getSdkVersion(); //root["maxalloc"] = ESP.getMaxAllocHeap(); + #ifdef WLED_DEBUG + root["resetReason0"] = (int)rtc_get_reset_reason(0); + root["resetReason1"] = (int)rtc_get_reset_reason(1); + #endif root["lwip"] = 0; #else root["arch"] = "esp8266"; root["core"] = ESP.getCoreVersion(); //root["maxalloc"] = ESP.getMaxFreeBlockSize(); + #ifdef WLED_DEBUG + root["resetReason"] = (int)ESP.getResetInfoPtr()->reason; + #endif root["lwip"] = LWIP_VERSION_MAJOR; #endif From c66af86d88fae5e0b26fd9390ed13f73c53f8769 Mon Sep 17 00:00:00 2001 From: pille Date: Sat, 22 Feb 2020 18:13:21 +0100 Subject: [PATCH 050/509] fix out-of-sync detection on E1.31 packets --- wled00/wled07_notify.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino index 6af7416bc..fd83f1f81 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled07_notify.ino @@ -91,13 +91,12 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ //E1.31 protocol support // skip out-of-sequence packets - if (p->sequence_number < e131LastSequenceNumber && p->sequence_number - e131LastSequenceNumber > -20){ + if (p->sequence_number < e131LastSequenceNumber && p->sequence_number > 20 && e131LastSequenceNumber < 250){ DEBUG_PRINT("skipping E1.31 frame (last seq="); DEBUG_PRINT(e131LastSequenceNumber); DEBUG_PRINT(", current seq="); DEBUG_PRINT(p->sequence_number); DEBUG_PRINTLN(")"); - e131LastSequenceNumber = p->sequence_number; return; } e131LastSequenceNumber = p->sequence_number; From 392277100c80ab9be062c71345d6d8361189e188 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sun, 23 Feb 2020 02:18:25 +0100 Subject: [PATCH 051/509] Release of WLED v0.9.1 --- wled00/wled08_led.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index 124e43bd6..8aeac5dfb 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -79,7 +79,7 @@ bool colorChanged() { if (col[i] != colIT[i]) return true; if (colSec[i] != colSecIT[i]) return true; - if (col[i] != colNlT[i]) return true; + //if (col[i] != colNlT[i]) return true; (this effectively made the ESP send out sync packets every time colorUpdated() is called, even if nothing changed) } if (bri != briIT) return true; return false; From 513bc2c0ab1577dff4638592277c9f5f89019938 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Sun, 23 Feb 2020 22:21:32 +0100 Subject: [PATCH 052/509] Correct SunRise/NightLight with Color Fade (#710) --- wled00/wled08_led.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index 8aeac5dfb..d1ccc0d66 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -231,15 +231,15 @@ void handleNightlight() nightlightDelayMs = (int)(nightlightDelayMins*60000); nightlightActiveOld = true; briNlT = bri; - for (byte i=0; i<4; i++) colNlT[i] = col[i]; // remember starting color + for (byte i=0; i<4; i++) colNlT[i] = colT[i]; // remember starting color } float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs); if (nightlightFade) { bri = briNlT + ((nightlightTargetBri - briNlT)*nper); - if (nightlightColorFade) // color fading only is enabled with "NF=2" + if (nightlightColorFade) // color fading only is enabled with "NF=2" { - for (byte i=0; i<4; i++) col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color + for (byte i=0; i<4; i++) colT[i] = colNlT[i]+ ((colSecT[i] - colNlT[i])*nper); // fading from actual color to secondary color } colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); } From 8be72f6f2353e87c36a4ee93804fa83793128b23 Mon Sep 17 00:00:00 2001 From: jwingefeld Date: Sun, 23 Feb 2020 22:24:51 +0100 Subject: [PATCH 053/509] DMX Support for WLED (#704) * initial dmx setup * adds support for multiple fixtures, addr gaps, start addresses and all that good DMX stuff * removes init function. do not need. * adds some comments, removes others. words. * added menu entry and dummy HTML * added server request handler * cloned options page UI for DMX * only add code when DMX is enabled * added infobutton to HTML * DMX settings form * procedurally generated HTML form. OBACHT: Values still not coming from the EEPROM. * upped eeprom version to 15 * changed index for set to 255 to 6 because web interface wants it that way * gets values for XML from actual settings * changes the default values for dmx to blanks * reads and writes DMX settings from EEPROM (2550 - 2569) * fixes addressing bug in DMX EEPROM read * saves settings from WebUI to memory * disables DMX by default * changed a comment in the ENABLE_DMX line * makes the display of the DMX entry in settings dependant on WLED_DMX_ENABLE * adds the server listener for the DMX map * fixes a bug when selecting 255 for a channel at the dmx settings page * now actually reads the DMX settings back to the HTML UI. * cleans up a little * adds a warning message to the HTML UI when setting up defunct DMX settings * changed DMX EEPROM addressing to close a gap * basic DMX map * fixes a few styling flaws and bugs in the DMX map * changes config variables to uint16_t Co-authored-by: Aircoookie --- wled00/html_other.h | 30 +++++++ wled00/html_settings.h | 69 +++++++++++++-- wled00/wled00.ino | 187 +++++++++++++++++++++------------------ wled00/wled01_eeprom.ino | 26 +++++- wled00/wled02_xml.ino | 27 +++++- wled00/wled03_set.ino | 28 +++++- wled00/wled05_init.ino | 4 +- wled00/wled18_server.ino | 49 +++++++++- wled00/wled21_dmx.ino | 55 ++++++++++++ 9 files changed, 378 insertions(+), 97 deletions(-) create mode 100644 wled00/wled21_dmx.ino diff --git a/wled00/html_other.h b/wled00/html_other.h index c7d3e855a..e27c64dde 100644 --- a/wled00/html_other.h +++ b/wled00/html_other.h @@ -15,6 +15,36 @@ const char PAGE_msg[] PROGMEM = R"=====(

%MSG%)====="; +//DMX channel map +const char PAGE_dmxmap[] PROGMEM = R"=====( + +DMX Map + + +
...
)====="; + //firmware update page const char PAGE_update[] PROGMEM = R"=====( diff --git a/wled00/html_settings.h b/wled00/html_settings.h index a3ba54a2e..157d6b4ca 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -1,23 +1,23 @@ /* - * Settings html - */ + Settings html +*/ //common CSS of settings pages const char PAGE_settingsCss[] PROGMEM = R"=====()====="; - //settings menu const char PAGE_settings[] PROGMEM = R"=====( -WLED Settings +WLED Settings
-
+
%DMXMENU%
+ )====="; @@ -172,6 +172,64 @@ Skip first LED:
)====="; +#ifdef WLED_ENABLE_DMX +//DMX Output settings +const char PAGE_settings_dmx[] PROGMEM = R"=====( +DMX Settings"); } diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index f7485917d..0f2cb9ef3 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -27,8 +27,9 @@ bool isAsterisksOnly(const char* str, byte maxLen) //called upon POST settings form submit void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) { - //0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec - if (subPage <1 || subPage >6) return; + + //0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 7: DMX + if (subPage <1 || subPage >7) return; //WIFI SETTINGS if (subPage == 1) @@ -293,6 +294,29 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) aOtaEnabled = request->hasArg("AO"); } } + #ifdef WLED_ENABLE_DMX // include only if DMX is enabled + if (subPage == 7) + { + int t = request->arg("CN").toInt(); + if (t>0 && t<16) { + DMXChannels = t; + } + t = request->arg("CS").toInt(); + if (t>0 && t<513) { + DMXStart = t; + } + t = request->arg("CG").toInt(); + if (t>0 && t<513) { + DMXGap = t; + } + for (int i=0; i<15; i++) { + String argname = "CH" + String((i+1)); + t = request->arg(argname).toInt(); + DMXFixtureMap[i] = t; + } + } + + #endif if (subPage != 6 || !doReboot) saveSettingsToEEPROM(); //do not save if factory reset if (subPage == 2) { strip.init(useRGBW,ledCount,skipFirstLed); diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index c4f0b45bd..bf1be5d99 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -83,7 +83,9 @@ void wledInit() if (strlen(cmDNS) > 0) ArduinoOTA.setHostname(cmDNS); } #endif - + #ifdef WLED_ENABLE_DMX + dmx.init(512); // initialize with bus length + #endif //HTTP server page init initServer(); } diff --git a/wled00/wled18_server.ino b/wled00/wled18_server.ino index f7162d3e5..cf67e79f8 100644 --- a/wled00/wled18_server.ino +++ b/wled00/wled18_server.ino @@ -82,6 +82,11 @@ void initServer() serveMessage(request, 200,"UI settings saved.","Redirecting...",1); }); + server.on("/settings/dmx", HTTP_POST, [](AsyncWebServerRequest *request){ + handleSettingsSet(request, 7); + serveMessage(request, 200,"UI settings saved.","Redirecting...",1); + }); + server.on("/settings/sync", HTTP_POST, [](AsyncWebServerRequest *request){ handleSettingsSet(request, 4); serveMessage(request, 200,"Sync settings saved.","Redirecting...",1); @@ -201,6 +206,16 @@ void initServer() }); } + + #ifdef WLED_ENABLE_DMX + server.on("/dmxmap", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send_P(200, "text/html", PAGE_dmxmap , dmxProcessor); + }); + #else + server.on("/dmxmap", HTTP_GET, [](AsyncWebServerRequest *request){ + serveMessage(request, 501, "Not implemented", "DMX support is not enabled in this build.", 254); + }); + #endif server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ if (captivePortal(request)) return; serveIndexOrWelcome(request); @@ -301,10 +316,38 @@ String settingsProcessor(const String& var) getSettingsJS(optionType, buf); return String(buf); } + + #ifdef WLED_ENABLE_DMX + + if (var == "DMXMENU") { + return String("
"); + } + + #endif if (var == "SCSS") return String(FPSTR(PAGE_settingsCss)); return String(); } +String dmxProcessor(const String& var) +{ + String mapJS; + #ifdef WLED_ENABLE_DMX + if (var == "DMXVARS") { + mapJS += "\nCN=" + String(DMXChannels) + ";\n"; + mapJS += "CS=" + String(DMXStart) + ";\n"; + mapJS += "CG=" + String(DMXGap) + ";\n"; + mapJS += "LC=" + String(ledCount) + ";\n"; + mapJS += "var CH=["; + for (int i=0;i<15;i++) { + mapJS += String(DMXFixtureMap[i]) + ","; + } + mapJS += "0];"; + } + #endif + + return mapJS; +} + void serveSettings(AsyncWebServerRequest* request) { @@ -318,6 +361,9 @@ void serveSettings(AsyncWebServerRequest* request) else if (url.indexOf("sync") > 0) subPage = 4; else if (url.indexOf("time") > 0) subPage = 5; else if (url.indexOf("sec") > 0) subPage = 6; + #ifdef WLED_ENABLE_DMX // include only if DMX is enabled + else if (url.indexOf("dmx") > 0) subPage = 7; + #endif } else subPage = 255; //welcome page if (subPage == 1 && wifiLock && otaLock) @@ -339,7 +385,8 @@ void serveSettings(AsyncWebServerRequest* request) case 4: request->send_P(200, "text/html", PAGE_settings_sync, settingsProcessor); break; case 5: request->send_P(200, "text/html", PAGE_settings_time, settingsProcessor); break; case 6: request->send_P(200, "text/html", PAGE_settings_sec , settingsProcessor); break; + case 7: request->send_P(200, "text/html", PAGE_settings_dmx , settingsProcessor); break; case 255: request->send_P(200, "text/html", PAGE_welcome); break; - default: request->send_P(200, "text/html", PAGE_settings); + default: request->send_P(200, "text/html", PAGE_settings , settingsProcessor); } } diff --git a/wled00/wled21_dmx.ino b/wled00/wled21_dmx.ino new file mode 100644 index 000000000..4230f07d8 --- /dev/null +++ b/wled00/wled21_dmx.ino @@ -0,0 +1,55 @@ +/* + * Support for DMX via MAX485. + * Needs the espdmx library. You might have to change the output pin within the library. Sketchy, i know. + * https://github.com/Rickgg/ESP-Dmx + */ +#ifdef WLED_ENABLE_DMX + +void handleDMX() { + // TODO: calculate brightness manually if no shutter channel is set + + uint8_t brightness = strip.getBrightness(); + + for (int i = 0; i < ledCount; i++) { // uses the amount of LEDs as fixture count + + uint32_t in = strip.getPixelColor(i); // time to get the colors for the individual fixtures as suggested by AirCookie at issue #462 + byte w = in >> 24 & 0xFF; + byte r = in >> 16 & 0xFF; + byte g = in >> 8 & 0xFF; + byte b = in & 0xFF; + + int DMXFixtureStart = DMXStart + (DMXGap * i); + for (int j = 0; j < DMXChannels; j++) { + int DMXAddr = DMXFixtureStart + j; + switch (DMXFixtureMap[j]) { + case 0: // Set this channel to 0. Good way to tell strobe- and fade-functions to fuck right off. + dmx.write(DMXAddr, 0); + break; + case 1: // Red + dmx.write(DMXAddr, r); + break; + case 2: // Green + dmx.write(DMXAddr, g); + break; + case 3: // Blue + dmx.write(DMXAddr, b); + break; + case 4: // White + dmx.write(DMXAddr, w); + break; + case 5: // Shutter channel. Controls the brightness. + dmx.write(DMXAddr, brightness); + break; + case 6:// Sets this channel to 255. Like 0, but more wholesome. + dmx.write(DMXAddr, 255); + break; + } + } + } + + dmx.update(); // update the DMX bus +} + +#else +void handleDMX() {} +#endif From 9a0db83f83c6cbfc4dcc17763dd6983de72086a6 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sun, 23 Feb 2020 21:03:36 -0500 Subject: [PATCH 054/509] Added Heltec WiFi-Kit-8 with 0.91" display --- .../Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino index 9e6e0b793..3b7a05fe8 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino @@ -2,7 +2,8 @@ #include //Dallastemperature sensor #ifdef ARDUINO_ARCH_ESP32 //ESP32 boards uint8_t SCL_PIN = 22; -uint8_t SDA_PIN = 21; +uint8_t SDA_PIN = 21; +// uint8_t RST_PIN = 16; // Uncoment for Heltec WiFi-Kit-8 OneWire oneWire(23); #else //ESP8266 boards uint8_t SCL_PIN = 5; @@ -13,7 +14,7 @@ OneWire oneWire(13); //ESP8266 Wemos D1 mini board use SCL=5 SDA=4 while ESP32 Wemos32 mini board use SCL=22 SDA=21 #define U8X8_PIN_SCL SCL_PIN #define U8X8_PIN_SDA SDA_PIN - +//#define U8X8_PIN_RESET RST_PIN // Uncoment for Heltec WiFi-Kit-8 // Dallas sensor DallasTemperature sensor(&oneWire); long temptimer = millis(); @@ -29,6 +30,8 @@ long lastMeasure = 0; U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA // --> Second choise of cheap I2C OLED 128X64 0.96" or 1.3" //U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA +// --> Third choise Heltec WiFi-Kit-8 with build-in OLED 128X32 0.91" +//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_RESET, U8X8_PIN_SCL, U8X8_PIN_SDA); // Constracor for Heltec WiFi-Kit-8 // gets called once at boot. Do all initialization that doesn't depend on // network here void userSetup() { From a8e7aa99e8b6ba7413175cee738a6288bfcd765e Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sun, 23 Feb 2020 22:48:58 -0500 Subject: [PATCH 055/509] Update wled06_usermod.ino --- usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino index 3b7a05fe8..5373d54fe 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino @@ -3,11 +3,11 @@ #ifdef ARDUINO_ARCH_ESP32 //ESP32 boards uint8_t SCL_PIN = 22; uint8_t SDA_PIN = 21; -// uint8_t RST_PIN = 16; // Uncoment for Heltec WiFi-Kit-8 OneWire oneWire(23); #else //ESP8266 boards uint8_t SCL_PIN = 5; uint8_t SDA_PIN = 4; +// uint8_t RST_PIN = 16; // Uncoment for Heltec WiFi-Kit-8 OneWire oneWire(13); #endif //The SCL and SDA pins are defined here. From e8fd5de5b26ec084d09e48749fb8608f6c182b5a Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 24 Feb 2020 12:18:30 +0100 Subject: [PATCH 056/509] HTML API "/url" for the current effect settings (#664) --- wled00/wled02_xml.ino | 47 ++++++++++++++++++++++++++++++++++++++++ wled00/wled18_server.ino | 4 ++++ 2 files changed, 51 insertions(+) diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index 561f7723d..e5083131d 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -99,6 +99,53 @@ char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr) if (request != nullptr) request->send(200, "text/xml", obuf); } +char* URL_response(AsyncWebServerRequest *request) +{ + char sbuf[256]; //allocate local buffer if none passed + char s2buf[100]; + obuf = s2buf; + olen = 0; + + char s[16]; + oappend("http://"); + IPAddress localIP = WiFi.localIP(); + sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]); + oappend(s); + oappend("/win&A="); + oappendi(bri); + oappend("&CL=h"); + for (int i = 0; i < 3; i++) + { + sprintf(s,"%02X", col[i]); + oappend(s); + } + oappend("&C2=h"); + for (int i = 0; i < 3; i++) + { + sprintf(s,"%02X", colSec[i]); + oappend(s); + } + oappend("&FX="); + oappendi(effectCurrent); + oappend("&SX="); + oappendi(effectSpeed); + oappend("&IX="); + oappendi(effectIntensity); + oappend("&FP="); + oappendi(effectPalette); + + obuf = sbuf; + olen = 0; + + oappend("
"); + oappend(s2buf); + oappend(""); + + if (request != nullptr) request->send(200, "text/html", obuf); +} + //append a numeric setting to string buffer void sappend(char stype, const char* key, int val) { diff --git a/wled00/wled18_server.ino b/wled00/wled18_server.ino index cf67e79f8..826425d13 100644 --- a/wled00/wled18_server.ino +++ b/wled00/wled18_server.ino @@ -143,6 +143,10 @@ void initServer() request->send_P(200, "text/html", PAGE_usermod); }); + server.on("/url", HTTP_GET, [](AsyncWebServerRequest *request){ + URL_response(request); + }); + server.on("/teapot", HTTP_GET, [](AsyncWebServerRequest *request){ serveMessage(request, 418, "418. I'm a teapot.", "(Tangible Embedded Advanced Project Of Twinkling)", 254); }); From 5d7e8924641492dc4a58f324f52db97e313c5293 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Mon, 24 Feb 2020 12:44:41 +0100 Subject: [PATCH 057/509] Different PIO settings --- platformio.ini | 22 ++++++++++++---------- readme.md | 2 +- wled00/wled00.ino | 4 ++-- wled00/wled19_json.ino | 1 - 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/platformio.ini b/platformio.ini index dd5f7a73c..017997570 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,6 +16,10 @@ default_envs = nodemcuv2 ; default_envs = esp8285_4CH_MagicHome ; default_envs = esp8285_4CH_H801 ; default_envs = esp8285_5CH_H801 +# Release binaries follow +; default_envs = nodemcuv2, esp01, esp01_1m, esp32dev, + + [common] framework = arduino @@ -82,30 +86,28 @@ arduino_core_stage = https://github.com/platformio/platform-espressif8266.git#fe platform = ${common:esp8266.arduino_core_2_6_3} build_flags = -D ESP8266 - -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH + -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH -Wl,-Teagle.flash.4m1m.ld ;;;; Required for core > v2.5.0 or staging version 4MB Flash 3MB SPIFFs lib_ignore = AsyncTCP [common:esp8266_1M] -platform = espressif8266@1.8.0 +platform = ${common:esp8266.arduino_core_2_6_3} build_flags = - -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH - -Wl,-Teagle.flash.1m0.ld ;;;; Compile with no SPIFFS to leave space for OTA - ; -D WLED_DISABLE_MOBILE_UI + -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH + -Wl,-Teagle.flash.1m.ld ;;;; Compile with no SPIFFS to leave space for OTA ; -D WLED_DISABLE_OTA ; -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE ; -D WLED_DISABLE_HUESYNC - ; -D WLED_DISABLE_INFRARED + -D WLED_DISABLE_INFRARED lib_ignore = ${common:esp8266.lib_ignore} [common:esp8266_512k] -platform = espressif8266@1.8.0 +platform = ${common:esp8266.arduino_core_2_6_3} build_flags = - -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH - -Wl,-Teagle.flash.512k0.ld ;;;; Compile with no SPIFFS - ; -D WLED_DISABLE_MOBILE_UI + -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH + -Wl,-Teagle.flash.512k.ld ;;;; Compile with no SPIFFS -D WLED_DISABLE_OTA ; -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK diff --git a/readme.md b/readme.md index 044344ea1..1cbe9b804 100644 --- a/readme.md +++ b/readme.md @@ -11,7 +11,7 @@ A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs! ### Features: -- WS2812FX library integrated for almost 100 special effects +- WS2812FX library integrated for over 100 special effects - FastLED noise effects and palettes - Modern UI with color, effect and segment controls - Segments to set different effects and colors to parts of the LEDs diff --git a/wled00/wled00.ino b/wled00/wled00.ino index ee97c85f5..921b204be 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -21,7 +21,7 @@ //#define WLED_DISABLE_BLYNK //saves 6kb //#define WLED_DISABLE_CRONIXIE //saves 3kb //#define WLED_DISABLE_HUESYNC //saves 4kb -//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 25kb (!) +//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 12kb #define WLED_ENABLE_MQTT //saves 12kb #define WLED_ENABLE_ADALIGHT //saves 500b only @@ -106,7 +106,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2002192 +#define VERSION 2002222 char versionString[] = "0.9.1"; diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index 6bf9aafda..5cc1f519d 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -321,7 +321,6 @@ void serializeInfo(JsonObject root) root["brand"] = "WLED"; root["product"] = "DIY light"; - root["btype"] = "src"; root["mac"] = escapedMac; } From 7360b882acff7e0c6a52d675324d688ff39136e1 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Mon, 24 Feb 2020 12:54:23 +0100 Subject: [PATCH 058/509] DMX settings only when enabled --- wled00/wled00.ino | 7 ++++--- wled00/wled01_eeprom.ino | 8 +++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 4da5c7003..606439756 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -262,13 +262,14 @@ bool aOtaEnabled = true; //ArduinoOTA allows easy updates d uint16_t userVar0 = 0, userVar1 = 0; +#ifdef WLED_ENABLE_DMX //dmx CONFIG -uint16_t DMXChannels = 7; // number of channels per fixture -uint16_t DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +byte DMXChannels = 7; // number of channels per fixture +byte DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // assigns the different channels to different functions. See wled21_dmx.ino for more information. uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. uint16_t DMXStart = 10; // start address of the first fixture - +#endif //internal global variable declarations diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index 73508a4f0..0ff9497fe 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -258,15 +258,17 @@ void saveSettingsToEEPROM() EEPROM.write(2523, (mqttPort >> 8) & 0xFF); // DMX (2530 - 2549) + #ifdef WLED_ENABLE_DMX EEPROM.write(2530, DMXChannels); EEPROM.write(2531, DMXGap & 0xFF); EEPROM.write(2532, (DMXGap >> 8) & 0xFF); EEPROM.write(2533, DMXStart & 0xFF); EEPROM.write(2534, (DMXStart >> 8) & 0xFF); - for (int i=0;i<15;i++) { + for (int i=0; i<15; i++) { EEPROM.write(2535+i, DMXFixtureMap[i]); } // last used: 2549. maybe leave a few bytes for future expansion and go on with 2600 kthxbye. + #endif commit(); } @@ -536,7 +538,7 @@ void loadSettingsFromEEPROM(bool first) readStringFromEEPROM(2220, blynkApiKey, 35); if (strlen(blynkApiKey) < 25) blynkApiKey[0] = 0; - + #ifdef WLED_ENABLE_DMX // DMX (2530 - 2549)2535 DMXChannels = EEPROM.read(2530); DMXGap = EEPROM.read(2531) + ((EEPROM.read(2532) << 8) & 0xFF00); @@ -545,7 +547,7 @@ void loadSettingsFromEEPROM(bool first) for (int i=0;i<15;i++) { DMXFixtureMap[i] = EEPROM.read(2535+i); } //last used: 2549. maybe leave a few bytes for future expansion and go on with 2600 kthxbye. - + #endif //user MOD memory //2944 - 3071 reserved From 0455c09e4cb2812d0c99acaf300a7627cadf805a Mon Sep 17 00:00:00 2001 From: zewelor Date: Mon, 24 Feb 2020 16:42:24 +0100 Subject: [PATCH 059/509] Allow platformio ini overrides --- .gitignore | 1 + platformio.ini | 1 + platformio_override.ini.example | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 platformio_override.ini.example diff --git a/.gitignore b/.gitignore index 2116e6930..ea49cb51f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ !.vscode/extensions.json /wled00/Release /wled00/extLibs +/platformio_override.ini diff --git a/platformio.ini b/platformio.ini index 017997570..127457d27 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,6 +6,7 @@ src_dir = ./wled00 data_dir = ./wled00/data ;lib_extra_dirs = ./wled00/src lib_dir = ./wled00/src +extra_configs = platformio_override.ini ; Please uncomment one of the 5 lines below to select your board default_envs = nodemcuv2 ; default_envs = esp01 diff --git a/platformio_override.ini.example b/platformio_override.ini.example new file mode 100644 index 000000000..03a77056a --- /dev/null +++ b/platformio_override.ini.example @@ -0,0 +1,18 @@ +; Example PlatformIO Project Configuration Override +; ------------------------------------------------------------------------------ +; Copy to platformio_override.ini to activate overrides +; ------------------------------------------------------------------------------ +; Please visit documentation: https://docs.platformio.org/page/projectconf.html + +[env:esp8266_1m_custom] +platform = ${common:esp8266.arduino_core_2_6_3} +build_flags = + -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH + -Wl,-Teagle.flash.1m.ld ;;;; Compile with no SPIFFS to leave space for OTA + ; -D WLED_DISABLE_OTA + -D WLED_DISABLE_ALEXA + -D WLED_DISABLE_BLYNK + -D WLED_DISABLE_CRONIXIE + -D WLED_DISABLE_HUESYNC + -D WLED_DISABLE_INFRARED +lib_ignore = ${common:esp8266.lib_ignore} \ No newline at end of file From 89f60a0422385f30f476907473e4f8edb5646a8d Mon Sep 17 00:00:00 2001 From: cschwinne Date: Mon, 24 Feb 2020 17:25:40 +0100 Subject: [PATCH 060/509] Refactor colorUpdated() --- platformio.ini | 5 ++--- wled00/const.h | 29 +++++++++++++++++++++-------- wled00/wled00.ino | 2 +- wled00/wled07_notify.ino | 1 - wled00/wled08_led.ino | 34 +++++++++++++++------------------- 5 files changed, 39 insertions(+), 32 deletions(-) diff --git a/platformio.ini b/platformio.ini index 017997570..08033581f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -109,11 +109,11 @@ build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH -Wl,-Teagle.flash.512k.ld ;;;; Compile with no SPIFFS -D WLED_DISABLE_OTA - ; -D WLED_DISABLE_ALEXA + -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC - ; -D WLED_DISABLE_INFRARED + -D WLED_DISABLE_INFRARED lib_ignore = ${common:esp8266.lib_ignore} [common:esp32] @@ -179,7 +179,6 @@ framework = ${common.framework} build_flags = ${common.build_flags} ${common:esp8266_512k.build_flags} - -D WLED_DISABLE_INFRARED lib_deps = ${common.lib_deps_external} lib_compat_mode = strict diff --git a/wled00/const.h b/wled00/const.h index 4d2875723..44065fec8 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -8,13 +8,13 @@ #define AP_BEHAVIOR_BUTTON_ONLY 3 //Only when button pressed for 6 sec //Notifier callMode -#define NOTIFIER_CALL_MODE_INIT 0 // no updates on init, can be used to disable updates +#define NOTIFIER_CALL_MODE_INIT 0 //no updates on init, can be used to disable updates #define NOTIFIER_CALL_MODE_DIRECT_CHANGE 1 #define NOTIFIER_CALL_MODE_BUTTON 2 #define NOTIFIER_CALL_MODE_NOTIFICATION 3 #define NOTIFIER_CALL_MODE_NIGHTLIGHT 4 #define NOTIFIER_CALL_MODE_NO_NOTIFY 5 -#define NOTIFIER_CALL_MODE_FX_CHANGED 6 +#define NOTIFIER_CALL_MODE_FX_CHANGED 6 //no longer used #define NOTIFIER_CALL_MODE_HUE 7 #define NOTIFIER_CALL_MODE_PRESET_CYCLE 8 #define NOTIFIER_CALL_MODE_BLYNK 9 @@ -36,11 +36,24 @@ #define REALTIME_MODE_ADALIGHT 5 //E1.31 DMX modes -#define DMX_MODE_DISABLED 0 //not used -#define DMX_MODE_SINGLE_RGB 1 //all LEDs same RGB color (3 channels) -#define DMX_MODE_SINGLE_DRGB 2 //all LEDs same RGB color and master dimmer (4 channels) -#define DMX_MODE_EFFECT 3 //trigger standalone effects of WLED (11 channels) -#define DMX_MODE_MULTIPLE_RGB 4 //every LED is addressed with its own RGB (ledCount * 3 channels) -#define DMX_MODE_MULTIPLE_DRGB 5 //every LED is addressed with its own RGB and share a master dimmer (ledCount * 3 + 1 channels) +#define DMX_MODE_DISABLED 0 //not used +#define DMX_MODE_SINGLE_RGB 1 //all LEDs same RGB color (3 channels) +#define DMX_MODE_SINGLE_DRGB 2 //all LEDs same RGB color and master dimmer (4 channels) +#define DMX_MODE_EFFECT 3 //trigger standalone effects of WLED (11 channels) +#define DMX_MODE_MULTIPLE_RGB 4 //every LED is addressed with its own RGB (ledCount * 3 channels) +#define DMX_MODE_MULTIPLE_DRGB 5 //every LED is addressed with its own RGB and share a master dimmer (ledCount * 3 + 1 channels) + +//Light capability byte (unused) +#define TYPE_WS2812_RGB 0 +#define TYPE_SK6812_RGBW 1 +#define TYPE_WS2812_WWA 2 //amber + warm + cold white +#define TYPE_APA102 3 +#define TYPE_LPD8806 4 +#define TYPE_WS2801 5 +#define TYPE_ANALOG_1CH 6 //single channel PWM. Uses value of brightest RGBW channel +#define TYPE_ANALOG_2CH 7 //analog WW + CW +#define TYPE_ANALOG_3CH 8 //analog RGB +#define TYPE_ANALOG_4CH 9 //analog RGBW +#define TYPE_ANALOG_5CH 10 //analog RGB + WW + CW #endif diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 606439756..9b5a92ee6 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -111,7 +111,7 @@ DMXESPSerial dmx; #endif //version code in format yymmddb (b = daily build) -#define VERSION 2002241 +#define VERSION 2002242 char versionString[] = "0.9.1"; diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino index fd83f1f81..7f691dd0f 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled07_notify.ino @@ -15,7 +15,6 @@ void notify(byte callMode, bool followUp=false) case NOTIFIER_CALL_MODE_DIRECT_CHANGE: if (!notifyDirect) return; break; case NOTIFIER_CALL_MODE_BUTTON: if (!notifyButton) return; break; case NOTIFIER_CALL_MODE_NIGHTLIGHT: if (!notifyDirect) return; break; - case NOTIFIER_CALL_MODE_FX_CHANGED: if (!notifyDirect) return; break; //fx change case NOTIFIER_CALL_MODE_HUE: if (!notifyHue) return; break; case NOTIFIER_CALL_MODE_PRESET_CYCLE: if (!notifyDirect) return; break; case NOTIFIER_CALL_MODE_BLYNK: if (!notifyDirect) return; break; diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index d1ccc0d66..e3afcda55 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -95,28 +95,30 @@ void colorUpdated(int callMode) callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) strip.applyToAllSelected = true; //if not from JSON api, which directly sets segments bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette); - if (!colorChanged()) + bool colChanged = colorChanged(); + + if (fxChanged || colChanged) { + if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0; + if (isPreset) {isPreset = false;} + else {currentPreset = -1;} + + notify(callMode); + + //set flag to update blynk and mqtt + if (callMode != NOTIFIER_CALL_MODE_PRESET_CYCLE) interfaceUpdateCallMode = callMode; + } else { if (nightlightActive && !nightlightActiveOld && callMode != NOTIFIER_CALL_MODE_NOTIFICATION && callMode != NOTIFIER_CALL_MODE_NO_NOTIFY) { notify(NOTIFIER_CALL_MODE_NIGHTLIGHT); interfaceUpdateCallMode = NOTIFIER_CALL_MODE_NIGHTLIGHT; - return; } - else if (fxChanged) { - notify(NOTIFIER_CALL_MODE_FX_CHANGED); - if (callMode != NOTIFIER_CALL_MODE_PRESET_CYCLE) interfaceUpdateCallMode = NOTIFIER_CALL_MODE_FX_CHANGED; - if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0; - if (isPreset) {isPreset = false;} - else {currentPreset = -1;} - } - return; //no change } - if (realtimeTimeout == UINT32_MAX) realtimeTimeout = 0; - if (isPreset) {isPreset = false;} - else {currentPreset = -1;} + + if (!colChanged) return; //following code is for e.g. initiating transitions + if (callMode != NOTIFIER_CALL_MODE_NO_NOTIFY && nightlightActive && nightlightFade) { briNlT = bri; @@ -137,8 +139,6 @@ void colorUpdated(int callMode) briIT = bri; if (bri > 0) briLast = bri; - notify(callMode); - if (fadeTransition) { //set correct delay if not using notification delay @@ -164,10 +164,6 @@ void colorUpdated(int callMode) setLedsStandard(); strip.trigger(); } - - if (callMode == NOTIFIER_CALL_MODE_PRESET_CYCLE) return; - //set flag to update blynk and mqtt - interfaceUpdateCallMode = callMode; } From 2e77dcc660c92c0be3de7da8a6f1974a0f31ab56 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 24 Feb 2020 17:27:59 +0100 Subject: [PATCH 061/509] Correct sun rise (#713) --- wled00/wled00.ino | 6 +++--- wled00/wled08_led.ino | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 9b5a92ee6..870b8a63d 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -150,8 +150,8 @@ bool useRGBW = false; //SK6812 strips can contain an ext bool turnOnAtBoot = true; //turn on LEDs at power-up byte bootPreset = 0; //save preset to load after power-up -byte col[] {255, 160, 0, 0}; //default RGB(W) color -byte colSec[] {0, 0, 0, 0}; //default RGB(W) secondary color +byte col[] {255, 160, 0, 0}; //current RGB(W) primary color. col[] should be updated if you want to change the color. +byte colSec[] {0, 0, 0, 0}; //current RGB(W) secondary color byte briS = 128; //default brightness byte nightlightTargetBri = 0; //brightness after nightlight is over @@ -282,7 +282,7 @@ bool wasConnected = false; //color byte colOld[] {0, 0, 0, 0}; //color before transition -byte colT[] {0, 0, 0, 0}; //current color +byte colT[] {0, 0, 0, 0}; //color that is currently displayed on the LEDs byte colIT[] {0, 0, 0, 0}; //color that was last sent to LEDs byte colSecT[] {0, 0, 0, 0}; byte colSecOld[] {0, 0, 0, 0}; diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index e3afcda55..3764a57c5 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -227,15 +227,15 @@ void handleNightlight() nightlightDelayMs = (int)(nightlightDelayMins*60000); nightlightActiveOld = true; briNlT = bri; - for (byte i=0; i<4; i++) colNlT[i] = colT[i]; // remember starting color + for (byte i=0; i<4; i++) colNlT[i] = col[i]; // remember starting color } float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs); if (nightlightFade) { bri = briNlT + ((nightlightTargetBri - briNlT)*nper); - if (nightlightColorFade) // color fading only is enabled with "NF=2" + if (nightlightColorFade) // color fading only is enabled with "NF=2" { - for (byte i=0; i<4; i++) colT[i] = colNlT[i]+ ((colSecT[i] - colNlT[i])*nper); // fading from actual color to secondary color + for (byte i=0; i<4; i++) col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color } colorUpdated(NOTIFIER_CALL_MODE_NO_NOTIFY); } From 3dcc3492e8e92544330966dcdb216b912e6c6db9 Mon Sep 17 00:00:00 2001 From: zewelor Date: Mon, 24 Feb 2020 18:48:21 +0100 Subject: [PATCH 062/509] Allow to override some costs --- wled00/NpbWrapper.h | 19 ++++++++++++++++--- wled00/const.h | 5 +++++ wled00/wled00.ino | 18 +++++++++++++----- wled00/wled05_init.ino | 4 ++-- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index a9fbd7c2e..9709d8aa4 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -13,12 +13,25 @@ //#define WLED_USE_H801 //H801 controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well //#define WLED_USE_5CH_LEDS //5 Channel H801 for cold and warm white +#ifndef BTNPIN #define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) -#define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 -#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... -#define AUXPIN -1 //debug auxiliary output pin (-1 to disable) +#endif +#ifndef IR_PIN +#define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 +#endif + +#ifndef RLYPIN +#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... +#endif + +#ifndef AUXPIN +#define AUXPIN -1 //debug auxiliary output pin (-1 to disable) +#endif + +#ifndef RLYMDE #define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on +#endif //END CONFIGURATION diff --git a/wled00/const.h b/wled00/const.h index 4d2875723..bf29ce76b 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -1,6 +1,11 @@ #ifndef wled_const_h #define wled_const_h +//Defaults +#define DEFAULT_CLIENT_SSID "Your_Network" +#define DEFAULT_AP_PASS "wled1234" +#define DEFAULT_OTA_PASS "wledota" + //Access point behavior #define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot #define AP_BEHAVIOR_NO_CONN 1 //Open when no connection (either after boot or if connection is lost) diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 606439756..475dfb065 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -85,6 +85,14 @@ DMXESPSerial dmx; #include "ir_codes.h" #include "const.h" +#ifndef CLIENT_SSID +#define CLIENT_SSID DEFAULT_CLIENT_SSID +#endif + +#ifndef CLIENT_PASS +#define CLIENT_PASS "" +#endif + #if IR_PIN < 0 #ifndef WLED_DISABLE_INFRARED @@ -117,8 +125,8 @@ char versionString[] = "0.9.1"; //AP and OTA default passwords (for maximum change them!) -char apPass[65] = "wled1234"; -char otaPass[33] = "wledota"; +char apPass[65] = DEFAULT_AP_PASS; +char otaPass[33] = DEFAULT_OTA_PASS; //Hardware CONFIG (only changeble HERE, not at runtime) @@ -130,8 +138,8 @@ char ntpServerName[33] = "0.wled.pool.ntp.org";//NTP server to use //WiFi CONFIG (all these can be changed via web UI, no need to set them here) -char clientSSID[33] = "Your_Network"; -char clientPass[65] = ""; +char clientSSID[33] = CLIENT_SSID; +char clientPass[65] = CLIENT_PASS; char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) char apSSID[33] = ""; //AP off by default (unless setup) byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) @@ -468,7 +476,7 @@ bool e131NewData = false; WS2812FX strip = WS2812FX(); #define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) -#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID,"Your_Network") != 0) +#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID,DEFAULT_CLIENT_SSID) != 0) //debug macros #ifdef WLED_DEBUG diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index bf1be5d99..40e3bef67 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -43,7 +43,7 @@ void wledInit() loadSettingsFromEEPROM(true); beginStrip(); userSetup(); - if (strcmp(clientSSID,"Your_Network") == 0) showWelcomePage = true; + if (strcmp(clientSSID,DEFAULT_CLIENT_SSID) == 0) showWelcomePage = true; WiFi.persistent(false); if (macroBoot>0) applyMacro(macroBoot); @@ -126,7 +126,7 @@ void initAP(bool resetAP=false){ if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) return; if (!apSSID[0] || resetAP) strcpy(apSSID, "WLED-AP"); - if (resetAP) strcpy(apPass,"wled1234"); + if (resetAP) strcpy(apPass,DEFAULT_AP_PASS); DEBUG_PRINT("Opening access point "); DEBUG_PRINTLN(apSSID); WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255,255,255,0)); From 4a834ecfc8353b4daec0dc80bf58af7b05974bd9 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Mon, 24 Feb 2020 19:08:29 +0100 Subject: [PATCH 063/509] Fix UTC offset not working --- wled00/wled10_ntp.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wled00/wled10_ntp.ino b/wled00/wled10_ntp.ino index bf8df064d..2c5a64c45 100644 --- a/wled00/wled10_ntp.ino +++ b/wled00/wled10_ntp.ino @@ -164,9 +164,9 @@ void setCountdown() bool checkCountdown() { unsigned long n = now(); - local = countdownTime - n; + if (countdownMode) local = countdownTime - n + utcOffsetSecs; if (n > countdownTime) { - local = n - countdownTime; + if (countdownMode) local = n - countdownTime + utcOffsetSecs; if (!countdownOverTriggered) { if (macroCountdown != 0) applyMacro(macroCountdown); From 2d75526395237e8fb78e9063a6588b31c86a3cce Mon Sep 17 00:00:00 2001 From: cschwinne Date: Mon, 24 Feb 2020 19:36:25 +0100 Subject: [PATCH 064/509] Fix brightness transition updating too often --- wled00/FX.h | 3 +++ wled00/FX_fcn.cpp | 5 +---- wled00/wled00.ino | 3 +-- wled00/wled01_eeprom.ino | 4 ++-- wled00/wled08_led.ino | 7 ------- 5 files changed, 7 insertions(+), 15 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index eec42990e..a518317f9 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -56,6 +56,9 @@ #define MAX_SEGMENT_DATA 8192 #endif +#define LED_SKIP_AMOUNT 1 +#define MIN_SHOW_DELAY 15 + #define NUM_COLORS 3 /* number of colors per segment */ #define SEGMENT _segments[_segment_index] #define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x]) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 0707392d2..b495de64b 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -27,9 +27,6 @@ #include "FX.h" #include "palettes.h" -#define LED_SKIP_AMOUNT 1 -#define MIN_SHOW_DELAY 15 - void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) { if (supportWhite == _useRgbw && countPixels == _length) return; @@ -380,7 +377,7 @@ void WS2812FX::setBrightness(uint8_t b) { if (_brightness == b) return; _brightness = (gammaCorrectBri) ? gamma8(b) : b; _segment_index = 0; - if (SEGENV.next_time > millis() + 22) show();//apply brightness change immediately if no refresh soon + if (SEGENV.next_time > millis() + 22 && millis() - _lastShow > MIN_SHOW_DELAY) show();//apply brightness change immediately if no refresh soon } uint8_t WS2812FX::getMode(void) { diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 445406b9b..66a17eea2 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -119,7 +119,7 @@ DMXESPSerial dmx; #endif //version code in format yymmddb (b = daily build) -#define VERSION 2002242 +#define VERSION 2002243 char versionString[] = "0.9.1"; @@ -167,7 +167,6 @@ byte nightlightDelayMins = 60; bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. bool fadeTransition = true; //enable crossfading color transition -bool enableSecTransition = true; //also enable transition for secondary color uint16_t transitionDelay = 750; //default crossfade duration in ms bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index 0ff9497fe..703785c14 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -159,7 +159,7 @@ void saveSettingsToEEPROM() EEPROM.write(396, (utcOffsetSecs<0)); //is negative EEPROM.write(397, syncToggleReceive); EEPROM.write(398, (ledCount >> 8) & 0xFF); - EEPROM.write(399, !enableSecTransition); + //EEPROM.write(399, was !enableSecTransition); //favorite setting (preset) memory (25 slots/ each 20byte) //400 - 940 reserved @@ -527,7 +527,7 @@ void loadSettingsFromEEPROM(bool first) wifiLock = EEPROM.read(393); utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00); if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative - enableSecTransition = !EEPROM.read(399); + //!EEPROM.read(399); was enableSecTransition //favorite setting (preset) memory (25 slots/ each 20byte) //400 - 899 reserved diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index 3764a57c5..93642fc29 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -40,13 +40,6 @@ void setAllLeds() { if (val > 255) val = 255; strip.setBrightness(val); } - if (!enableSecTransition) - { - for (byte i = 0; i<4; i++) - { - colSecT[i] = colSec[i]; - } - } if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY) { colorRGBtoRGBW(colT); From 730ba12c8dc1421cec7983c27728210e2f196fc9 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 24 Feb 2020 22:09:33 +0100 Subject: [PATCH 065/509] Indents for the #ifdef's in wled00.ino (#716) --- wled00/wled00.ino | 117 +++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 66a17eea2..c147dca34 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -36,22 +36,22 @@ //library inclusions #include #ifdef WLED_ENABLE_DMX -#include -DMXESPSerial dmx; + #include + DMXESPSerial dmx; #endif #ifdef ESP8266 - #include - #include - #include - extern "C" { - #include - } -#else -#include -#include "esp_wifi.h" -#include -#include -#include "SPIFFS.h" + #include + #include + #include + extern "C" { + #include + } +#else //ESP32 + #include + #include "esp_wifi.h" + #include + #include + #include "SPIFFS.h" #endif #include @@ -59,20 +59,20 @@ DMXESPSerial dmx; #include #include #ifndef WLED_DISABLE_OTA -#include + #include #endif #include #include "src/dependencies/time/TimeLib.h" #include "src/dependencies/timezone/Timezone.h" #ifndef WLED_DISABLE_ALEXA -#define ESPALEXA_ASYNC -#define ESPALEXA_NO_SUBPAGE -#define ESPALEXA_MAXDEVICES 1 -//#define ESPALEXA_DEBUG -#include "src/dependencies/espalexa/Espalexa.h" + #define ESPALEXA_ASYNC + #define ESPALEXA_NO_SUBPAGE + #define ESPALEXA_MAXDEVICES 1 + // #define ESPALEXA_DEBUG + #include "src/dependencies/espalexa/Espalexa.h" #endif #ifndef WLED_DISABLE_BLYNK -#include "src/dependencies/blynk/BlynkSimpleEsp.h" + #include "src/dependencies/blynk/BlynkSimpleEsp.h" #endif #include "src/dependencies/e131/ESPAsyncE131.h" #include "src/dependencies/async-mqtt-client/AsyncMqttClient.h" @@ -95,15 +95,15 @@ DMXESPSerial dmx; #if IR_PIN < 0 -#ifndef WLED_DISABLE_INFRARED -#define WLED_DISABLE_INFRARED -#endif + #ifndef WLED_DISABLE_INFRARED + #define WLED_DISABLE_INFRARED + #endif #endif #ifndef WLED_DISABLE_INFRARED -#include -#include -#include + #include + #include + #include #endif // remove flicker because PWM signal of RGB channels can become out of phase @@ -270,12 +270,12 @@ bool aOtaEnabled = true; //ArduinoOTA allows easy updates d uint16_t userVar0 = 0, userVar1 = 0; #ifdef WLED_ENABLE_DMX -//dmx CONFIG -byte DMXChannels = 7; // number of channels per fixture -byte DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + //dmx CONFIG + byte DMXChannels = 7; // number of channels per fixture + byte DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // assigns the different channels to different functions. See wled21_dmx.ino for more information. -uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. -uint16_t DMXStart = 10; // start address of the first fixture + uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. + uint16_t DMXStart = 10; // start address of the first fixture #endif @@ -398,7 +398,6 @@ byte realtimeMode = REALTIME_MODE_INACTIVE; IPAddress realtimeIP = (0,0,0,0); unsigned long realtimeTimeout = 0; - //mqtt long lastMqttReconnectAttempt = 0; long lastInterfaceUpdate = 0; @@ -406,17 +405,17 @@ byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; char mqttStatusTopic[40] = ""; //this must be global because of async handlers #if AUXPIN >= 0 -//auxiliary debug pin -byte auxTime = 0; -unsigned long auxStartTime = 0; -bool auxActive = false, auxActiveBefore = false; + //auxiliary debug pin + byte auxTime = 0; + unsigned long auxStartTime = 0; + bool auxActive = false, auxActiveBefore = false; #endif //alexa udp String escapedMac; #ifndef WLED_DISABLE_ALEXA -Espalexa espalexa; -EspalexaDevice* espalexaDevice; + Espalexa espalexa; + EspalexaDevice* espalexaDevice; #endif //dns server @@ -431,6 +430,7 @@ IPAddress ntpServerIP; uint16_t ntpLocalPort = 2390; #define NTP_PACKET_SIZE 48 +//maximum number of LEDs - MAX_LEDS is comming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue #define MAX_LEDS 1500 #define MAX_LEDS_DMA 500 @@ -439,6 +439,7 @@ uint16_t ntpLocalPort = 2390; char* obuf; uint16_t olen = 0; +//presets uint16_t savedPresets = 0; int8_t currentPreset = -1; bool isPreset = false; @@ -479,26 +480,26 @@ WS2812FX strip = WS2812FX(); //debug macros #ifdef WLED_DEBUG -#define DEBUG_PRINT(x) Serial.print (x) -#define DEBUG_PRINTLN(x) Serial.println (x) -#define DEBUG_PRINTF(x) Serial.printf (x) -unsigned long debugTime = 0; -int lastWifiState = 3; -unsigned long wifiStateChangedTime = 0; -int loops = 0; + #define DEBUG_PRINT(x) Serial.print (x) + #define DEBUG_PRINTLN(x) Serial.println (x) + #define DEBUG_PRINTF(x) Serial.printf (x) + unsigned long debugTime = 0; + int lastWifiState = 3; + unsigned long wifiStateChangedTime = 0; + int loops = 0; #else -#define DEBUG_PRINT(x) -#define DEBUG_PRINTLN(x) -#define DEBUG_PRINTF(x) + #define DEBUG_PRINT(x) + #define DEBUG_PRINTLN(x) + #define DEBUG_PRINTF(x) #endif //filesystem #ifndef WLED_DISABLE_FILESYSTEM -#include -#ifdef ARDUINO_ARCH_ESP32 -#include "SPIFFS.h" -#endif -#include "SPIFFSEditor.h" + #include + #ifdef ARDUINO_ARCH_ESP32 + #include "SPIFFS.h" + #endif + #include "SPIFFSEditor.h" #endif @@ -564,9 +565,9 @@ void loop() { handleOverlays(); yield(); - #ifdef WLED_USE_ANALOG_LEDS +#ifdef WLED_USE_ANALOG_LEDS strip.setRgbwPwm(); - #endif +#endif if (doReboot) reset(); @@ -586,9 +587,9 @@ void loop() { if (!offMode) strip.service(); } yield(); - #ifdef ESP8266 +#ifdef ESP8266 MDNS.update(); - #endif +#endif if (millis() - lastMqttReconnectAttempt > 30000) initMqtt(); //DEBUG serial logging From d5def30c5964e6ca0f0da75447cb48d1dfc4d818 Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Mon, 24 Feb 2020 16:36:03 -0500 Subject: [PATCH 066/509] Update wled06_usermod.ino --- .../Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino index 3b7a05fe8..9e6e0b793 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino @@ -2,8 +2,7 @@ #include //Dallastemperature sensor #ifdef ARDUINO_ARCH_ESP32 //ESP32 boards uint8_t SCL_PIN = 22; -uint8_t SDA_PIN = 21; -// uint8_t RST_PIN = 16; // Uncoment for Heltec WiFi-Kit-8 +uint8_t SDA_PIN = 21; OneWire oneWire(23); #else //ESP8266 boards uint8_t SCL_PIN = 5; @@ -14,7 +13,7 @@ OneWire oneWire(13); //ESP8266 Wemos D1 mini board use SCL=5 SDA=4 while ESP32 Wemos32 mini board use SCL=22 SDA=21 #define U8X8_PIN_SCL SCL_PIN #define U8X8_PIN_SDA SDA_PIN -//#define U8X8_PIN_RESET RST_PIN // Uncoment for Heltec WiFi-Kit-8 + // Dallas sensor DallasTemperature sensor(&oneWire); long temptimer = millis(); @@ -30,8 +29,6 @@ long lastMeasure = 0; U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA // --> Second choise of cheap I2C OLED 128X64 0.96" or 1.3" //U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA -// --> Third choise Heltec WiFi-Kit-8 with build-in OLED 128X32 0.91" -//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_RESET, U8X8_PIN_SCL, U8X8_PIN_SDA); // Constracor for Heltec WiFi-Kit-8 // gets called once at boot. Do all initialization that doesn't depend on // network here void userSetup() { From 70bf957a8a3b0199960771980da957d910fd7279 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Mon, 24 Feb 2020 16:44:56 -0500 Subject: [PATCH 067/509] Added Heltec WiFi-Kit-8 --- usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino index c0f6ce85b..58a4e0e6a 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino @@ -14,7 +14,7 @@ OneWire oneWire(13); //ESP8266 Wemos D1 mini board use SCL=5 SDA=4 while ESP32 Wemos32 mini board use SCL=22 SDA=21 #define U8X8_PIN_SCL SCL_PIN #define U8X8_PIN_SDA SDA_PIN - +//#define U8X8_PIN_RESET RST_PIN // Uncoment for Heltec WiFi-Kit-8 // Dallas sensor DallasTemperature sensor(&oneWire); long temptimer = millis(); @@ -30,6 +30,8 @@ long lastMeasure = 0; U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA // --> Second choise of cheap I2C OLED 128X64 0.96" or 1.3" //U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA +// --> Third choise of Heltec WiFi-Kit-8 OLED 128X32 0.91" +//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_RESET, U8X8_PIN_SCL, U8X8_PIN_SDA); // Constracor for Heltec WiFi-Kit-8 // gets called once at boot. Do all initialization that doesn't depend on // network here void userSetup() { From a78f17abec323055836fb1a517603e7ae5ade751 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Mon, 24 Feb 2020 16:48:01 -0500 Subject: [PATCH 068/509] Update readme.md --- usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md index be97d4b8c..765e56831 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -1,4 +1,5 @@ # Wemos D1 mini and Wemos32 mini shield +- Added third choice of controller Heltec WiFi-Kit-8. Totally DIY but with OLED display. ## Project repository - [Original repository](https://github.com/srg74/WLED-wemos-shield) - WLED Wemos shield repository - [Wemos shield project Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) From 1221661ae32f7c0c08fe5e4891a7b6bd3efb8059 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Mon, 24 Feb 2020 16:51:11 -0500 Subject: [PATCH 069/509] Added Heltec WiFi-Kit-8 to UserMod (#717) --- usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md | 1 + .../Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md index be97d4b8c..765e56831 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -1,4 +1,5 @@ # Wemos D1 mini and Wemos32 mini shield +- Added third choice of controller Heltec WiFi-Kit-8. Totally DIY but with OLED display. ## Project repository - [Original repository](https://github.com/srg74/WLED-wemos-shield) - WLED Wemos shield repository - [Wemos shield project Wiki](https://github.com/srg74/WLED-wemos-shield/wiki) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino index 9e6e0b793..58a4e0e6a 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino @@ -7,13 +7,14 @@ OneWire oneWire(23); #else //ESP8266 boards uint8_t SCL_PIN = 5; uint8_t SDA_PIN = 4; +// uint8_t RST_PIN = 16; // Uncoment for Heltec WiFi-Kit-8 OneWire oneWire(13); #endif //The SCL and SDA pins are defined here. //ESP8266 Wemos D1 mini board use SCL=5 SDA=4 while ESP32 Wemos32 mini board use SCL=22 SDA=21 #define U8X8_PIN_SCL SCL_PIN #define U8X8_PIN_SDA SDA_PIN - +//#define U8X8_PIN_RESET RST_PIN // Uncoment for Heltec WiFi-Kit-8 // Dallas sensor DallasTemperature sensor(&oneWire); long temptimer = millis(); @@ -29,6 +30,8 @@ long lastMeasure = 0; U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA // --> Second choise of cheap I2C OLED 128X64 0.96" or 1.3" //U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA +// --> Third choise of Heltec WiFi-Kit-8 OLED 128X32 0.91" +//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_RESET, U8X8_PIN_SCL, U8X8_PIN_SDA); // Constracor for Heltec WiFi-Kit-8 // gets called once at boot. Do all initialization that doesn't depend on // network here void userSetup() { From f304a6891fdfdab774b40ce1a47d62fd419f84a9 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 25 Feb 2020 02:19:12 +0100 Subject: [PATCH 070/509] Free more than 2kB of RAM Store Palettes in PROGMEM F() select long and rarely used strings Refactor hue error --- wled00/FX.h | 1 + wled00/FX_fcn.cpp | 25 +++++++---- wled00/NpbWrapper.h | 2 +- wled00/const.h | 9 ++++ wled00/html_settings.h | 2 +- wled00/palettes.h | 91 ++++++++++++++++++---------------------- wled00/wled00.ino | 4 +- wled00/wled02_xml.ino | 31 +++++++++----- wled00/wled15_hue.ino | 27 ++++++------ wled00/wled18_server.ino | 34 +++++++-------- wled00/wled19_json.ino | 2 +- 11 files changed, 123 insertions(+), 105 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index a518317f9..abb8c6f00 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -591,6 +591,7 @@ class WS2812FX { uint8_t _brightness; static uint16_t _usedSegmentData; + void load_gradient_palette(uint8_t); void handle_palette(void); void fill(uint32_t); diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index b495de64b..ee0ca73ae 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -324,7 +324,7 @@ uint8_t WS2812FX::getModeCount() uint8_t WS2812FX::getPaletteCount() { - return 13 + gGradientPaletteCount; + return 13 + GRADIENT_PALETTE_COUNT; } //TODO transitions @@ -707,6 +707,15 @@ CRGB WS2812FX::col_to_crgb(uint32_t color) } +void WS2812FX::load_gradient_palette(uint8_t index) +{ + byte i = constrain(index, 0, GRADIENT_PALETTE_COUNT -1); + byte tcp[72]; //support gradient palettes with up to 18 entries + memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[i])), 72); + targetPalette.loadDynamicGradientPalette(tcp); +} + + /* * FastLED palette modes helper function. Limitation: Due to memory reasons, multiple active segments with FastLED will disable the Palette transitions */ @@ -724,13 +733,13 @@ void WS2812FX::handle_palette(void) case 0: {//default palette. Differs depending on effect switch (SEGMENT.mode) { - case FX_MODE_FIRE_2012 : targetPalette = gGradientPalettes[22]; break;//heat palette - case FX_MODE_COLORWAVES : targetPalette = gGradientPalettes[13]; break;//landscape 33 + case FX_MODE_FIRE_2012 : load_gradient_palette(22); break;//heat palette + case FX_MODE_COLORWAVES : load_gradient_palette(13); break;//landscape 33 case FX_MODE_FILLNOISE8 : targetPalette = OceanColors_p; break; - case FX_MODE_NOISE16_1 : targetPalette = gGradientPalettes[17]; break;//Drywet - case FX_MODE_NOISE16_2 : targetPalette = gGradientPalettes[30]; break;//Blue cyan yellow - case FX_MODE_NOISE16_3 : targetPalette = gGradientPalettes[22]; break;//heat palette - case FX_MODE_NOISE16_4 : targetPalette = gGradientPalettes[13]; break;//landscape 33 + case FX_MODE_NOISE16_1 : load_gradient_palette(17); break;//Drywet + case FX_MODE_NOISE16_2 : load_gradient_palette(30); break;//Blue cyan yellow + case FX_MODE_NOISE16_3 : load_gradient_palette(22); break;//heat palette + case FX_MODE_NOISE16_4 : load_gradient_palette(13); break;//landscape 33 //case FX_MODE_GLITTER : targetPalette = RainbowColors_p; break; default: targetPalette = PartyColors_p; break;//palette, bpm @@ -787,7 +796,7 @@ void WS2812FX::handle_palette(void) case 12: //Rainbow stripe colors targetPalette = RainbowStripeColors_p; break; default: //progmem palettes - targetPalette = gGradientPalettes[constrain(SEGMENT.palette -13, 0, gGradientPaletteCount -1)]; + load_gradient_palette(SEGMENT.palette -13); } if (singleSegmentMode && paletteFade) //only blend if just one segment uses FastLED mode diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 9709d8aa4..f12d057f9 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -4,7 +4,7 @@ //PIN CONFIGURATION #ifndef LEDPIN -#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) +#define LEDPIN 5 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) #endif //#define USE_APA102 // Uncomment for using APA102 LEDs. //#define USE_WS2801 // Uncomment for using WS2801 LEDs (make sure you have NeoPixelBus v2.5.6 or newer) diff --git a/wled00/const.h b/wled00/const.h index 242536c9c..b54215cab 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -61,4 +61,13 @@ #define TYPE_ANALOG_4CH 9 //analog RGBW #define TYPE_ANALOG_5CH 10 //analog RGB + WW + CW +//Hue error codes +#define HUE_ERROR_INACTIVE 0 +#define HUE_ERROR_UNAUTHORIZED 1 +#define HUE_ERROR_LIGHTID 3 +#define HUE_ERROR_PUSHLINK 101 +#define HUE_ERROR_JSON_PARSING 250 +#define HUE_ERROR_TIMEOUT 251 +#define HUE_ERROR_ACTIVE 255 + #endif diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 157d6b4ca..7340e62d5 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -335,7 +335,7 @@ Hue Bridge IP:

Press the pushlink button on the bridge, after that save this page!
(when first connecting)
-Hue status: Internal ESP Error!
+Hue status: Disabled in this build
diff --git a/wled00/palettes.h b/wled00/palettes.h index fbdd7bb56..293843952 100644 --- a/wled00/palettes.h +++ b/wled00/palettes.h @@ -13,7 +13,9 @@ #ifndef PalettesWLED_h #define PalettesWLED_h -DEFINE_GRADIENT_PALETTE( ib_jul01_gp ) { +#define GRADIENT_PALETTE_COUNT 38 + +const byte ib_jul01_gp[] PROGMEM = { 0, 194, 1, 1, 94, 1, 29, 18, 132, 57,131, 28, @@ -24,7 +26,7 @@ DEFINE_GRADIENT_PALETTE( ib_jul01_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 20 bytes of program space. -DEFINE_GRADIENT_PALETTE( es_vintage_57_gp ) { +const byte es_vintage_57_gp[] PROGMEM = { 0, 2, 1, 1, 53, 18, 1, 0, 104, 69, 29, 1, @@ -37,7 +39,7 @@ DEFINE_GRADIENT_PALETTE( es_vintage_57_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 32 bytes of program space. -DEFINE_GRADIENT_PALETTE( es_vintage_01_gp ) { +const byte es_vintage_01_gp[] PROGMEM = { 0, 4, 1, 1, 51, 16, 0, 1, 76, 97,104, 3, @@ -53,7 +55,7 @@ DEFINE_GRADIENT_PALETTE( es_vintage_01_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 20 bytes of program space. -DEFINE_GRADIENT_PALETTE( es_rivendell_15_gp ) { +const byte es_rivendell_15_gp[] PROGMEM = { 0, 1, 14, 5, 101, 16, 36, 14, 165, 56, 68, 30, @@ -67,7 +69,7 @@ DEFINE_GRADIENT_PALETTE( es_rivendell_15_gp ) { // Size: 36 bytes of program space. // Edited to be brighter -DEFINE_GRADIENT_PALETTE( rgi_15_gp ) { +const byte rgi_15_gp[] PROGMEM = { 0, 4, 1, 70, 31, 55, 1, 30, 63, 255, 4, 7, @@ -84,7 +86,7 @@ DEFINE_GRADIENT_PALETTE( rgi_15_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 8 bytes of program space. -DEFINE_GRADIENT_PALETTE( retro2_16_gp ) { +const byte retro2_16_gp[] PROGMEM = { 0, 188,135, 1, 255, 46, 7, 1}; @@ -94,7 +96,7 @@ DEFINE_GRADIENT_PALETTE( retro2_16_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 20 bytes of program space. -DEFINE_GRADIENT_PALETTE( Analogous_1_gp ) { +const byte Analogous_1_gp[] PROGMEM = { 0, 3, 0,255, 63, 23, 0,255, 127, 67, 0,255, @@ -107,7 +109,7 @@ DEFINE_GRADIENT_PALETTE( Analogous_1_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 20 bytes of program space. -DEFINE_GRADIENT_PALETTE( es_pinksplash_08_gp ) { +const byte es_pinksplash_08_gp[] PROGMEM = { 0, 126, 11,255, 127, 197, 1, 22, 175, 210,157,172, @@ -120,7 +122,7 @@ DEFINE_GRADIENT_PALETTE( es_pinksplash_08_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 16 bytes of program space. -DEFINE_GRADIENT_PALETTE( es_ocean_breeze_036_gp ) { +const byte es_ocean_breeze_036_gp[] PROGMEM = { 0, 1, 6, 7, 89, 1, 99,111, 153, 144,209,255, @@ -132,7 +134,7 @@ DEFINE_GRADIENT_PALETTE( es_ocean_breeze_036_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 88 bytes of program space. -DEFINE_GRADIENT_PALETTE( departure_gp ) { +const byte departure_gp[] PROGMEM = { 0, 8, 3, 0, 42, 23, 7, 0, 63, 75, 38, 6, @@ -152,7 +154,7 @@ DEFINE_GRADIENT_PALETTE( departure_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 36 bytes of program space. -DEFINE_GRADIENT_PALETTE( es_landscape_64_gp ) { +const byte es_landscape_64_gp[] PROGMEM = { 0, 0, 0, 0, 37, 2, 25, 1, 76, 15,115, 5, @@ -169,7 +171,7 @@ DEFINE_GRADIENT_PALETTE( es_landscape_64_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 24 bytes of program space. -DEFINE_GRADIENT_PALETTE( es_landscape_33_gp ) { +const byte es_landscape_33_gp[] PROGMEM = { 0, 1, 5, 0, 19, 32, 23, 1, 38, 161, 55, 1, @@ -183,7 +185,7 @@ DEFINE_GRADIENT_PALETTE( es_landscape_33_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 28 bytes of program space. -DEFINE_GRADIENT_PALETTE( rainbowsherbet_gp ) { +const byte rainbowsherbet_gp[] PROGMEM = { 0, 255, 33, 4, 43, 255, 68, 25, 86, 255, 7, 25, @@ -198,7 +200,7 @@ DEFINE_GRADIENT_PALETTE( rainbowsherbet_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 24 bytes of program space. -DEFINE_GRADIENT_PALETTE( gr65_hult_gp ) { +const byte gr65_hult_gp[] PROGMEM = { 0, 247,176,247, 48, 255,136,255, 89, 220, 29,226, @@ -212,7 +214,7 @@ DEFINE_GRADIENT_PALETTE( gr65_hult_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 32 bytes of program space. -DEFINE_GRADIENT_PALETTE( gr64_hult_gp ) { +const byte gr64_hult_gp[] PROGMEM = { 0, 1,124,109, 66, 1, 93, 79, 104, 52, 65, 1, @@ -228,7 +230,7 @@ DEFINE_GRADIENT_PALETTE( gr64_hult_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 28 bytes of program space. -DEFINE_GRADIENT_PALETTE( GMT_drywet_gp ) { +const byte GMT_drywet_gp[] PROGMEM = { 0, 47, 30, 2, 42, 213,147, 24, 84, 103,219, 52, @@ -243,7 +245,7 @@ DEFINE_GRADIENT_PALETTE( GMT_drywet_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 24 bytes of program space. -DEFINE_GRADIENT_PALETTE( ib15_gp ) { +const byte ib15_gp[] PROGMEM = { 0, 113, 91,147, 72, 157, 88, 78, 89, 208, 85, 33, @@ -257,7 +259,7 @@ DEFINE_GRADIENT_PALETTE( ib15_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 20 bytes of program space. -DEFINE_GRADIENT_PALETTE( Tertiary_01_gp ) { +const byte Tertiary_01_gp[] PROGMEM = { 0, 0, 1,255, 63, 3, 68, 45, 127, 23,255, 0, @@ -270,7 +272,7 @@ DEFINE_GRADIENT_PALETTE( Tertiary_01_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 52 bytes of program space. -DEFINE_GRADIENT_PALETTE( lava_gp ) { +const byte lava_gp[] PROGMEM = { 0, 0, 0, 0, 46, 18, 0, 0, 96, 113, 0, 0, @@ -291,7 +293,7 @@ DEFINE_GRADIENT_PALETTE( lava_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 28 bytes of program space. -DEFINE_GRADIENT_PALETTE( fierce_ice_gp ) { +const byte fierce_ice_gp[] PROGMEM = { 0, 0, 0, 0, 59, 0, 9, 45, 119, 0, 38,255, @@ -306,7 +308,7 @@ DEFINE_GRADIENT_PALETTE( fierce_ice_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 44 bytes of program space. -DEFINE_GRADIENT_PALETTE( Colorfull_gp ) { +const byte Colorfull_gp[] PROGMEM = { 0, 10, 85, 5, 25, 29,109, 18, 60, 59,138, 42, @@ -325,7 +327,7 @@ DEFINE_GRADIENT_PALETTE( Colorfull_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 44 bytes of program space. -DEFINE_GRADIENT_PALETTE( Pink_Purple_gp ) { +const byte Pink_Purple_gp[] PROGMEM = { 0, 19, 2, 39, 25, 26, 4, 45, 51, 33, 6, 52, @@ -344,7 +346,7 @@ DEFINE_GRADIENT_PALETTE( Pink_Purple_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 28 bytes of program space. -DEFINE_GRADIENT_PALETTE( Sunset_Real_gp ) { +const byte Sunset_Real_gp[] PROGMEM = { 0, 120, 0, 0, 22, 179, 22, 0, 51, 255,104, 0, @@ -359,7 +361,7 @@ DEFINE_GRADIENT_PALETTE( Sunset_Real_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 44 bytes of program space. -DEFINE_GRADIENT_PALETTE( Sunset_Yellow_gp ) { +const byte Sunset_Yellow_gp[] PROGMEM = { 0, 10, 62,123, 36, 56,130,103, 87, 153,225, 85, @@ -378,7 +380,7 @@ DEFINE_GRADIENT_PALETTE( Sunset_Yellow_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 60 bytes of program space. -DEFINE_GRADIENT_PALETTE( Beech_gp ) { +const byte Beech_gp[] PROGMEM = { 0, 255,252,214, 12, 255,252,214, 22, 255,252,214, @@ -401,7 +403,7 @@ DEFINE_GRADIENT_PALETTE( Beech_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 32 bytes of program space. -DEFINE_GRADIENT_PALETTE( Another_Sunset_gp ) { +const byte Another_Sunset_gp[] PROGMEM = { 0, 110, 49, 11, 29, 55, 34, 10, 68, 22, 22, 9, @@ -420,7 +422,7 @@ DEFINE_GRADIENT_PALETTE( Another_Sunset_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 52 bytes of program space. -DEFINE_GRADIENT_PALETTE( es_autumn_19_gp ) { +const byte es_autumn_19_gp[] PROGMEM = { 0, 26, 1, 1, 51, 67, 4, 1, 84, 118, 14, 1, @@ -441,7 +443,7 @@ DEFINE_GRADIENT_PALETTE( es_autumn_19_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 28 bytes of program space. -DEFINE_GRADIENT_PALETTE( BlacK_Blue_Magenta_White_gp ) { +const byte BlacK_Blue_Magenta_White_gp[] PROGMEM = { 0, 0, 0, 0, 42, 0, 0, 45, 84, 0, 0,255, @@ -456,7 +458,7 @@ DEFINE_GRADIENT_PALETTE( BlacK_Blue_Magenta_White_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 20 bytes of program space. -DEFINE_GRADIENT_PALETTE( BlacK_Magenta_Red_gp ) { +const byte BlacK_Magenta_Red_gp[] PROGMEM = { 0, 0, 0, 0, 63, 42, 0, 45, 127, 255, 0,255, @@ -469,7 +471,7 @@ DEFINE_GRADIENT_PALETTE( BlacK_Magenta_Red_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 28 bytes of program space. -DEFINE_GRADIENT_PALETTE( BlacK_Red_Magenta_Yellow_gp ) { +const byte BlacK_Red_Magenta_Yellow_gp[] PROGMEM = { 0, 0, 0, 0, 42, 42, 0, 0, 84, 255, 0, 0, @@ -484,7 +486,7 @@ DEFINE_GRADIENT_PALETTE( BlacK_Red_Magenta_Yellow_gp ) { // converted for FastLED with gammas (2.6, 2.2, 2.5) // Size: 20 bytes of program space. -DEFINE_GRADIENT_PALETTE( Blue_Cyan_Yellow_gp ) { +const byte Blue_Cyan_Yellow_gp[] PROGMEM = { 0, 0, 0,255, 63, 0, 55,255, 127, 0,255,255, @@ -494,7 +496,7 @@ DEFINE_GRADIENT_PALETTE( Blue_Cyan_Yellow_gp ) { //Custom palette by Aircoookie -DEFINE_GRADIENT_PALETTE( Orange_Teal_gp ) { +const byte Orange_Teal_gp[] PROGMEM = { 0, 0,150, 92, 55, 0,150, 92, 200, 255, 72, 0, @@ -502,7 +504,7 @@ DEFINE_GRADIENT_PALETTE( Orange_Teal_gp ) { //Custom palette by Aircoookie -DEFINE_GRADIENT_PALETTE( Tiamat_gp ) { +const byte Tiamat_gp[] PROGMEM = { 0, 1, 2, 14, //gc 33, 2, 5, 35, //gc from 47, 61,126 100, 13,135, 92, //gc from 88,242,247 @@ -517,7 +519,7 @@ DEFINE_GRADIENT_PALETTE( Tiamat_gp ) { //Custom palette by Aircoookie -DEFINE_GRADIENT_PALETTE( April_Night_gp ) { +const byte April_Night_gp[] PROGMEM = { 0, 1, 5, 45, //deep blue 10, 1, 5, 45, 25, 5,169,175, //light blue @@ -536,7 +538,7 @@ DEFINE_GRADIENT_PALETTE( April_Night_gp ) { 244, 1, 5, 45, 255, 1, 5, 45}; -DEFINE_GRADIENT_PALETTE( Orangery_gp ) { +const byte Orangery_gp[] PROGMEM = { 0, 255, 95, 23, 30, 255, 82, 0, 60, 223, 13, 8, @@ -548,7 +550,7 @@ DEFINE_GRADIENT_PALETTE( Orangery_gp ) { 255, 213, 37, 4}; //inspired by Mark Kriegsman https://gist.github.com/kriegsman/756ea6dcae8e30845b5a -DEFINE_GRADIENT_PALETTE( C9_gp ) { +const byte C9_gp[] PROGMEM = { 0, 184, 4, 0, //red 60, 184, 4, 0, 65, 144, 44, 2, //amber @@ -558,14 +560,14 @@ DEFINE_GRADIENT_PALETTE( C9_gp ) { 195, 7, 7, 88, //blue 255, 7, 7, 88}; -DEFINE_GRADIENT_PALETTE( Sakura_gp ) { +const byte Sakura_gp[] PROGMEM = { 0, 196, 19, 10, 65, 255, 69, 45, 130, 223, 45, 72, 195, 255, 82,103, 255, 223, 13, 17}; -DEFINE_GRADIENT_PALETTE( Aurora_gp ) { +const byte Aurora_gp[] PROGMEM = { 0, 1, 5, 45, //deep blue 64, 0,200, 23, 128, 0,255, 0, //green @@ -578,13 +580,7 @@ DEFINE_GRADIENT_PALETTE( Aurora_gp ) { // This will let us programmatically choose one based on // a number, rather than having to activate each explicitly // by name every time. -// Since it is const, this array could also be moved -// into PROGMEM to save SRAM, but for simplicity of illustration -// we'll keep it in a regular SRAM array. -// -// This list of color palettes acts as a "playlist"; you can -// add or delete, or re-arrange as you wish. -const TProgmemRGBGradientPalettePtr gGradientPalettes[] = { +const byte* const gGradientPalettes[] PROGMEM = { Sunset_Real_gp, //13-00 Sunset es_rivendell_15_gp, //14-01 Rivendell es_ocean_breeze_036_gp, //15-02 Breeze @@ -625,9 +621,4 @@ const TProgmemRGBGradientPalettePtr gGradientPalettes[] = { Aurora_gp, //50-37 Aurora }; - -// Count of how many cpt-city gradients are defined: -const uint8_t gGradientPaletteCount = - sizeof( gGradientPalettes) / sizeof( TProgmemRGBGradientPalettePtr ); - #endif diff --git a/wled00/wled00.ino b/wled00/wled00.ino index c147dca34..937895779 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -119,7 +119,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2002243 +#define VERSION 2002251 char versionString[] = "0.9.1"; @@ -350,7 +350,7 @@ bool udpConnected = false, udpRgbConnected = false; bool showWelcomePage = false; //hue -char hueError[25] = "Inactive"; +byte hueError = HUE_ERROR_INACTIVE; //uint16_t hueFailCount = 0; float hueXLast = 0, hueYLast = 0; uint16_t hueHueLast = 0, hueCtLast = 0; diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index e5083131d..d538e0c49 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -9,7 +9,7 @@ char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr) obuf = (dest == nullptr)? sbuf:dest; olen = 0; - oappend(""); + oappend((const char*)F("")); oappendi((nightlightActive && nightlightFade) ? briT : bri); oappend(""); @@ -65,7 +65,7 @@ char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr) { mesg += "E1.31 mode "; mesg += DMXMode; - mesg += " at DMX Address "; + mesg += F(" at DMX Address "); mesg += DMXAddress; mesg += " from "; mesg += realtimeIP[0]; @@ -85,7 +85,7 @@ char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr) mesg += realtimeIP[i]; } } else if (realtimeMode == REALTIME_MODE_ADALIGHT) { - mesg += "USB Adalight"; + mesg += F("USB Adalight"); } else { //generic mesg += "data"; } @@ -137,11 +137,11 @@ char* URL_response(AsyncWebServerRequest *request) obuf = sbuf; olen = 0; - oappend(""); + oappend((const char*)F("\" target=\"_blank\">")); oappend(s2buf); - oappend(""); + oappend((const char*)F("")); if (request != nullptr) request->send(200, "text/html", obuf); } @@ -355,9 +355,7 @@ void getSettingsJS(byte subPage, char* dest) sappends('s',"MG",mqttGroupTopic); #endif - #ifdef WLED_DISABLE_HUESYNC - sappends('m',"(\"hms\")[0]","Unsupported in build"); - #else + #ifndef WLED_DISABLE_HUESYNC sappend('v',"H0",hueIP[0]); sappend('v',"H1",hueIP[1]); sappend('v',"H2",hueIP[2]); @@ -368,7 +366,20 @@ void getSettingsJS(byte subPage, char* dest) sappend('c',"HO",hueApplyOnOff); sappend('c',"HB",hueApplyBri); sappend('c',"HC",hueApplyColor); - sappends('m',"(\"hms\")[0]",hueError); + char hueErrorString[25]; + switch (hueError) + { + case HUE_ERROR_INACTIVE : strcpy(hueErrorString,(char*)F("Inactive")); break; + case HUE_ERROR_ACTIVE : strcpy(hueErrorString,(char*)F("Active")); break; + case HUE_ERROR_UNAUTHORIZED : strcpy(hueErrorString,(char*)F("Unauthorized")); break; + case HUE_ERROR_LIGHTID : strcpy(hueErrorString,(char*)F("Invalid light ID")); break; + case HUE_ERROR_PUSHLINK : strcpy(hueErrorString,(char*)F("Link button not pressed")); break; + case HUE_ERROR_JSON_PARSING : strcpy(hueErrorString,(char*)F("JSON parsing error")); break; + case HUE_ERROR_TIMEOUT : strcpy(hueErrorString,(char*)F("Timeout")); break; + default: sprintf(hueErrorString,"Bridge Error %i",hueError); + } + + sappends('m',"(\"hms\")[0]",hueErrorString); #endif } diff --git a/wled00/wled15_hue.ino b/wled00/wled15_hue.ino index 77e6622c6..5f6b8f5bf 100644 --- a/wled00/wled15_hue.ino +++ b/wled00/wled15_hue.ino @@ -23,7 +23,7 @@ void handleHue() reconnectHue(); } else { hueClient->close(); - if (hueError[0] == 'A') strcpy(hueError,"Inactive"); + if (hueError == HUE_ERROR_ACTIVE) hueError = HUE_ERROR_INACTIVE; } } @@ -44,7 +44,7 @@ void reconnectHue() void onHueError(void* arg, AsyncClient* client, int8_t error) { DEBUG_PRINTLN("Hue err"); - strcpy(hueError,"Request timeout"); + hueError = HUE_ERROR_TIMEOUT; } void onHueConnect(void* arg, AsyncClient* client) @@ -59,15 +59,15 @@ void sendHuePoll() String req = ""; if (hueAuthRequired) { - req += "POST /api HTTP/1.1\r\nHost: "; + req += F("POST /api HTTP/1.1\r\nHost: "); req += hueIP.toString(); - req += "\r\nContent-Length: 25\r\n\r\n{\"devicetype\":\"wled#esp\"}"; + req += F("\r\nContent-Length: 25\r\n\r\n{\"devicetype\":\"wled#esp\"}"); } else { req += "GET /api/"; req += hueApiKey; req += "/lights/" + String(huePollLightId); - req += " HTTP/1.1\r\nHost: "; + req += F(" HTTP/1.1\r\nHost: "); req += hueIP.toString(); req += "\r\n\r\n"; } @@ -93,21 +93,18 @@ void onHueData(void* arg, AsyncClient* client, void *data, size_t len) auto error = deserializeJson(root, str); if (error) { - strcpy(hueError,"JSON parsing error"); return; + hueError = HUE_ERROR_JSON_PARSING; return; } int hueErrorCode = root[0]["error"]["type"]; if (hueErrorCode)//hue bridge returned error { + hueError = hueErrorCode; switch (hueErrorCode) { - case 1: strcpy(hueError,"Unauthorized"); hueAuthRequired = true; break; - case 3: strcpy(hueError,"Invalid light ID"); huePollingEnabled = false; break; - case 101: strcpy(hueError,"Link button not pressed"); hueAuthRequired = true; break; - default: - char coerr[18]; - sprintf(coerr,"Bridge Error %i",hueErrorCode); - strcpy(hueError,coerr); + case 1: hueAuthRequired = true; break; //Unauthorized user + case 3: huePollingEnabled = false; break; //Invalid light ID + case 101: hueAuthRequired = true; break; //link button not presset } return; } @@ -133,7 +130,7 @@ void onHueData(void* arg, AsyncClient* client, void *data, size_t len) auto error = deserializeJson(root, str); if (error) { - strcpy(hueError,"JSON parsing error"); return; + hueError = HUE_ERROR_JSON_PARSING; return; } float hueX=0, hueY=0; @@ -173,7 +170,7 @@ void onHueData(void* arg, AsyncClient* client, void *data, size_t len) hueBri = 0; } - strcpy(hueError,"Active"); + hueError = HUE_ERROR_ACTIVE; //apply vals if (hueBri != hueBriLast) diff --git a/wled00/wled18_server.ino b/wled00/wled18_server.ino index 826425d13..f11a64bec 100644 --- a/wled00/wled18_server.ino +++ b/wled00/wled18_server.ino @@ -62,44 +62,44 @@ void initServer() }); server.on("/reset", HTTP_GET, [](AsyncWebServerRequest *request){ - serveMessage(request, 200,"Rebooting now...","Please wait ~10 seconds...",129); + serveMessage(request, 200,"Rebooting now...",F("Please wait ~10 seconds..."),129); doReboot = true; }); server.on("/settings/wifi", HTTP_POST, [](AsyncWebServerRequest *request){ if (!(wifiLock && otaLock)) handleSettingsSet(request, 1); - serveMessage(request, 200,"WiFi settings saved.","Please connect to the new IP (if changed)",129); + serveMessage(request, 200,F("WiFi settings saved."),F("Please connect to the new IP (if changed)"),129); forceReconnect = true; }); server.on("/settings/leds", HTTP_POST, [](AsyncWebServerRequest *request){ handleSettingsSet(request, 2); - serveMessage(request, 200,"LED settings saved.","Redirecting...",1); + serveMessage(request, 200,F("LED settings saved."),"Redirecting...",1); }); server.on("/settings/ui", HTTP_POST, [](AsyncWebServerRequest *request){ handleSettingsSet(request, 3); - serveMessage(request, 200,"UI settings saved.","Redirecting...",1); + serveMessage(request, 200,F("UI settings saved."),"Redirecting...",1); }); server.on("/settings/dmx", HTTP_POST, [](AsyncWebServerRequest *request){ handleSettingsSet(request, 7); - serveMessage(request, 200,"UI settings saved.","Redirecting...",1); + serveMessage(request, 200,F("UI settings saved."),"Redirecting...",1); }); server.on("/settings/sync", HTTP_POST, [](AsyncWebServerRequest *request){ handleSettingsSet(request, 4); - serveMessage(request, 200,"Sync settings saved.","Redirecting...",1); + serveMessage(request, 200,F("Sync settings saved."),"Redirecting...",1); }); server.on("/settings/time", HTTP_POST, [](AsyncWebServerRequest *request){ handleSettingsSet(request, 5); - serveMessage(request, 200,"Time settings saved.","Redirecting...",1); + serveMessage(request, 200,F("Time settings saved."),"Redirecting...",1); }); server.on("/settings/sec", HTTP_POST, [](AsyncWebServerRequest *request){ handleSettingsSet(request, 6); - if (!doReboot) serveMessage(request, 200,"Security settings saved.","Rebooting, please wait ~10 seconds...",129); + if (!doReboot) serveMessage(request, 200,F("Security settings saved."),F("Rebooting, please wait ~10 seconds..."),129); doReboot = true; }); @@ -148,7 +148,7 @@ void initServer() }); server.on("/teapot", HTTP_GET, [](AsyncWebServerRequest *request){ - serveMessage(request, 418, "418. I'm a teapot.", "(Tangible Embedded Advanced Project Of Twinkling)", 254); + serveMessage(request, 418, F("418. I'm a teapot."), F("(Tangible Embedded Advanced Project Of Twinkling)"), 254); }); //if OTA is allowed @@ -161,7 +161,7 @@ void initServer() #endif #else server.on("/edit", HTTP_GET, [](AsyncWebServerRequest *request){ - serveMessage(request, 501, "Not implemented", "The SPIFFS editor is disabled in this build.", 254); + serveMessage(request, 501, "Not implemented", F("The SPIFFS editor is disabled in this build."), 254); }); #endif //init ota page @@ -173,9 +173,9 @@ void initServer() server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){ if (Update.hasError()) { - serveMessage(request, 500, "Failed updating firmware!", "Please check your file and retry!", 254); return; + serveMessage(request, 500, F("Failed updating firmware!"), F("Please check your file and retry!"), 254); return; } - serveMessage(request, 200, "Successfully updated firmware!", "Please wait while the module reboots...", 131); + serveMessage(request, 200, F("Successfully updated firmware!"), F("Please wait while the module reboots..."), 131); doReboot = true; },[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ if(!index){ @@ -197,7 +197,7 @@ void initServer() #else server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){ - serveMessage(request, 501, "Not implemented", "OTA updates are disabled in this build.", 254); + serveMessage(request, 501, "Not implemented", F("OTA updates are disabled in this build."), 254); }); #endif } else @@ -217,7 +217,7 @@ void initServer() }); #else server.on("/dmxmap", HTTP_GET, [](AsyncWebServerRequest *request){ - serveMessage(request, 501, "Not implemented", "DMX support is not enabled in this build.", 254); + serveMessage(request, 501, "Not implemented", F("DMX support is not enabled in this build."), 254); }); #endif server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ @@ -292,10 +292,10 @@ String msgProcessor(const String& var) messageBody += ""; } else if (optt == 253) { - messageBody += "

"; //button to settings + messageBody += F("

"); //button to settings } else if (optt == 254) { - messageBody += "

"; + messageBody += F("

"); } return messageBody; } @@ -324,7 +324,7 @@ String settingsProcessor(const String& var) #ifdef WLED_ENABLE_DMX if (var == "DMXMENU") { - return String("
"); + return String(F("
")); } #endif diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index 5cc1f519d..4d9359731 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -343,7 +343,7 @@ void serveJson(AsyncWebServerRequest* request) return; } else if (url.length() > 6) { //not just /json - request->send( 501, "application/json", "{\"error\":\"Not implemented\"}"); + request->send( 501, "application/json", F("{\"error\":\"Not implemented\"}")); return; } From 755448f9f5a8ed9349f828a4b57f711725c421ee Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 25 Feb 2020 02:25:17 +0100 Subject: [PATCH 071/509] Fix LED pin changed --- readme.md | 2 +- wled00/NpbWrapper.h | 4 ++-- wled00/wled00.ino | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index 1cbe9b804..c796ca5c9 100644 --- a/readme.md +++ b/readme.md @@ -12,7 +12,7 @@ A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control ### Features: - WS2812FX library integrated for over 100 special effects -- FastLED noise effects and palettes +- FastLED noise effects and 50 palettes - Modern UI with color, effect and segment controls - Segments to set different effects and colors to parts of the LEDs - Settings page - configuration over network diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index f12d057f9..71367d980 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -4,7 +4,7 @@ //PIN CONFIGURATION #ifndef LEDPIN -#define LEDPIN 5 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) +#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) #endif //#define USE_APA102 // Uncomment for using APA102 LEDs. //#define USE_WS2801 // Uncomment for using WS2801 LEDs (make sure you have NeoPixelBus v2.5.6 or newer) @@ -30,7 +30,7 @@ #endif #ifndef RLYMDE -#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on +#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on #endif //END CONFIGURATION diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 937895779..f214929ce 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -119,7 +119,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2002251 +#define VERSION 2002252 char versionString[] = "0.9.1"; @@ -430,7 +430,7 @@ IPAddress ntpServerIP; uint16_t ntpLocalPort = 2390; #define NTP_PACKET_SIZE 48 -//maximum number of LEDs - MAX_LEDS is comming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue +//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue #define MAX_LEDS 1500 #define MAX_LEDS_DMA 500 From 143179cac9d98a48146c8f2a907b227250842c9f Mon Sep 17 00:00:00 2001 From: zewelor Date: Tue, 25 Feb 2020 08:42:28 +0100 Subject: [PATCH 072/509] Use new platformio ldscript syntax --- platformio.ini | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index 581bc9951..fcbb7b285 100644 --- a/platformio.ini +++ b/platformio.ini @@ -88,33 +88,33 @@ platform = ${common:esp8266.arduino_core_2_6_3} build_flags = -D ESP8266 -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH - -Wl,-Teagle.flash.4m1m.ld ;;;; Required for core > v2.5.0 or staging version 4MB Flash 3MB SPIFFs +board_build.ldscript = eagle.flash.4m1m.ld ;;;; Required for core > v2.5.0 or staging version 4MB Flash 3MB SPIFFs lib_ignore = AsyncTCP [common:esp8266_1M] platform = ${common:esp8266.arduino_core_2_6_3} build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH - -Wl,-Teagle.flash.1m.ld ;;;; Compile with no SPIFFS to leave space for OTA ; -D WLED_DISABLE_OTA ; -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE ; -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED +board_build.ldscript = eagle.flash.1m.ld ;;;; Compile with no SPIFFS to leave space for OTA lib_ignore = ${common:esp8266.lib_ignore} [common:esp8266_512k] platform = ${common:esp8266.arduino_core_2_6_3} build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH - -Wl,-Teagle.flash.512k.ld ;;;; Compile with no SPIFFS -D WLED_DISABLE_OTA -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED +board_build.ldscript = eagle.flash.512k.ld ;;;; Compile with no SPIFFS lib_ignore = ${common:esp8266.lib_ignore} [common:esp32] @@ -136,6 +136,7 @@ framework = ${common.framework} build_flags = ${common.build_flags} ${common:esp8266.build_flags} +board_build.ldscript = ${common:esp8266.board_build.ldscript} lib_deps = ${common.lib_deps_external} lib_compat_mode = strict @@ -150,6 +151,7 @@ framework = ${common.framework} build_flags = ${common.build_flags} ${common:esp8266.build_flags} +board_build.ldscript = ${common:esp8266.board_build.ldscript} lib_deps = ${common.lib_deps_external} lib_compat_mode = strict @@ -166,6 +168,7 @@ build_flags = ${common:esp8266_1M.build_flags} # disable IR because there is no pin for it -D WLED_DISABLE_INFRARED +board_build.ldscript = ${common:esp8266_1M.board_build.ldscript} lib_deps = ${common.lib_deps_external} lib_compat_mode = strict @@ -180,6 +183,7 @@ framework = ${common.framework} build_flags = ${common.build_flags} ${common:esp8266_512k.build_flags} +board_build.ldscript = ${common:esp8266_512k.board_build.ldscript} lib_deps = ${common.lib_deps_external} lib_compat_mode = strict @@ -194,6 +198,7 @@ framework = ${common.framework} build_flags = ${common.build_flags} ${common:esp8266.build_flags} +board_build.ldscript = ${common:esp8266.board_build.ldscript} lib_deps = ${common.lib_deps_external} lib_compat_mode = strict @@ -225,6 +230,7 @@ build_flags = ${common:esp8266_1M.build_flags} -D WLED_DISABLE_HUESYNC -D WLED_USE_ANALOG_LEDS +board_build.ldscript = ${common:esp8266_1M.board_build.ldscript} lib_deps = ${common.lib_deps_external} lib_compat_mode = strict @@ -242,6 +248,7 @@ build_flags = -D WLED_DISABLE_HUESYNC -D WLED_USE_ANALOG_LEDS -D WLED_USE_H801 +board_build.ldscript = ${common:esp8266_1M.board_build.ldscript} lib_deps = ${common.lib_deps_external} lib_compat_mode = strict @@ -260,6 +267,7 @@ build_flags = -D WLED_USE_ANALOG_LEDS -D WLED_USE_H801 -D WLED_ENABLE_5CH_LEDS +board_build.ldscript = ${common:esp8266_1M.board_build.ldscript} lib_deps = ${common.lib_deps_external} lib_compat_mode = strict From a776b8ac31d6bf552db4cbdeb971114809dc7e2d Mon Sep 17 00:00:00 2001 From: Def3nder Date: Wed, 26 Feb 2020 11:17:56 +0100 Subject: [PATCH 073/509] Refactor platformio.ini (#721) * Override script updated accordingly * ldscriipt for 1m0 adjusted * backup files deleted * deletion of wled00,ino.cpp * remove travis build from PIO --- platformio.ini | 363 +++++++++++++------------------- platformio_override.ini.example | 29 ++- 2 files changed, 163 insertions(+), 229 deletions(-) diff --git a/platformio.ini b/platformio.ini index fcbb7b285..5549cc179 100644 --- a/platformio.ini +++ b/platformio.ini @@ -2,273 +2,208 @@ ; Please visit documentation: https://docs.platformio.org/page/projectconf.html [platformio] -src_dir = ./wled00 +src_dir = ./wled00 data_dir = ./wled00/data -;lib_extra_dirs = ./wled00/src -lib_dir = ./wled00/src -extra_configs = platformio_override.ini +lib_dir = ./wled00/src +extra_configs = + platformio_override.ini + ; Please uncomment one of the 5 lines below to select your board default_envs = nodemcuv2 ; default_envs = esp01 ; default_envs = esp01_1m ; default_envs = esp07 ; default_envs = d1_mini +; default_envs = d1_mini_debug ; default_envs = esp32dev ; default_envs = esp8285_4CH_MagicHome ; default_envs = esp8285_4CH_H801 ; default_envs = esp8285_5CH_H801 + # Release binaries follow -; default_envs = nodemcuv2, esp01, esp01_1m, esp32dev, - - +; default_envs = nodemcuv2, esp01, esp01_1m, esp32dev [common] -framework = arduino -monitor_speed = 115200 -board_build.flash_mode = dout -upload_speed = 115200 -upload_speed_fast = 921600 -build_flags = - -w ; supresses all C/C++ warnings - ; -D VERSION=0.8.5 - ; -D DEBUG - #build_flags for the IRremoteESP8266 library (enabled decoders have to appear here) - -D _IR_ENABLE_DEFAULT_=false - -D DECODE_HASH=true - -D DECODE_NEC=true - -D DECODE_SONY=true - -D DECODE_SAMSUNG=true - -D DECODE_LG=true - -# TODO replace libs in /lib with managed libs in here if possible. -# If they are not changed it's just a matter of setting the correct version and change the import statement -lib_deps_external = - #Blynk@0.5.4(changed) - #E131@1.0.0(changed) - FastLED@3.3.2 - NeoPixelBus@2.5.6 - ESPAsyncTCP@1.2.0 - ESPAsyncUDP@697c75a025 - AsyncTCP@1.0.3 - Esp Async WebServer@1.2.0 - #ArduinoJson@5.13.5 - #IRremoteESP8266@2.7.2 - https://github.com/crankyoldgit/IRremoteESP8266.git - #Time@1.5 - #Timezone@1.2.1 - #For use SSD1306 OLED display uncomment following - #U8g2@~2.27.2 - #For Dallas sensor uncomment following 2 lines - #DallasTemperature@~3.8.0 - #OneWire@~2.3.5 -[common:esp8266] # ------------------------------------------------------------------------------ # PLATFORM: # !! DO NOT confuse platformio's ESP8266 development platform with Arduino core for ESP8266 -# We use Arduino Core 2.5.0 (platformIO 2.0.4) as default # # arduino core 2.3.0 = platformIO 1.5.0 # arduino core 2.4.0 = platformIO 1.6.0 # arduino core 2.4.1 = platformIO 1.7.3 # arduino core 2.4.2 = platformIO 1.8.0 # arduino core 2.5.0 = platformIO 2.0.4 -# arduino core stage = platformIO feature#stage +# arduino core 2.5.1 = platformIO 2.1.1 +# arduino core 2.5.2 = platformIO 2.2.3 +# arduino core 2.6.1 = platformIO 2.3.0 +# arduino core 2.6.2 = platformIO 2.3.1 +# arduino core 2.6.3 = platformIO 2.3.2 # ------------------------------------------------------------------------------ arduino_core_2_3_0 = espressif8266@1.5.0 arduino_core_2_4_0 = espressif8266@1.6.0 arduino_core_2_4_1 = espressif8266@1.7.3 arduino_core_2_4_2 = espressif8266@1.8.0 arduino_core_2_5_0 = espressif8266@2.0.4 +arduino_core_2_5_1 = espressif8266@2.1.1 arduino_core_2_5_2 = espressif8266@2.2.3 arduino_core_2_6_1 = espressif8266@2.3.0 arduino_core_2_6_2 = espressif8266@2.3.1 -arduino_core_2_6_3 = espressif8266@2.3.3 -arduino_core_stage = https://github.com/platformio/platform-espressif8266.git#feature/stage -platform = ${common:esp8266.arduino_core_2_6_3} -build_flags = - -D ESP8266 - -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH -board_build.ldscript = eagle.flash.4m1m.ld ;;;; Required for core > v2.5.0 or staging version 4MB Flash 3MB SPIFFs -lib_ignore = AsyncTCP +arduino_core_2_6_3 = espressif8266@2.3.2 -[common:esp8266_1M] -platform = ${common:esp8266.arduino_core_2_6_3} -build_flags = - -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH - ; -D WLED_DISABLE_OTA - ; -D WLED_DISABLE_ALEXA - -D WLED_DISABLE_BLYNK - -D WLED_DISABLE_CRONIXIE - ; -D WLED_DISABLE_HUESYNC - -D WLED_DISABLE_INFRARED -board_build.ldscript = eagle.flash.1m.ld ;;;; Compile with no SPIFFS to leave space for OTA -lib_ignore = ${common:esp8266.lib_ignore} +# Development platforms +arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop +arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage -[common:esp8266_512k] -platform = ${common:esp8266.arduino_core_2_6_3} -build_flags = - -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH - -D WLED_DISABLE_OTA - -D WLED_DISABLE_ALEXA - -D WLED_DISABLE_BLYNK - -D WLED_DISABLE_CRONIXIE - -D WLED_DISABLE_HUESYNC - -D WLED_DISABLE_INFRARED -board_build.ldscript = eagle.flash.512k.ld ;;;; Compile with no SPIFFS -lib_ignore = ${common:esp8266.lib_ignore} +platform = ${common.arduino_core_2_4_2} +platform_latest = ${common.arduino_core_2_6_3} -[common:esp32] -platform = espressif32@1.11.2 -build_flags = - -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH - -D ARDUINO_ARCH_ESP32 -lib_ignore = - ESPAsyncTCP - ESPAsyncUDP +# ------------------------------------------------------------------------------ +# FLAGS: DEBUG +# +# ------------------------------------------------------------------------------ +debug_flags = -D DEBUG=1 -D WLED_DEBUG -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_TLS_MEM +#if needed (for memleaks etc) also add; -DDEBUG_ESP_OOM -include "umm_malloc/umm_malloc_cfg.h" + +# ------------------------------------------------------------------------------ +# FLAGS: ldscript +# ldscript_512k ( 512 KB) = 487 KB sketch, 4 KB eeprom, no spiffs, 16 KB reserved +# ldscript_1m0m (1024 KB) = 999 KB sketch, 4 KB eeprom, no spiffs, 16 KB reserved +# ldscript_2m1m (2048 KB) = 1019 KB sketch, 4 KB eeprom, 1004 KB spiffs, 16 KB reserved +# ldscript_4m1m (4096 KB) = 1019 KB sketch, 4 KB eeprom, 1002 KB spiffs, 16 KB reserved, 2048 KB empty/ota? +# ldscript_4m3m (4096 KB) = 1019 KB sketch, 4 KB eeprom, 3040 KB spiffs, 16 KB reserved +# +# Available lwIP variants (macros): +# -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH = v1.4 Higher Bandwidth (default) +# -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY = v2 Lower Memory +# -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH = v2 Higher Bandwidth +# +# BearSSL performance: +# When building with -DSECURE_CLIENT=SECURE_CLIENT_BEARSSL, please add `board_build.f_cpu = 160000000` to the environment configuration +# +# BearSSL ciphers: +# When building on core >= 2.5, you can add the build flag -DBEARSSL_SSL_BASIC in order to build BearSSL with a limited set of ciphers: +# TLS_RSA_WITH_AES_128_CBC_SHA256 / AES128-SHA256 +# TLS_RSA_WITH_AES_256_CBC_SHA256 / AES256-SHA256 +# TLS_RSA_WITH_AES_128_CBC_SHA / AES128-SHA +# TLS_RSA_WITH_AES_256_CBC_SHA / AES256-SHA +# This reduces the OTA size with ~45KB, so it's especially useful on low memory boards (512k/1m). +# ------------------------------------------------------------------------------ +build_flags = -g -w -DMQTT_MAX_PACKET_SIZE=1024 -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH + -DSECURE_CLIENT=SECURE_CLIENT_BEARSSL -DBEARSSL_SSL_BASIC +build_flags_esp8266 = ${common.build_flags} -DESP8266 +build_flags_esp32 = ${common.build_flags} -DARDUINO_ARCH_ESP32 + +ldscript_512k = eagle.flash.512k.ld ;for older versions change this to eagle.flash.512k0.ld +ldscript_1m0m = eagle.flash.1m.ld ;for older versions change this to eagle.flash.1m0.ld +ldscript_2m1m = eagle.flash.2m1m.ld +ldscript_4m1m = eagle.flash.4m1m.ld +ldscript_4m3m = eagle.flash.4m3m.ld + +shared_libdeps_dir = ./wled00/src + +# ------------------------------------------------------------------------------ +# COMMON SETTINGS: +# ------------------------------------------------------------------------------ +[env] +framework = arduino +board_build.flash_mode = dout +monitor_speed = 115200 +upload_speed = 115200 +lib_extra_dirs = + ${common.shared_libdeps_dir} + +# ------------------------------------------------------------------------------ +# LIBRARIES: required dependencies +# Please note that we don't always use the latest version of a library. +# +# The following libraries have been included (and some of them changd) in the source: +# ArduinoJson@5.13.5, Blynk@0.5.4(changed), E131@1.0.0(changed), Time@1.5, Timezone@1.2.1 +# ------------------------------------------------------------------------------ +lib_compat_mode = strict +lib_deps = + FastLED@3.3.2 + NeoPixelBus@2.5.6 + ESPAsyncTCP@1.2.0 + ESPAsyncUDP@697c75a025 + AsyncTCP@1.0.3 + Esp Async WebServer@1.2.0 + IRremoteESP8266@2.7.3 + #For use SSD1306 OLED display uncomment following + #U8g2@~2.27.2 + #For Dallas sensor uncomment following 2 lines + #DallasTemperature@~3.8.0 + #OneWire@~2.3.5 +lib_ignore = + AsyncTCP + +# ------------------------------------------------------------------------------ +# WLED BUILDS +# ------------------------------------------------------------------------------ -# see: http://docs.platformio.org/en/latest/platforms/espressif8266.html [env:nodemcuv2] board = nodemcuv2 -platform = ${common:esp8266.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp8266.build_flags} -board_build.ldscript = ${common:esp8266.board_build.ldscript} -lib_deps = - ${common.lib_deps_external} -lib_compat_mode = strict -lib_ignore = ${common:esp8266.lib_ignore} - -[env:d1_mini] -board = d1_mini -platform = ${common:esp8266.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp8266.build_flags} -board_build.ldscript = ${common:esp8266.board_build.ldscript} -lib_deps = - ${common.lib_deps_external} -lib_compat_mode = strict -lib_ignore = ${common:esp8266.lib_ignore} - -[env:esp01_1m] -board = esp01_1m -platform = ${common:esp8266_1M.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp8266_1M.build_flags} - # disable IR because there is no pin for it - -D WLED_DISABLE_INFRARED -board_build.ldscript = ${common:esp8266_1M.board_build.ldscript} -lib_deps = - ${common.lib_deps_external} -lib_compat_mode = strict -lib_ignore = ${common:esp8266.lib_ignore} +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_4m1m} +build_flags = ${common.build_flags_esp8266} [env:esp01] board = esp01 -platform = ${common:esp8266_512k.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp8266_512k.build_flags} -board_build.ldscript = ${common:esp8266_512k.board_build.ldscript} -lib_deps = - ${common.lib_deps_external} -lib_compat_mode = strict -lib_ignore = ${common:esp8266.lib_ignore} +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_512k} +build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK + -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED + +[env:esp01_1m] +board = esp01_1m +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_1m0m} +build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_INFRARED [env:esp07] board = esp07 -platform = ${common:esp8266.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp8266.build_flags} -board_build.ldscript = ${common:esp8266.board_build.ldscript} -lib_deps = - ${common.lib_deps_external} -lib_compat_mode = strict -lib_ignore = ${common:esp8266.lib_ignore} +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_4m1m} +build_flags = ${common.build_flags_esp8266} + +[env:d1_mini] +board = d1_mini +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_4m1m} +build_flags = ${common.build_flags_esp8266} -# see: http://docs.platformio.org/en/latest/platforms/espressif32.html [env:esp32dev] board = esp32dev -platform = ${common:esp32.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed_fast} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp32.build_flags} -lib_deps = - ${common.lib_deps_external} -lib_ignore = ${common:esp32.lib_ignore} -lib_compat_mode = strict +platform = espressif32@1.11.2 +build_flags = ${common.build_flags_esp32} +lib_ignore = + ESPAsyncTCP + ESPAsyncUDP [env:esp8285_4CH_MagicHome] board = esp8285 -platform = ${common:esp8266_1M.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp8266_1M.build_flags} - -D WLED_DISABLE_HUESYNC - -D WLED_USE_ANALOG_LEDS -board_build.ldscript = ${common:esp8266_1M.board_build.ldscript} -lib_deps = - ${common.lib_deps_external} -lib_compat_mode = strict -lib_ignore = ${common:esp8266.lib_ignore} +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_1m0m} +build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_HUESYNC -D WLED_USE_ANALOG_LEDS [env:esp8285_4CH_H801] board = esp8285 -platform = ${common:esp8266_1M.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp8266_1M.build_flags} - -D WLED_DISABLE_HUESYNC - -D WLED_USE_ANALOG_LEDS - -D WLED_USE_H801 -board_build.ldscript = ${common:esp8266_1M.board_build.ldscript} -lib_deps = - ${common.lib_deps_external} -lib_compat_mode = strict -lib_ignore = ${common:esp8266.lib_ignore} +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_1m0m} +build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_HUESYNC -D WLED_USE_ANALOG_LEDS -D WLED_USE_H801 [env:esp8285_5CH_H801] board = esp8285 -platform = ${common:esp8266_1M.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp8266_1M.build_flags} - -D WLED_DISABLE_HUESYNC - -D WLED_USE_ANALOG_LEDS - -D WLED_USE_H801 - -D WLED_ENABLE_5CH_LEDS -board_build.ldscript = ${common:esp8266_1M.board_build.ldscript} -lib_deps = - ${common.lib_deps_external} -lib_compat_mode = strict -lib_ignore = ${common:esp8266.lib_ignore} +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_1m0m} +build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_HUESYNC -D WLED_USE_ANALOG_LEDS -D WLED_USE_H801 -D WLED_ENABLE_5CH_LEDS + +# ------------------------------------------------------------------------------ +# DEVELOPMENT BOARDS +# ------------------------------------------------------------------------------ + +[env:d1_mini_debug] +board = d1_mini +build_type = debug +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_4m1m} +build_flags = ${common.build_flags_esp8266} ${common.debug_flags} diff --git a/platformio_override.ini.example b/platformio_override.ini.example index 03a77056a..09c301728 100644 --- a/platformio_override.ini.example +++ b/platformio_override.ini.example @@ -1,18 +1,17 @@ -; Example PlatformIO Project Configuration Override -; ------------------------------------------------------------------------------ -; Copy to platformio_override.ini to activate overrides -; ------------------------------------------------------------------------------ -; Please visit documentation: https://docs.platformio.org/page/projectconf.html +# Example PlatformIO Project Configuration Override +# ------------------------------------------------------------------------------ +# Copy to platformio_override.ini to activate overrides +# ------------------------------------------------------------------------------ +# Please visit documentation: https://docs.platformio.org/page/projectconf.html [env:esp8266_1m_custom] -platform = ${common:esp8266.arduino_core_2_6_3} -build_flags = - -D PIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH - -Wl,-Teagle.flash.1m.ld ;;;; Compile with no SPIFFS to leave space for OTA - ; -D WLED_DISABLE_OTA - -D WLED_DISABLE_ALEXA +board = esp01_1m +platform = ${common.arduino_core_2_4_2} +board_build.ldscript = ${common.ldscript_1m0m} +build_flags = ${common.build_flags_esp8266} + -D WLED_DISABLE_OTA + -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK - -D WLED_DISABLE_CRONIXIE - -D WLED_DISABLE_HUESYNC - -D WLED_DISABLE_INFRARED -lib_ignore = ${common:esp8266.lib_ignore} \ No newline at end of file + -D WLED_DISABLE_CRONIXIE + -D WLED_DISABLE_HUESYNC + -D WLED_DISABLE_INFRARED \ No newline at end of file From 81da8261a00fe9e3e7a4ec7780fae3be8c5b2783 Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Wed, 26 Feb 2020 19:16:33 -0500 Subject: [PATCH 074/509] Added board heltec_wifi_kit_8 --- platformio.ini | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platformio.ini b/platformio.ini index 5549cc179..3300c58ae 100644 --- a/platformio.ini +++ b/platformio.ini @@ -14,6 +14,7 @@ default_envs = nodemcuv2 ; default_envs = esp01_1m ; default_envs = esp07 ; default_envs = d1_mini +; default_envs = heltec_wifi_kit_8 ; default_envs = d1_mini_debug ; default_envs = esp32dev ; default_envs = esp8285_4CH_MagicHome @@ -171,6 +172,12 @@ platform = ${common.platform_latest} board_build.ldscript = ${common.ldscript_4m1m} build_flags = ${common.build_flags_esp8266} +[env:heltec_wifi_kit_8] +board = d1_mini +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_4m1m} +build_flags = ${common.build_flags_esp8266} + [env:esp32dev] board = esp32dev platform = espressif32@1.11.2 From 57d3120b45f7ce48149db3732ecabab9da9b1656 Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Wed, 26 Feb 2020 19:21:57 -0500 Subject: [PATCH 075/509] Grammar correction --- usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino index 58a4e0e6a..576795fb4 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino @@ -31,7 +31,7 @@ U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_ // --> Second choise of cheap I2C OLED 128X64 0.96" or 1.3" //U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA // --> Third choise of Heltec WiFi-Kit-8 OLED 128X32 0.91" -//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_RESET, U8X8_PIN_SCL, U8X8_PIN_SDA); // Constracor for Heltec WiFi-Kit-8 +//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_RESET, U8X8_PIN_SCL, U8X8_PIN_SDA); // Constructor for Heltec WiFi-Kit-8 // gets called once at boot. Do all initialization that doesn't depend on // network here void userSetup() { From e3269f6edce9fe21212bf7a3fee17af56ae86037 Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Wed, 26 Feb 2020 20:36:27 -0500 Subject: [PATCH 076/509] Update wled06_usermod.ino --- usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino index 576795fb4..d75cf0a74 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino @@ -32,8 +32,7 @@ U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_ //U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA // --> Third choise of Heltec WiFi-Kit-8 OLED 128X32 0.91" //U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_RESET, U8X8_PIN_SCL, U8X8_PIN_SDA); // Constructor for Heltec WiFi-Kit-8 -// gets called once at boot. Do all initialization that doesn't depend on -// network here +// gets called once at boot. Do all initialization that doesn't depend on network here void userSetup() { sensor.begin(); //Start Dallas temperature sensor u8x8.begin(); From 9eb646085eac4cbfe97454ed78d7154efc86467d Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Thu, 27 Feb 2020 09:52:48 +0100 Subject: [PATCH 077/509] Reduce CPU load during interrupt handler See https://github.com/esp8266/Arduino/pull/7057#issuecomment-591632232 --- .../dependencies/arduino/core_esp8266_waveform.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/wled00/src/dependencies/arduino/core_esp8266_waveform.cpp b/wled00/src/dependencies/arduino/core_esp8266_waveform.cpp index 6a52b1b3a..57b3c315c 100644 --- a/wled00/src/dependencies/arduino/core_esp8266_waveform.cpp +++ b/wled00/src/dependencies/arduino/core_esp8266_waveform.cpp @@ -224,8 +224,8 @@ static ICACHE_RAM_ATTR void timer1Interrupt() { endPin = 32 - __builtin_clz(waveformEnabled); } - if (waveformEnabled) { bool done = false; + if (waveformEnabled) { do { nextEventCycles = microsecondsToClockCycles(MAXIRQUS); for (int i = startPin; i <= endPin; i++) { @@ -257,7 +257,13 @@ static ICACHE_RAM_ATTR void timer1Interrupt() { // Check for toggles int32_t cyclesToGo = wave->nextServiceCycle - now; if (cyclesToGo < 0) { - cyclesToGo = -((-cyclesToGo) % (wave->nextTimeHighCycles + wave->nextTimeLowCycles)); + // See #7057 + // The following is a no-op unless we have overshot by an entire waveform cycle. + // As modulus is an expensive operation, this code is removed for now: + // cyclesToGo = -((-cyclesToGo) % (wave->nextTimeHighCycles + wave->nextTimeLowCycles)); + // + // Alternative version with lower CPU impact: + // while (-cyclesToGo > wave->nextTimeHighCycles + wave->nextTimeLowCycles) { cyclesToGo += wave->nextTimeHighCycles + wave->nextTimeLowCycles)}; waveformState ^= mask; if (waveformState & mask) { if (i == 16) { @@ -309,4 +315,4 @@ static ICACHE_RAM_ATTR void timer1Interrupt() { } }; -#endif \ No newline at end of file +#endif From cffee7bfa7902f417fa34a6b439fd77c92bd9800 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Fri, 28 Feb 2020 16:27:18 +0100 Subject: [PATCH 078/509] Fix 24-key IR remote (#738) --- wled00/wled20_ir.ino | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/wled00/wled20_ir.ino b/wled00/wled20_ir.ino index 617518c31..c65a4c58e 100644 --- a/wled00/wled20_ir.ino +++ b/wled00/wled20_ir.ino @@ -90,8 +90,8 @@ void decodeIR(uint32_t code) // sets bright plain white default: return; } - colorUpdated(NOTIFIER_CALL_MODE_BUTTON); //for notifier, IR is considered a button input } + colorUpdated(NOTIFIER_CALL_MODE_BUTTON); //for notifier, IR is considered a button input //code <= 0xF70000 also invalid } @@ -356,25 +356,25 @@ void decodeIR6(uint32_t code) /* next palette */ relativeChange(&effectPalette, 1); switch(lastIR6ColourIdx) { - case 0: colorFromUint32(COLOR_RED); break; - case 1: colorFromUint32(COLOR_REDDISH); break; - case 2:colorFromUint32(COLOR_ORANGE); break; - case 3:colorFromUint32(COLOR_YELLOWISH); break; - case 4:colorFromUint32(COLOR_GREEN); break; - case 5:colorFromUint32(COLOR_GREENISH); break; - case 6:colorFromUint32(COLOR_TURQUOISE); break; - case 7: colorFromUint32(COLOR_CYAN); break; - case 8:colorFromUint32(COLOR_BLUE); break; - case 9:colorFromUint32(COLOR_DEEPBLUE); break; - case 10:colorFromUint32(COLOR_PURPLE); break; - case 11:colorFromUint32(COLOR_PINK); break; - case 12:colorFromUint32(COLOR_WHITE); break; - default:break; + case 0: colorFromUint32(COLOR_RED); break; + case 1: colorFromUint32(COLOR_REDDISH); break; + case 2: colorFromUint32(COLOR_ORANGE); break; + case 3: colorFromUint32(COLOR_YELLOWISH); break; + case 4: colorFromUint32(COLOR_GREEN); break; + case 5: colorFromUint32(COLOR_GREENISH); break; + case 6: colorFromUint32(COLOR_TURQUOISE); break; + case 7: colorFromUint32(COLOR_CYAN); break; + case 8: colorFromUint32(COLOR_BLUE); break; + case 9: colorFromUint32(COLOR_DEEPBLUE); break; + case 10:colorFromUint32(COLOR_PURPLE); break; + case 11:colorFromUint32(COLOR_PINK); break; + case 12:colorFromUint32(COLOR_WHITE); break; + default: break; } lastIR6ColourIdx++; if(lastIR6ColourIdx > 12) lastIR6ColourIdx = 0; break; - case IR6_MUTE: effectCurrent = 0; effectPalette = 0; colorFromUint32(COLOR_WHITE); bri=255; break; + case IR6_MUTE: effectCurrent = 0; effectPalette = 0; colorFromUint32(COLOR_WHITE); bri=255; break; } lastValidCode = code; } From 480e7f5b5463a8c34f169e01791d0005d70c5125 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Fri, 28 Feb 2020 18:53:38 +0100 Subject: [PATCH 079/509] Add all release environments to platformio.ini (#736) --- platformio.ini | 37 +++++++++++++++++++++++++++++---- platformio_override.ini.example | 19 ++++++++++++++++- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/platformio.ini b/platformio.ini index 5549cc179..9128d50e2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -21,7 +21,7 @@ default_envs = nodemcuv2 ; default_envs = esp8285_5CH_H801 # Release binaries follow -; default_envs = nodemcuv2, esp01, esp01_1m, esp32dev +; default_envs = nodemcuv2, esp01, esp01_1m, esp32dev, custom_WS2801, custom_APA102, custom_LEDPIN_16, custom_LEDPIN_4 [common] # ------------------------------------------------------------------------------ @@ -48,7 +48,7 @@ arduino_core_2_5_1 = espressif8266@2.1.1 arduino_core_2_5_2 = espressif8266@2.2.3 arduino_core_2_6_1 = espressif8266@2.3.0 arduino_core_2_6_2 = espressif8266@2.3.1 -arduino_core_2_6_3 = espressif8266@2.3.2 +arduino_core_2_6_3 = espressif8266@2.3.3 # Development platforms arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop @@ -61,8 +61,9 @@ platform_latest = ${common.arduino_core_2_6_3} # FLAGS: DEBUG # # ------------------------------------------------------------------------------ -debug_flags = -D DEBUG=1 -D WLED_DEBUG -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_TLS_MEM +debug_flags = -D DEBUG=1 -D WLED_DEBUG -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_TLS_MEM #if needed (for memleaks etc) also add; -DDEBUG_ESP_OOM -include "umm_malloc/umm_malloc_cfg.h" +#-DDEBUG_ESP_CORE is not working right now # ------------------------------------------------------------------------------ # FLAGS: ldscript @@ -88,7 +89,7 @@ debug_flags = -D DEBUG=1 -D WLED_DEBUG -DDEBUG_ESP_CORE -DDEBUG_ESP_WIFI -DDEBUG # TLS_RSA_WITH_AES_256_CBC_SHA / AES256-SHA # This reduces the OTA size with ~45KB, so it's especially useful on low memory boards (512k/1m). # ------------------------------------------------------------------------------ -build_flags = -g -w -DMQTT_MAX_PACKET_SIZE=1024 -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH +build_flags = -g -w -DMQTT_MAX_PACKET_SIZE=1024 -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH -DSECURE_CLIENT=SECURE_CLIENT_BEARSSL -DBEARSSL_SSL_BASIC build_flags_esp8266 = ${common.build_flags} -DESP8266 build_flags_esp32 = ${common.build_flags} -DARDUINO_ARCH_ESP32 @@ -207,3 +208,31 @@ build_type = debug platform = ${common.platform_latest} board_build.ldscript = ${common.ldscript_4m1m} build_flags = ${common.build_flags_esp8266} ${common.debug_flags} + +# ------------------------------------------------------------------------------ +# custom board configurations +# ------------------------------------------------------------------------------ + +[env:custom_LEDPIN_4] +board = d1_mini +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_4m1m} +build_flags = ${common.build_flags_esp8266} -D LEDPIN=4 -D IRPIN=5 + +[env:custom_LEDPIN_16] +board = d1_mini +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_4m1m} +build_flags = ${common.build_flags_esp8266} -D LEDPIN=16 + +[env:custom_APA102] +board = d1_mini +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_4m1m} +build_flags = ${common.build_flags_esp8266} -D USE_APA102 + +[env:custom_WS2801] +board = d1_mini +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_4m1m} +build_flags = ${common.build_flags_esp8266} -D USE_WS2801 diff --git a/platformio_override.ini.example b/platformio_override.ini.example index 09c301728..46119f159 100644 --- a/platformio_override.ini.example +++ b/platformio_override.ini.example @@ -14,4 +14,21 @@ build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC - -D WLED_DISABLE_INFRARED \ No newline at end of file + -D WLED_DISABLE_INFRARED +; PIN defines - uncomment and change, if needed: +; -D LEDPIN=2 +; -D BTNPIN=0 +; -D IR_PIN=4 +; -D RLYPIN=12 +; -D RLYMDE=1 +; digital LED strip types - uncomment only one ! - this will disable WS281x / SK681x support +; -D USE_APA102 +; -D USE_WS2801 +; -D USE_LPD8806 +; to drive analog LED strips (aka 5050), uncomment the following +; PWM pins 5,12,13,15 are used with Magic Home LED Controller (default) +; -D WLED_USE_ANALOG_LEDS +; for the H801 controler (PINs 15,13,12,14 (W2 = 04)) uncomment this +; -D WLED_USE_H801 +; and to enable channel 5 for RGBW-CT led strips this +; -D WLED_USE_5CH_LEDS From d0d56c4416203a5bc7991fbe13858656cdbdf69f Mon Sep 17 00:00:00 2001 From: Def3nder Date: Sat, 29 Feb 2020 16:30:15 +0100 Subject: [PATCH 080/509] Travis.CI builds only for default_envs (#739) --- .travis.yml | 14 +++++++++++--- platformio.ini | 20 +++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5d9762615..882fe54aa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,18 +18,26 @@ # it (remove "# " before each line) or use own configuration according to the # Travis CI documentation (see above). # +# * Test the Travis config here: +# < https://config.travis-ci.com/explore > +# language: python python: - - "2.7" -sudo: false + # - "2.7" + - "3.5" +os: linux cache: + bundler: true + ccache: true directories: - "~/.platformio" + - "~/.buildcache" env: - PLATFORMIO_CI_SRC=wled00 install: - pip install -U platformio - platformio update script: - - platformio ci --project-conf=./platformio.ini + # - platformio ci --project-conf=./platformio.ini + - platformio run \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 9128d50e2..ed95659ea 100644 --- a/platformio.ini +++ b/platformio.ini @@ -5,11 +5,24 @@ src_dir = ./wled00 data_dir = ./wled00/data lib_dir = ./wled00/src +build_cache_dir = ~/.buildcache extra_configs = platformio_override.ini -; Please uncomment one of the 5 lines below to select your board -default_envs = nodemcuv2 +# ------------------------------------------------------------------------------ +# ENVIRONMENTS +# +# Please uncomment one of the lines below to select your board(s) +# ------------------------------------------------------------------------------ + +# Travis CI binaries +default_envs = d1_mini, esp01, esp01_1m, esp32dev + +# Release binaries follow +; default_envs = nodemcuv2, esp01, esp01_1m, esp32dev, custom_WS2801, custom_APA102, custom_LEDPIN_16, custom_LEDPIN_4 + +# Single binaries +; default_envs = nodemcuv2 ; default_envs = esp01 ; default_envs = esp01_1m ; default_envs = esp07 @@ -20,9 +33,6 @@ default_envs = nodemcuv2 ; default_envs = esp8285_4CH_H801 ; default_envs = esp8285_5CH_H801 -# Release binaries follow -; default_envs = nodemcuv2, esp01, esp01_1m, esp32dev, custom_WS2801, custom_APA102, custom_LEDPIN_16, custom_LEDPIN_4 - [common] # ------------------------------------------------------------------------------ # PLATFORM: From 14a5ab6740269a21986cf5971962fe65e85b107b Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 29 Feb 2020 18:24:51 +0100 Subject: [PATCH 081/509] Fixed Chase modes --- wled00/FX.cpp | 135 ++++++++++++++++++++++++---------------------- wled00/wled00.ino | 2 +- 2 files changed, 71 insertions(+), 66 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index eb0435224..022b4b232 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -379,7 +379,7 @@ uint16_t WS2812FX::mode_rainbow_cycle(void) { /* * theater chase function */ -uint16_t WS2812FX::theater_chase(uint32_t color1, uint32_t color2, bool dopalette) { +uint16_t WS2812FX::theater_chase(uint32_t color1, uint32_t color2, bool do_palette) { byte gap = 2 + ((255 - SEGMENT.intensity) >> 5); uint32_t cycleTime = 50 + (255 - SEGMENT.speed)*2; uint32_t it = now / cycleTime; @@ -391,7 +391,7 @@ uint16_t WS2812FX::theater_chase(uint32_t color1, uint32_t color2, bool dopalett for(uint16_t i = 0; i < SEGLEN; i++) { if((i % gap) == SEGENV.aux0) { - if (dopalette) + if (do_palette) { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } else { @@ -690,58 +690,68 @@ uint16_t WS2812FX::mode_android(void) { * color1 = background color * color2 and color3 = colors of two adjacent leds */ -uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, bool dopalette) { +uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do_palette) { uint16_t counter = now * ((SEGMENT.speed >> 2) + 1); uint16_t a = counter * SEGLEN >> 16; + + bool chase_random = (SEGMENT.mode == FX_MODE_CHASE_RANDOM); + if (chase_random) { + if (a < SEGENV.step) //we hit the start again, choose new color for Chase random + { + SEGENV.aux1 = SEGENV.aux0; //store previous random color + SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0); + } + color1 = color_wheel(SEGENV.aux0); + } SEGENV.step = a; - uint8_t size = 1 + (SEGMENT.intensity * SEGLEN >> 10); - if (SEGENV.call == 0) {SEGENV.aux0 = 0; SEGENV.aux1 = a;} + // Use intensity setting to vary chase up to 1/2 string length - uint16_t b = (a + size) % SEGLEN; - uint16_t c = (b + size) % SEGLEN; + uint8_t size = 1 + (SEGMENT.intensity * SEGLEN >> 10); - if (dopalette) color1 = color_from_palette(a, true, PALETTE_SOLID_WRAP, 1); + uint16_t b = a + size; //"trail" of chase, filled with color1 + if (b > SEGLEN) b -= SEGLEN; + uint16_t c = b + size; + if (c > SEGLEN) c -= SEGLEN; - setPixelColor(a, color1); - if (SEGENV.aux0 == 0) { // catch the first pixels after color change from "chase random" (because they have the "old" color) - for (uint16_t i = 0; i < a; i++) { - uint32_t color = getPixelColor(0); - setPixelColor(i, color1); + //background + if (do_palette) + { + for(uint16_t i = 0; i < SEGLEN; i++) { + setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } - SEGENV.aux0 = 1; - } - setPixelColor(b, color2); - setPixelColor(c, color3); + } else fill(color1); - if (a != SEGENV.aux1) { // when speed is too fast, this catches the gaps - if (a > SEGENV.aux1) { - for (uint16_t i = SEGENV.aux1; i <= a; i++) { // sometimes the step-length varies from one to the next call - therefor "<= a" and not "< a" - setPixelColor(i, color1); - uint16_t b1 = (i + size) % SEGLEN; - uint16_t c1 = (b1 + size) % SEGLEN; - setPixelColor(b1, color2); - setPixelColor(c1, color3); - } - } else { - for (uint16_t i = SEGENV.aux1; i <= SEGLEN; i++) { // from last position to the end - setPixelColor(i, color1); - uint16_t b1 = (i + size) % SEGLEN; - uint16_t c1 = (b1 + size) % SEGLEN; - setPixelColor(b1, color2); - setPixelColor(c1, color3); - } - for (uint16_t i = 0; i < a; i++) { // from 0 to the actual position - setPixelColor(i, color1); - uint16_t b1 = (i + size) % SEGLEN; - uint16_t c1 = (b1 + size) % SEGLEN; - setPixelColor(b1, color2); - setPixelColor(c1, color3); - } - SEGENV.step = 0; - SEGENV.aux0 = 0; - } + //if random, fill old background between a and end + if (chase_random) + { + color1 = color_wheel(SEGENV.aux1); + for (uint16_t i = a; i < SEGLEN; i++) + setPixelColor(i, color1); + } + + //fill between points a and b with color2 + if (a < b) + { + for (uint16_t i = a; i < b; i++) + setPixelColor(i, color2); + } else { + for (uint16_t i = a; i < SEGLEN; i++) //fill until end + setPixelColor(i, color2); + for (uint16_t i = 0; i < b; i++) //fill from start until b + setPixelColor(i, color2); + } + + //fill between points b and c with color2 + if (b < c) + { + for (uint16_t i = b; i < c; i++) + setPixelColor(i, color3); + } else { + for (uint16_t i = b; i < SEGLEN; i++) //fill until end + setPixelColor(i, color3); + for (uint16_t i = 0; i < c; i++) //fill from start until c + setPixelColor(i, color3); } - SEGENV.aux1 = ++a; return FRAMETIME; } @@ -751,7 +761,7 @@ uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, bool * Bicolor chase, more primary color. */ uint16_t WS2812FX::mode_chase_color(void) { - return chase(SEGCOLOR(1), SEGCOLOR(0), SEGCOLOR(0), true); + return chase(SEGCOLOR(1), (SEGCOLOR(2)) ? SEGCOLOR(2) : SEGCOLOR(0), SEGCOLOR(0), true); } @@ -759,12 +769,19 @@ uint16_t WS2812FX::mode_chase_color(void) { * Primary running followed by random color. */ uint16_t WS2812FX::mode_chase_random(void) { - if (!SEGENV.allocateData(2)) return mode_static(); //allocation failed - if (SEGENV.call == 0) SEGENV.data[0] = 0; - if (SEGENV.step == 0) { - SEGENV.data[0] = get_random_wheel_index(SEGENV.data[0]); - } - return chase(color_wheel(SEGENV.data[0]), SEGCOLOR(0), SEGCOLOR(0), false); + return chase(SEGCOLOR(1), (SEGCOLOR(2)) ? SEGCOLOR(2) : SEGCOLOR(0), SEGCOLOR(0), false); +} + + +/* + * Primary, secondary running on rainbow. + */ +uint16_t WS2812FX::mode_chase_rainbow(void) { + uint8_t color_sep = 256 / SEGLEN; + uint8_t color_index = SEGENV.call & 0xFF; + uint32_t color = color_wheel(((SEGENV.step * color_sep) + color_index) & 0xFF); + + return chase(color, SEGCOLOR(0), SEGCOLOR(1), false); } @@ -860,18 +877,6 @@ uint16_t WS2812FX::mode_traffic_light(void) { } -/* - * Primary, secondary running on rainbow. - */ -uint16_t WS2812FX::mode_chase_rainbow(void) { - uint8_t color_sep = 256 / SEGLEN; - uint8_t color_index = SEGENV.call & 0xFF; - uint32_t color = color_wheel(((SEGENV.step * color_sep) + color_index) & 0xFF); - - return chase(color, SEGCOLOR(0), SEGCOLOR(1), 0); -} - - /* * Sec flashes running on prim. */ @@ -3161,4 +3166,4 @@ uint16_t WS2812FX::mode_heartbeat(void) { } return FRAMETIME; -} \ No newline at end of file +} diff --git a/wled00/wled00.ino b/wled00/wled00.ino index f214929ce..2ce923df2 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -119,7 +119,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2002252 +#define VERSION 2002291 char versionString[] = "0.9.1"; From 18dad0c72cce118b96126bbf9f622d64f1c94ee0 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 29 Feb 2020 18:42:55 +0100 Subject: [PATCH 082/509] Remove defunct presetApplyCol and presetApplyFx --- wled00/wled00.ino | 2 +- wled00/wled01_eeprom.ino | 34 +++++++++++++++------------------- wled00/wled03_set.ino | 10 ++-------- wled00/wled05_init.ino | 2 +- wled00/wled08_led.ino | 2 +- wled00/wled13_cronixie.ino | 12 ++++++------ 6 files changed, 26 insertions(+), 36 deletions(-) diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 2ce923df2..104592b0c 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -390,7 +390,7 @@ bool presetCyclingEnabled = false; byte presetCycleMin = 1, presetCycleMax = 5; uint16_t presetCycleTime = 1250; unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin; -bool presetApplyBri = false, presetApplyCol = true, presetApplyFx = true; +bool presetApplyBri = true; bool saveCurrPresetCycConf = false; //realtime diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index 703785c14..b0da64516 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -232,8 +232,8 @@ void saveSettingsToEEPROM() EEPROM.write(2208, presetCycleMin); EEPROM.write(2209, presetCycleMax); EEPROM.write(2210, presetApplyBri); - EEPROM.write(2211, presetApplyCol); - EEPROM.write(2212, presetApplyFx); + // was EEPROM.write(2211, presetApplyCol); + // was EEPROM.write(2212, presetApplyFx); saveCurrPresetCycConf = false; } @@ -519,8 +519,8 @@ void loadSettingsFromEEPROM(bool first) presetCycleMin = EEPROM.read(2208); presetCycleMax = EEPROM.read(2209); presetApplyBri = EEPROM.read(2210); - presetApplyCol = EEPROM.read(2211); - presetApplyFx = EEPROM.read(2212); + //was presetApplyCol = EEPROM.read(2211); + //was presetApplyFx = EEPROM.read(2212); } bootPreset = EEPROM.read(389); @@ -583,7 +583,7 @@ void savedToPresets() } } -bool applyPreset(byte index, bool loadBri = true, bool loadCol = true, bool loadFX = true) +bool applyPreset(byte index, bool loadBri = true) { if (index == 255 || index == 0) { @@ -596,22 +596,18 @@ bool applyPreset(byte index, bool loadBri = true, bool loadCol = true, bool load if (EEPROM.read(i) != 1) return false; strip.applyToAllSelected = true; if (loadBri) bri = EEPROM.read(i+1); - if (loadCol) + + for (byte j=0; j<4; j++) { - for (byte j=0; j<4; j++) - { - col[j] = EEPROM.read(i+j+2); - colSec[j] = EEPROM.read(i+j+6); - } - strip.setColor(2, EEPROM.read(i+12), EEPROM.read(i+13), EEPROM.read(i+14), EEPROM.read(i+15)); //tertiary color - } - if (loadFX) - { - effectCurrent = EEPROM.read(i+10); - effectSpeed = EEPROM.read(i+11); - effectIntensity = EEPROM.read(i+16); - effectPalette = EEPROM.read(i+17); + col[j] = EEPROM.read(i+j+2); + colSec[j] = EEPROM.read(i+j+6); } + strip.setColor(2, EEPROM.read(i+12), EEPROM.read(i+13), EEPROM.read(i+14), EEPROM.read(i+15)); //tertiary color + + effectCurrent = EEPROM.read(i+10); + effectSpeed = EEPROM.read(i+11); + effectIntensity = EEPROM.read(i+16); + effectPalette = EEPROM.read(i+17); } else { if (EEPROM.read(i) != 2) return false; strip.applyToAllSelected = false; diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 0f2cb9ef3..69a7d9b7a 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -460,18 +460,12 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) pos = req.indexOf("PA="); //apply brightness from preset if (pos > 0) presetApplyBri = (req.charAt(pos+3) != '0'); - pos = req.indexOf("PC="); //apply color from preset - if (pos > 0) presetApplyCol = (req.charAt(pos+3) != '0'); - - pos = req.indexOf("PX="); //apply effects from preset - if (pos > 0) presetApplyFx = (req.charAt(pos+3) != '0'); - pos = req.indexOf("PS="); //saves current in preset if (pos > 0) savePreset(getNumVal(&req, pos)); //apply preset if (updateVal(&req, "PL=", &presetCycCurr, presetCycleMin, presetCycleMax)) { - applyPreset(presetCycCurr, presetApplyBri, presetApplyCol, presetApplyFx); + applyPreset(presetCycCurr, presetApplyBri); } //set brightness @@ -653,7 +647,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) pos = req.indexOf("NB="); if (pos > 0) //sets backlight { - presetApplyFx = (req.charAt(pos+3) != '0'); + cronixieBacklight = (req.charAt(pos+3) != '0'); if (overlayCurrent == 3) strip.setCronixieBacklight(cronixieBacklight); overlayRefreshedTime = 0; } diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 40e3bef67..29ae0e7ab 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -100,7 +100,7 @@ void beginStrip() pinMode(BTNPIN, INPUT_PULLUP); #endif - if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true); + if (bootPreset > 0) applyPreset(bootPreset, turnOnAtBoot); colorUpdated(NOTIFIER_CALL_MODE_INIT); //init relay pin diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index 93642fc29..f6e8b4eea 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -251,7 +251,7 @@ void handleNightlight() //also handle preset cycle here if (presetCyclingEnabled && (millis() - presetCycledTime > presetCycleTime)) { - applyPreset(presetCycCurr,presetApplyBri,presetApplyCol,presetApplyFx); + applyPreset(presetCycCurr,presetApplyBri); presetCycCurr++; if (presetCycCurr > presetCycleMax) presetCycCurr = presetCycleMin; if (presetCycCurr > 25) presetCycCurr = 1; colorUpdated(NOTIFIER_CALL_MODE_PRESET_CYCLE); diff --git a/wled00/wled13_cronixie.ino b/wled00/wled13_cronixie.ino index de89aede2..897c94f92 100644 --- a/wled00/wled13_cronixie.ino +++ b/wled00/wled13_cronixie.ino @@ -97,8 +97,8 @@ void setCronixie() case '-': dP[i] = 11; break; case 'r': dP[i] = random(1,7); break; //random btw. 1-6 case 'R': dP[i] = random(0,10); break; //random btw. 0-9 - case 't': break; //Test upw. - case 'T': break; //Test dnw. + //case 't': break; //Test upw. + //case 'T': break; //Test dnw. case 'b': dP[i] = 14 + getSameCodeLength('b',i,cronixieDisplay); i = i+dP[i]-14; break; case 'B': dP[i] = 14 + getSameCodeLength('B',i,cronixieDisplay); i = i+dP[i]-14; break; case 'h': dP[i] = 70 + getSameCodeLength('h',i,cronixieDisplay); i = i+dP[i]-70; break; @@ -113,8 +113,8 @@ void setCronixie() case 'y': dP[i] = 86 + getSameCodeLength('y',i,cronixieDisplay); i = i+dP[i]-86; break; case 'I': dP[i] = 39 + getSameCodeLength('I',i,cronixieDisplay); i = i+dP[i]-39; break; //Month. Don't ask me why month and minute both start with M. case 'i': dP[i] = 89 + getSameCodeLength('i',i,cronixieDisplay); i = i+dP[i]-89; break; - case 'W': break; - case 'w': break; + //case 'W': break; + //case 'w': break; case 'D': dP[i] = 43 + getSameCodeLength('D',i,cronixieDisplay); i = i+dP[i]-43; break; case 'd': dP[i] = 93 + getSameCodeLength('d',i,cronixieDisplay); i = i+dP[i]-93; break; case '0': dP[i] = 0; break; @@ -127,8 +127,8 @@ void setCronixie() case '7': dP[i] = 7; break; case '8': dP[i] = 8; break; case '9': dP[i] = 9; break; - case 'V': break; //user var0 - case 'v': break; //user var1 + //case 'V': break; //user var0 + //case 'v': break; //user var1 } } DEBUG_PRINT("result "); From 79da716a449a189b9fca7e51abf2faedd472783c Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 29 Feb 2020 19:52:47 +0100 Subject: [PATCH 083/509] Split esp01_1m env into 1m_full and 1m_ota (closes #740 ) --- platformio.ini | 19 +++++++++++++------ wled00/wled00.ino | 4 +--- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/platformio.ini b/platformio.ini index ed95659ea..c4e79a716 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,15 +16,16 @@ extra_configs = # ------------------------------------------------------------------------------ # Travis CI binaries -default_envs = d1_mini, esp01, esp01_1m, esp32dev +default_envs = d1_mini, esp01, esp01_1m_ota, esp32dev # Release binaries follow -; default_envs = nodemcuv2, esp01, esp01_1m, esp32dev, custom_WS2801, custom_APA102, custom_LEDPIN_16, custom_LEDPIN_4 +; default_envs = nodemcuv2, esp01, esp01_1m_ota, esp01_1m_full, esp32dev, custom_WS2801, custom_APA102, custom_LEDPIN_16, custom_LEDPIN_4 # Single binaries ; default_envs = nodemcuv2 ; default_envs = esp01 -; default_envs = esp01_1m +; default_envs = esp01_1m_ota +; default_envs = esp01_1m_full ; default_envs = esp07 ; default_envs = d1_mini ; default_envs = d1_mini_debug @@ -162,13 +163,19 @@ board = esp01 platform = ${common.platform_latest} board_build.ldscript = ${common.ldscript_512k} build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK - -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED + -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED -[env:esp01_1m] +[env:esp01_1m_ota] board = esp01_1m platform = ${common.platform_latest} board_build.ldscript = ${common.ldscript_1m0m} -build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_INFRARED +build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED + +[env:esp01_1m_full] +board = esp01_1m +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_1m0m} +build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA [env:esp07] board = esp07 diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 104592b0c..fda0a110c 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -119,7 +119,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2002291 +#define VERSION 2002292 char versionString[] = "0.9.1"; @@ -541,8 +541,6 @@ bool oappendi(int i) //boot starts here void setup() { - - wledInit(); } From f28502514f39546dcc00e20e5bb86a5446261b28 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Sun, 1 Mar 2020 12:25:44 +0100 Subject: [PATCH 084/509] Remember lastColor and last Bri for Solid RGBW (#743) --- wled00/FX_fcn.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index ee0ca73ae..2392392de 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -863,7 +863,9 @@ void WS2812FX::setRgbwPwm(void) { } #else bus->SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255); - #endif + #endif + _analogLastColor = color; + _analogLastBri = b; } #else void WS2812FX::setRgbwPwm() {} From b804101c24b4b1d72516f3da2fdef44050e65728 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 2 Mar 2020 12:24:10 +0100 Subject: [PATCH 085/509] lift NeoPixelBus library to 2.5.7 (#747) --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index c4e79a716..0ef2630ce 100644 --- a/platformio.ini +++ b/platformio.ini @@ -134,7 +134,7 @@ lib_extra_dirs = lib_compat_mode = strict lib_deps = FastLED@3.3.2 - NeoPixelBus@2.5.6 + NeoPixelBus@2.5.7 ESPAsyncTCP@1.2.0 ESPAsyncUDP@697c75a025 AsyncTCP@1.0.3 From b86f58befe173590438c0aa427837fe872425d7d Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 2 Mar 2020 12:41:14 +0100 Subject: [PATCH 086/509] IR remotes can disable NightLight with "OFF" (#745) * IR can disable Nightlight with "OFF" --- wled00/wled08_led.ino | 1 - wled00/wled20_ir.ino | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index f6e8b4eea..63009f983 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -72,7 +72,6 @@ bool colorChanged() { if (col[i] != colIT[i]) return true; if (colSec[i] != colSecIT[i]) return true; - //if (col[i] != colNlT[i]) return true; (this effectively made the ESP send out sync packets every time colorUpdated() is called, even if nothing changed) } if (bri != briIT) return true; return false; diff --git a/wled00/wled20_ir.ino b/wled00/wled20_ir.ino index c65a4c58e..3cd604b21 100644 --- a/wled00/wled20_ir.ino +++ b/wled00/wled20_ir.ino @@ -91,6 +91,7 @@ void decodeIR(uint32_t code) default: return; } } + if (nightlightActive && bri == 0) nightlightActive = false; colorUpdated(NOTIFIER_CALL_MODE_BUTTON); //for notifier, IR is considered a button input //code <= 0xF70000 also invalid } From 267887908ef47851a7b2fddf19bf67213cd62952 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 2 Mar 2020 13:31:34 +0100 Subject: [PATCH 087/509] New IRremote functions (#746) * Switch to strip.getPaletteCount() * fixed color conversion errors Co-authored-by: Aircoookie --- wled00/wled20_ir.ino | 89 +++++++++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 25 deletions(-) diff --git a/wled00/wled20_ir.ino b/wled00/wled20_ir.ino index 3cd604b21..64c131c21 100644 --- a/wled00/wled20_ir.ino +++ b/wled00/wled20_ir.ino @@ -35,14 +35,55 @@ bool decodeIRCustom(uint32_t code) //relatively change brightness, minumum A=5 -void relativeChange(byte* property, int8_t amount, byte lowerBoundary =0) +void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF) { int16_t new_val = (int16_t) *property + amount; - if (new_val > 0xFF) new_val = 0xFF; + if (new_val > higherBoundary) new_val = higherBoundary; else if (new_val < lowerBoundary) new_val = lowerBoundary; - *property = new_val; + *property = (byte)constrain(new_val,0.1,255.1); } +void changeEffectSpeed(int8_t amount) +{ + if (effectCurrent != 0) { + int16_t new_val = (int16_t) effectSpeed + amount; + effectSpeed = (byte)constrain(new_val,0.1,255.1); + } else { // if Effect == "solid Color", change the hue of the primary color + CRGB fastled_col; + fastled_col.red = col[0]; + fastled_col.green = col[1]; + fastled_col.blue = col[2]; + CHSV prim_hsv = rgb2hsv_approximate(fastled_col); + int16_t new_val = (int16_t) prim_hsv.h + amount; + if (new_val > 255) new_val -= 255; // roll-over if bigger than 255 + if (new_val < 0) new_val += 255; // roll-over if smaller than 0 + prim_hsv.h = (byte)new_val; + hsv2rgb_rainbow(prim_hsv, fastled_col); + col[0] = fastled_col.red; + col[1] = fastled_col.green; + col[2] = fastled_col.blue; + } +} + +void changeEffectIntensity(int8_t amount) +{ + if (effectCurrent != 0) { + int16_t new_val = (int16_t) effectIntensity + amount; + effectIntensity = (byte)constrain(new_val,0.1,255.1); + } else { // if Effect == "solid Color", change the saturation of the primary color + CRGB fastled_col; + fastled_col.red = col[0]; + fastled_col.green = col[1]; + fastled_col.blue = col[2]; + CHSV prim_hsv = rgb2hsv_approximate(fastled_col); + int16_t new_val = (int16_t) prim_hsv.s + amount; + prim_hsv.s = (byte)constrain(new_val,0.1,255.1); // constrain to 0-255 + hsv2rgb_rainbow(prim_hsv, fastled_col); + col[0] = fastled_col.red; + col[1] = fastled_col.green; + col[2] = fastled_col.blue; + } +} void decodeIR(uint32_t code) { @@ -242,10 +283,10 @@ void decodeIR40(uint32_t code) case IR40_W50 : bri = 127; break; case IR40_W75 : bri = 191; break; case IR40_W100 : bri = 255; break; - case IR40_QUICK : relativeChange(&effectSpeed, 10); break; - case IR40_SLOW : relativeChange(&effectSpeed, -10, 5); break; - case IR40_JUMP7 : relativeChange(&effectIntensity, 10); break; - case IR40_AUTO : relativeChange(&effectIntensity, -10, 5); break; + case IR40_QUICK : changeEffectSpeed( 16); break; + case IR40_SLOW : changeEffectSpeed(-16); break; + case IR40_JUMP7 : changeEffectIntensity( 16); break; + case IR40_AUTO : changeEffectIntensity(-16); break; case IR40_JUMP3 : if (!applyPreset(1)) { effectCurrent = FX_MODE_STATIC; effectPalette = 0; } break; case IR40_FADE3 : if (!applyPreset(2)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; case IR40_FADE7 : if (!applyPreset(3)) { effectCurrent = FX_MODE_FIRE_FLICKER; effectPalette = 0; } break; @@ -293,14 +334,14 @@ void decodeIR44(uint32_t code) case IR44_COLDWHITE2 : { if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; } else colorFromUint24(COLOR_COLDWHITE2); } break; - case IR44_REDPLUS : relativeChange(&effectCurrent, 1); break; + case IR44_REDPLUS : relativeChange(&effectCurrent, 1, 0, MODE_COUNT); break; case IR44_REDMINUS : relativeChange(&effectCurrent, -1, 0); break; - case IR44_GREENPLUS : relativeChange(&effectPalette, 1); break; + case IR44_GREENPLUS : relativeChange(&effectPalette, 1, 0, strip.getPaletteCount() -1); break; case IR44_GREENMINUS : relativeChange(&effectPalette, -1, 0); break; - case IR44_BLUEPLUS : relativeChange(&effectIntensity, 10); break; - case IR44_BLUEMINUS : relativeChange(&effectIntensity, -10, 5); break; - case IR44_QUICK : relativeChange(&effectSpeed, 10); break; - case IR44_SLOW : relativeChange(&effectSpeed, -10, 5); break; + case IR44_BLUEPLUS : changeEffectIntensity( 16); break; + case IR44_BLUEMINUS : changeEffectIntensity(-16); break; + case IR44_QUICK : changeEffectSpeed( 16); break; + case IR44_SLOW : changeEffectSpeed(-16); break; case IR44_DIY1 : if (!applyPreset(1)) { effectCurrent = FX_MODE_STATIC; effectPalette = 0; } break; case IR44_DIY2 : if (!applyPreset(2)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; case IR44_DIY3 : if (!applyPreset(3)) { effectCurrent = FX_MODE_FIRE_FLICKER; effectPalette = 0; } break; @@ -319,7 +360,7 @@ void decodeIR44(uint32_t code) void decodeIR21(uint32_t code) { - switch (code) { + switch (code) { case IR21_BRIGHTER: relativeChange(&bri, 10); break; case IR21_DARKER: relativeChange(&bri, -10, 5); break; case IR21_OFF: briLast = bri; bri = 0; break; @@ -342,20 +383,19 @@ void decodeIR21(uint32_t code) case IR21_FADE: if (!applyPreset(3)) { effectCurrent = FX_MODE_BREATH; effectPalette = 0; } break; case IR21_SMOOTH: if (!applyPreset(4)) { effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; } break; default: return; - } - lastValidCode = code; + } + lastValidCode = code; } void decodeIR6(uint32_t code) { switch (code) { - case IR6_POWER: toggleOnOff(); break; - case IR6_CHANNEL_UP: relativeChange(&bri, 10); break; - case IR6_CHANNEL_DOWN: relativeChange(&bri, -10, 5); break; - case IR6_VOLUME_UP: /* next effect */ relativeChange(&effectCurrent, 1); break; - case IR6_VOLUME_DOWN: - /* next palette */ - relativeChange(&effectPalette, 1); + case IR6_POWER: toggleOnOff(); break; + case IR6_CHANNEL_UP: relativeChange(&bri, 10); break; + case IR6_CHANNEL_DOWN: relativeChange(&bri, -10, 5); break; + case IR6_VOLUME_UP: relativeChange(&effectCurrent, 1, 0, MODE_COUNT); break; // next effect + case IR6_VOLUME_DOWN: // next palette + relativeChange(&effectPalette, 1, 0, strip.getPaletteCount() -1); switch(lastIR6ColourIdx) { case 0: colorFromUint32(COLOR_RED); break; case 1: colorFromUint32(COLOR_REDDISH); break; @@ -373,8 +413,7 @@ void decodeIR6(uint32_t code) default: break; } lastIR6ColourIdx++; - if(lastIR6ColourIdx > 12) lastIR6ColourIdx = 0; - break; + if(lastIR6ColourIdx > 12) lastIR6ColourIdx = 0; break; case IR6_MUTE: effectCurrent = 0; effectPalette = 0; colorFromUint32(COLOR_WHITE); bri=255; break; } lastValidCode = code; From 89fa053310e149cb1a6caf1a2e2e2346fe03601d Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 3 Mar 2020 17:53:47 +0100 Subject: [PATCH 088/509] Add "np" API option to not commit Re-add IRremote flags to platformio.ini --- platformio.ini | 8 ++++++++ wled00/wled00.ino | 2 +- wled00/wled01_eeprom.ino | 8 ++++---- wled00/wled03_set.ino | 11 +++++++++-- wled00/wled19_json.ino | 5 ++++- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/platformio.ini b/platformio.ini index c4e79a716..31cd30bda 100644 --- a/platformio.ini +++ b/platformio.ini @@ -102,6 +102,14 @@ debug_flags = -D DEBUG=1 -D WLED_DEBUG -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT # ------------------------------------------------------------------------------ build_flags = -g -w -DMQTT_MAX_PACKET_SIZE=1024 -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH -DSECURE_CLIENT=SECURE_CLIENT_BEARSSL -DBEARSSL_SSL_BASIC + #build_flags for the IRremoteESP8266 library (enabled decoders have to appear here) + -D _IR_ENABLE_DEFAULT_=false + -D DECODE_HASH=true + -D DECODE_NEC=true + -D DECODE_SONY=true + -D DECODE_SAMSUNG=true + -D DECODE_LG=true + build_flags_esp8266 = ${common.build_flags} -DESP8266 build_flags_esp32 = ${common.build_flags} -DARDUINO_ARCH_ESP32 diff --git a/wled00/wled00.ino b/wled00/wled00.ino index fda0a110c..325cc73e7 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -119,7 +119,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2002292 +#define VERSION 2003031 char versionString[] = "0.9.1"; diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index b0da64516..acfc8dcee 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -621,7 +621,7 @@ bool applyPreset(byte index, bool loadBri = true) return true; } -void savePreset(byte index) +void savePreset(byte index, bool persist = true) { if (index > 16) return; if (index < 1) {saveSettingsToEEPROM();return;} @@ -653,7 +653,7 @@ void savePreset(byte index) memcpy(EEPROM.getDataPtr() +i+2, seg, 240); } - commit(); + if (persist) commit(); savedToPresets(); currentPreset = index; isPreset = true; @@ -689,7 +689,7 @@ void applyMacro(byte index) } -void saveMacro(byte index, String mc, bool sing=true) //only commit on single save, not in settings +void saveMacro(byte index, String mc, bool persist = true) //only commit on single save, not in settings { index-=1; if (index > 15) return; @@ -698,5 +698,5 @@ void saveMacro(byte index, String mc, bool sing=true) //only commit on single sa { EEPROM.write(i, mc.charAt(i-s)); } - if (sing) commit(); + if (persist) commit(); } diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 69a7d9b7a..d38971490 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -372,6 +372,13 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) DEBUG_PRINT("API req: "); DEBUG_PRINTLN(req); + //write presets and macros saved to flash directly? + bool persistSaves = true; + pos = req.indexOf("NP"); + if (pos > 0) { + persistSaves = false; + } + //save macro, requires &MS=() format pos = req.indexOf("&MS="); if (pos > 0) { @@ -381,7 +388,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) int en = req.indexOf(')'); String mc = req.substring(pos); if (en > 0) mc = req.substring(pos, en); - saveMacro(i, mc); + saveMacro(i, mc, persistSaves); } pos = req.indexOf("IN"); @@ -461,7 +468,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) if (pos > 0) presetApplyBri = (req.charAt(pos+3) != '0'); pos = req.indexOf("PS="); //saves current in preset - if (pos > 0) savePreset(getNumVal(&req, pos)); + if (pos > 0) savePreset(getNumVal(&req, pos), persistSaves); //apply preset if (updateVal(&req, "PL=", &presetCycCurr, presetCycleMin, presetCycleMax)) { diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index 4d9359731..237912d63 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -156,8 +156,11 @@ bool deserializeState(JsonObject root) colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE); + //write presets to flash directly? + bool persistSaves = !(root["np"] | false); + ps = root["psave"] | -1; - if (ps >= 0) savePreset(ps); + if (ps >= 0) savePreset(ps, persistSaves); return stateResponse; } From 4f34cfb6549e79b37b8d1a5eae20760a2e8d2bb4 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Wed, 4 Mar 2020 11:45:25 +0100 Subject: [PATCH 089/509] Add custom32_LEDPIN_16 environment (from #748 ) --- platformio.ini | 10 +++++++++- wled00/const.h | 12 +++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/platformio.ini b/platformio.ini index 6e1bae316..c1663c4e2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -19,7 +19,7 @@ extra_configs = default_envs = d1_mini, esp01, esp01_1m_ota, esp32dev # Release binaries follow -; default_envs = nodemcuv2, esp01, esp01_1m_ota, esp01_1m_full, esp32dev, custom_WS2801, custom_APA102, custom_LEDPIN_16, custom_LEDPIN_4 +; default_envs = nodemcuv2, esp01, esp01_1m_ota, esp01_1m_full, esp32dev, custom_WS2801, custom_APA102, custom_LEDPIN_16, custom_LEDPIN_4, custom32_LEDPIN_16 # Single binaries ; default_envs = nodemcuv2 @@ -261,3 +261,11 @@ board = d1_mini platform = ${common.platform_latest} board_build.ldscript = ${common.ldscript_4m1m} build_flags = ${common.build_flags_esp8266} -D USE_WS2801 + +[env:custom32_LEDPIN_16] +board = esp32dev +platform = espressif32@1.11.2 +build_flags = ${common.build_flags_esp32} -D LEDPIN=16 +lib_ignore = + ESPAsyncTCP + ESPAsyncUDP diff --git a/wled00/const.h b/wled00/const.h index b54215cab..21be19536 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -49,17 +49,19 @@ #define DMX_MODE_MULTIPLE_DRGB 5 //every LED is addressed with its own RGB and share a master dimmer (ledCount * 3 + 1 channels) //Light capability byte (unused) -#define TYPE_WS2812_RGB 0 -#define TYPE_SK6812_RGBW 1 -#define TYPE_WS2812_WWA 2 //amber + warm + cold white -#define TYPE_APA102 3 -#define TYPE_LPD8806 4 +#define TYPE_NONE 0 //light is not configured +#define TYPE_RESERVED 1 //unused. Might indicate a "virtual" light +#define TYPE_WS2812_RGB 2 +#define TYPE_SK6812_RGBW 3 +#define TYPE_WS2812_WWA 4 //amber + warm + cold white #define TYPE_WS2801 5 #define TYPE_ANALOG_1CH 6 //single channel PWM. Uses value of brightest RGBW channel #define TYPE_ANALOG_2CH 7 //analog WW + CW #define TYPE_ANALOG_3CH 8 //analog RGB #define TYPE_ANALOG_4CH 9 //analog RGBW #define TYPE_ANALOG_5CH 10 //analog RGB + WW + CW +#define TYPE_APA102 11 +#define TYPE_LPD8806 12 //Hue error codes #define HUE_ERROR_INACTIVE 0 From ed3234d949294221d7a064cd2ec09b1a0e218303 Mon Sep 17 00:00:00 2001 From: srg74 Date: Wed, 4 Mar 2020 23:01:00 -0500 Subject: [PATCH 090/509] Update UserMod Updating UserMod as per request from discourse forum user. He want to use with ESP32 also as QuinLED board support to types - ESP8266 ans ESP32. Removed .txt file as it create an extra step in setup. --- usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt | 3 +-- usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt | 8 -------- .../wled06_usermod.ino | 19 +++++++++++++++---- 3 files changed, 16 insertions(+), 14 deletions(-) delete mode 100644 usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt diff --git a/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt b/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt index 612873360..eb8da7ee1 100644 --- a/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt +++ b/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt @@ -1,8 +1,7 @@ -These files allow WLED 0.8.6 to report the temp sensor on the Quinled board to MQTT. I use it to report the board temp to Home Assistant via MQTT, so it will send notifications if something happens and the board start to heat up. +These files allow WLED 0.9.1 to report the temp sensor on the Quinled board to MQTT. I use it to report the board temp to Home Assistant via MQTT, so it will send notifications if something happens and the board start to heat up. This code uses Aircookie's WLED software. It has a premade file for user modifications. I use it to publish the temperature from the dallas temperature sensor on the Quinled board. The entries for the top of the WLED00 file, initializes the required libraries, and variables for the sensor. The .ino file waits for 60 seconds, and checks to see if the MQTT server is connected (thanks Aircoookie). It then poles the sensor, and published it using the MQTT service already running, using the main topic programmed in the WLED UI. To install: -Add the entries in the WLED00 file to the top of the same file from Aircoookies WLED. Replace the WLED06_usermod.ino file in Aircoookies WLED folder. diff --git a/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt b/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt deleted file mode 100644 index 661a7e249..000000000 --- a/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt +++ /dev/null @@ -1,8 +0,0 @@ -//Intiating code for QuinLED Dig-Uno temp sensor -//Uncomment Celsius if that is your prefered temperature scale -#include -OneWire oneWire(14); -DallasTemperature sensors(&oneWire); -long temptimer = millis(); -long lastMeasure = 0; -//#define Celsius diff --git a/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino b/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino index 1309a4f83..d4b77ccc1 100644 --- a/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino +++ b/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino @@ -1,8 +1,19 @@ -//starts Dallas Temp service on boot +//Intiating code for QuinLED Dig-Uno temp sensor +//Uncomment Celsius if that is your prefered temperature scale +#include //Dallastemperature sensor +#ifdef ARDUINO_ARCH_ESP32 //ESP32 boards +OneWire oneWire(18); +#else //ESP8266 boards +OneWire oneWire(14); +#endif +DallasTemperature sensor(&oneWire); +long temptimer = millis(); +long lastMeasure = 0; +#define Celsius // Show temperature mesaurement in Celcius otherwise is in Fahrenheit void userSetup() { // Start the DS18B20 sensor - sensors.begin(); + sensor.begin(); } //gets called every time WiFi is (re-)connected. Initialize own network interfaces here @@ -21,11 +32,11 @@ void userLoop() //Check if MQTT Connected, otherwise it will crash the 8266 if (mqtt != nullptr){ - sensors.requestTemperatures(); + sensor.requestTemperatures(); //Gets prefered temperature scale based on selection in definitions section #ifdef Celsius - float board_temperature = sensors.getTempCByIndex(0); + float board_temperature = sensor.getTempCByIndex(0); #else float board_temperature = sensors.getTempFByIndex(0); #endif From 8d669b12b6dc4edc0a0ba63cf0f3ef8ed0bf70d5 Mon Sep 17 00:00:00 2001 From: srg74 Date: Wed, 4 Mar 2020 23:15:12 -0500 Subject: [PATCH 091/509] Truing to fix failed build --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index a8d21c846..91bdd8675 100644 --- a/platformio.ini +++ b/platformio.ini @@ -152,8 +152,8 @@ lib_deps = #For use SSD1306 OLED display uncomment following #U8g2@~2.27.2 #For Dallas sensor uncomment following 2 lines - #DallasTemperature@~3.8.0 - #OneWire@~2.3.5 + DallasTemperature@~3.8.0 + OneWire@~2.3.5 lib_ignore = AsyncTCP From 453f4b549b649bab18583bbefdd454d5316985dc Mon Sep 17 00:00:00 2001 From: Aircoookie Date: Thu, 5 Mar 2020 09:39:43 +0100 Subject: [PATCH 092/509] Trying to fix failed build (#756) --- platformio.ini | 11 +++++++++-- usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt | 3 +-- usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt | 8 -------- .../wled06_usermod.ino | 19 +++++++++++++++---- .../wled06_usermod.ino | 5 ++--- 5 files changed, 27 insertions(+), 19 deletions(-) delete mode 100644 usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt diff --git a/platformio.ini b/platformio.ini index c1663c4e2..91bdd8675 100644 --- a/platformio.ini +++ b/platformio.ini @@ -28,6 +28,7 @@ default_envs = d1_mini, esp01, esp01_1m_ota, esp32dev ; default_envs = esp01_1m_full ; default_envs = esp07 ; default_envs = d1_mini +; default_envs = heltec_wifi_kit_8 ; default_envs = d1_mini_debug ; default_envs = esp32dev ; default_envs = esp8285_4CH_MagicHome @@ -151,8 +152,8 @@ lib_deps = #For use SSD1306 OLED display uncomment following #U8g2@~2.27.2 #For Dallas sensor uncomment following 2 lines - #DallasTemperature@~3.8.0 - #OneWire@~2.3.5 + DallasTemperature@~3.8.0 + OneWire@~2.3.5 lib_ignore = AsyncTCP @@ -197,6 +198,12 @@ platform = ${common.platform_latest} board_build.ldscript = ${common.ldscript_4m1m} build_flags = ${common.build_flags_esp8266} +[env:heltec_wifi_kit_8] +board = d1_mini +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_4m1m} +build_flags = ${common.build_flags_esp8266} + [env:esp32dev] board = esp32dev platform = espressif32@1.11.2 diff --git a/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt b/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt index 612873360..eb8da7ee1 100644 --- a/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt +++ b/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt @@ -1,8 +1,7 @@ -These files allow WLED 0.8.6 to report the temp sensor on the Quinled board to MQTT. I use it to report the board temp to Home Assistant via MQTT, so it will send notifications if something happens and the board start to heat up. +These files allow WLED 0.9.1 to report the temp sensor on the Quinled board to MQTT. I use it to report the board temp to Home Assistant via MQTT, so it will send notifications if something happens and the board start to heat up. This code uses Aircookie's WLED software. It has a premade file for user modifications. I use it to publish the temperature from the dallas temperature sensor on the Quinled board. The entries for the top of the WLED00 file, initializes the required libraries, and variables for the sensor. The .ino file waits for 60 seconds, and checks to see if the MQTT server is connected (thanks Aircoookie). It then poles the sensor, and published it using the MQTT service already running, using the main topic programmed in the WLED UI. To install: -Add the entries in the WLED00 file to the top of the same file from Aircoookies WLED. Replace the WLED06_usermod.ino file in Aircoookies WLED folder. diff --git a/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt b/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt deleted file mode 100644 index 661a7e249..000000000 --- a/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled00.txt +++ /dev/null @@ -1,8 +0,0 @@ -//Intiating code for QuinLED Dig-Uno temp sensor -//Uncomment Celsius if that is your prefered temperature scale -#include -OneWire oneWire(14); -DallasTemperature sensors(&oneWire); -long temptimer = millis(); -long lastMeasure = 0; -//#define Celsius diff --git a/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino b/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino index 1309a4f83..d4b77ccc1 100644 --- a/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino +++ b/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino @@ -1,8 +1,19 @@ -//starts Dallas Temp service on boot +//Intiating code for QuinLED Dig-Uno temp sensor +//Uncomment Celsius if that is your prefered temperature scale +#include //Dallastemperature sensor +#ifdef ARDUINO_ARCH_ESP32 //ESP32 boards +OneWire oneWire(18); +#else //ESP8266 boards +OneWire oneWire(14); +#endif +DallasTemperature sensor(&oneWire); +long temptimer = millis(); +long lastMeasure = 0; +#define Celsius // Show temperature mesaurement in Celcius otherwise is in Fahrenheit void userSetup() { // Start the DS18B20 sensor - sensors.begin(); + sensor.begin(); } //gets called every time WiFi is (re-)connected. Initialize own network interfaces here @@ -21,11 +32,11 @@ void userLoop() //Check if MQTT Connected, otherwise it will crash the 8266 if (mqtt != nullptr){ - sensors.requestTemperatures(); + sensor.requestTemperatures(); //Gets prefered temperature scale based on selection in definitions section #ifdef Celsius - float board_temperature = sensors.getTempCByIndex(0); + float board_temperature = sensor.getTempCByIndex(0); #else float board_temperature = sensors.getTempFByIndex(0); #endif diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino index 58a4e0e6a..d75cf0a74 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino @@ -31,9 +31,8 @@ U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_ // --> Second choise of cheap I2C OLED 128X64 0.96" or 1.3" //U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA // --> Third choise of Heltec WiFi-Kit-8 OLED 128X32 0.91" -//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_RESET, U8X8_PIN_SCL, U8X8_PIN_SDA); // Constracor for Heltec WiFi-Kit-8 -// gets called once at boot. Do all initialization that doesn't depend on -// network here +//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_RESET, U8X8_PIN_SCL, U8X8_PIN_SDA); // Constructor for Heltec WiFi-Kit-8 +// gets called once at boot. Do all initialization that doesn't depend on network here void userSetup() { sensor.begin(); //Start Dallas temperature sensor u8x8.begin(); From 0d355dbf35bd382e28ae675c03094c927269c68a Mon Sep 17 00:00:00 2001 From: jwingefeld Date: Fri, 6 Mar 2020 23:45:45 +0100 Subject: [PATCH 093/509] Usermod: Project Cars rpm indicator and shift lights (#759) * project cars shiftlight usermod * added readme * rephrased stuff in readme.md because reasons Co-authored-by: Jan --- usermods/project_cars_shiftlight/readme.md | 23 +++++ .../wled06_usermod.ino | 96 +++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 usermods/project_cars_shiftlight/readme.md create mode 100644 usermods/project_cars_shiftlight/wled06_usermod.ino diff --git a/usermods/project_cars_shiftlight/readme.md b/usermods/project_cars_shiftlight/readme.md new file mode 100644 index 000000000..4490a2ba1 --- /dev/null +++ b/usermods/project_cars_shiftlight/readme.md @@ -0,0 +1,23 @@ +### Shift Light for Project Cars + +Turn your WLED lights into a rev light and shift indicator for Project Cars. + +It is pretty straight forward to use. + +1. Make sure, your WLED device and your PC/console are on the same network and can talk to each other + +2. Go to the gameplay settings menu in PCARS and enable UDP. There are 9 numbers you can choose from. This is the refresh rate. The lower the number, the better. But you might run into problems at faster rates. + +| Number | Updates/Second | +| ------ | -------------- | +| 1 | 60 | +| 2 | 50 | +| 3 | 40 | +| 4 | 30 | +| 5 | 20 | +| 6 | 15 | +| 7 | 10 | +| 8 | 05 | +| 9 | 1 | + +3. once you enter a race, WLED should automatically shift to PCARS mode. Done. diff --git a/usermods/project_cars_shiftlight/wled06_usermod.ino b/usermods/project_cars_shiftlight/wled06_usermod.ino new file mode 100644 index 000000000..b00c2946a --- /dev/null +++ b/usermods/project_cars_shiftlight/wled06_usermod.ino @@ -0,0 +1,96 @@ +/* + * Car rev display and shift indicator for Project Cars + * + * This works via the UDP telemetry function. You'll need to enable it in the settings of the game. + * I've had good results with settings around 5 (20 fps). + * + */ +const uint8_t PCARS_dimcolor = 20; +WiFiUDP UDP; +const unsigned int PCARS_localUdpPort = 5606; // local port to listen on +char PCARS_packet[2048]; + +char PCARS_tempChar[2]; // Temporary array for u16 conversion + +u16 PCARS_RPM; +u16 PCARS_maxRPM; + +long PCARS_lastRead = millis() - 2001; +float PCARS_rpmRatio; + + +void userSetup() +{ + UDP.begin(PCARS_localUdpPort); +} + +void userConnected() +{ + // new wifi, who dis? +} + +void userLoop() +{ + PCARS_readValues(); + if (PCARS_lastRead > millis() - 2000) { + PCARS_buildcolorbars(); + } +} + +void PCARS_readValues() { + + int PCARS_packetSize = UDP.parsePacket(); + if (PCARS_packetSize) { + int len = UDP.read(PCARS_packet, PCARS_packetSize); + if (len > 0) { + PCARS_packet[len] = 0; + } + if (len == 1367) { // Telemetry packet. Ignoring everything else. + PCARS_lastRead = millis(); + + arlsLock(realtimeTimeoutMs, REALTIME_MODE_GENERIC); + // current RPM + memcpy(&PCARS_tempChar, &PCARS_packet[124], 2); + PCARS_RPM = (PCARS_tempChar[1] << 8) + PCARS_tempChar[0]; + + // max RPM + memcpy(&PCARS_tempChar, &PCARS_packet[126], 2); + PCARS_maxRPM = (PCARS_tempChar[1] << 8) + PCARS_tempChar[0]; + + if (PCARS_maxRPM) { + PCARS_rpmRatio = constrain((float)PCARS_RPM / (float)PCARS_maxRPM, 0, 1); + } else { + PCARS_rpmRatio = 0.0; + } + } + } +} +void PCARS_buildcolorbars() { + boolean activated = false; + float ledratio = 0; + + for (uint16_t i = 0; i < ledCount; i++) { + if (PCARS_rpmRatio < .95 || (millis() % 100 > 70 )) { + + ledratio = (float)i / (float)ledCount; + if (ledratio < PCARS_rpmRatio) { + activated = true; + } else { + activated = false; + } + if (ledratio > 0.66) { + setRealtimePixel(i, 0, 0, PCARS_dimcolor + ((255 - PCARS_dimcolor)*activated), 0); + } else if (ledratio > 0.33) { + setRealtimePixel(i, PCARS_dimcolor + ((255 - PCARS_dimcolor)*activated), 0, 0, 0); + } else { + setRealtimePixel(i, 0, PCARS_dimcolor + ((255 - PCARS_dimcolor)*activated), 0, 0); + } + } + else { + setRealtimePixel(i, 0, 0, 0, 0); + + } + } + colorUpdated(5); + strip.show(); +} \ No newline at end of file From bffe2d7bd0e537275b55ca5d1c0cb01d99c1d216 Mon Sep 17 00:00:00 2001 From: pille Date: Tue, 10 Mar 2020 17:33:23 +0100 Subject: [PATCH 094/509] track E1.31 seqcuence numbers for each universe individually, wrt #742 --- wled00/wled00.ino | 5 ++--- wled00/wled02_xml.ino | 2 -- wled00/wled07_notify.ino | 33 +++++++++++++++++++-------------- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 325cc73e7..28fb3c0c1 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -206,11 +206,12 @@ bool receiveDirect = true; //receive UDP realtime bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black +#define E131_MAX_UNIVERSE_COUNT 9 uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] uint8_t DMXOldDimmer = 0; //only update brightness on change -uint8_t e131LastSequenceNumber = 0; //to detect packet loss +uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss bool e131Multicast = false; //multicast or unicast bool mqttEnabled = false; @@ -464,8 +465,6 @@ void handleE131Packet(e131_packet_t*, IPAddress); void arlsLock(uint32_t,byte); void handleOverlayDraw(); -#define E131_MAX_UNIVERSE_COUNT 9 - //udp interface objects WiFiUDP notifierUdp, rgbUdp; WiFiUDP ntpUdp; diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index d538e0c49..f27086f6e 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -74,8 +74,6 @@ char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr) mesg += "."; mesg += realtimeIP[i]; } - mesg += " seq="; - mesg += e131LastSequenceNumber; } else if (realtimeMode == REALTIME_MODE_UDP || realtimeMode == REALTIME_MODE_HYPERION) { mesg += "UDP from "; mesg += realtimeIP[0]; diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino index 7f691dd0f..b3c98567e 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled07_notify.ino @@ -88,26 +88,31 @@ void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC) void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ //E1.31 protocol support - - // skip out-of-sequence packets - if (p->sequence_number < e131LastSequenceNumber && p->sequence_number > 20 && e131LastSequenceNumber < 250){ - DEBUG_PRINT("skipping E1.31 frame (last seq="); - DEBUG_PRINT(e131LastSequenceNumber); - DEBUG_PRINT(", current seq="); - DEBUG_PRINT(p->sequence_number); - DEBUG_PRINTLN(")"); - return; - } - e131LastSequenceNumber = p->sequence_number; - // update status info - realtimeIP = clientIP; - uint16_t uni = htons(p->universe); uint8_t previousUniverses = uni - e131Universe; uint16_t possibleLEDsInCurrentUniverse; uint16_t dmxChannels = htons(p->property_value_count) -1; + // only listen for universes we're handling & allocated memory + if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return; + + // skip out-of-sequence packets + if (p->sequence_number < e131LastSequenceNumber[uni-e131Universe] && p->sequence_number > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){ + DEBUG_PRINT("skipping E1.31 frame (last seq="); + DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]); + DEBUG_PRINT(", current seq="); + DEBUG_PRINT(p->sequence_number); + DEBUG_PRINT(", universe="); + DEBUG_PRINT(uni); + DEBUG_PRINTLN(")"); + return; + } + e131LastSequenceNumber[uni-e131Universe] = p->sequence_number; + + // update status info + realtimeIP = clientIP; + switch (DMXMode) { case DMX_MODE_DISABLED: return; // nothing to do From 62510ac6a3a81051b2871504dafaedc87009a7a0 Mon Sep 17 00:00:00 2001 From: pille Date: Tue, 10 Mar 2020 18:21:16 +0100 Subject: [PATCH 095/509] add E1.31 packet out-of-sequence config option, wrt #742 --- wled00/data/settings_sync.htm | 1 + wled00/html_settings.h | 1 + wled00/wled00.ino | 1 + wled00/wled01_eeprom.ino | 10 +++++++++- wled00/wled02_xml.ino | 1 + wled00/wled03_set.ino | 1 + wled00/wled07_notify.ino | 22 +++++++++++----------- 7 files changed, 25 insertions(+), 12 deletions(-) diff --git a/wled00/data/settings_sync.htm b/wled00/data/settings_sync.htm index b4bcf0599..5cf4b6082 100644 --- a/wled00/data/settings_sync.htm +++ b/wled00/data/settings_sync.htm @@ -85,6 +85,7 @@

Realtime

Receive UDP realtime:

E1.31 (sACN)
+ Skip out-of-sequence packets (freeze instead of flicker):
Multicast mode:
E1.31 start universe:
Reboot required. Check out LedFx!

diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 7340e62d5..c7badc16f 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -284,6 +284,7 @@ Send notifications twice:

Realtime

Receive UDP realtime:

E1.31 (sACN)
+Skip out-of-sequence packets (freeze instead of flicker):
Use E1.31 multicast:
E1.31 start universe:
Reboot required. Check out LedFx!
diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 28fb3c0c1..a6b169241 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -213,6 +213,7 @@ uint16_t DMXAddress = 1; //DMX start address of fixture, a. uint8_t DMXOldDimmer = 0; //only update brightness on change uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss bool e131Multicast = false; //multicast or unicast +bool e131SkipOutOfSequence = false; //freeze instead of flickering bool mqttEnabled = false; char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index acfc8dcee..1f0e8426f 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -6,7 +6,7 @@ #define EEPSIZE 2560 //Maximum is 4096 //eeprom Version code, enables default settings instead of 0 init on update -#define EEPVER 17 +#define EEPVER 18 //0 -> old version, default //1 -> 0.4p 1711272 and up //2 -> 0.4p 1711302 and up @@ -25,6 +25,7 @@ //15-> 0.9.0-b3 //16-> 0.9.1 //17-> 0.9.1-dmx +//18-> 0.9.1-e131 void commit() { @@ -208,6 +209,7 @@ void saveSettingsToEEPROM() EEPROM.write(2181, macroNl); EEPROM.write(2182, macroDoublePress); + EEPROM.write(2189, e131SkipOutOfSequence); EEPROM.write(2190, e131Universe & 0xFF); EEPROM.write(2191, (e131Universe >> 8) & 0xFF); EEPROM.write(2192, e131Multicast); @@ -505,6 +507,12 @@ void loadSettingsFromEEPROM(bool first) noWifiSleep = EEPROM.read(370); //} + if (lastEEPROMversion > 17) + { + e131SkipOutOfSequence = EEPROM.read(2189); + } else { + e131SkipOutOfSequence = true; + } receiveDirect = !EEPROM.read(2200); notifyMacro = EEPROM.read(2201); diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index f27086f6e..100be4822 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -324,6 +324,7 @@ void getSettingsJS(byte subPage, char* dest) sappend('c',"SM",notifyMacro); sappend('c',"S2",notifyTwice); sappend('c',"RD",receiveDirect); + sappend('c',"ES",e131SkipOutOfSequence); sappend('c',"EM",e131Multicast); sappend('v',"EU",e131Universe); sappend('v',"DA",DMXAddress); diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index d38971490..5a7f4db63 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -138,6 +138,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) notifyTwice = request->hasArg("S2"); receiveDirect = request->hasArg("RD"); + e131SkipOutOfSequence = request->hasArg("ES"); e131Multicast = request->hasArg("EM"); t = request->arg("EU").toInt(); if (t > 0 && t <= 63999) e131Universe = t; diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino index b3c98567e..b1fab41e5 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled07_notify.ino @@ -97,17 +97,17 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ // only listen for universes we're handling & allocated memory if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return; - // skip out-of-sequence packets - if (p->sequence_number < e131LastSequenceNumber[uni-e131Universe] && p->sequence_number > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){ - DEBUG_PRINT("skipping E1.31 frame (last seq="); - DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]); - DEBUG_PRINT(", current seq="); - DEBUG_PRINT(p->sequence_number); - DEBUG_PRINT(", universe="); - DEBUG_PRINT(uni); - DEBUG_PRINTLN(")"); - return; - } + if (e131SkipOutOfSequence) + if (p->sequence_number < e131LastSequenceNumber[uni-e131Universe] && p->sequence_number > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){ + DEBUG_PRINT("skipping E1.31 frame (last seq="); + DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]); + DEBUG_PRINT(", current seq="); + DEBUG_PRINT(p->sequence_number); + DEBUG_PRINT(", universe="); + DEBUG_PRINT(uni); + DEBUG_PRINTLN(")"); + return; + } e131LastSequenceNumber[uni-e131Universe] = p->sequence_number; // update status info From d21e82b020909d76462d9a786d672004f41a24a1 Mon Sep 17 00:00:00 2001 From: Aircoookie Date: Thu, 12 Mar 2020 23:26:38 +0100 Subject: [PATCH 096/509] Create changelog --- CHANGELOG.md | 10 ++++++++++ wled00/wled00.ino | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..f9e5b0f3d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +## WLED changelog + +### Development versions after 0.9.1 release + + +#### Build 2003121 + +Created changelog.md - make tracking changes to code easier +Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection + diff --git a/wled00/wled00.ino b/wled00/wled00.ino index a6b169241..ba2d4b684 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -119,7 +119,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2003031 +#define VERSION 2003121 char versionString[] = "0.9.1"; From 5b312d4c8b325e59b08598aa6b9a635fa3e339fa Mon Sep 17 00:00:00 2001 From: Mike Date: Fri, 13 Mar 2020 08:04:55 +0100 Subject: [PATCH 097/509] Make it better readable Make it better readable and make use of single line for add/chgange and/or delete --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9e5b0f3d..fd5aa8460 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,6 @@ #### Build 2003121 -Created changelog.md - make tracking changes to code easier -Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection +- Created changelog.md - make tracking changes to code easier +- Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection From c2ab3f96a7a52ec9f80ce25f56b302d80a4c3a73 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Fri, 13 Mar 2020 20:42:15 -0400 Subject: [PATCH 098/509] gitignore update --- .gitignore | 2 ++ platformio.ini | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ea49cb51f..df0f9e85c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ /wled00/Release /wled00/extLibs /platformio_override.ini +.DS_Store +.gitignore diff --git a/platformio.ini b/platformio.ini index 91bdd8675..cf0ba25c8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,7 +27,7 @@ default_envs = d1_mini, esp01, esp01_1m_ota, esp32dev ; default_envs = esp01_1m_ota ; default_envs = esp01_1m_full ; default_envs = esp07 -; default_envs = d1_mini +default_envs = d1_mini ; default_envs = heltec_wifi_kit_8 ; default_envs = d1_mini_debug ; default_envs = esp32dev From 37a31a9b9470ac4ffde15a68f7728b95f248f74d Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Fri, 13 Mar 2020 20:44:05 -0400 Subject: [PATCH 099/509] Update platformio.ini --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index cf0ba25c8..91bdd8675 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,7 +27,7 @@ default_envs = d1_mini, esp01, esp01_1m_ota, esp32dev ; default_envs = esp01_1m_ota ; default_envs = esp01_1m_full ; default_envs = esp07 -default_envs = d1_mini +; default_envs = d1_mini ; default_envs = heltec_wifi_kit_8 ; default_envs = d1_mini_debug ; default_envs = esp32dev From d36796429e908694e477e0b6c3ec2d975ba4011e Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 14 Mar 2020 11:28:42 +0100 Subject: [PATCH 100/509] Various small fixes Fixed color of main segment returned in JSON API during transition not being target color - Fixed arlsLock() being called after pixels set in E1.31, (closes #772) - Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment) --- CHANGELOG.md | 6 ++++++ wled00/FX_fcn.cpp | 14 ++++++++++++-- wled00/wled00.ino | 2 +- wled00/wled07_notify.ino | 5 ++++- wled00/wled19_json.ino | 27 +++++++++++++++++++-------- 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd5aa8460..cbc45e927 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ ### Development versions after 0.9.1 release +#### Build 2003141 + +- Fixed color of main segment returned in JSON API during transition not being target color (closes #765) +- Fixed arlsLock() being called after pixels set in E1.31 (closes #772) +- Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment) + #### Build 2003121 - Created changelog.md - make tracking changes to code easier diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 2392392de..59f69da4d 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -335,6 +335,8 @@ bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) { Segment& seg = _segments[getMainSegmentId()]; uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette; + bool applied = false; + if (applyToAllSelected) { for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { @@ -344,9 +346,12 @@ bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) { _segments[i].intensity = in; _segments[i].palette = p; setMode(i, m); + applied = true; } } - } else { + } + + if (!applyToAllSelected || !applied) { seg.speed = s; seg.intensity = in; seg.palette = p; @@ -363,12 +368,17 @@ void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w void WS2812FX::setColor(uint8_t slot, uint32_t c) { if (slot >= NUM_COLORS) return; + + bool applied = false; + if (applyToAllSelected) { for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { if (_segments[i].isSelected()) _segments[i].colors[slot] = c; } - } else { + } + + if (!applyToAllSelected || !applied) { _segments[getMainSegmentId()].colors[slot] = c; } } diff --git a/wled00/wled00.ino b/wled00/wled00.ino index ba2d4b684..f9648dcf1 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -119,7 +119,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2003121 +#define VERSION 2003141 char versionString[] = "0.9.1"; diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino index b1fab41e5..8fcbdbe82 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled07_notify.ino @@ -121,6 +121,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ case DMX_MODE_SINGLE_RGB: if (uni != e131Universe) return; if (dmxChannels-DMXAddress+1 < 3) return; + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); for (uint16_t i = 0; i < ledCount; i++) setRealtimePixel(i, p->property_values[DMXAddress+0], p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], 0); break; @@ -128,6 +129,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ case DMX_MODE_SINGLE_DRGB: if (uni != e131Universe) return; if (dmxChannels-DMXAddress+1 < 4) return; + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); if (DMXOldDimmer != p->property_values[DMXAddress+0]) { DMXOldDimmer = p->property_values[DMXAddress+0]; bri = p->property_values[DMXAddress+0]; @@ -166,6 +168,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ break; case DMX_MODE_MULTIPLE_RGB: + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); if (previousUniverses == 0) { // first universe of this fixture possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3; @@ -187,6 +190,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ break; case DMX_MODE_MULTIPLE_DRGB: + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); if (previousUniverses == 0) { // first universe of this fixture if (DMXOldDimmer != p->property_values[DMXAddress+0]) { @@ -218,7 +222,6 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ break; } - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); e131NewData = true; } diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index 237912d63..df9bceadc 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -31,12 +31,14 @@ void deserializeSegment(JsonObject elem, byte it) { int rgbw[] = {0,0,0,0}; byte cp = copyArray(colX, rgbw); - seg.colors[i] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF))); + if (cp == 1 && rgbw[0] == 0) seg.colors[i] = 0; - if (id == strip.getMainSegmentId()) //temporary + if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment { if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];} if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];} + } else { + seg.colors[i] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF))); } } } @@ -175,15 +177,24 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id) root["spc"] = seg.spacing; JsonArray colarr = root.createNestedArray("col"); - + for (uint8_t i = 0; i < 3; i++) { JsonArray colX = colarr.createNestedArray(); - colX.add((seg.colors[i] >> 16) & 0xFF); - colX.add((seg.colors[i] >> 8) & 0xFF); - colX.add((seg.colors[i]) & 0xFF); - if (useRGBW) - colX.add((seg.colors[i] >> 24) & 0xFF); + if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment + { + if (i == 0) { + colX.add(col[0]); colX.add(col[1]); colX.add(col[2]); if (useRGBW) colX.add(col[3]); + } else { + colX.add(colSec[0]); colX.add(colSec[1]); colX.add(colSec[2]); if (useRGBW) colX.add(colSec[3]); + } + } else { + colX.add((seg.colors[i] >> 16) & 0xFF); + colX.add((seg.colors[i] >> 8) & 0xFF); + colX.add((seg.colors[i]) & 0xFF); + if (useRGBW) + colX.add((seg.colors[i] >> 24) & 0xFF); + } } root["fx"] = seg.mode; From c246e5af35d71e7742d9bed4547a1bd4e9bd297e Mon Sep 17 00:00:00 2001 From: hobbyquaker Date: Sun, 15 Mar 2020 12:38:49 +0100 Subject: [PATCH 101/509] add battery-keypad-controller usermod --- usermods/battery_keypad_controller/README.md | 13 ++ .../assets/bat-key-ctrl-1.jpg | Bin 0 -> 326475 bytes .../assets/bat-key-ctrl-2.jpg | Bin 0 -> 256061 bytes .../assets/bat-key-ctrl-3.jpg | Bin 0 -> 352184 bytes .../wled06_usermod.ino | 152 ++++++++++++++++++ 5 files changed, 165 insertions(+) create mode 100644 usermods/battery_keypad_controller/README.md create mode 100644 usermods/battery_keypad_controller/assets/bat-key-ctrl-1.jpg create mode 100644 usermods/battery_keypad_controller/assets/bat-key-ctrl-2.jpg create mode 100644 usermods/battery_keypad_controller/assets/bat-key-ctrl-3.jpg create mode 100644 usermods/battery_keypad_controller/wled06_usermod.ino diff --git a/usermods/battery_keypad_controller/README.md b/usermods/battery_keypad_controller/README.md new file mode 100644 index 000000000..6262b21cd --- /dev/null +++ b/usermods/battery_keypad_controller/README.md @@ -0,0 +1,13 @@ +# Battery powered controller with keypad + +I'm using this controller for a festival totem. Runs on 3 18650 Cells, can deliver >5A current. + +Via keypad one can select 8 presets, change effect, effect speed, effect intensity and palette. Brightness can be +adjusted with a potentiometer. + + +## Pictures + +![bat-key-ctrl-1](assets/bat-key-ctrl-1.jpg) +![bat-key-ctrl-2](assets/bat-key-ctrl-2.jpg) +![bat-key-ctrl-3](assets/bat-key-ctrl-3.jpg) diff --git a/usermods/battery_keypad_controller/assets/bat-key-ctrl-1.jpg b/usermods/battery_keypad_controller/assets/bat-key-ctrl-1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f352ba3a379134990283eb52ccb2659ae35d6be9 GIT binary patch literal 326475 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%0AEQe8comPWd+ccwLCR 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νRod~sS(0O+?jF~To^$uBjO~rk+hqroN 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%0DneBOz?+7C4uiY(5542cZ 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%0DM|6%Zyl`N96ZEANXbCzjSZE@Seg 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 z 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
2mCCnpZv9 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�$Ah{#N&)q<3`l=T}gFq9_r7= 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

0kFReCM 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%0DSGo^Q%%pYacdYv4h4b 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 S!k4urFaH2ulamvZKmXbHMfGt2 literal 0 HcmV?d00001 diff --git a/usermods/battery_keypad_controller/wled06_usermod.ino b/usermods/battery_keypad_controller/wled06_usermod.ino new file mode 100644 index 000000000..dd001c8d0 --- /dev/null +++ b/usermods/battery_keypad_controller/wled06_usermod.ino @@ -0,0 +1,152 @@ +/* + * WLED usermod for keypad and brightness-pot. + * 3'2020 https://github.com/hobbyquaker + */ + +#include +const byte keypad_rows = 4; +const byte keypad_cols = 4; +char keypad_keys[keypad_rows][keypad_cols] = { + {'1', '2', '3', 'A'}, + {'4', '5', '6', 'B'}, + {'7', '8', '9', 'C'}, + {'*', '0', '#', 'D'} +}; + +byte keypad_colPins[keypad_rows] = {D3, D2, D1, D0}; +byte keypad_rowPins[keypad_cols] = {D7, D6, D5, D4}; + +Keypad myKeypad = Keypad(makeKeymap(keypad_keys), keypad_rowPins, keypad_colPins, keypad_rows, keypad_cols); + +void userSetup() +{ + +} + +void userConnected() +{ + +} + +long lastTime = 0; +int delayMs = 20; //we want to do something every 2 seconds + +void userLoop() +{ + if (millis()-lastTime > delayMs) + { + + long analog = analogRead(0); + int new_bri = 1; + if (analog > 900) { + new_bri = 255; + } else if (analog > 30) { + new_bri = dim8_video(map(analog, 31, 900, 16, 255)); + } + if (bri != new_bri) { + bri = new_bri; + colorUpdated(1); + + } + + char myKey = myKeypad.getKey(); + if (myKey != NULL) { + switch (myKey) { + case '1': + applyPreset(1); + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + case '2': + applyPreset(2); + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + case '3': + applyPreset(3); + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + case '4': + applyPreset(4); + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + case '5': + applyPreset(5); + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + case '6': + applyPreset(6); + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + case 'A': + applyPreset(7); + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + case 'B': + applyPreset(8); + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + + case '7': + effectCurrent += 1; + if (effectCurrent >= MODE_COUNT) effectCurrent = 0; + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + case '*': + effectCurrent -= 1; + if (effectCurrent < 0) effectCurrent = (MODE_COUNT-1); + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + + case '8': + if (effectSpeed < 240) { + effectSpeed += 12; + } else if (effectSpeed < 255) { + effectSpeed += 1; + } + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + case '0': + if (effectSpeed > 15) { + effectSpeed -= 12; + } else if (effectSpeed > 0) { + effectSpeed -= 1; + } + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + + case '9': + if (effectIntensity < 240) { + effectIntensity += 12; + } else if (effectIntensity < 255) { + effectIntensity += 1; + } + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + case '#': + if (effectIntensity > 15) { + effectIntensity -= 12; + } else if (effectIntensity > 0) { + effectIntensity -= 1; + } + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + + case 'C': + effectPalette += 1; + if (effectPalette >= 50) effectPalette = 0; + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + case 'D': + effectPalette -= 1; + if (effectPalette <= 0) effectPalette = 50; + colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); + break; + break; + + } + + } + + lastTime = millis(); + } + +} \ No newline at end of file From dbef0e65833632e273e4b18418cb07d27e78d3c0 Mon Sep 17 00:00:00 2001 From: hobbyquaker Date: Sun, 15 Mar 2020 12:43:09 +0100 Subject: [PATCH 102/509] fix lint issues --- usermods/battery_keypad_controller/README.md | 1 - usermods/battery_keypad_controller/wled06_usermod.ino | 1 - 2 files changed, 2 deletions(-) diff --git a/usermods/battery_keypad_controller/README.md b/usermods/battery_keypad_controller/README.md index 6262b21cd..77e3c1e46 100644 --- a/usermods/battery_keypad_controller/README.md +++ b/usermods/battery_keypad_controller/README.md @@ -5,7 +5,6 @@ I'm using this controller for a festival totem. Runs on 3 18650 Cells, can deliv Via keypad one can select 8 presets, change effect, effect speed, effect intensity and palette. Brightness can be adjusted with a potentiometer. - ## Pictures ![bat-key-ctrl-1](assets/bat-key-ctrl-1.jpg) diff --git a/usermods/battery_keypad_controller/wled06_usermod.ino b/usermods/battery_keypad_controller/wled06_usermod.ino index dd001c8d0..877713b61 100644 --- a/usermods/battery_keypad_controller/wled06_usermod.ino +++ b/usermods/battery_keypad_controller/wled06_usermod.ino @@ -140,7 +140,6 @@ void userLoop() if (effectPalette <= 0) effectPalette = 50; colorUpdated(NOTIFIER_CALL_MODE_FX_CHANGED); break; - break; } From c28027496d6bcc2cb61c10f0519acc52cbbb61e6 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Thu, 19 Mar 2020 00:37:35 -0400 Subject: [PATCH 103/509] Fix initialization bug when toggling skip first. --- wled00/FX_fcn.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 59f69da4d..158e3923e 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -29,11 +29,11 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) { - if (supportWhite == _useRgbw && countPixels == _length) return; + if (supportWhite == _useRgbw && countPixels == _length && _skipFirstMode == skipFirst) return; RESET_RUNTIME; _useRgbw = supportWhite; - _skipFirstMode = skipFirst; _length = countPixels; + _skipFirstMode = skipFirst; uint8_t ty = 1; if (supportWhite) ty = 2; From e5c3629e2ef7b186a458241660d6fedb09542532 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sat, 21 Mar 2020 00:57:54 +0100 Subject: [PATCH 104/509] Added custom per-LED mapping --- CHANGELOG.md | 5 +++++ readme.md | 4 ++++ wled00/FX_fcn.cpp | 31 ++++++++++++++++++++++++++++++- wled00/NpbWrapper.h | 2 +- wled00/html_settings.h | 2 +- wled00/wled00.ino | 2 +- 6 files changed, 42 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbc45e927..631162c7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ### Development versions after 0.9.1 release +#### Build 2003211 + +- Added custom mapping compile define to FX_fcn.h +- Merged pull request #784 by @TravisDean: Fixed initialization bug when toggling skip first +- Added link to youtube videos by Room31 to readme #### Build 2003141 diff --git a/readme.md b/readme.md index c796ca5c9..53671c6b9 100644 --- a/readme.md +++ b/readme.md @@ -50,6 +50,10 @@ DrZzs has made some excellent video guides: If you'd rather read, here is a very [detailed step-by-step beginner tutorial](https://tynick.com/blog/11-03-2019/getting-started-with-wled-on-esp8266/) by tynick! +Russian speakers, check out the videos by Room31: +[WLED Firmware Overview: Interface and Settings](https://youtu.be/h7lKsczEI7E) +[ESP8266 based LED controller for WS2812b strip. WLED Firmware + OpenHAB](https://youtu.be/K4ioTt3XvGc) + ### Other Licensed under the MIT license diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 59f69da4d..faf9b2931 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -27,6 +27,23 @@ #include "FX.h" #include "palettes.h" +//enable custom per-LED mapping. This can allow for better effects on matrices or special displays +//#define WLED_CUSTOM_LED_MAPPING + +#ifdef WLED_CUSTOM_LED_MAPPING +//this is just an example (30 LEDs). It will first set all even, then all uneven LEDs. +const uint16_t customMappingTable[] = { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, + 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29}; + +//another example. Switches direction every 5 LEDs. +/*const uint16_t customMappingTable[] = { + 0, 1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 11, 12, 13, 14, + 19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25};*/ + +const uint16_t customMappingSize = sizeof(customMappingTable)/sizeof(uint16_t); //30 in example +#endif + void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) { if (supportWhite == _useRgbw && countPixels == _length) return; @@ -142,10 +159,16 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) int16_t indexSet = realIndex + (reversed ? -j : j); int16_t indexSetRev = indexSet; if (reverseMode) indexSetRev = _length - 1 - indexSet; + #ifdef WLED_CUSTOM_LED_MAPPING + if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet]; + #endif if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) bus->SetPixelColor(indexSet + skip, col); } } else { //live data, etc. if (reverseMode) i = _length - 1 - i; + #ifdef WLED_CUSTOM_LED_MAPPING + if (i < customMappingSize) i = customMappingTable[i]; + #endif bus->SetPixelColor(i + skip, col); } if (skip && i == 0) { @@ -430,7 +453,13 @@ uint32_t WS2812FX::getColor(void) { uint32_t WS2812FX::getPixelColor(uint16_t i) { - i = realPixelIndex(i) + (_skipFirstMode ? LED_SKIP_AMOUNT : 0); + i = realPixelIndex(i); + + #ifdef WLED_CUSTOM_LED_MAPPING + if (i < customMappingSize) i = customMappingTable[i]; + #endif + + if (_skipFirstMode) i += LED_SKIP_AMOUNT; if (_cronixieMode) { diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 71367d980..673d82492 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -4,7 +4,7 @@ //PIN CONFIGURATION #ifndef LEDPIN -#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) +#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) #endif //#define USE_APA102 // Uncomment for using APA102 LEDs. //#define USE_WS2801 // Uncomment for using WS2801 LEDs (make sure you have NeoPixelBus v2.5.6 or newer) diff --git a/wled00/html_settings.h b/wled00/html_settings.h index c7badc16f..266016959 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -284,9 +284,9 @@ Send notifications twice:

Realtime

Receive UDP realtime:

E1.31 (sACN)
-Skip out-of-sequence packets (freeze instead of flicker):
Use E1.31 multicast:
E1.31 start universe:
+Skip out-of-sequence packets:
Reboot required. Check out
LedFx!
DMX start address:
DMX mode: diff --git a/wled00/wled00.ino b/wled00/wled00.ino index f9648dcf1..69517073c 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -119,7 +119,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2003141 +#define VERSION 2003211 char versionString[] = "0.9.1"; From a4f0c9195e820b936f215a0ce6fd987c7ca953c1 Mon Sep 17 00:00:00 2001 From: Thomas Stockklauser Date: Sun, 22 Mar 2020 11:38:29 +0100 Subject: [PATCH 105/509] 1. Fix an Issue withtin the DMX Compiler Flags if you dont use it in wled00.ino 2. Fix the Build / working environment for Visual Studio and make a better Folder Structure within the Visual Studio Project --- wled00/__vm/.wled00.vsarduino.h | 15 +++++---------- wled00/__vm/Compile.vmps.xml | 6 +++--- wled00/wled00.ino | 2 ++ wled00/wled00.vcxproj | 4 ++-- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/wled00/__vm/.wled00.vsarduino.h b/wled00/__vm/.wled00.vsarduino.h index 722f8378f..2a9ef40a4 100644 --- a/wled00/__vm/.wled00.vsarduino.h +++ b/wled00/__vm/.wled00.vsarduino.h @@ -17,8 +17,10 @@ #define __ESP32_ESP32__ #define ESP_PLATFORM #define HAVE_CONFIG_H +#define GCC_NOT_5_2_0 0 +#define WITH_POSIX #define F_CPU 240000000L -#define ARDUINO 10809 +#define ARDUINO 108011 #define ARDUINO_ESP32_DEV #define ARDUINO_ARCH_ESP32 #define ESP32 @@ -92,18 +94,11 @@ typedef long pthread_cond_t; #include "arduino.h" #include -//#include "..\generic\Common.h" -//#include "..\generic\pins_arduino.h" - -//#undef F -//#define F(string_literal) ((const PROGMEM char *)(string_literal)) -//#undef PSTR -//#define PSTR(string_literal) ((const PROGMEM char *)(string_literal)) -//current vc++ does not understand this syntax so use older arduino example for intellisense -//todo:move to the new clang/gcc project types. #define interrupts() sei() #define noInterrupts() cli() +#define ESP_LOGI(tag, ...) + #include "wled00.ino" #include "wled01_eeprom.ino" #include "wled02_xml.ino" diff --git a/wled00/__vm/Compile.vmps.xml b/wled00/__vm/Compile.vmps.xml index a7819d208..6390398ed 100644 --- a/wled00/__vm/Compile.vmps.xml +++ b/wled00/__vm/Compile.vmps.xml @@ -1,8 +1,8 @@ - - + + - + diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 69517073c..80f9d79b0 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -552,7 +552,9 @@ void loop() { handleSerial(); handleNotifications(); handleTransitions(); +#ifdef WLED_ENABLE_DMX handleDMX(); +#endif userLoop(); yield(); diff --git a/wled00/wled00.vcxproj b/wled00/wled00.vcxproj index b9842e0a4..2183ad262 100644 --- a/wled00/wled00.vcxproj +++ b/wled00/wled00.vcxproj @@ -73,9 +73,9 @@ true true true - $(ProjectDir)..\wled00;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\WiFi\src;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\ESPmDNS\src;C:\Program Files (x86)\Arduino\libraries\AsyncTCP;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\SPIFFS\src;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\FS\src;C:\Program Files (x86)\Arduino\libraries\ESPAsyncWebServer\src;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\EEPROM\src;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\DNSServer\src;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\ArduinoOTA\src;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\Update\src;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\AsyncUDP\src;$(ProjectDir)..\..\..\User\Thomas\Documents\Arduino\libraries\NeoPixelBus_by_Makuna\src;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\libraries\SPI\src;$(ProjectDir)..\..\..\User\Thomas\Documents\Arduino\libraries\FastLED;C:\Program Files (x86)\Arduino\libraries;$(ProjectDir)..\..\..\User\Thomas\Documents\Arduino\libraries;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\libraries;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\cores\esp32;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\cores\esp32\apps;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\cores\esp32\libb64;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\variants\esp32;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\config;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\app_trace;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\app_update;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\asio;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\bootloader_support;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\bt;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\coap;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\console;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\driver;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\esp-tls;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\esp32;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\esp_adc_cal;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\esp_event;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\esp_http_client;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\esp_http_server;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\esp_https_ota;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\esp_ringbuf;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\ethernet;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\expat;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\fatfs;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\freemodbus;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\freertos;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\heap;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\idf_test;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\jsmn;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\json;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\libsodium;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\log;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\lwip;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\mbedtls;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\mdns;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\micro-ecc;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\mqtt;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\newlib;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\nghttp;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\nvs_flash;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\openssl;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\protobuf-c;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\protocomm;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\pthread;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\sdmmc;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\smartconfig_ack;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\soc;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\spi_flash;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\spiffs;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\tcp_transport;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\tcpip_adapter;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\ulp;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\vfs;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\wear_levelling;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\wifi_provisioning;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\wpa_supplicant;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\xtensa-debug-module;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\esp32-camera;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\esp-face;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\hardware\esp32\1.0.2\tools\sdk\include\fb_gfx;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\lib\gcc\xtensa-esp32-elf\5.2.0\include;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\xtensa-esp32-elf\include\c++\5.2.0\xtensa-esp32-elf;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\xtensa-esp32-elf\include;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\xtensa-esp32-elf\include\c++\5.2.0;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\include\c++\5.2.0;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\include;C:\Users\thoma\AppData\Local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\include\include;%(AdditionalIncludeDirectories) + $(ProjectDir)..\wled00;C:\Program Files (x86)\Arduino\libraries\WiFi\src;C:\Program Files (x86)\Arduino\libraries\WiFi\src\utility;C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src;C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino;C:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\yun;C:\Program Files (x86)\Arduino\hardware\tools\avr\\lib\gcc\avr\7.3.0\include;C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include;C:\Program Files (x86)\Arduino\hardware\tools\avr\\lib\gcc\avr\7.3.0\include;C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include-fixed;C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include\avr;C:\Program Files (x86)\Arduino\hardware\tools\avr\lib\gcc\avr\4.9.2\include;C:\Program Files (x86)\Arduino\hardware\tools\avr\lib\gcc\avr\4.9.2\include;C:\Program Files (x86)\Arduino\hardware\tools\avr\lib\gcc\avr\4.9.3\include;%(AdditionalIncludeDirectories) $(ProjectDir)__vm\.wled00.vsarduino.h;%(ForcedIncludeFiles) - __ESP32_esp32__;__ESP32_ESP32__;ESP_PLATFORM;HAVE_CONFIG_H;F_CPU=240000000L;ARDUINO=10809;ARDUINO_ESP32_DEV;ARDUINO_ARCH_ESP32;ESP32;CORE_DEBUG_LEVEL=0;__cplusplus=201103L;_VMICRO_INTELLISENSE;%(PreprocessorDefinitions) + __AVR_atmega32u4__;__AVR_ATmega32U4__;__AVR_ATmega32u4__;F_CPU=16000000L;ARDUINO=108011;ARDUINO_AVR_YUN;ARDUINO_ARCH_AVR;USB_VID=0x2341;USB_PID=0x8041;__cplusplus=201103L;_VMICRO_INTELLISENSE;%(PreprocessorDefinitions) true From 53f09c0630385049e0d1bad125513c707e493b78 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sun, 22 Mar 2020 17:45:09 +0100 Subject: [PATCH 106/509] Moved Cronixie driver from FX library to drawOverlay handler --- CHANGELOG.md | 4 ++ wled00/FX.h | 7 --- wled00/FX_fcn.cpp | 117 +++++++------------------------------ wled00/wled00.ino | 2 +- wled00/wled03_set.ino | 6 -- wled00/wled11_ol.ino | 13 +++-- wled00/wled13_cronixie.ino | 43 +++++++++++--- 7 files changed, 69 insertions(+), 123 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 631162c7a..321eea8aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ### Development versions after 0.9.1 release +#### Build 2003221 + +- Moved Cronixie driver from FX library to drawOverlay handler + #### Build 2003211 - Added custom mapping compile define to FX_fcn.h diff --git a/wled00/FX.h b/wled00/FX.h index abb8c6f00..d24250f9b 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -407,9 +407,6 @@ class WS2812FX { setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), setColor(uint8_t slot, uint32_t c), setBrightness(uint8_t b), - driverModeCronixie(bool b), - setCronixieDigits(byte* d), - setCronixieBacklight(bool b), setRange(uint16_t i, uint16_t i2, uint32_t col), setShowCallback(show_callback cb), setTransitionMode(bool t), @@ -597,13 +594,9 @@ class WS2812FX { bool _useRgbw = false, - _cronixieMode, - _cronixieBacklightEnabled, _skipFirstMode, _triggered; - byte _cronixieDigits[6]; - mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element show_callback _callback = nullptr; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 7bc02defb..055686237 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -147,90 +147,32 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) } col.W = w; - if (!_cronixieMode) - { - uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; - if (SEGLEN) {//from segment - /* Set all the pixels in the group, ensuring _skipFirstMode is honored */ - bool reversed = reverseMode ^ IS_REVERSE; - uint16_t realIndex = realPixelIndex(i); + uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; + if (SEGLEN) {//from segment + /* Set all the pixels in the group, ensuring _skipFirstMode is honored */ + bool reversed = reverseMode ^ IS_REVERSE; + uint16_t realIndex = realPixelIndex(i); - for (uint16_t j = 0; j < SEGMENT.grouping; j++) { - int16_t indexSet = realIndex + (reversed ? -j : j); - int16_t indexSetRev = indexSet; - if (reverseMode) indexSetRev = _length - 1 - indexSet; - #ifdef WLED_CUSTOM_LED_MAPPING - if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet]; - #endif - if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) bus->SetPixelColor(indexSet + skip, col); - } - } else { //live data, etc. - if (reverseMode) i = _length - 1 - i; + for (uint16_t j = 0; j < SEGMENT.grouping; j++) { + int16_t indexSet = realIndex + (reversed ? -j : j); + int16_t indexSetRev = indexSet; + if (reverseMode) indexSetRev = _length - 1 - indexSet; #ifdef WLED_CUSTOM_LED_MAPPING - if (i < customMappingSize) i = customMappingTable[i]; + if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet]; #endif - bus->SetPixelColor(i + skip, col); + if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) bus->SetPixelColor(indexSet + skip, col); } - if (skip && i == 0) { - for (uint16_t j = 0; j < skip; j++) { - bus->SetPixelColor(j, RgbwColor(0, 0, 0, 0)); - } - } - return; + } else { //live data, etc. + if (reverseMode) i = _length - 1 - i; + #ifdef WLED_CUSTOM_LED_MAPPING + if (i < customMappingSize) i = customMappingTable[i]; + #endif + bus->SetPixelColor(i + skip, col); } - - //CRONIXIE - if(i>6)return; - byte o = 10*i; - if (_cronixieBacklightEnabled && _cronixieDigits[i] <11) - { - byte r2 = _segments[0].colors[1] >>16; - byte g2 = _segments[0].colors[1] >> 8; - byte b2 = _segments[0].colors[1]; - byte w2 = _segments[0].colors[1] >>24; - for (int j=o; j< o+19; j++) - { - bus->SetPixelColor(j, RgbwColor(r2,g2,b2,w2)); + if (skip && i == 0) { + for (uint16_t j = 0; j < skip; j++) { + bus->SetPixelColor(j, RgbwColor(0, 0, 0, 0)); } - } else - { - for (int j=o; j< o+19; j++) - { - bus->SetPixelColor(j, RgbwColor(0,0,0,0)); - } - } - if (_skipFirstMode) o += LED_SKIP_AMOUNT; - switch(_cronixieDigits[i]) - { - case 0: bus->SetPixelColor(o+5, col); break; - case 1: bus->SetPixelColor(o+0, col); break; - case 2: bus->SetPixelColor(o+6, col); break; - case 3: bus->SetPixelColor(o+1, col); break; - case 4: bus->SetPixelColor(o+7, col); break; - case 5: bus->SetPixelColor(o+2, col); break; - case 6: bus->SetPixelColor(o+8, col); break; - case 7: bus->SetPixelColor(o+3, col); break; - case 8: bus->SetPixelColor(o+9, col); break; - case 9: bus->SetPixelColor(o+4, col); break; - } -} - -void WS2812FX::driverModeCronixie(bool b) -{ - _cronixieMode = b; - _segments[0].stop = (b) ? 6 : _length; -} - -void WS2812FX::setCronixieBacklight(bool b) -{ - _cronixieBacklightEnabled = b; -} - -void WS2812FX::setCronixieDigits(byte d[]) -{ - for (int i = 0; i<6; i++) - { - _cronixieDigits[i] = d[i]; } } @@ -461,25 +403,6 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) if (_skipFirstMode) i += LED_SKIP_AMOUNT; - if (_cronixieMode) - { - if(i>6)return 0; - byte o = 10*i; - switch(_cronixieDigits[i]) - { - case 0: i=o+5; break; - case 1: i=o+0; break; - case 2: i=o+6; break; - case 3: i=o+1; break; - case 4: i=o+7; break; - case 5: i=o+2; break; - case 6: i=o+8; break; - case 7: i=o+3; break; - case 8: i=o+9; break; - case 9: i=o+4; break; - default: return 0; - } - } if (i >= _lengthRaw) return 0; RgbwColor col = bus->GetPixelColorRgbw(i); diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 80f9d79b0..55f714f58 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -119,7 +119,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2003211 +#define VERSION 2003221 char versionString[] = "0.9.1"; diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 5a7f4db63..fc82256d2 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -217,12 +217,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) analogClockSecondsTrail = request->hasArg("OS"); strcpy(cronixieDisplay,request->arg("CX").c_str()); - bool cbOld = cronixieBacklight; cronixieBacklight = request->hasArg("CB"); - if (cbOld != cronixieBacklight && overlayCurrent == 3) - { - strip.setCronixieBacklight(cronixieBacklight); overlayRefreshedTime = 0; - } countdownMode = request->hasArg("CE"); countdownYear = request->arg("CY").toInt(); countdownMonth = request->arg("CI").toInt(); @@ -656,7 +651,6 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) if (pos > 0) //sets backlight { cronixieBacklight = (req.charAt(pos+3) != '0'); - if (overlayCurrent == 3) strip.setCronixieBacklight(cronixieBacklight); overlayRefreshedTime = 0; } #endif diff --git a/wled00/wled11_ol.ino b/wled00/wled11_ol.ino index cfe8a1f9f..93f7b96df 100644 --- a/wled00/wled11_ol.ino +++ b/wled00/wled11_ol.ino @@ -6,13 +6,12 @@ void initCronixie() { if (overlayCurrent == 3 && !cronixieInit) { - strip.driverModeCronixie(true); - strip.setCronixieBacklight(cronixieBacklight); setCronixie(); + strip.getSegment(0).grouping = 10; //10 LEDs per digit cronixieInit = true; } else if (cronixieInit && overlayCurrent != 3) { - strip.driverModeCronixie(false); + strip.getSegment(0).grouping = 1; cronixieInit = false; } } @@ -120,6 +119,10 @@ void _overlayAnalogCountdown() void handleOverlayDraw() { - if (overlayCurrent != 1) return; //only analog clock - _overlayAnalogClock(); + if (!overlayCurrent) return; + switch (overlayCurrent) + { + case 1: _overlayAnalogClock(); break; + case 3: _drawOverlayCronixie(); break; + } } diff --git a/wled00/wled13_cronixie.ino b/wled00/wled13_cronixie.ino index 897c94f92..dd687ca14 100644 --- a/wled00/wled13_cronixie.ino +++ b/wled00/wled13_cronixie.ino @@ -1,6 +1,10 @@ /* * Support for the Cronixie clock */ +#ifndef WLED_DISABLE_CRONIXIE +byte _digitOut[6] = {10,10,10,10,10,10}; +#endif + byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) { byte counter = 0; @@ -161,7 +165,6 @@ void _overlayCronixie() if (h>12) h-=12; else if (h==0) h+=12; } - byte _digitOut[]{10,10,10,10,10,10}; for (int i = 0; i < 6; i++) { if (dP[i] < 12) _digitOut[i] = dP[i]; @@ -184,8 +187,8 @@ void _overlayCronixie() case 37: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //YY case 39: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //YYYY - case 16: _digitOut[i+2] = ((h0/3)&1)?1:0; i++; //BBB (BBBB NI) - case 15: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:0; i++; //BB + //case 16: _digitOut[i+2] = ((h0/3)&1)?1:0; i++; //BBB (BBBB NI) + //case 15: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:0; i++; //BB case 14: _digitOut[i] = (h0>11)?1:0; break; //B } } else @@ -195,8 +198,8 @@ void _overlayCronixie() case 71: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //hh case 75: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //mm case 81: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ss - case 66: _digitOut[i+2] = ((h0/3)&1)?1:10; i++; //bbb (bbbb NI) - case 65: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:10; i++; //bb + //case 66: _digitOut[i+2] = ((h0/3)&1)?1:10; i++; //bbb (bbbb NI) + //case 65: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:10; i++; //bb case 64: _digitOut[i] = (h0>11)?1:10; break; //b case 93: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //d @@ -208,7 +211,33 @@ void _overlayCronixie() } } } - strip.setCronixieDigits(_digitOut); - //strip.trigger(); //this has a drawback, no effects slower than RefreshMs. advantage: Quick update, not dependant on effect time + #endif +} + +void _drawOverlayCronixie() +{ + #ifndef WLED_DISABLE_CRONIXIE + byte offsets[] = {5, 0, 6, 1, 7, 2, 8, 3, 9, 4}; + + for (uint16_t i = 0; i < 6; i++) + { + byte o = 10*i; + byte excl = 10; + if(_digitOut[i] < 10) excl = offsets[_digitOut[i]]; + excl += o; + + if (cronixieBacklight && _digitOut[i] <11) + { + uint32_t col = strip.gamma32(strip.getSegment(0).colors[1]); + for (uint16_t j=o; j< o+10; j++) { + if (j != excl) strip.setPixelColor(j, col); + } + } else + { + for (uint16_t j=o; j< o+10; j++) { + if (j != excl) strip.setPixelColor(j, 0); + } + } + } #endif } From ed729c32d2d2e6a6ffefa29cd009047eadea08dd Mon Sep 17 00:00:00 2001 From: cschwinne Date: Wed, 25 Mar 2020 00:59:48 +0100 Subject: [PATCH 107/509] Fixed Alexa whites --- CHANGELOG.md | 4 ++ wled00/src/dependencies/espalexa/Espalexa.h | 13 ++--- .../dependencies/espalexa/EspalexaDevice.cpp | 51 ++++++++----------- .../dependencies/espalexa/EspalexaDevice.h | 6 +-- wled00/wled00.ino | 3 +- wled00/wled12_alexa.ino | 28 +++++++--- wled00/wled14_colors.ino | 6 +-- 7 files changed, 61 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 321eea8aa..68243a3ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ### Development versions after 0.9.1 release +#### Build 2003222 + +- Fixed Alexa Whites on non-RGBW lights (bump Espalexa to 2.4.5) + #### Build 2003221 - Moved Cronixie driver from FX library to drawOverlay handler diff --git a/wled00/src/dependencies/espalexa/Espalexa.h b/wled00/src/dependencies/espalexa/Espalexa.h index 49c9b6a9a..7a1312f85 100644 --- a/wled00/src/dependencies/espalexa/Espalexa.h +++ b/wled00/src/dependencies/espalexa/Espalexa.h @@ -10,7 +10,7 @@ */ /* * @title Espalexa library - * @version 2.4.4 + * @version 2.4.5 * @author Christian Schwinne * @license MIT * @contributors d-999 @@ -49,7 +49,7 @@ #include #ifdef ESPALEXA_DEBUG - #pragma message "Espalexa 2.4.4 debug mode" + #pragma message "Espalexa 2.4.5 debug mode" #define EA_DEBUG(x) Serial.print (x) #define EA_DEBUGLN(x) Serial.println (x) #else @@ -164,7 +164,7 @@ private: json += "\",\"modelid\":\"" + modelidString(dev->getType()); json += "\",\"manufacturername\":\"Philips\",\"productname\":\"E" + String(static_cast(dev->getType())); json += "\",\"uniqueid\":\"" + String(encodeLightId(deviceId+1)); - json += "\",\"swversion\":\"espalexa-2.4.4\"}"; + json += "\",\"swversion\":\"espalexa-2.4.5\"}"; return json; } @@ -188,7 +188,7 @@ private: } res += "\r\nFree Heap: " + (String)ESP.getFreeHeap(); res += "\r\nUptime: " + (String)millis(); - res += "\r\n\r\nEspalexa library v2.4.4 by Christian Schwinne 2020"; + res += "\r\n\r\nEspalexa library v2.4.5 by Christian Schwinne 2020"; server->send(200, "text/plain", res); } #endif @@ -370,9 +370,10 @@ public: if (!discoverable) return; //do not reply to M-SEARCH if not discoverable String request = packetBuffer; - if(request.indexOf("M-SEARCH") >= 0) { + if(request.indexOf("M-SEA") >= 0) { //M-SEARCH EA_DEBUGLN(request); - if(request.indexOf("upnp:rootdevice") > 0 || request.indexOf("asic:1") > 0 || request.indexOf("ssdp:all") > 0) { + //match upnp:rootdevice, device:basic:1, ssdp:all and ssdp:discover + if(request.indexOf("np:rootd") > 0 || request.indexOf("asic:1") > 0 || request.indexOf("dp:all") > 0 || request.indexOf("dp:dis") > 0) { EA_DEBUGLN("Responding search req..."); respondToSearch(); } diff --git a/wled00/src/dependencies/espalexa/EspalexaDevice.cpp b/wled00/src/dependencies/espalexa/EspalexaDevice.cpp index 25d70bb0b..520cf4418 100644 --- a/wled00/src/dependencies/espalexa/EspalexaDevice.cpp +++ b/wled00/src/dependencies/espalexa/EspalexaDevice.cpp @@ -122,37 +122,28 @@ uint32_t EspalexaDevice::getRGB() float temp = 10000/ _ct; //kelvins = 1,000,000/mired (and that /100) float r, g, b; -// Cold white to warm white receiving from Alexa: _ct = 199, 234, 284, 350, 383 (from cold white to warm white) - switch (_ct) { - case 199: rgb[0]=255,rgb[1]=255,rgb[2]=255;rgb[3]=255;break; - case 234: rgb[0]=127,rgb[1]=127,rgb[2]=127;rgb[3]=255;break; - case 284: rgb[0]=0,rgb[1]=0,rgb[2]=0;rgb[3]=255;break; - case 350: rgb[0]=130,rgb[1]=90,rgb[2]=0;rgb[3]=255;break; - case 383: rgb[0]=255,rgb[1]=153,rgb[2]=0;rgb[3]=255;break; - default: { - if( temp <= 66 ){ - r = 255; - g = temp; - g = 99.470802 * log(g) - 161.119568; - if( temp <= 19){ - b = 0; - } else { - b = temp-10; - b = 138.517731 * log(b) - 305.044793; - } - } else { - r = temp - 60; - r = 329.698727 * pow(r, -0.13320476); - g = temp - 60; - g = 288.12217 * pow(g, -0.07551485 ); - b = 255; - } - - rgb[0] = (byte)constrain(r,0.1,255.1); - rgb[1] = (byte)constrain(g,0.1,255.1); - rgb[2] = (byte)constrain(b,0.1,255.1); + if (temp <= 66) { + r = 255; + g = temp; + g = 99.470802 * log(g) - 161.119568; + if (temp <= 19) { + b = 0; + } else { + b = temp-10; + b = 138.517731 * log(b) - 305.044793; } + } else { + r = temp - 60; + r = 329.698727 * pow(r, -0.13320476); + g = temp - 60; + g = 288.12217 * pow(g, -0.07551485 ); + b = 255; } + + rgb[0] = (byte)constrain(r,0.1,255.1); + rgb[1] = (byte)constrain(g,0.1,255.1); + rgb[2] = (byte)constrain(b,0.1,255.1); + } else if (_mode == EspalexaColorMode::hs) { float h = ((float)_hue)/65535.0; @@ -226,7 +217,7 @@ uint32_t EspalexaDevice::getRGB() rgb[1] = 255.0*g; rgb[2] = 255.0*b; } - _rgb = ((rgb[3] << 24) | (rgb[0] << 16) | (rgb[1] << 8) | (rgb[2])); //white value is only >0 if Alexa did provide a CT value, RGB colors will not be touched. + _rgb = ((rgb[0] << 16) | (rgb[1] << 8) | (rgb[2])); return _rgb; } diff --git a/wled00/src/dependencies/espalexa/EspalexaDevice.h b/wled00/src/dependencies/espalexa/EspalexaDevice.h index a66449165..4785591fe 100644 --- a/wled00/src/dependencies/espalexa/EspalexaDevice.h +++ b/wled00/src/dependencies/espalexa/EspalexaDevice.h @@ -5,9 +5,9 @@ typedef class EspalexaDevice; -typedef void (*BrightnessCallbackFunction) (uint8_t b); -typedef void (*DeviceCallbackFunction) (EspalexaDevice* d); -typedef void (*ColorCallbackFunction) (uint8_t br, uint32_t col); +typedef std::function BrightnessCallbackFunction; +typedef std::function DeviceCallbackFunction; +typedef std::function ColorCallbackFunction; enum class EspalexaColorMode : uint8_t { none = 0, ct = 1, hs = 2, xy = 3 }; enum class EspalexaDeviceType : uint8_t { onoff = 0, dimmable = 1, whitespectrum = 2, color = 3, extendedcolor = 4 }; diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 55f714f58..7c64796d6 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -7,7 +7,6 @@ * @author Christian Schwinne */ - //ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). //ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). @@ -119,7 +118,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2003221 +#define VERSION 2003222 char versionString[] = "0.9.1"; diff --git a/wled00/wled12_alexa.ino b/wled00/wled12_alexa.ino index 9c27041b7..5163640e2 100644 --- a/wled00/wled12_alexa.ino +++ b/wled00/wled12_alexa.ino @@ -61,12 +61,28 @@ void onAlexaChange(EspalexaDevice* dev) colorUpdated(NOTIFIER_CALL_MODE_ALEXA); } else //color { - uint32_t color = espalexaDevice->getRGB(); - col[3] = ((color >> 24) & 0xFF); // white color from Alexa is "pure white only" - col[0] = ((color >> 16) & 0xFF); - col[1] = ((color >> 8) & 0xFF); - col[2] = (color & 0xFF); - if (useRGBW && col[3] == 0) colorRGBtoRGBW(col); // do not touch white value if EspalexaDevice.cpp did set the white channel + if (espalexaDevice->getColorMode() == EspalexaColorMode::ct) //shade of white + { + uint16_t ct = espalexaDevice->getCt(); + if (useRGBW) + { + switch (ct) { //these values empirically look good on RGBW + case 199: col[0]=255; col[1]=255; col[2]=255; col[3]=255; break; + case 234: col[0]=127; col[1]=127; col[2]=127; col[3]=255; break; + case 284: col[0]= 0; col[1]= 0; col[2]= 0; col[3]=255; break; + case 350: col[0]=130; col[1]= 90; col[2]= 0; col[3]=255; break; + case 383: col[0]=255; col[1]=153; col[2]= 0; col[3]=255; break; + } + } else { + colorCTtoRGB(ct, col); + } + } else { + uint32_t color = espalexaDevice->getRGB(); + + col[0] = ((color >> 16) & 0xFF); + col[1] = ((color >> 8) & 0xFF); + col[2] = ( color & 0xFF); + } colorUpdated(NOTIFIER_CALL_MODE_ALEXA); } } diff --git a/wled00/wled14_colors.ino b/wled00/wled14_colors.ino index c8ca0dcbe..a1db307ae 100644 --- a/wled00/wled14_colors.ino +++ b/wled00/wled14_colors.ino @@ -57,10 +57,9 @@ void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break; case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q; } - if (useRGBW) colorRGBtoRGBW(col); + if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col); } -#ifndef WLED_DISABLE_HUESYNC void colorCTtoRGB(uint16_t mired, byte* rgb) //white spectrum to rgb { //this is only an approximation using WS2812B with gamma correction enabled @@ -81,9 +80,10 @@ void colorCTtoRGB(uint16_t mired, byte* rgb) //white spectrum to rgb } else { rgb[0]=237;rgb[1]=255;rgb[2]=239;//150 } - if (useRGBW) colorRGBtoRGBW(col); + if (useRGBW && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col); } +#ifndef WLED_DISABLE_HUESYNC void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy) { float z = 1.0f - x - y; From 594c0b85507ec7e5ae29cfa72102d6a2aa58ba08 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Wed, 25 Mar 2020 04:00:55 -0400 Subject: [PATCH 108/509] Transform ino to h/cpp. Class WLED created. --- wled00/wled.cpp | 503 ++++++++++++++ wled00/wled.h | 529 +++++++++++++++ wled00/wled00.ino | 612 +----------------- wled00/wled05_init.ino | 339 ---------- ...{wled06_usermod.ino => wled06_usermod.cpp} | 1 + wled00/{wled12_alexa.ino => wled_alexa.cpp} | 10 +- wled00/wled_alexa.h | 16 + wled00/{wled16_blynk.ino => wled_blynk.cpp} | 6 +- wled00/wled_blynk.h | 13 + wled00/{wled09_button.ino => wled_button.cpp} | 2 + wled00/wled_button.h | 12 + wled00/{wled14_colors.ino => wled_colors.cpp} | 12 +- wled00/wled_colors.h | 20 + ...{wled13_cronixie.ino => wled_cronixie.cpp} | 20 +- wled00/wled_cronixie.h | 13 + wled00/{wled21_dmx.ino => wled_dmx.cpp} | 9 +- wled00/wled_dmx.h | 11 + wled00/{wled01_eeprom.ino => wled_eeprom.cpp} | 6 +- wled00/wled_eeprom.h | 22 + wled00/{wled04_file.ino => wled_file.cpp} | 14 +- wled00/wled_file.h | 12 + wled00/{wled15_hue.ino => wled_hue.cpp} | 7 +- wled00/wled_hue.h | 10 + wled00/{wled20_ir.ino => wled_ir.cpp} | 5 +- wled00/wled_ir.h | 9 + wled00/{wled19_json.ino => wled_json.cpp} | 5 +- wled00/wled_json.h | 15 + wled00/{wled08_led.ino => wled_led.cpp} | 8 +- wled00/wled_led.h | 19 + wled00/{wled17_mqtt.ino => wled_mqtt.cpp} | 5 +- wled00/wled_mqtt.h | 9 + wled00/{wled07_notify.ino => wled_notify.cpp} | 6 +- wled00/wled_notify.h | 17 + wled00/{wled10_ntp.ino => wled_ntp.cpp} | 62 +- wled00/wled_ntp.h | 76 +++ wled00/{wled11_ol.ino => wled_overlay.cpp} | 5 +- wled00/wled_overlay.h | 12 + wled00/{wled18_server.ino => wled_server.cpp} | 7 +- wled00/wled_server.h | 18 + wled00/{wled03_set.ino => wled_set.cpp} | 4 + wled00/wled_set.h | 12 + wled00/{wled02_xml.ino => wled_xml.cpp} | 7 +- wled00/wled_xml.h | 15 + 43 files changed, 1441 insertions(+), 1074 deletions(-) create mode 100644 wled00/wled.cpp create mode 100644 wled00/wled.h delete mode 100644 wled00/wled05_init.ino rename wled00/{wled06_usermod.ino => wled06_usermod.cpp} (97%) rename wled00/{wled12_alexa.ino => wled_alexa.cpp} (89%) create mode 100644 wled00/wled_alexa.h rename wled00/{wled16_blynk.ino => wled_blynk.cpp} (94%) create mode 100644 wled00/wled_blynk.h rename wled00/{wled09_button.ino => wled_button.cpp} (98%) create mode 100644 wled00/wled_button.h rename wled00/{wled14_colors.ino => wled_colors.cpp} (96%) create mode 100644 wled00/wled_colors.h rename wled00/{wled13_cronixie.ino => wled_cronixie.cpp} (97%) create mode 100644 wled00/wled_cronixie.h rename wled00/{wled21_dmx.ino => wled_dmx.cpp} (89%) create mode 100644 wled00/wled_dmx.h rename wled00/{wled01_eeprom.ino => wled_eeprom.cpp} (99%) create mode 100644 wled00/wled_eeprom.h rename wled00/{wled04_file.ino => wled_file.cpp} (95%) create mode 100644 wled00/wled_file.h rename wled00/{wled15_hue.ino => wled_hue.cpp} (99%) create mode 100644 wled00/wled_hue.h rename wled00/{wled20_ir.ino => wled_ir.cpp} (99%) create mode 100644 wled00/wled_ir.h rename wled00/{wled19_json.ino => wled_json.cpp} (99%) create mode 100644 wled00/wled_json.h rename wled00/{wled08_led.ino => wled_led.cpp} (98%) create mode 100644 wled00/wled_led.h rename wled00/{wled17_mqtt.ino => wled_mqtt.cpp} (98%) create mode 100644 wled00/wled_mqtt.h rename wled00/{wled07_notify.ino => wled_notify.cpp} (99%) create mode 100644 wled00/wled_notify.h rename wled00/{wled10_ntp.ino => wled_ntp.cpp} (58%) create mode 100644 wled00/wled_ntp.h rename wled00/{wled11_ol.ino => wled_overlay.cpp} (98%) create mode 100644 wled00/wled_overlay.h rename wled00/{wled18_server.ino => wled_server.cpp} (99%) create mode 100644 wled00/wled_server.h rename wled00/{wled03_set.ino => wled_set.cpp} (99%) create mode 100644 wled00/wled_set.h rename wled00/{wled02_xml.ino => wled_xml.cpp} (99%) create mode 100644 wled00/wled_xml.h diff --git a/wled00/wled.cpp b/wled00/wled.cpp new file mode 100644 index 000000000..50a83f27e --- /dev/null +++ b/wled00/wled.cpp @@ -0,0 +1,503 @@ +#include "wled.h" + +WLED::WLED() { + +} + +//turns all LEDs off and restarts ESP +void WLED::reset() +{ + briT = 0; + long dly = millis(); + while (millis() - dly < 250) + { + yield(); //enough time to send response to client + } + setAllLeds(); + DEBUG_PRINTLN("MODULE RESET"); + ESP.restart(); +} + +bool oappendi(int i) +{ + char s[11]; + sprintf(s, "%ld", i); + return oappend(s); +} + +bool oappend(const char *txt) +{ + uint16_t len = strlen(txt); + if (olen + len >= OMAX) + return false; //buffer full + strcpy(obuf + olen, txt); + olen += len; + return true; +} + +void WLED::loop() +{ + handleIR(); //2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too + handleConnection(); + handleSerial(); + handleNotifications(); + handleTransitions(); +#ifdef WLED_ENABLE_DMX + handleDMX(); +#endif + userLoop(); + + yield(); + handleIO(); + handleIR(); + handleNetworkTime(); + handleAlexa(); + + handleOverlays(); + yield(); +#ifdef WLED_USE_ANALOG_LEDS + strip.setRgbwPwm(); +#endif + + if (doReboot) + reset(); + + if (!realtimeMode) //block stuff if WARLS/Adalight is enabled + { + if (apActive) + dnsServer.processNextRequest(); +#ifndef WLED_DISABLE_OTA + if (WLED_CONNECTED && aOtaEnabled) + ArduinoOTA.handle(); +#endif + handleNightlight(); + yield(); + + handleHue(); + handleBlynk(); + + yield(); + if (!offMode) + strip.service(); + } + yield(); +#ifdef ESP8266 + MDNS.update(); +#endif + if (millis() - lastMqttReconnectAttempt > 30000) + initMqtt(); + +//DEBUG serial logging +#ifdef WLED_DEBUG + if (millis() - debugTime > 9999) + { + DEBUG_PRINTLN("---DEBUG INFO---"); + DEBUG_PRINT("Runtime: "); + DEBUG_PRINTLN(millis()); + DEBUG_PRINT("Unix time: "); + DEBUG_PRINTLN(now()); + DEBUG_PRINT("Free heap: "); + DEBUG_PRINTLN(ESP.getFreeHeap()); + DEBUG_PRINT("Wifi state: "); + DEBUG_PRINTLN(WiFi.status()); + if (WiFi.status() != lastWifiState) + { + wifiStateChangedTime = millis(); + } + lastWifiState = WiFi.status(); + DEBUG_PRINT("State time: "); + DEBUG_PRINTLN(wifiStateChangedTime); + DEBUG_PRINT("NTP last sync: "); + DEBUG_PRINTLN(ntpLastSyncTime); + DEBUG_PRINT("Client IP: "); + DEBUG_PRINTLN(WiFi.localIP()); + DEBUG_PRINT("Loops/sec: "); + DEBUG_PRINTLN(loops / 10); + loops = 0; + debugTime = millis(); + } + loops++; +#endif // WLED_DEBU +} + +void WLED::wledInit() +{ + EEPROM.begin(EEPSIZE); + ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); + if (ledCount > MAX_LEDS || ledCount == 0) + ledCount = 30; + +#ifdef ESP8266 +#if LEDPIN == 3 + if (ledCount > MAX_LEDS_DMA) + ledCount = MAX_LEDS_DMA; //DMA method uses too much ram +#endif +#endif + Serial.begin(115200); + Serial.setTimeout(50); + DEBUG_PRINTLN(); + DEBUG_PRINT("---WLED "); + DEBUG_PRINT(versionString); + DEBUG_PRINT(" "); + DEBUG_PRINT(VERSION); + DEBUG_PRINTLN(" INIT---"); +#ifdef ARDUINO_ARCH_ESP32 + DEBUG_PRINT("esp32 "); + DEBUG_PRINTLN(ESP.getSdkVersion()); +#else + DEBUG_PRINT("esp8266 "); + DEBUG_PRINTLN(ESP.getCoreVersion()); +#endif + int heapPreAlloc = ESP.getFreeHeap(); + DEBUG_PRINT("heap "); + DEBUG_PRINTLN(ESP.getFreeHeap()); + + strip.init(EEPROM.read(372), ledCount, EEPROM.read(2204)); //init LEDs quickly + strip.setBrightness(0); + + DEBUG_PRINT("LEDs inited. heap usage ~"); + DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap()); + +#ifndef WLED_DISABLE_FILESYSTEM +#ifdef ARDUINO_ARCH_ESP32 + SPIFFS.begin(true); +#endif + SPIFFS.begin(); +#endif + + DEBUG_PRINTLN("Load EEPROM"); + loadSettingsFromEEPROM(true); + beginStrip(); + userSetup(); + if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0) + showWelcomePage = true; + WiFi.persistent(false); + + if (macroBoot > 0) + applyMacro(macroBoot); + Serial.println("Ada"); + + //generate module IDs + escapedMac = WiFi.macAddress(); + escapedMac.replace(":", ""); + escapedMac.toLowerCase(); + if (strcmp(cmDNS, "x") == 0) //fill in unique mdns default + { + strcpy(cmDNS, "wled-"); + sprintf(cmDNS + 5, "%*s", 6, escapedMac.c_str() + 6); + } + if (mqttDeviceTopic[0] == 0) + { + strcpy(mqttDeviceTopic, "wled/"); + sprintf(mqttDeviceTopic + 5, "%*s", 6, escapedMac.c_str() + 6); + } + if (mqttClientID[0] == 0) + { + strcpy(mqttClientID, "WLED-"); + sprintf(mqttClientID + 5, "%*s", 6, escapedMac.c_str() + 6); + } + + strip.service(); + +#ifndef WLED_DISABLE_OTA + if (aOtaEnabled) + { + ArduinoOTA.onStart([]() { +#ifdef ESP8266 + wifi_set_sleep_type(NONE_SLEEP_T); +#endif + DEBUG_PRINTLN("Start ArduinoOTA"); + }); + if (strlen(cmDNS) > 0) + ArduinoOTA.setHostname(cmDNS); + } +#endif +#ifdef WLED_ENABLE_DMX + dmx.init(512); // initialize with bus length +#endif + //HTTP server page init + initServer(); +} + +void WLED::beginStrip() +{ + // Initialize NeoPixel Strip and button + strip.setShowCallback(handleOverlayDraw); + +#ifdef BTNPIN + pinMode(BTNPIN, INPUT_PULLUP); +#endif + + if (bootPreset > 0) + applyPreset(bootPreset, turnOnAtBoot); + colorUpdated(NOTIFIER_CALL_MODE_INIT); + +//init relay pin +#if RLYPIN >= 0 + pinMode(RLYPIN, OUTPUT); +#if RLYMDE + digitalWrite(RLYPIN, bri); +#else + digitalWrite(RLYPIN, !bri); +#endif +#endif + + //disable button if it is "pressed" unintentionally +#ifdef BTNPIN + if (digitalRead(BTNPIN) == LOW) + buttonEnabled = false; +#else + buttonEnabled = false; +#endif +} + +void WLED::initAP(bool resetAP = false) +{ + if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) + return; + + if (!apSSID[0] || resetAP) + strcpy(apSSID, "WLED-AP"); + if (resetAP) + strcpy(apPass, DEFAULT_AP_PASS); + DEBUG_PRINT("Opening access point "); + DEBUG_PRINTLN(apSSID); + WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0)); + WiFi.softAP(apSSID, apPass, apChannel, apHide); + + if (!apActive) //start captive portal if AP active + { + DEBUG_PRINTLN("Init AP interfaces"); + server.begin(); + if (udpPort > 0 && udpPort != ntpLocalPort) + { + udpConnected = notifierUdp.begin(udpPort); + } + if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) + { + udpRgbConnected = rgbUdp.begin(udpRgbPort); + } + + dnsServer.setErrorReplyCode(DNSReplyCode::NoError); + dnsServer.start(53, "*", WiFi.softAPIP()); + } + apActive = true; +} + +void WLED::initConnection() +{ + WiFi.disconnect(); //close old connections +#ifdef ESP8266 + WiFi.setPhyMode(WIFI_PHY_MODE_11N); +#endif + + if (staticIP[0] != 0 && staticGateway[0] != 0) + { + WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8, 8, 8, 8)); + } + else + { + WiFi.config(0U, 0U, 0U); + } + + lastReconnectAttempt = millis(); + + if (!WLED_WIFI_CONFIGURED) + { + DEBUG_PRINT("No connection configured. "); + if (!apActive) + initAP(); //instantly go to ap mode + return; + } + else if (!apActive) + { + if (apBehavior == AP_BEHAVIOR_ALWAYS) + { + initAP(); + } + else + { + DEBUG_PRINTLN("Access point disabled."); + WiFi.softAPdisconnect(true); + } + } + showWelcomePage = false; + + DEBUG_PRINT("Connecting to "); + DEBUG_PRINT(clientSSID); + DEBUG_PRINTLN("..."); + +#ifdef ESP8266 + WiFi.hostname(serverDescription); +#endif + + WiFi.begin(clientSSID, clientPass); + +#ifdef ARDUINO_ARCH_ESP32 + WiFi.setSleep(!noWifiSleep); + WiFi.setHostname(serverDescription); +#else + wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); +#endif +} + +void WLED::initInterfaces() +{ + DEBUG_PRINTLN("Init STA interfaces"); + + if (hueIP[0] == 0) + { + hueIP[0] = WiFi.localIP()[0]; + hueIP[1] = WiFi.localIP()[1]; + hueIP[2] = WiFi.localIP()[2]; + } + + //init Alexa hue emulation + if (alexaEnabled) + alexaInit(); + +#ifndef WLED_DISABLE_OTA + if (aOtaEnabled) + ArduinoOTA.begin(); +#endif + + strip.service(); + // Set up mDNS responder: + if (strlen(cmDNS) > 0) + { + if (!aOtaEnabled) + MDNS.begin(cmDNS); + + DEBUG_PRINTLN("mDNS started"); + MDNS.addService("http", "tcp", 80); + MDNS.addService("wled", "tcp", 80); + MDNS.addServiceTxt("wled", "tcp", "mac", escapedMac.c_str()); + } + server.begin(); + + if (udpPort > 0 && udpPort != ntpLocalPort) + { + udpConnected = notifierUdp.begin(udpPort); + if (udpConnected && udpRgbPort != udpPort) + udpRgbConnected = rgbUdp.begin(udpRgbPort); + } + if (ntpEnabled) + ntpConnected = ntpUdp.begin(ntpLocalPort); + + initBlynk(blynkApiKey); + e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST, e131Universe, E131_MAX_UNIVERSE_COUNT); + reconnectHue(); + initMqtt(); + interfacesInited = true; + wasConnected = true; +} + +byte stacO = 0; +uint32_t lastHeap; +unsigned long heapTime = 0; + +void WLED::handleConnection() +{ + if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) + return; + if (lastReconnectAttempt == 0) + initConnection(); + + //reconnect WiFi to clear stale allocations if heap gets too low + if (millis() - heapTime > 5000) + { + uint32_t heap = ESP.getFreeHeap(); + if (heap < 9000 && lastHeap < 9000) + { + DEBUG_PRINT("Heap too low! "); + DEBUG_PRINTLN(heap); + forceReconnect = true; + } + lastHeap = heap; + heapTime = millis(); + } + + byte stac = 0; + if (apActive) + { +#ifdef ESP8266 + stac = wifi_softap_get_station_num(); +#else + wifi_sta_list_t stationList; + esp_wifi_ap_get_sta_list(&stationList); + stac = stationList.num; +#endif + if (stac != stacO) + { + stacO = stac; + DEBUG_PRINT("Connected AP clients: "); + DEBUG_PRINTLN(stac); + if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) + { //trying to connect, but not connected + if (stac) + WiFi.disconnect(); //disable search so that AP can work + else + initConnection(); //restart search + } + } + } + if (forceReconnect) + { + DEBUG_PRINTLN("Forcing reconnect."); + initConnection(); + interfacesInited = false; + forceReconnect = false; + wasConnected = false; + return; + } + if (!WLED_CONNECTED) + { + if (interfacesInited) + { + DEBUG_PRINTLN("Disconnected!"); + interfacesInited = false; + initConnection(); + } + if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) + initConnection(); + if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) + initAP(); + } + else if (!interfacesInited) + { //newly connected + DEBUG_PRINTLN(""); + DEBUG_PRINT("Connected! IP address: "); + DEBUG_PRINTLN(WiFi.localIP()); + initInterfaces(); + userConnected(); + + //shut down AP + if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) + { + dnsServer.stop(); + WiFi.softAPdisconnect(true); + apActive = false; + DEBUG_PRINTLN("Access point disabled."); + } + } +} + +//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp +int WLED::getSignalQuality(int rssi) +{ + int quality = 0; + + if (rssi <= -100) + { + quality = 0; + } + else if (rssi >= -50) + { + quality = 100; + } + else + { + quality = 2 * (rssi + 100); + } + return quality; +} \ No newline at end of file diff --git a/wled00/wled.h b/wled00/wled.h new file mode 100644 index 000000000..4f9b79afd --- /dev/null +++ b/wled00/wled.h @@ -0,0 +1,529 @@ +#ifndef WLED_H +#define WLED_H + +/* + Main sketch, global variable declarations +*/ +/* + * @title WLED project sketch + * @version 0.9.1 + * @author Christian Schwinne + */ + +//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). + +//ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). +//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): + +//You are required to disable over-the-air updates: +//#define WLED_DISABLE_OTA //saves 14kb + +//You need to choose some of these features to disable: +//#define WLED_DISABLE_ALEXA //saves 11kb +//#define WLED_DISABLE_BLYNK //saves 6kb +//#define WLED_DISABLE_CRONIXIE //saves 3kb +//#define WLED_DISABLE_HUESYNC //saves 4kb +//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 12kb +#define WLED_ENABLE_MQTT //saves 12kb +#define WLED_ENABLE_ADALIGHT //saves 500b only +//#define WLED_ENABLE_DMX //uses 3.5kb + +#define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet +//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version +//#define WLED_ENABLE_FS_EDITOR //enable /edit page for editing SPIFFS content. Will also be disabled with OTA lock + +//to toggle usb serial debug (un)comment the following line +//#define WLED_DEBUG + +//library inclusions +#include +#ifdef WLED_ENABLE_DMX +#include +DMXESPSerial dmx; +#endif +#ifdef ESP8266 +#include +#include +#include +extern "C" +{ +#include +} +#else //ESP32 +#include +#include "esp_wifi.h" +#include +#include +#include "SPIFFS.h" +#endif + +#include +#include +#include +#include +#ifndef WLED_DISABLE_OTA +#include +#endif +#include +#include "src/dependencies/time/TimeLib.h" +#include "src/dependencies/timezone/Timezone.h" +#ifndef WLED_DISABLE_ALEXA +#define ESPALEXA_ASYNC +#define ESPALEXA_NO_SUBPAGE +#define ESPALEXA_MAXDEVICES 1 +// #define ESPALEXA_DEBUG +#include "src/dependencies/espalexa/Espalexa.h" +#endif +#ifndef WLED_DISABLE_BLYNK +#include "src/dependencies/blynk/BlynkSimpleEsp.h" +#endif +#include "src/dependencies/e131/ESPAsyncE131.h" +#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h" +#include "src/dependencies/json/AsyncJson-v6.h" +#include "src/dependencies/json/ArduinoJson-v6.h" +#include "html_ui.h" +#include "html_settings.h" +#include "html_other.h" +#include "FX.h" +#include "ir_codes.h" +#include "const.h" + +#ifndef CLIENT_SSID +#define CLIENT_SSID DEFAULT_CLIENT_SSID +#endif + +#ifndef CLIENT_PASS +#define CLIENT_PASS "" +#endif + +#if IR_PIN < 0 +#ifndef WLED_DISABLE_INFRARED +#define WLED_DISABLE_INFRARED +#endif +#endif + +#ifndef WLED_DISABLE_INFRARED +#include +#include +#include +#endif + +// remove flicker because PWM signal of RGB channels can become out of phase +#if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266) +#include "src/dependencies/arduino/core_esp8266_waveform.h" +#endif + +// enable additional debug output +#ifdef WLED_DEBUG +#ifndef ESP8266 +#include +#endif +#endif + +//version code in format yymmddb (b = daily build) +#define VERSION 2003222 + +char versionString[] = "0.9.1"; + +//AP and OTA default passwords (for maximum change them!) +char apPass[65] = DEFAULT_AP_PASS; +char otaPass[33] = DEFAULT_OTA_PASS; + +//Hardware CONFIG (only changeble HERE, not at runtime) +//LED strip pin, button pin and IR pin changeable in NpbWrapper.h! + +byte auxDefaultState = 0; //0: input 1: high 2: low +byte auxTriggeredState = 0; //0: input 1: high 2: low +char ntpServerName[33] = "0.wled.pool.ntp.org"; //NTP server to use + +//WiFi CONFIG (all these can be changed via web UI, no need to set them here) +char clientSSID[33] = CLIENT_SSID; +char clientPass[65] = CLIENT_PASS; +char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) +char apSSID[33] = ""; //AP off by default (unless setup) +byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) +byte apHide = 0; //hidden AP SSID +byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no connection after boot by default +IPAddress staticIP(0, 0, 0, 0); //static IP of ESP +IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP +IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks +bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues + +//LED CONFIG +uint16_t ledCount = 30; //overcurrent prevented by ABL +bool useRGBW = false; //SK6812 strips can contain an extra White channel +#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit +bool turnOnAtBoot = true; //turn on LEDs at power-up +byte bootPreset = 0; //save preset to load after power-up + +byte col[]{255, 160, 0, 0}; //current RGB(W) primary color. col[] should be updated if you want to change the color. +byte colSec[]{0, 0, 0, 0}; //current RGB(W) secondary color +byte briS = 128; //default brightness + +byte nightlightTargetBri = 0; //brightness after nightlight is over +byte nightlightDelayMins = 60; +bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over +bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. +bool fadeTransition = true; //enable crossfading color transition +uint16_t transitionDelay = 750; //default crossfade duration in ms + +bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) +byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) + +//User Interface CONFIG +char serverDescription[33] = "WLED"; //Name of module +bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise + +//Sync CONFIG +bool buttonEnabled = true; +byte irEnabled = 0; //Infrared receiver + +uint16_t udpPort = 21324; //WLED notifier default port +uint16_t udpRgbPort = 19446; //Hyperion port + +bool receiveNotificationBrightness = true; //apply brightness from incoming notifications +bool receiveNotificationColor = true; //apply color +bool receiveNotificationEffects = true; //apply effects setup +bool notifyDirect = false; //send notification if change via UI or HTTP API +bool notifyButton = false; //send if updated by button or infrared remote +bool notifyAlexa = false; //send notification if updated via Alexa +bool notifyMacro = false; //send notification for macro +bool notifyHue = true; //send notification if Hue light changes +bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably + +bool alexaEnabled = true; //enable device discovery by Amazon Echo +char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand + +char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made + +uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode +int arlsOffset = 0; //realtime LED offset +bool receiveDirect = true; //receive UDP realtime +bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source +bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black + +#define E131_MAX_UNIVERSE_COUNT 9 +uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) +uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) +uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +uint8_t DMXOldDimmer = 0; //only update brightness on change +uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss +bool e131Multicast = false; //multicast or unicast +bool e131SkipOutOfSequence = false; //freeze instead of flickering + +bool mqttEnabled = false; +char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) +char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices) +char mqttServer[33] = ""; //both domains and IPs should work (no SSL) +char mqttUser[41] = ""; //optional: username for MQTT auth +char mqttPass[41] = ""; //optional: password for MQTT auth +char mqttClientID[41] = ""; //override the client ID +uint16_t mqttPort = 1883; + +bool huePollingEnabled = false; //poll hue bridge for light state +uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response +char hueApiKey[47] = "api"; //key token will be obtained from bridge +byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) +IPAddress hueIP = (0, 0, 0, 0); //IP address of the bridge +bool hueApplyOnOff = true; +bool hueApplyBri = true; +bool hueApplyColor = true; + +//Time CONFIG +bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros +bool useAMPM = false; //12h/24h clock format +byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino +int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation + +byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie +byte overlayMin = 0, overlayMax = ledCount - 1; //boundaries of overlay mode + +byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be +bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel +bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position + +char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino +bool cronixieBacklight = true; //Allow digits to be back-illuminated + +bool countdownMode = false; //Clock will count down towards date +byte countdownYear = 20, countdownMonth = 1; //Countdown target date, year is last two digits +byte countdownDay = 1, countdownHour = 0; +byte countdownMin = 0, countdownSec = 0; + +byte macroBoot = 0; //macro loaded after startup +byte macroNl = 0; //after nightlight delay over +byte macroCountdown = 0; +byte macroAlexaOn = 0, macroAlexaOff = 0; +byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; + +//Security CONFIG +bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks +bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled +bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on + +uint16_t userVar0 = 0, userVar1 = 0; + +#ifdef WLED_ENABLE_DMX +//dmx CONFIG +byte DMXChannels = 7; // number of channels per fixture +byte DMXFixtureMap[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +// assigns the different channels to different functions. See wled21_dmx.ino for more information. +uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. +uint16_t DMXStart = 10; // start address of the first fixture +#endif + +//internal global variable declarations +//wifi +bool apActive = false; +bool forceReconnect = false; +uint32_t lastReconnectAttempt = 0; +bool interfacesInited = false; +bool wasConnected = false; + +//color +byte colOld[]{0, 0, 0, 0}; //color before transition +byte colT[]{0, 0, 0, 0}; //color that is currently displayed on the LEDs +byte colIT[]{0, 0, 0, 0}; //color that was last sent to LEDs +byte colSecT[]{0, 0, 0, 0}; +byte colSecOld[]{0, 0, 0, 0}; +byte colSecIT[]{0, 0, 0, 0}; + +byte lastRandomIndex = 0; //used to save last random color so the new one is not the same + +//transitions +bool transitionActive = false; +uint16_t transitionDelayDefault = transitionDelay; +uint16_t transitionDelayTemp = transitionDelay; +unsigned long transitionStartTime; +float tperLast = 0; //crossfade transition progress, 0.0f - 1.0f +bool jsonTransitionOnce = false; + +//nightlight +bool nightlightActive = false; +bool nightlightActiveOld = false; +uint32_t nightlightDelayMs = 10; +uint8_t nightlightDelayMinsDefault = nightlightDelayMins; +unsigned long nightlightStartTime; +byte briNlT = 0; //current nightlight brightness +byte colNlT[]{0, 0, 0, 0}; //current nightlight color + +//brightness +unsigned long lastOnTime = 0; +bool offMode = !turnOnAtBoot; +byte bri = briS; +byte briOld = 0; +byte briT = 0; +byte briIT = 0; +byte briLast = 128; //brightness before turned off. Used for toggle function +byte whiteLast = 128; //white channel before turned off. Used for toggle function + +//button +bool buttonPressedBefore = false; +bool buttonLongPressed = false; +unsigned long buttonPressedTime = 0; +unsigned long buttonWaitTime = 0; + +//notifications +bool notifyDirectDefault = notifyDirect; +bool receiveNotifications = true; +unsigned long notificationSentTime = 0; +byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; +bool notificationTwoRequired = false; + +//effects +byte effectCurrent = 0; +byte effectSpeed = 128; +byte effectIntensity = 128; +byte effectPalette = 0; + +//network +bool udpConnected = false, udpRgbConnected = false; + +//ui style +bool showWelcomePage = false; + +//hue +byte hueError = HUE_ERROR_INACTIVE; +//uint16_t hueFailCount = 0; +float hueXLast = 0, hueYLast = 0; +uint16_t hueHueLast = 0, hueCtLast = 0; +byte hueSatLast = 0, hueBriLast = 0; +unsigned long hueLastRequestSent = 0; +bool hueAuthRequired = false; +bool hueReceived = false; +bool hueStoreAllowed = false, hueNewKey = false; + +//overlays +byte overlayCurrent = overlayDefault; +byte overlaySpeed = 200; +unsigned long overlayRefreshMs = 200; +unsigned long overlayRefreshedTime; + +//cronixie +byte dP[]{0, 0, 0, 0, 0, 0}; +bool cronixieInit = false; + +//countdown +unsigned long countdownTime = 1514764800L; +bool countdownOverTriggered = true; + +//timer +byte lastTimerMinute = 0; +byte timerHours[] = {0, 0, 0, 0, 0, 0, 0, 0}; +byte timerMinutes[] = {0, 0, 0, 0, 0, 0, 0, 0}; +byte timerMacro[] = {0, 0, 0, 0, 0, 0, 0, 0}; +byte timerWeekday[] = {255, 255, 255, 255, 255, 255, 255, 255}; //weekdays to activate on +//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity + +//blynk +bool blynkEnabled = false; + +//preset cycling +bool presetCyclingEnabled = false; +byte presetCycleMin = 1, presetCycleMax = 5; +uint16_t presetCycleTime = 1250; +unsigned long presetCycledTime = 0; +byte presetCycCurr = presetCycleMin; +bool presetApplyBri = true; +bool saveCurrPresetCycConf = false; + +//realtime +byte realtimeMode = REALTIME_MODE_INACTIVE; +IPAddress realtimeIP = (0, 0, 0, 0); +unsigned long realtimeTimeout = 0; + +//mqtt +long lastMqttReconnectAttempt = 0; +long lastInterfaceUpdate = 0; +byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; +char mqttStatusTopic[40] = ""; //this must be global because of async handlers + +#if AUXPIN >= 0 + //auxiliary debug pin +byte auxTime = 0; +unsigned long auxStartTime = 0; +bool auxActive = false, auxActiveBefore = false; +#endif + +//alexa udp +String escapedMac; +#ifndef WLED_DISABLE_ALEXA +Espalexa espalexa; +EspalexaDevice *espalexaDevice; +#endif + +//dns server +DNSServer dnsServer; + +//network time +bool ntpConnected = false; +time_t local = 0; +unsigned long ntpLastSyncTime = 999000000L; +unsigned long ntpPacketSentTime = 999000000L; +IPAddress ntpServerIP; +uint16_t ntpLocalPort = 2390; +#define NTP_PACKET_SIZE 48 + +//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue +#define MAX_LEDS 1500 +#define MAX_LEDS_DMA 500 + +//string temp buffer (now stored in stack locally) +#define OMAX 2048 +char *obuf; +uint16_t olen = 0; + +//presets +uint16_t savedPresets = 0; +int8_t currentPreset = -1; +bool isPreset = false; + +byte errorFlag = 0; + +String messageHead, messageSub; +byte optionType; + +bool doReboot = false; //flag to initiate reboot from async handlers +bool doPublishMqtt = false; + +//server library objects +AsyncWebServer server(80); +AsyncClient *hueClient = NULL; +AsyncMqttClient *mqtt = NULL; + +//function prototypes +void colorFromUint32(uint32_t, bool = false); +void serveMessage(AsyncWebServerRequest *, uint16_t, String, String, byte); +void handleE131Packet(e131_packet_t *, IPAddress); +void arlsLock(uint32_t, byte); +void handleOverlayDraw(); + +//udp interface objects +WiFiUDP notifierUdp, rgbUdp; +WiFiUDP ntpUdp; +ESPAsyncE131 e131(handleE131Packet); +bool e131NewData = false; + +//led fx library object +WS2812FX strip = WS2812FX(); + +#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) +#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) + +//debug macros +#ifdef WLED_DEBUG +#define DEBUG_PRINT(x) Serial.print(x) +#define DEBUG_PRINTLN(x) Serial.println(x) +#define DEBUG_PRINTF(x) Serial.printf(x) +unsigned long debugTime = 0; +int lastWifiState = 3; +unsigned long wifiStateChangedTime = 0; +int loops = 0; +#else +#define DEBUG_PRINT(x) +#define DEBUG_PRINTLN(x) +#define DEBUG_PRINTF(x) +#endif + + +// TODO: Inline? +//append new c string to temp buffer efficiently +bool oappend(const char *txt); +//append new number to temp buffer efficiently +bool oappendi(int i); + +class WLED +{ +public: + static WLED &instance() + { + static WLED instance; + return instance; + } + + WLED(); + + void wledInit(); + + void reset(); + void loop(); + + + //boot starts here + void setup() + { + wledInit(); + } + + void loop(); + +private: + void wledInit(); + void beginStrip(); + + void handleConnection(); + void initAP(bool resetAP = false); + void initConnection(); + void initInterfaces(); +}; +#endif // WLED_H diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 7c64796d6..fc06f2114 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -1,617 +1,13 @@ /* - Main sketch, global variable declarations + Arduino Studio support file. */ -/* - * @title WLED project sketch - * @version 0.9.1 - * @author Christian Schwinne - */ +#include "wled.h" -//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). - -//ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). -//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): - -//You are required to disable over-the-air updates: -//#define WLED_DISABLE_OTA //saves 14kb - -//You need to choose some of these features to disable: -//#define WLED_DISABLE_ALEXA //saves 11kb -//#define WLED_DISABLE_BLYNK //saves 6kb -//#define WLED_DISABLE_CRONIXIE //saves 3kb -//#define WLED_DISABLE_HUESYNC //saves 4kb -//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 12kb -#define WLED_ENABLE_MQTT //saves 12kb -#define WLED_ENABLE_ADALIGHT //saves 500b only -//#define WLED_ENABLE_DMX //uses 3.5kb - -#define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet -//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version -//#define WLED_ENABLE_FS_EDITOR //enable /edit page for editing SPIFFS content. Will also be disabled with OTA lock - -//to toggle usb serial debug (un)comment the following line -//#define WLED_DEBUG - -//library inclusions -#include -#ifdef WLED_ENABLE_DMX - #include - DMXESPSerial dmx; -#endif -#ifdef ESP8266 - #include - #include - #include - extern "C" { - #include - } -#else //ESP32 - #include - #include "esp_wifi.h" - #include - #include - #include "SPIFFS.h" -#endif - -#include -#include -#include -#include -#ifndef WLED_DISABLE_OTA - #include -#endif -#include -#include "src/dependencies/time/TimeLib.h" -#include "src/dependencies/timezone/Timezone.h" -#ifndef WLED_DISABLE_ALEXA - #define ESPALEXA_ASYNC - #define ESPALEXA_NO_SUBPAGE - #define ESPALEXA_MAXDEVICES 1 - // #define ESPALEXA_DEBUG - #include "src/dependencies/espalexa/Espalexa.h" -#endif -#ifndef WLED_DISABLE_BLYNK - #include "src/dependencies/blynk/BlynkSimpleEsp.h" -#endif -#include "src/dependencies/e131/ESPAsyncE131.h" -#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h" -#include "src/dependencies/json/AsyncJson-v6.h" -#include "src/dependencies/json/ArduinoJson-v6.h" -#include "html_ui.h" -#include "html_settings.h" -#include "html_other.h" -#include "FX.h" -#include "ir_codes.h" -#include "const.h" - -#ifndef CLIENT_SSID -#define CLIENT_SSID DEFAULT_CLIENT_SSID -#endif - -#ifndef CLIENT_PASS -#define CLIENT_PASS "" -#endif - - -#if IR_PIN < 0 - #ifndef WLED_DISABLE_INFRARED - #define WLED_DISABLE_INFRARED - #endif -#endif - -#ifndef WLED_DISABLE_INFRARED - #include - #include - #include -#endif - -// remove flicker because PWM signal of RGB channels can become out of phase -#if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266) - #include "src/dependencies/arduino/core_esp8266_waveform.h" -#endif - -// enable additional debug output -#ifdef WLED_DEBUG - #ifndef ESP8266 - #include - #endif -#endif - -//version code in format yymmddb (b = daily build) -#define VERSION 2003222 - -char versionString[] = "0.9.1"; - - -//AP and OTA default passwords (for maximum change them!) -char apPass[65] = DEFAULT_AP_PASS; -char otaPass[33] = DEFAULT_OTA_PASS; - - -//Hardware CONFIG (only changeble HERE, not at runtime) -//LED strip pin, button pin and IR pin changeable in NpbWrapper.h! - -byte auxDefaultState = 0; //0: input 1: high 2: low -byte auxTriggeredState = 0; //0: input 1: high 2: low -char ntpServerName[33] = "0.wled.pool.ntp.org";//NTP server to use - - -//WiFi CONFIG (all these can be changed via web UI, no need to set them here) -char clientSSID[33] = CLIENT_SSID; -char clientPass[65] = CLIENT_PASS; -char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) -char apSSID[33] = ""; //AP off by default (unless setup) -byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) -byte apHide = 0; //hidden AP SSID -byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no connection after boot by default -IPAddress staticIP(0, 0, 0, 0); //static IP of ESP -IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP -IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks -bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues - - -//LED CONFIG -uint16_t ledCount = 30; //overcurrent prevented by ABL -bool useRGBW = false; //SK6812 strips can contain an extra White channel -#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit -bool turnOnAtBoot = true; //turn on LEDs at power-up -byte bootPreset = 0; //save preset to load after power-up - -byte col[] {255, 160, 0, 0}; //current RGB(W) primary color. col[] should be updated if you want to change the color. -byte colSec[] {0, 0, 0, 0}; //current RGB(W) secondary color -byte briS = 128; //default brightness - -byte nightlightTargetBri = 0; //brightness after nightlight is over -byte nightlightDelayMins = 60; -bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over -bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. -bool fadeTransition = true; //enable crossfading color transition -uint16_t transitionDelay = 750; //default crossfade duration in ms - -bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) -byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) - - -//User Interface CONFIG -char serverDescription[33] = "WLED"; //Name of module -bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise - - -//Sync CONFIG -bool buttonEnabled = true; -byte irEnabled = 0; //Infrared receiver - -uint16_t udpPort = 21324; //WLED notifier default port -uint16_t udpRgbPort = 19446; //Hyperion port - -bool receiveNotificationBrightness = true; //apply brightness from incoming notifications -bool receiveNotificationColor = true; //apply color -bool receiveNotificationEffects = true; //apply effects setup -bool notifyDirect = false; //send notification if change via UI or HTTP API -bool notifyButton = false; //send if updated by button or infrared remote -bool notifyAlexa = false; //send notification if updated via Alexa -bool notifyMacro = false; //send notification for macro -bool notifyHue = true; //send notification if Hue light changes -bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably - -bool alexaEnabled = true; //enable device discovery by Amazon Echo -char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand - -char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made - -uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode -int arlsOffset = 0; //realtime LED offset -bool receiveDirect = true; //receive UDP realtime -bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source -bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black - -#define E131_MAX_UNIVERSE_COUNT 9 -uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) -uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] -uint8_t DMXOldDimmer = 0; //only update brightness on change -uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss -bool e131Multicast = false; //multicast or unicast -bool e131SkipOutOfSequence = false; //freeze instead of flickering - -bool mqttEnabled = false; -char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) -char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices) -char mqttServer[33] = ""; //both domains and IPs should work (no SSL) -char mqttUser[41] = ""; //optional: username for MQTT auth -char mqttPass[41] = ""; //optional: password for MQTT auth -char mqttClientID[41] = ""; //override the client ID -uint16_t mqttPort = 1883; - -bool huePollingEnabled = false; //poll hue bridge for light state -uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response -char hueApiKey[47] = "api"; //key token will be obtained from bridge -byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) -IPAddress hueIP = (0, 0, 0, 0); //IP address of the bridge -bool hueApplyOnOff = true; -bool hueApplyBri = true; -bool hueApplyColor = true; - - -//Time CONFIG -bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros -bool useAMPM = false; //12h/24h clock format -byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino -int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation - -byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie -byte overlayMin = 0, overlayMax = ledCount - 1; //boundaries of overlay mode - -byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be -bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel -bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position - -char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino -bool cronixieBacklight = true; //Allow digits to be back-illuminated - -bool countdownMode = false; //Clock will count down towards date -byte countdownYear = 20, countdownMonth = 1; //Countdown target date, year is last two digits -byte countdownDay = 1, countdownHour = 0; -byte countdownMin = 0, countdownSec = 0; - - -byte macroBoot = 0; //macro loaded after startup -byte macroNl = 0; //after nightlight delay over -byte macroCountdown = 0; -byte macroAlexaOn = 0, macroAlexaOff = 0; -byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; - - -//Security CONFIG -bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks -bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled -bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on - - -uint16_t userVar0 = 0, userVar1 = 0; - -#ifdef WLED_ENABLE_DMX - //dmx CONFIG - byte DMXChannels = 7; // number of channels per fixture - byte DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - // assigns the different channels to different functions. See wled21_dmx.ino for more information. - uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. - uint16_t DMXStart = 10; // start address of the first fixture -#endif - - -//internal global variable declarations -//wifi -bool apActive = false; -bool forceReconnect = false; -uint32_t lastReconnectAttempt = 0; -bool interfacesInited = false; -bool wasConnected = false; - -//color -byte colOld[] {0, 0, 0, 0}; //color before transition -byte colT[] {0, 0, 0, 0}; //color that is currently displayed on the LEDs -byte colIT[] {0, 0, 0, 0}; //color that was last sent to LEDs -byte colSecT[] {0, 0, 0, 0}; -byte colSecOld[] {0, 0, 0, 0}; -byte colSecIT[] {0, 0, 0, 0}; - -byte lastRandomIndex = 0; //used to save last random color so the new one is not the same - -//transitions -bool transitionActive = false; -uint16_t transitionDelayDefault = transitionDelay; -uint16_t transitionDelayTemp = transitionDelay; -unsigned long transitionStartTime; -float tperLast = 0; //crossfade transition progress, 0.0f - 1.0f -bool jsonTransitionOnce = false; - -//nightlight -bool nightlightActive = false; -bool nightlightActiveOld = false; -uint32_t nightlightDelayMs = 10; -uint8_t nightlightDelayMinsDefault = nightlightDelayMins; -unsigned long nightlightStartTime; -byte briNlT = 0; //current nightlight brightness -byte colNlT[] {0, 0, 0, 0}; //current nightlight color - -//brightness -unsigned long lastOnTime = 0; -bool offMode = !turnOnAtBoot; -byte bri = briS; -byte briOld = 0; -byte briT = 0; -byte briIT = 0; -byte briLast = 128; //brightness before turned off. Used for toggle function -byte whiteLast = 128; //white channel before turned off. Used for toggle function - -//button -bool buttonPressedBefore = false; -bool buttonLongPressed = false; -unsigned long buttonPressedTime = 0; -unsigned long buttonWaitTime = 0; - -//notifications -bool notifyDirectDefault = notifyDirect; -bool receiveNotifications = true; -unsigned long notificationSentTime = 0; -byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; -bool notificationTwoRequired = false; - -//effects -byte effectCurrent = 0; -byte effectSpeed = 128; -byte effectIntensity = 128; -byte effectPalette = 0; - -//network -bool udpConnected = false, udpRgbConnected = false; - -//ui style -bool showWelcomePage = false; - -//hue -byte hueError = HUE_ERROR_INACTIVE; -//uint16_t hueFailCount = 0; -float hueXLast = 0, hueYLast = 0; -uint16_t hueHueLast = 0, hueCtLast = 0; -byte hueSatLast = 0, hueBriLast = 0; -unsigned long hueLastRequestSent = 0; -bool hueAuthRequired = false; -bool hueReceived = false; -bool hueStoreAllowed = false, hueNewKey = false; - -//overlays -byte overlayCurrent = overlayDefault; -byte overlaySpeed = 200; -unsigned long overlayRefreshMs = 200; -unsigned long overlayRefreshedTime; - -//cronixie -byte dP[] {0, 0, 0, 0, 0, 0}; -bool cronixieInit = false; - -//countdown -unsigned long countdownTime = 1514764800L; -bool countdownOverTriggered = true; - -//timer -byte lastTimerMinute = 0; -byte timerHours[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMinutes[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMacro[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerWeekday[] = {255, 255, 255, 255, 255, 255, 255, 255}; //weekdays to activate on -//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity - -//blynk -bool blynkEnabled = false; - -//preset cycling -bool presetCyclingEnabled = false; -byte presetCycleMin = 1, presetCycleMax = 5; -uint16_t presetCycleTime = 1250; -unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin; -bool presetApplyBri = true; -bool saveCurrPresetCycConf = false; - -//realtime -byte realtimeMode = REALTIME_MODE_INACTIVE; -IPAddress realtimeIP = (0,0,0,0); -unsigned long realtimeTimeout = 0; - -//mqtt -long lastMqttReconnectAttempt = 0; -long lastInterfaceUpdate = 0; -byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; -char mqttStatusTopic[40] = ""; //this must be global because of async handlers - -#if AUXPIN >= 0 - //auxiliary debug pin - byte auxTime = 0; - unsigned long auxStartTime = 0; - bool auxActive = false, auxActiveBefore = false; -#endif - -//alexa udp -String escapedMac; -#ifndef WLED_DISABLE_ALEXA - Espalexa espalexa; - EspalexaDevice* espalexaDevice; -#endif - -//dns server -DNSServer dnsServer; - -//network time -bool ntpConnected = false; -time_t local = 0; -unsigned long ntpLastSyncTime = 999000000L; -unsigned long ntpPacketSentTime = 999000000L; -IPAddress ntpServerIP; -uint16_t ntpLocalPort = 2390; -#define NTP_PACKET_SIZE 48 - -//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue -#define MAX_LEDS 1500 -#define MAX_LEDS_DMA 500 - -//string temp buffer (now stored in stack locally) -#define OMAX 2048 -char* obuf; -uint16_t olen = 0; - -//presets -uint16_t savedPresets = 0; -int8_t currentPreset = -1; -bool isPreset = false; - -byte errorFlag = 0; - -String messageHead, messageSub; -byte optionType; - -bool doReboot = false; //flag to initiate reboot from async handlers -bool doPublishMqtt = false; - -//server library objects -AsyncWebServer server(80); -AsyncClient* hueClient = NULL; -AsyncMqttClient* mqtt = NULL; - -//function prototypes -void colorFromUint32(uint32_t, bool = false); -void serveMessage(AsyncWebServerRequest*, uint16_t, String, String, byte); -void handleE131Packet(e131_packet_t*, IPAddress); -void arlsLock(uint32_t,byte); -void handleOverlayDraw(); - -//udp interface objects -WiFiUDP notifierUdp, rgbUdp; -WiFiUDP ntpUdp; -ESPAsyncE131 e131(handleE131Packet); -bool e131NewData = false; - -//led fx library object -WS2812FX strip = WS2812FX(); - -#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) -#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID,DEFAULT_CLIENT_SSID) != 0) - -//debug macros -#ifdef WLED_DEBUG - #define DEBUG_PRINT(x) Serial.print (x) - #define DEBUG_PRINTLN(x) Serial.println (x) - #define DEBUG_PRINTF(x) Serial.printf (x) - unsigned long debugTime = 0; - int lastWifiState = 3; - unsigned long wifiStateChangedTime = 0; - int loops = 0; -#else - #define DEBUG_PRINT(x) - #define DEBUG_PRINTLN(x) - #define DEBUG_PRINTF(x) -#endif - -//filesystem -#ifndef WLED_DISABLE_FILESYSTEM - #include - #ifdef ARDUINO_ARCH_ESP32 - #include "SPIFFS.h" - #endif - #include "SPIFFSEditor.h" -#endif - - - -//turns all LEDs off and restarts ESP -void reset() -{ - briT = 0; - long dly = millis(); - while (millis() - dly < 250) - { - yield(); //enough time to send response to client - } - setAllLeds(); - DEBUG_PRINTLN("MODULE RESET"); - ESP.restart(); -} - - -//append new c string to temp buffer efficiently -bool oappend(const char* txt) -{ - uint16_t len = strlen(txt); - if (olen + len >= OMAX) return false; //buffer full - strcpy(obuf + olen, txt); - olen += len; - return true; -} - - -//append new number to temp buffer efficiently -bool oappendi(int i) -{ - char s[11]; - sprintf(s, "%ld", i); - return oappend(s); -} - - -//boot starts here void setup() { - wledInit(); + //auto& wled = Wled(); } - -//main program loop void loop() { - handleIR(); //2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too - handleConnection(); - handleSerial(); - handleNotifications(); - handleTransitions(); -#ifdef WLED_ENABLE_DMX - handleDMX(); -#endif - userLoop(); - yield(); - handleIO(); - handleIR(); - handleNetworkTime(); - handleAlexa(); - handleOverlays(); - yield(); -#ifdef WLED_USE_ANALOG_LEDS - strip.setRgbwPwm(); -#endif - - if (doReboot) reset(); - - if (!realtimeMode) //block stuff if WARLS/Adalight is enabled - { - if (apActive) dnsServer.processNextRequest(); -#ifndef WLED_DISABLE_OTA - if (WLED_CONNECTED && aOtaEnabled) ArduinoOTA.handle(); -#endif - handleNightlight(); - yield(); - - handleHue(); - handleBlynk(); - - yield(); - if (!offMode) strip.service(); - } - yield(); -#ifdef ESP8266 - MDNS.update(); -#endif - if (millis() - lastMqttReconnectAttempt > 30000) initMqtt(); - - //DEBUG serial logging -#ifdef WLED_DEBUG - if (millis() - debugTime > 9999) - { - DEBUG_PRINTLN("---DEBUG INFO---"); - DEBUG_PRINT("Runtime: "); DEBUG_PRINTLN(millis()); - DEBUG_PRINT("Unix time: "); DEBUG_PRINTLN(now()); - DEBUG_PRINT("Free heap: "); DEBUG_PRINTLN(ESP.getFreeHeap()); - DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(WiFi.status()); - if (WiFi.status() != lastWifiState) - { - wifiStateChangedTime = millis(); - } - lastWifiState = WiFi.status(); - DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime); - DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime); - DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP()); - DEBUG_PRINT("Loops/sec: "); DEBUG_PRINTLN(loops / 10); - loops = 0; - debugTime = millis(); - } - loops++; -#endif -} +} \ No newline at end of file diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino deleted file mode 100644 index 29ae0e7ab..000000000 --- a/wled00/wled05_init.ino +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Setup code - */ - -void wledInit() -{ - EEPROM.begin(EEPSIZE); - ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); - if (ledCount > MAX_LEDS || ledCount == 0) ledCount = 30; - - #ifdef ESP8266 - #if LEDPIN == 3 - if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram - #endif - #endif - Serial.begin(115200); - Serial.setTimeout(50); - DEBUG_PRINTLN(); - DEBUG_PRINT("---WLED "); DEBUG_PRINT(versionString); DEBUG_PRINT(" "); DEBUG_PRINT(VERSION); DEBUG_PRINTLN(" INIT---"); - #ifdef ARDUINO_ARCH_ESP32 - DEBUG_PRINT("esp32 "); DEBUG_PRINTLN(ESP.getSdkVersion()); - #else - DEBUG_PRINT("esp8266 "); DEBUG_PRINTLN(ESP.getCoreVersion()); - #endif - int heapPreAlloc = ESP.getFreeHeap(); - DEBUG_PRINT("heap "); - DEBUG_PRINTLN(ESP.getFreeHeap()); - - strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //init LEDs quickly - strip.setBrightness(0); - - DEBUG_PRINT("LEDs inited. heap usage ~"); - DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap()); - - #ifndef WLED_DISABLE_FILESYSTEM - #ifdef ARDUINO_ARCH_ESP32 - SPIFFS.begin(true); - #endif - SPIFFS.begin(); - #endif - - DEBUG_PRINTLN("Load EEPROM"); - loadSettingsFromEEPROM(true); - beginStrip(); - userSetup(); - if (strcmp(clientSSID,DEFAULT_CLIENT_SSID) == 0) showWelcomePage = true; - WiFi.persistent(false); - - if (macroBoot>0) applyMacro(macroBoot); - Serial.println("Ada"); - - //generate module IDs - escapedMac = WiFi.macAddress(); - escapedMac.replace(":", ""); - escapedMac.toLowerCase(); - if (strcmp(cmDNS,"x") == 0) //fill in unique mdns default - { - strcpy(cmDNS, "wled-"); - sprintf(cmDNS+5, "%*s", 6, escapedMac.c_str()+6); - } - if (mqttDeviceTopic[0] == 0) - { - strcpy(mqttDeviceTopic, "wled/"); - sprintf(mqttDeviceTopic+5, "%*s", 6, escapedMac.c_str()+6); - } - if (mqttClientID[0] == 0) - { - strcpy(mqttClientID, "WLED-"); - sprintf(mqttClientID+5, "%*s", 6, escapedMac.c_str()+6); - } - - strip.service(); - - #ifndef WLED_DISABLE_OTA - if (aOtaEnabled) - { - ArduinoOTA.onStart([]() { - #ifdef ESP8266 - wifi_set_sleep_type(NONE_SLEEP_T); - #endif - DEBUG_PRINTLN("Start ArduinoOTA"); - }); - if (strlen(cmDNS) > 0) ArduinoOTA.setHostname(cmDNS); - } - #endif - #ifdef WLED_ENABLE_DMX - dmx.init(512); // initialize with bus length - #endif - //HTTP server page init - initServer(); -} - - -void beginStrip() -{ - // Initialize NeoPixel Strip and button - strip.setShowCallback(handleOverlayDraw); - -#ifdef BTNPIN - pinMode(BTNPIN, INPUT_PULLUP); -#endif - - if (bootPreset > 0) applyPreset(bootPreset, turnOnAtBoot); - colorUpdated(NOTIFIER_CALL_MODE_INIT); - - //init relay pin - #if RLYPIN >= 0 - pinMode(RLYPIN, OUTPUT); - #if RLYMDE - digitalWrite(RLYPIN, bri); - #else - digitalWrite(RLYPIN, !bri); - #endif - #endif - - //disable button if it is "pressed" unintentionally -#ifdef BTNPIN - if(digitalRead(BTNPIN) == LOW) buttonEnabled = false; -#else - buttonEnabled = false; -#endif -} - - -void initAP(bool resetAP=false){ - if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) return; - - if (!apSSID[0] || resetAP) strcpy(apSSID, "WLED-AP"); - if (resetAP) strcpy(apPass,DEFAULT_AP_PASS); - DEBUG_PRINT("Opening access point "); - DEBUG_PRINTLN(apSSID); - WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255,255,255,0)); - WiFi.softAP(apSSID, apPass, apChannel, apHide); - - if (!apActive) //start captive portal if AP active - { - DEBUG_PRINTLN("Init AP interfaces"); - server.begin(); - if (udpPort > 0 && udpPort != ntpLocalPort) - { - udpConnected = notifierUdp.begin(udpPort); - } - if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) - { - udpRgbConnected = rgbUdp.begin(udpRgbPort); - } - - dnsServer.setErrorReplyCode(DNSReplyCode::NoError); - dnsServer.start(53, "*", WiFi.softAPIP()); - } - apActive = true; -} - -void initConnection() -{ - WiFi.disconnect(); //close old connections - #ifdef ESP8266 - WiFi.setPhyMode(WIFI_PHY_MODE_11N); - #endif - - if (staticIP[0] != 0 && staticGateway[0] != 0) - { - WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8,8,8,8)); - } else - { - WiFi.config(0U, 0U, 0U); - } - - lastReconnectAttempt = millis(); - - if (!WLED_WIFI_CONFIGURED) - { - DEBUG_PRINT("No connection configured. "); - if (!apActive) initAP(); //instantly go to ap mode - return; - } else if (!apActive) { - if (apBehavior == AP_BEHAVIOR_ALWAYS) - { - initAP(); - } else - { - DEBUG_PRINTLN("Access point disabled."); - WiFi.softAPdisconnect(true); - } - } - showWelcomePage = false; - - DEBUG_PRINT("Connecting to "); - DEBUG_PRINT(clientSSID); - DEBUG_PRINTLN("..."); - - #ifdef ESP8266 - WiFi.hostname(serverDescription); - #endif - - WiFi.begin(clientSSID, clientPass); - - #ifdef ARDUINO_ARCH_ESP32 - WiFi.setSleep(!noWifiSleep); - WiFi.setHostname(serverDescription); - #else - wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); - #endif -} - -void initInterfaces() { - DEBUG_PRINTLN("Init STA interfaces"); - - if (hueIP[0] == 0) - { - hueIP[0] = WiFi.localIP()[0]; - hueIP[1] = WiFi.localIP()[1]; - hueIP[2] = WiFi.localIP()[2]; - } - - //init Alexa hue emulation - if (alexaEnabled) alexaInit(); - - #ifndef WLED_DISABLE_OTA - if (aOtaEnabled) ArduinoOTA.begin(); - #endif - - strip.service(); - // Set up mDNS responder: - if (strlen(cmDNS) > 0) - { - if (!aOtaEnabled) MDNS.begin(cmDNS); - - DEBUG_PRINTLN("mDNS started"); - MDNS.addService("http", "tcp", 80); - MDNS.addService("wled", "tcp", 80); - MDNS.addServiceTxt("wled", "tcp", "mac", escapedMac.c_str()); - } - server.begin(); - - if (udpPort > 0 && udpPort != ntpLocalPort) - { - udpConnected = notifierUdp.begin(udpPort); - if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort); - } - if (ntpEnabled) ntpConnected = ntpUdp.begin(ntpLocalPort); - - initBlynk(blynkApiKey); - e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe, E131_MAX_UNIVERSE_COUNT); - reconnectHue(); - initMqtt(); - interfacesInited = true; - wasConnected = true; -} - -byte stacO = 0; -uint32_t lastHeap; -unsigned long heapTime = 0; - -void handleConnection() { - if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) return; - if (lastReconnectAttempt == 0) initConnection(); - - //reconnect WiFi to clear stale allocations if heap gets too low - if (millis() - heapTime > 5000) - { - uint32_t heap = ESP.getFreeHeap(); - if (heap < 9000 && lastHeap < 9000) { - DEBUG_PRINT("Heap too low! "); - DEBUG_PRINTLN(heap); - forceReconnect = true; - } - lastHeap = heap; - heapTime = millis(); - } - - byte stac = 0; - if (apActive) { - #ifdef ESP8266 - stac = wifi_softap_get_station_num(); - #else - wifi_sta_list_t stationList; - esp_wifi_ap_get_sta_list(&stationList); - stac = stationList.num; - #endif - if (stac != stacO) - { - stacO = stac; - DEBUG_PRINT("Connected AP clients: "); - DEBUG_PRINTLN(stac); - if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { //trying to connect, but not connected - if (stac) WiFi.disconnect(); //disable search so that AP can work - else initConnection(); //restart search - } - } - } - if (forceReconnect) { - DEBUG_PRINTLN("Forcing reconnect."); - initConnection(); - interfacesInited = false; - forceReconnect = false; - wasConnected = false; - return; - } - if (!WLED_CONNECTED) { - if (interfacesInited) { - DEBUG_PRINTLN("Disconnected!"); - interfacesInited = false; - initConnection(); - } - if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) initConnection(); - if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) initAP(); - } else if (!interfacesInited) { //newly connected - DEBUG_PRINTLN(""); - DEBUG_PRINT("Connected! IP address: "); - DEBUG_PRINTLN(WiFi.localIP()); - initInterfaces(); - userConnected(); - - //shut down AP - if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) - { - dnsServer.stop(); - WiFi.softAPdisconnect(true); - apActive = false; - DEBUG_PRINTLN("Access point disabled."); - } - } -} - -//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp -int getSignalQuality(int rssi) -{ - int quality = 0; - - if (rssi <= -100) { - quality = 0; - } else if (rssi >= -50) { - quality = 100; - } else { - quality = 2 * (rssi + 100); - } - return quality; -} diff --git a/wled00/wled06_usermod.ino b/wled00/wled06_usermod.cpp similarity index 97% rename from wled00/wled06_usermod.ino rename to wled00/wled06_usermod.cpp index 010d0f386..c780ffeeb 100644 --- a/wled00/wled06_usermod.ino +++ b/wled00/wled06_usermod.cpp @@ -1,3 +1,4 @@ +#include "wled.h" /* * This file allows you to add own functionality to WLED more easily * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality diff --git a/wled00/wled12_alexa.ino b/wled00/wled_alexa.cpp similarity index 89% rename from wled00/wled12_alexa.ino rename to wled00/wled_alexa.cpp index 5163640e2..b68843cbc 100644 --- a/wled00/wled12_alexa.ino +++ b/wled00/wled_alexa.cpp @@ -1,10 +1,6 @@ -/* - * Alexa Voice On/Off/Brightness Control. Emulates a Philips Hue bridge to Alexa. - * - * This was put together from these two excellent projects: - * https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch - * https://github.com/probonopd/ESP8266HueEmulator - */ +#include "wled_alexa.h" +#include "wled.h" +#include "src/dependencies/espalexa/EspalexaDevice.h" #ifndef WLED_DISABLE_ALEXA void onAlexaChange(EspalexaDevice* dev); diff --git a/wled00/wled_alexa.h b/wled00/wled_alexa.h new file mode 100644 index 000000000..4bf7bd123 --- /dev/null +++ b/wled00/wled_alexa.h @@ -0,0 +1,16 @@ +#ifndef WLED_ALEXA_H +#define WLED_ALEXA_H +/* + * Alexa Voice On/Off/Brightness Control. Emulates a Philips Hue bridge to Alexa. + * + * This was put together from these two excellent projects: + * https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch + * https://github.com/probonopd/ESP8266HueEmulator + */ +class EspalexaDevice; +void onAlexaChange(EspalexaDevice* dev); +void alexaInit(); +void handleAlexa(); +void onAlexaChange(EspalexaDevice* dev); + +#define WLED_ALEXA_H \ No newline at end of file diff --git a/wled00/wled16_blynk.ino b/wled00/wled_blynk.cpp similarity index 94% rename from wled00/wled16_blynk.ino rename to wled00/wled_blynk.cpp index ea4d68771..c6754a231 100644 --- a/wled00/wled16_blynk.ino +++ b/wled00/wled_blynk.cpp @@ -1,6 +1,6 @@ -/* - * Remote light control with the free Blynk app - */ +#include "wled_blynk.h" +#include "wled.h" +#include "src/dependencies/blynk/Blynk/BlynkHandlers.h" uint16_t blHue = 0; byte blSat = 255; diff --git a/wled00/wled_blynk.h b/wled00/wled_blynk.h new file mode 100644 index 000000000..e8c8341b5 --- /dev/null +++ b/wled00/wled_blynk.h @@ -0,0 +1,13 @@ +#ifndef WLED_BLYNK_H +#define WLED_BLYNK_H +#include +/* + * Remote light control with the free Blynk app + */ + +void initBlynk(const char* auth); +void handleBlynk(); +void updateBlynk(); +// Unsure if the macro expansions need to accessed through the declaration... TODO + +#endif //WLED_BLYNK_H \ No newline at end of file diff --git a/wled00/wled09_button.ino b/wled00/wled_button.cpp similarity index 98% rename from wled00/wled09_button.ino rename to wled00/wled_button.cpp index 1cd868bec..12fe5b49b 100644 --- a/wled00/wled09_button.ino +++ b/wled00/wled_button.cpp @@ -1,3 +1,5 @@ +#include "wled_button.h" +#include "wled.h" /* * Physical IO */ diff --git a/wled00/wled_button.h b/wled00/wled_button.h new file mode 100644 index 000000000..5f8944773 --- /dev/null +++ b/wled00/wled_button.h @@ -0,0 +1,12 @@ +#ifndef WLED_BUTTON_H +#define WLED_BUTTON_H +#include +/* + * Physical IO + */ + +void shortPressAction(); +void handleButton(); +void handleIO(); + +#endif // WLED_BUTTON_H \ No newline at end of file diff --git a/wled00/wled14_colors.ino b/wled00/wled_colors.cpp similarity index 96% rename from wled00/wled14_colors.ino rename to wled00/wled_colors.cpp index a1db307ae..dcd32e574 100644 --- a/wled00/wled14_colors.ino +++ b/wled00/wled_colors.cpp @@ -1,6 +1,5 @@ -/* - * Color conversion methods - */ +#include "wled_colors.h" +#include "wled.h" void colorFromUint32(uint32_t in, bool secondary) { @@ -18,7 +17,7 @@ void colorFromUint32(uint32_t in, bool secondary) } //load a color without affecting the white channel -void colorFromUint24(uint32_t in, bool secondary = false) +void colorFromUint24(uint32_t in, bool secondary) { if (secondary) { colSec[0] = in >> 16 & 0xFF; @@ -32,7 +31,7 @@ void colorFromUint24(uint32_t in, bool secondary = false) } //relatively change white brightness, minumum A=5 -void relativeChangeWhite(int8_t amount, byte lowerBoundary =0) +void relativeChangeWhite(int8_t amount, byte lowerBoundary) { int16_t new_val = (int16_t) col[3] + amount; if (new_val > 0xFF) new_val = 0xFF; @@ -149,7 +148,8 @@ void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.develo xy[0] = X / (X + Y + Z); xy[1] = Y / (X + Y + Z); } -#endif +#endif // WLED_DISABLE_HUESYNC + void colorFromDecOrHexString(byte* rgb, char* in) { diff --git a/wled00/wled_colors.h b/wled00/wled_colors.h new file mode 100644 index 000000000..2b3ff32c5 --- /dev/null +++ b/wled00/wled_colors.h @@ -0,0 +1,20 @@ +#ifndef WLED_COLORS_H +#define WLED_COLORS_H +#include +/* + * Color conversion methods + */ + +void colorFromUint32(uint32_t in, bool secondary); +void colorFromUint24(uint32_t in, bool secondary = false); +void relativeChangeWhite(int8_t amount, byte lowerBoundary = 0); +void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb +void colorCTtoRGB(uint16_t mired, byte* rgb); //white spectrum to rgb + +void colorXYtoRGB(float x, float y, byte* rgb); // only defined if huesync disabled TODO +void colorRGBtoXY(byte* rgb, float* xy); // only defined if huesync disabled TODO + +void colorFromDecOrHexString(byte* rgb, char* in); +void colorRGBtoRGBW(byte* rgb); //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY) + +#endif //WLED_COLORS_H \ No newline at end of file diff --git a/wled00/wled13_cronixie.ino b/wled00/wled_cronixie.cpp similarity index 97% rename from wled00/wled13_cronixie.ino rename to wled00/wled_cronixie.cpp index dd687ca14..107af752a 100644 --- a/wled00/wled13_cronixie.ino +++ b/wled00/wled_cronixie.cpp @@ -1,9 +1,8 @@ -/* - * Support for the Cronixie clock - */ +#include "wled_cronixie.h" +#include "wled.h" + #ifndef WLED_DISABLE_CRONIXIE byte _digitOut[6] = {10,10,10,10,10,10}; -#endif byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) { @@ -23,7 +22,6 @@ byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) void setCronixie() { - #ifndef WLED_DISABLE_CRONIXIE /* * digit purpose index * 0-9 | 0-9 (incl. random) @@ -144,12 +142,10 @@ void setCronixie() DEBUG_PRINTLN((int)dP[5]); _overlayCronixie(); //refresh - #endif } void _overlayCronixie() { - #ifndef WLED_DISABLE_CRONIXIE byte h = hour(local); byte h0 = h; byte m = minute(local); @@ -211,12 +207,10 @@ void _overlayCronixie() } } } - #endif } void _drawOverlayCronixie() { - #ifndef WLED_DISABLE_CRONIXIE byte offsets[] = {5, 0, 6, 1, 7, 2, 8, 3, 9, 4}; for (uint16_t i = 0; i < 6; i++) @@ -239,5 +233,11 @@ void _drawOverlayCronixie() } } } - #endif } + +#else // WLED_DISABLE_CRONIXIE +byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) {} +void setCronixie() {} +void _overlayCronixie() {} +void _drawOverlayCronixie() {} +#endif diff --git a/wled00/wled_cronixie.h b/wled00/wled_cronixie.h new file mode 100644 index 000000000..9dea69b33 --- /dev/null +++ b/wled00/wled_cronixie.h @@ -0,0 +1,13 @@ +#ifndef WLED_CRONIXIE_H +#define WLED_CRONIXIE_H +#include +/* + * Support for the Cronixie clock + */ + +byte getSameCodeLength(char code, int index, char const cronixieDisplay[]); +void setCronixie(); +void _overlayCronixie(); +void _drawOverlayCronixie(); + +#endif // WLED_CRONIXIE_H \ No newline at end of file diff --git a/wled00/wled21_dmx.ino b/wled00/wled_dmx.cpp similarity index 89% rename from wled00/wled21_dmx.ino rename to wled00/wled_dmx.cpp index 4230f07d8..f620f7779 100644 --- a/wled00/wled21_dmx.ino +++ b/wled00/wled_dmx.cpp @@ -1,10 +1,7 @@ -/* - * Support for DMX via MAX485. - * Needs the espdmx library. You might have to change the output pin within the library. Sketchy, i know. - * https://github.com/Rickgg/ESP-Dmx - */ -#ifdef WLED_ENABLE_DMX +#include "wled_dmx.h" +#include "wled.h" +#ifdef WLED_ENABLE_DMX void handleDMX() { // TODO: calculate brightness manually if no shutter channel is set diff --git a/wled00/wled_dmx.h b/wled00/wled_dmx.h new file mode 100644 index 000000000..94cbb0d25 --- /dev/null +++ b/wled00/wled_dmx.h @@ -0,0 +1,11 @@ +#ifndef WLED_DMX_H +#define WLED_DMX_H +/* + * Support for DMX via MAX485. + * Needs the espdmx library. You might have to change the output pin within the library. Sketchy, i know. + * https://github.com/Rickgg/ESP-Dmx + */ + +void handleDMX(); + +#endif //WLED_DMX_H \ No newline at end of file diff --git a/wled00/wled01_eeprom.ino b/wled00/wled_eeprom.cpp similarity index 99% rename from wled00/wled01_eeprom.ino rename to wled00/wled_eeprom.cpp index 1f0e8426f..0ddbf57fd 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled_eeprom.cpp @@ -1,7 +1,5 @@ -/* - * Methods to handle saving and loading to non-volatile memory - * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map - */ +#include "wled_eeprom.h" +#include "wled.h" #define EEPSIZE 2560 //Maximum is 4096 diff --git a/wled00/wled_eeprom.h b/wled00/wled_eeprom.h new file mode 100644 index 000000000..fe5c2cbfe --- /dev/null +++ b/wled00/wled_eeprom.h @@ -0,0 +1,22 @@ +#ifndef WLED_EPPROM_H +#define WLED_EPPROM_H +#include +/* + * Methods to handle saving and loading to non-volatile memory + * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map + */ + +void commit(); +void clearEEPROM(); +void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len); +void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len); +void saveSettingsToEEPROM(); +void loadSettingsFromEEPROM(bool first); +void savedToPresets(); +bool applyPreset(byte index, bool loadBri = true); +void savePreset(byte index, bool persist = true); +void loadMacro(byte index, char* m); +void applyMacro(byte index); +void saveMacro(byte index, String mc, bool persist = true); //only commit on single save, not in settings + +#endif //WLED_EPPROM_H diff --git a/wled00/wled04_file.ino b/wled00/wled_file.cpp similarity index 95% rename from wled00/wled04_file.ino rename to wled00/wled_file.cpp index de7523281..700d66eea 100644 --- a/wled00/wled04_file.ino +++ b/wled00/wled_file.cpp @@ -1,6 +1,14 @@ -/* - * Utility for SPIFFS filesystem & Serial console - */ +#include "wled_file.h" +#include "wled.h" +//filesystem +#ifndef WLED_DISABLE_FILESYSTEM +#include +#ifdef ARDUINO_ARCH_ESP32 +#include "SPIFFS.h" +#endif +#include "SPIFFSEditor.h" +#endif + enum class AdaState { Header_A, Header_d, diff --git a/wled00/wled_file.h b/wled00/wled_file.h new file mode 100644 index 000000000..7457ec4cd --- /dev/null +++ b/wled00/wled_file.h @@ -0,0 +1,12 @@ +#ifndef WLED_FILE_H +#define WLED_FILE_H +#include +#include +/* + * Utility for SPIFFS filesystem & Serial console + */ + +void handleSerial(); +bool handleFileRead(AsyncWebServerRequest*, String path); + +#endif // WLED_FILE_H \ No newline at end of file diff --git a/wled00/wled15_hue.ino b/wled00/wled_hue.cpp similarity index 99% rename from wled00/wled15_hue.ino rename to wled00/wled_hue.cpp index 5f6b8f5bf..082685d70 100644 --- a/wled00/wled15_hue.ino +++ b/wled00/wled_hue.cpp @@ -1,7 +1,8 @@ -/* - * Sync to Philips hue lights - */ +#include "wled_hue.h" +#include "wled.h" + #ifndef WLED_DISABLE_HUESYNC + void handleHue() { if (hueReceived) diff --git a/wled00/wled_hue.h b/wled00/wled_hue.h new file mode 100644 index 000000000..dcf397290 --- /dev/null +++ b/wled00/wled_hue.h @@ -0,0 +1,10 @@ +#ifndef WLED_HUE_H +#define WLED_HUE_H +/* + * Sync to Philips hue lights + */ + +void handleHue(); +void reconnectHue(); + +#endif //WLED_HUE_H \ No newline at end of file diff --git a/wled00/wled20_ir.ino b/wled00/wled_ir.cpp similarity index 99% rename from wled00/wled20_ir.ino rename to wled00/wled_ir.cpp index 64c131c21..53f0d23f9 100644 --- a/wled00/wled20_ir.ino +++ b/wled00/wled_ir.cpp @@ -1,6 +1,5 @@ -/* - * Infrared sensor support for generic 24/40/44 key RGB remotes - */ +#include "wled_ir.h" +#include "wled.h" #if defined(WLED_DISABLE_INFRARED) void handleIR(){} diff --git a/wled00/wled_ir.h b/wled00/wled_ir.h new file mode 100644 index 000000000..3479f410b --- /dev/null +++ b/wled00/wled_ir.h @@ -0,0 +1,9 @@ +#ifndef WLED_IR_H +#define WLED_IR_H +/* + * Infrared sensor support for generic 24/40/44 key RGB remotes + */ + +void handleIR(); + +#endif //WLED_IR_H \ No newline at end of file diff --git a/wled00/wled19_json.ino b/wled00/wled_json.cpp similarity index 99% rename from wled00/wled19_json.ino rename to wled00/wled_json.cpp index df9bceadc..43d3136dd 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled_json.cpp @@ -1,6 +1,5 @@ -/* - * JSON API (De)serialization - */ +#include "wled_json.h" +#include "wled.h" void deserializeSegment(JsonObject elem, byte it) { diff --git a/wled00/wled_json.h b/wled00/wled_json.h new file mode 100644 index 000000000..83830fafa --- /dev/null +++ b/wled00/wled_json.h @@ -0,0 +1,15 @@ +#ifndef WLED_JSON_H +#define WLED_JSON_H +/* + * JSON API (De)serialization + */ + +void deserializeSegment(JsonObject elem, byte it); +bool deserializeState(JsonObject root); +void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id); +void serializeState(JsonObject root); +void serializeInfo(JsonObject root); +void serveJson(AsyncWebServerRequest* request); +void serveLiveLeds(AsyncWebServerRequest* request); + +#endif //WLED_JSON_H \ No newline at end of file diff --git a/wled00/wled08_led.ino b/wled00/wled_led.cpp similarity index 98% rename from wled00/wled08_led.ino rename to wled00/wled_led.cpp index 63009f983..aefb004a9 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled_led.cpp @@ -1,6 +1,6 @@ -/* - * LED methods - */ +#include "wled_led.h" +#include "wled.h" + void setValuesFromMainSeg() { WS2812FX::Segment& seg = strip.getSegment(strip.getMainSegmentId()); @@ -50,7 +50,7 @@ void setAllLeds() { } -void setLedsStandard(bool justColors = false) +void setLedsStandard(bool justColors) { for (byte i=0; i<4; i++) { diff --git a/wled00/wled_led.h b/wled00/wled_led.h new file mode 100644 index 000000000..aebe95e48 --- /dev/null +++ b/wled00/wled_led.h @@ -0,0 +1,19 @@ +#ifndef WLED_LED_H +#define WLED_LED_H +#include +/* + * LED methods + */ + +void setValuesFromMainSeg(); +void resetTimebase(); +void toggleOnOff(); +void setAllLeds(); +void setLedsStandard(bool justColors = false); +bool colorChanged(); +void colorUpdated(int callMode); +void updateInterfaces(uint8_t callMode); +void handleTransitions(); +void handleNightlight(); + +#endif \ No newline at end of file diff --git a/wled00/wled17_mqtt.ino b/wled00/wled_mqtt.cpp similarity index 98% rename from wled00/wled17_mqtt.ino rename to wled00/wled_mqtt.cpp index 741c807f8..d4fc80c06 100644 --- a/wled00/wled17_mqtt.ino +++ b/wled00/wled_mqtt.cpp @@ -1,6 +1,5 @@ -/* - * MQTT communication protocol for home automation - */ +#include "wled_mqtt.h" +#include "wled.h" #ifdef WLED_ENABLE_MQTT #define MQTT_KEEP_ALIVE_TIME 60 // contact the MQTT broker every 60 seconds diff --git a/wled00/wled_mqtt.h b/wled00/wled_mqtt.h new file mode 100644 index 000000000..f1c7160e5 --- /dev/null +++ b/wled00/wled_mqtt.h @@ -0,0 +1,9 @@ +#ifndef WLED_MQTT_H +#define WLED_MQTT_H +/* + * MQTT communication protocol for home automation + */ +bool initMqtt(); +void publishMqtt(); + +#endif //WLED_MQTT_H \ No newline at end of file diff --git a/wled00/wled07_notify.ino b/wled00/wled_notify.cpp similarity index 99% rename from wled00/wled07_notify.ino rename to wled00/wled_notify.cpp index 8fcbdbe82..7827aba96 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled_notify.cpp @@ -1,6 +1,6 @@ -/* - * UDP notifier - */ +#include "wled_notify.h" +#include "wled.h" +#include "src/dependencies/e131/ESPAsyncE131.h" #define WLEDPACKETSIZE 29 #define UDP_IN_MAXSIZE 1472 diff --git a/wled00/wled_notify.h b/wled00/wled_notify.h new file mode 100644 index 000000000..63d01142b --- /dev/null +++ b/wled00/wled_notify.h @@ -0,0 +1,17 @@ +#ifndef WLED_NOTIFY_H +#define WLED_NOTIFY_H +#include +#include "const.h" +/* + * UDP notifier + */ +union e131_packet_t; // Will this compile? +class IPAddress; + +void notify(byte callMode, bool followUp=false); +void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC); +void handleE131Packet(e131_packet_t* p, IPAddress clientIP); +void handleNotifications(); +void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w); + +#endif // WLED_NOTIFY_H \ No newline at end of file diff --git a/wled00/wled10_ntp.ino b/wled00/wled_ntp.cpp similarity index 58% rename from wled00/wled10_ntp.ino rename to wled00/wled_ntp.cpp index 2c5a64c45..82b99f963 100644 --- a/wled00/wled10_ntp.ino +++ b/wled00/wled_ntp.cpp @@ -1,63 +1,7 @@ -/* - * Acquires time from NTP server - */ +#include "wled_ntp.h" +#include "wled.h" +#include "wled_eeprom.h" -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); - -Timezone tzCASaskatchewan(CST, CST); //Central without DST - -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); - -TimeChangeRule NKST = {Last, Sun, Mar, 1, 510}; //Pyongyang Time = UTC + 8.5 hours -Timezone tzNK(NKST, NKST); - -TimeChangeRule IST = {Last, Sun, Mar, 1, 330}; // India Standard Time = UTC + 5.5 hours -Timezone tzIndia(IST, IST); - -Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia, &tzCASaskatchewan}; void handleNetworkTime() { diff --git a/wled00/wled_ntp.h b/wled00/wled_ntp.h new file mode 100644 index 000000000..142933421 --- /dev/null +++ b/wled00/wled_ntp.h @@ -0,0 +1,76 @@ +#ifndef WLED_NTP_H +#define WLED_NTP_H +#include +#include "timezone/Timezone.h" + +/* + * 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); + +Timezone tzCASaskatchewan(CST, CST); //Central without DST + +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); + +TimeChangeRule NKST = {Last, Sun, Mar, 1, 510}; //Pyongyang Time = UTC + 8.5 hours +Timezone tzNK(NKST, NKST); + +TimeChangeRule IST = {Last, Sun, Mar, 1, 330}; // India Standard Time = UTC + 5.5 hours +Timezone tzIndia(IST, IST); + +Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia, &tzCASaskatchewan}; + +void handleNetworkTime(); +void sendNTPPacket(); +bool checkNTPResponse(); +void updateLocalTime(); +void getTimeString(char* out); +bool checkCountdown(); +void setCountdown(); +byte weekdayMondayFirst(); +void checkTimers(); + +#endif // WLED_NTP_H \ No newline at end of file diff --git a/wled00/wled11_ol.ino b/wled00/wled_overlay.cpp similarity index 98% rename from wled00/wled11_ol.ino rename to wled00/wled_overlay.cpp index 93f7b96df..93348e79b 100644 --- a/wled00/wled11_ol.ino +++ b/wled00/wled_overlay.cpp @@ -1,6 +1,5 @@ -/* - * Used to draw clock overlays over the strip - */ +#include "wled_overlay.h" +#include "wled.h" void initCronixie() { diff --git a/wled00/wled_overlay.h b/wled00/wled_overlay.h new file mode 100644 index 000000000..47573978d --- /dev/null +++ b/wled00/wled_overlay.h @@ -0,0 +1,12 @@ +#ifndef WLED_OVERLAYS_H +#define WLED_OVERLAYS_H +#include +/* + * Used to draw clock overlays over the strip + */ + +void initCronixie(); +void handleOverlays(); +void handleOverlayDraw(); + +#endif // WLED_OVERLAY_H \ No newline at end of file diff --git a/wled00/wled18_server.ino b/wled00/wled_server.cpp similarity index 99% rename from wled00/wled18_server.ino rename to wled00/wled_server.cpp index f11a64bec..c73e027f1 100644 --- a/wled00/wled18_server.ino +++ b/wled00/wled_server.cpp @@ -1,6 +1,5 @@ -/* - * Server page definitions - */ +#include "wled_server.h" +#include "wled.h" //Is this an IP? bool isIp(String str) { @@ -303,7 +302,7 @@ String msgProcessor(const String& var) } -void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255) +void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl, byte optionT) { messageHead = headl; messageSub = subl; diff --git a/wled00/wled_server.h b/wled00/wled_server.h new file mode 100644 index 000000000..08679e179 --- /dev/null +++ b/wled00/wled_server.h @@ -0,0 +1,18 @@ +#ifndef WLED_SERVER_H +#define WLED_SERVER_H +/* + * Server page declarations + */ + +bool isIp(String str); +bool captivePortal(AsyncWebServerRequest *request); +void initServer(); +void serveIndexOrWelcome(AsyncWebServerRequest *request); +void serveIndex(AsyncWebServerRequest* request); +String msgProcessor(const String& var); +void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255); +String settingsProcessor(const String& var); +String dmxProcessor(const String& var); +void serveSettings(AsyncWebServerRequest* request); + +#endif //WLED_SERVER_H \ No newline at end of file diff --git a/wled00/wled03_set.ino b/wled00/wled_set.cpp similarity index 99% rename from wled00/wled03_set.ino rename to wled00/wled_set.cpp index fc82256d2..d81cac916 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled_set.cpp @@ -1,3 +1,7 @@ +#include "wled_set.h" +#include "wled.h" +#include "wled_hue.h" +#include "wled_colors.h" /* * Receives client input */ diff --git a/wled00/wled_set.h b/wled00/wled_set.h new file mode 100644 index 000000000..7efde0d75 --- /dev/null +++ b/wled00/wled_set.h @@ -0,0 +1,12 @@ +#ifndef WLED_SET_H +#define WLED_SET_H +#include +#include + +void _setRandomColor(bool _sec,bool fromButton=false); +bool isAsterisksOnly(const char* str, byte maxLen); +void handleSettingsSet(AsyncWebServerRequest *request, byte subPage); +int getNumVal(const String* req, uint16_t pos); +bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255); + +#endif // WLED_SET_H \ No newline at end of file diff --git a/wled00/wled02_xml.ino b/wled00/wled_xml.cpp similarity index 99% rename from wled00/wled02_xml.ino rename to wled00/wled_xml.cpp index 100be4822..07009cf3c 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled_xml.cpp @@ -1,6 +1,7 @@ -/* - * Sending XML status files to client - */ +#include "wled_xml.h" +#include "wled.h" +#include "wled_eeprom.h" + //build XML response to HTTP /win API request char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr) diff --git a/wled00/wled_xml.h b/wled00/wled_xml.h new file mode 100644 index 000000000..5cfb1dbb7 --- /dev/null +++ b/wled00/wled_xml.h @@ -0,0 +1,15 @@ +#ifndef WLED_XML_H +#define WLED_XML_H +#include +#include + +/* + * Sending XML status files to client + */ +char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr); +char* URL_response(AsyncWebServerRequest *request); +void sappend(char stype, const char* key, int val); +void sappends(char stype, const char* key, char* val); +void getSettingsJS(byte subPage, char* dest); + +#endif // WLED_XML_H \ No newline at end of file From 12131764d1e7ce305063021b6b4f581593eabfb3 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Wed, 25 Mar 2020 04:36:55 -0400 Subject: [PATCH 109/509] Prior to refactoring includes and forward definitions. --- .../src/dependencies/espalexa/EspalexaDevice.h | 2 +- wled00/wled.cpp | 18 ++++++++++++++++-- wled00/wled.h | 5 +---- wled00/wled00.ino | 6 +++--- wled00/wled_alexa.cpp | 1 + wled00/wled_alexa.h | 5 +++-- wled00/wled_eeprom.cpp | 5 ++++- wled00/wled_eeprom.h | 1 + wled00/wled_file.cpp | 4 ++++ wled00/wled_server.cpp | 5 +++++ wled00/wled_server.h | 1 + wled00/wled_set.cpp | 11 +++++++---- wled00/wled_set.h | 4 ++++ .../{wled06_usermod.cpp => wled_usermod.cpp} | 0 wled00/wled_usermod.h | 8 ++++++++ 15 files changed, 59 insertions(+), 17 deletions(-) rename wled00/{wled06_usermod.cpp => wled_usermod.cpp} (100%) create mode 100644 wled00/wled_usermod.h diff --git a/wled00/src/dependencies/espalexa/EspalexaDevice.h b/wled00/src/dependencies/espalexa/EspalexaDevice.h index 4785591fe..b964e0e32 100644 --- a/wled00/src/dependencies/espalexa/EspalexaDevice.h +++ b/wled00/src/dependencies/espalexa/EspalexaDevice.h @@ -1,6 +1,6 @@ #ifndef EspalexaDevice_h #define EspalexaDevice_h - +#include #include "Arduino.h" typedef class EspalexaDevice; diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 50a83f27e..97ed38787 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -1,4 +1,18 @@ #include "wled.h" +#include "wled_led.h" +#include "wled_ir.h" +#include "wled_notify.h" +#include "wled_alexa.h" +#include "wled_overlay.h" +#include "wled_file.h" +#include "wled_button.h" +#include "wled_ntp.h" +#include "wled_usermod.h" +#include "wled_blynk.h" +#include "wled_hue.h" +#include "wled_mqtt.h" +#include "wled_eeprom.h" +#include "wled_server.h" WLED::WLED() { @@ -251,7 +265,7 @@ void WLED::beginStrip() #endif } -void WLED::initAP(bool resetAP = false) +void WLED::initAP(bool resetAP) { if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) return; @@ -483,7 +497,7 @@ void WLED::handleConnection() } //by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp -int WLED::getSignalQuality(int rssi) +int getSignalQuality(int rssi) { int quality = 0; diff --git a/wled00/wled.h b/wled00/wled.h index 4f9b79afd..8ef30cbfe 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -491,6 +491,7 @@ int loops = 0; bool oappend(const char *txt); //append new number to temp buffer efficiently bool oappendi(int i); +int getSignalQuality(int rssi); class WLED { @@ -503,8 +504,6 @@ public: WLED(); - void wledInit(); - void reset(); void loop(); @@ -515,8 +514,6 @@ public: wledInit(); } - void loop(); - private: void wledInit(); void beginStrip(); diff --git a/wled00/wled00.ino b/wled00/wled00.ino index fc06f2114..ac993bf62 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -3,11 +3,11 @@ */ #include "wled.h" +WLED wled; void setup() { - //auto& wled = Wled(); + wled.instance(); // Force creation of static instance } void loop() { - - + wled.loop(); } \ No newline at end of file diff --git a/wled00/wled_alexa.cpp b/wled00/wled_alexa.cpp index b68843cbc..ce63a0192 100644 --- a/wled00/wled_alexa.cpp +++ b/wled00/wled_alexa.cpp @@ -1,6 +1,7 @@ #include "wled_alexa.h" #include "wled.h" #include "src/dependencies/espalexa/EspalexaDevice.h" +#include "const.h" #ifndef WLED_DISABLE_ALEXA void onAlexaChange(EspalexaDevice* dev); diff --git a/wled00/wled_alexa.h b/wled00/wled_alexa.h index 4bf7bd123..94ad0342b 100644 --- a/wled00/wled_alexa.h +++ b/wled00/wled_alexa.h @@ -7,10 +7,11 @@ * https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch * https://github.com/probonopd/ESP8266HueEmulator */ -class EspalexaDevice; +#include "src/dependencies/espalexa/EspalexaDevice.h" + void onAlexaChange(EspalexaDevice* dev); void alexaInit(); void handleAlexa(); void onAlexaChange(EspalexaDevice* dev); -#define WLED_ALEXA_H \ No newline at end of file +#endif // WLED_ALEXA_H \ No newline at end of file diff --git a/wled00/wled_eeprom.cpp b/wled00/wled_eeprom.cpp index 0ddbf57fd..1e2b0e620 100644 --- a/wled00/wled_eeprom.cpp +++ b/wled00/wled_eeprom.cpp @@ -1,7 +1,10 @@ #include "wled_eeprom.h" #include "wled.h" +#include "wled_cronixie.h" +#include "wled_ntp.h" +#include "wled_set.h" +#include "wled_led.h" -#define EEPSIZE 2560 //Maximum is 4096 //eeprom Version code, enables default settings instead of 0 init on update #define EEPVER 18 diff --git a/wled00/wled_eeprom.h b/wled00/wled_eeprom.h index fe5c2cbfe..19f61925a 100644 --- a/wled00/wled_eeprom.h +++ b/wled00/wled_eeprom.h @@ -5,6 +5,7 @@ * Methods to handle saving and loading to non-volatile memory * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map */ +#define EEPSIZE 2560 //Maximum is 4096 void commit(); void clearEEPROM(); diff --git a/wled00/wled_file.cpp b/wled00/wled_file.cpp index 700d66eea..81b86d6d3 100644 --- a/wled00/wled_file.cpp +++ b/wled00/wled_file.cpp @@ -1,5 +1,8 @@ #include "wled_file.h" #include "wled.h" +#include "wled_led.h" +#include "wled_notify.h" + //filesystem #ifndef WLED_DISABLE_FILESYSTEM #include @@ -21,6 +24,7 @@ enum class AdaState { Data_Blue }; +// Maybe Adalight should not be in filehandling? TODO void handleSerial() { #ifdef WLED_ENABLE_ADALIGHT diff --git a/wled00/wled_server.cpp b/wled00/wled_server.cpp index c73e027f1..542abea4c 100644 --- a/wled00/wled_server.cpp +++ b/wled00/wled_server.cpp @@ -1,5 +1,10 @@ #include "wled_server.h" #include "wled.h" +#include "wled_file.h" +#include "wled_set.h" +#include "wled_json.h" +#include "wled_xml.h" + //Is this an IP? bool isIp(String str) { diff --git a/wled00/wled_server.h b/wled00/wled_server.h index 08679e179..a03f83e1a 100644 --- a/wled00/wled_server.h +++ b/wled00/wled_server.h @@ -1,5 +1,6 @@ #ifndef WLED_SERVER_H #define WLED_SERVER_H +#include /* * Server page declarations */ diff --git a/wled00/wled_set.cpp b/wled00/wled_set.cpp index d81cac916..aff3f0cda 100644 --- a/wled00/wled_set.cpp +++ b/wled00/wled_set.cpp @@ -1,10 +1,13 @@ #include "wled_set.h" #include "wled.h" -#include "wled_hue.h" #include "wled_colors.h" -/* - * Receives client input - */ +#include "wled_hue.h" +#include "wled_led.h" +#include "wled_blynk.h" +#include "wled_eeprom.h" +#include "wled_alexa.h" +#include "wled_cronixie.h" +#include "wled_xml.h" void _setRandomColor(bool _sec,bool fromButton=false) { diff --git a/wled00/wled_set.h b/wled00/wled_set.h index 7efde0d75..ebee8c928 100644 --- a/wled00/wled_set.h +++ b/wled00/wled_set.h @@ -2,10 +2,14 @@ #define WLED_SET_H #include #include +/* + * Receives client input + */ void _setRandomColor(bool _sec,bool fromButton=false); bool isAsterisksOnly(const char* str, byte maxLen); void handleSettingsSet(AsyncWebServerRequest *request, byte subPage); +bool handleSet(AsyncWebServerRequest *request, const String& req); int getNumVal(const String* req, uint16_t pos); bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255); diff --git a/wled00/wled06_usermod.cpp b/wled00/wled_usermod.cpp similarity index 100% rename from wled00/wled06_usermod.cpp rename to wled00/wled_usermod.cpp diff --git a/wled00/wled_usermod.h b/wled00/wled_usermod.h new file mode 100644 index 000000000..61ef6b785 --- /dev/null +++ b/wled00/wled_usermod.h @@ -0,0 +1,8 @@ +#ifndef WLED_USERMOD_H +#define WLED_USERMOD_H + +void userSetup(); +void userConnected(); +void userLoop(); + +#endif // WLED_USERMOD_H \ No newline at end of file From 6f5e71164ae2174b47354c489b0ef0dda9fd66bd Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Wed, 25 Mar 2020 05:14:23 -0400 Subject: [PATCH 110/509] Further fixing of includes. --- wled00/wled.h | 2 +- wled00/wled_alexa.cpp | 4 +++- wled00/wled_button.cpp | 6 +++++- wled00/wled_eeprom.cpp | 6 +++--- wled00/wled_hue.cpp | 2 ++ wled00/wled_hue.h | 6 ++++++ wled00/wled_json.cpp | 2 ++ wled00/wled_json.h | 6 ++++++ wled00/wled_led.cpp | 5 +++++ wled00/wled_mqtt.cpp | 2 ++ wled00/wled_notify.cpp | 5 +++-- wled00/wled_notify.h | 2 +- 12 files changed, 39 insertions(+), 9 deletions(-) diff --git a/wled00/wled.h b/wled00/wled.h index 8ef30cbfe..c04dfa87b 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -514,7 +514,7 @@ public: wledInit(); } -private: +public: // TODO: privacy void wledInit(); void beginStrip(); diff --git a/wled00/wled_alexa.cpp b/wled00/wled_alexa.cpp index ce63a0192..1eb33e71d 100644 --- a/wled00/wled_alexa.cpp +++ b/wled00/wled_alexa.cpp @@ -1,7 +1,9 @@ #include "wled_alexa.h" #include "wled.h" -#include "src/dependencies/espalexa/EspalexaDevice.h" #include "const.h" +#include "wled_led.h" +#include "wled_eeprom.h" +#include "wled_colors.h" #ifndef WLED_DISABLE_ALEXA void onAlexaChange(EspalexaDevice* dev); diff --git a/wled00/wled_button.cpp b/wled00/wled_button.cpp index 12fe5b49b..3825cc846 100644 --- a/wled00/wled_button.cpp +++ b/wled00/wled_button.cpp @@ -1,5 +1,9 @@ #include "wled_button.h" #include "wled.h" +#include "wled_led.h" +#include "wled_eeprom.h" +#include "wled_set.h" + /* * Physical IO */ @@ -46,7 +50,7 @@ void handleButton() if (dur > 6000) //long press { - initAP(true); + WLED::instance().initAP(true); } else if (!buttonLongPressed) { //short press if (macroDoublePress) diff --git a/wled00/wled_eeprom.cpp b/wled00/wled_eeprom.cpp index 1e2b0e620..04b86289a 100644 --- a/wled00/wled_eeprom.cpp +++ b/wled00/wled_eeprom.cpp @@ -592,7 +592,7 @@ void savedToPresets() } } -bool applyPreset(byte index, bool loadBri = true) +bool applyPreset(byte index, bool loadBri) { if (index == 255 || index == 0) { @@ -630,7 +630,7 @@ bool applyPreset(byte index, bool loadBri = true) return true; } -void savePreset(byte index, bool persist = true) +void savePreset(byte index, bool persist) { if (index > 16) return; if (index < 1) {saveSettingsToEEPROM();return;} @@ -698,7 +698,7 @@ void applyMacro(byte index) } -void saveMacro(byte index, String mc, bool persist = true) //only commit on single save, not in settings +void saveMacro(byte index, String mc, bool persist) //only commit on single save, not in settings { index-=1; if (index > 15) return; diff --git a/wled00/wled_hue.cpp b/wled00/wled_hue.cpp index 082685d70..abdb4ffa7 100644 --- a/wled00/wled_hue.cpp +++ b/wled00/wled_hue.cpp @@ -1,5 +1,7 @@ #include "wled_hue.h" #include "wled.h" +#include "wled_colors.h" +#include "wled_eeprom.h" #ifndef WLED_DISABLE_HUESYNC diff --git a/wled00/wled_hue.h b/wled00/wled_hue.h index dcf397290..e9aa22b2a 100644 --- a/wled00/wled_hue.h +++ b/wled00/wled_hue.h @@ -3,8 +3,14 @@ /* * Sync to Philips hue lights */ +#include +#include void handleHue(); void reconnectHue(); +void onHueError(void* arg, AsyncClient* client, int8_t error); +void onHueConnect(void* arg, AsyncClient* client); +void sendHuePoll(); +void onHueData(void* arg, AsyncClient* client, void *data, size_t len); #endif //WLED_HUE_H \ No newline at end of file diff --git a/wled00/wled_json.cpp b/wled00/wled_json.cpp index 43d3136dd..17359462d 100644 --- a/wled00/wled_json.cpp +++ b/wled00/wled_json.cpp @@ -1,5 +1,7 @@ #include "wled_json.h" #include "wled.h" +#include "wled_eeprom.h" +#include "wled_led.h" void deserializeSegment(JsonObject elem, byte it) { diff --git a/wled00/wled_json.h b/wled00/wled_json.h index 83830fafa..a7c2473aa 100644 --- a/wled00/wled_json.h +++ b/wled00/wled_json.h @@ -3,6 +3,12 @@ /* * JSON API (De)serialization */ +#include +#include "ESPAsyncWebServer.h" +#include "src/dependencies/json/ArduinoJson-v6.h" +#include "src/dependencies/json/AsyncJson-v6.h" +#include "fx.h" +// TODO: AsynicWebServerRequest conflict? void deserializeSegment(JsonObject elem, byte it); bool deserializeState(JsonObject root); diff --git a/wled00/wled_led.cpp b/wled00/wled_led.cpp index aefb004a9..bd657a53b 100644 --- a/wled00/wled_led.cpp +++ b/wled00/wled_led.cpp @@ -1,5 +1,10 @@ #include "wled_led.h" #include "wled.h" +#include "wled_notify.h" +#include "wled_blynk.h" +#include "wled_eeprom.h" +#include "wled_mqtt.h" +#include "wled_colors.h" void setValuesFromMainSeg() { diff --git a/wled00/wled_mqtt.cpp b/wled00/wled_mqtt.cpp index d4fc80c06..ce69513ba 100644 --- a/wled00/wled_mqtt.cpp +++ b/wled00/wled_mqtt.cpp @@ -1,5 +1,7 @@ #include "wled_mqtt.h" #include "wled.h" +#include "wled_notify.h" +#include "wled_led.h" #ifdef WLED_ENABLE_MQTT #define MQTT_KEEP_ALIVE_TIME 60 // contact the MQTT broker every 60 seconds diff --git a/wled00/wled_notify.cpp b/wled00/wled_notify.cpp index 7827aba96..7913b4525 100644 --- a/wled00/wled_notify.cpp +++ b/wled00/wled_notify.cpp @@ -1,12 +1,13 @@ #include "wled_notify.h" #include "wled.h" #include "src/dependencies/e131/ESPAsyncE131.h" +#include "wled_led.h" #define WLEDPACKETSIZE 29 #define UDP_IN_MAXSIZE 1472 -void notify(byte callMode, bool followUp=false) +void notify(byte callMode, bool followUp) { if (!udpConnected) return; switch (callMode) @@ -71,7 +72,7 @@ void notify(byte callMode, bool followUp=false) } -void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC) +void arlsLock(uint32_t timeoutMs, byte md) { if (!realtimeMode){ for (uint16_t i = 0; i < ledCount; i++) diff --git a/wled00/wled_notify.h b/wled00/wled_notify.h index 63d01142b..2a2865b3b 100644 --- a/wled00/wled_notify.h +++ b/wled00/wled_notify.h @@ -5,7 +5,7 @@ /* * UDP notifier */ -union e131_packet_t; // Will this compile? +//union e131_packet_t; // Will this compile? class IPAddress; void notify(byte callMode, bool followUp=false); From ccf5e66f316f8d92063cf85a174abfec32226474 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Wed, 25 Mar 2020 05:43:12 -0400 Subject: [PATCH 111/509] Compiles, but does not link. --- wled00/wled_hue.cpp | 2 ++ wled00/wled_hue.h | 2 +- wled00/wled_mqtt.cpp | 3 +++ wled00/wled_notify.h | 1 + wled00/wled_overlay.cpp | 2 ++ wled00/wled_overlay.h | 2 ++ wled00/wled_server.h | 2 ++ wled00/wled_set.cpp | 4 ++-- wled00/wled_xml.cpp | 3 ++- 9 files changed, 17 insertions(+), 4 deletions(-) diff --git a/wled00/wled_hue.cpp b/wled00/wled_hue.cpp index abdb4ffa7..61756ec0e 100644 --- a/wled00/wled_hue.cpp +++ b/wled00/wled_hue.cpp @@ -2,6 +2,8 @@ #include "wled.h" #include "wled_colors.h" #include "wled_eeprom.h" +#include "wled_notify.h" +#include "wled_led.h" #ifndef WLED_DISABLE_HUESYNC diff --git a/wled00/wled_hue.h b/wled00/wled_hue.h index e9aa22b2a..8b26f8b6f 100644 --- a/wled00/wled_hue.h +++ b/wled00/wled_hue.h @@ -4,7 +4,7 @@ * Sync to Philips hue lights */ #include -#include +class AsyncClient; void handleHue(); void reconnectHue(); diff --git a/wled00/wled_mqtt.cpp b/wled00/wled_mqtt.cpp index ce69513ba..5e96a18f2 100644 --- a/wled00/wled_mqtt.cpp +++ b/wled00/wled_mqtt.cpp @@ -2,6 +2,9 @@ #include "wled.h" #include "wled_notify.h" #include "wled_led.h" +#include "wled_colors.h" +#include "wled_xml.h" +#include "wled_set.h" #ifdef WLED_ENABLE_MQTT #define MQTT_KEEP_ALIVE_TIME 60 // contact the MQTT broker every 60 seconds diff --git a/wled00/wled_notify.h b/wled00/wled_notify.h index 2a2865b3b..04c65aa43 100644 --- a/wled00/wled_notify.h +++ b/wled00/wled_notify.h @@ -1,6 +1,7 @@ #ifndef WLED_NOTIFY_H #define WLED_NOTIFY_H #include +#include "src/dependencies/e131/ESPAsyncE131.h" #include "const.h" /* * UDP notifier diff --git a/wled00/wled_overlay.cpp b/wled00/wled_overlay.cpp index 93348e79b..8cb707866 100644 --- a/wled00/wled_overlay.cpp +++ b/wled00/wled_overlay.cpp @@ -1,5 +1,7 @@ #include "wled_overlay.h" #include "wled.h" +#include "wled_cronixie.h" +#include "wled_ntp.h" void initCronixie() { diff --git a/wled00/wled_overlay.h b/wled00/wled_overlay.h index 47573978d..ec18f45b4 100644 --- a/wled00/wled_overlay.h +++ b/wled00/wled_overlay.h @@ -8,5 +8,7 @@ void initCronixie(); void handleOverlays(); void handleOverlayDraw(); +void _overlayAnalogCountdown(); +void _overlayAnalogClock(); #endif // WLED_OVERLAY_H \ No newline at end of file diff --git a/wled00/wled_server.h b/wled00/wled_server.h index a03f83e1a..46adc9629 100644 --- a/wled00/wled_server.h +++ b/wled00/wled_server.h @@ -4,6 +4,8 @@ /* * Server page declarations */ +class AsyncWebServerRequest; + bool isIp(String str); bool captivePortal(AsyncWebServerRequest *request); diff --git a/wled00/wled_set.cpp b/wled00/wled_set.cpp index aff3f0cda..66d9ff1ec 100644 --- a/wled00/wled_set.cpp +++ b/wled00/wled_set.cpp @@ -9,7 +9,7 @@ #include "wled_cronixie.h" #include "wled_xml.h" -void _setRandomColor(bool _sec,bool fromButton=false) +void _setRandomColor(bool _sec,bool fromButton) { lastRandomIndex = strip.get_random_wheel_index(lastRandomIndex); if (_sec){ @@ -337,7 +337,7 @@ int getNumVal(const String* req, uint16_t pos) //helper to get int value at a position in string -bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255) +bool updateVal(const String* req, const char* key, byte* val, byte minv, byte maxv) { int pos = req->indexOf(key); if (pos < 1) return false; diff --git a/wled00/wled_xml.cpp b/wled00/wled_xml.cpp index 07009cf3c..4f2b3f45b 100644 --- a/wled00/wled_xml.cpp +++ b/wled00/wled_xml.cpp @@ -1,10 +1,11 @@ #include "wled_xml.h" #include "wled.h" #include "wled_eeprom.h" +#include "wled_ntp.h" //build XML response to HTTP /win API request -char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr) +char* XML_response(AsyncWebServerRequest *request, char* dest) { char sbuf[(dest == nullptr)?1024:1]; //allocate local buffer if none passed obuf = (dest == nullptr)? sbuf:dest; From 07d6bfa98927c47a40742434f60986b485616eb3 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Wed, 25 Mar 2020 11:17:45 +0100 Subject: [PATCH 112/509] Added Pacifica effect (closes #790) --- CHANGELOG.md | 6 + wled00/FX.cpp | 106 ++++++++++++++++++ wled00/FX.h | 12 +- wled00/palettes.h | 11 +- .../dependencies/espalexa/EspalexaDevice.h | 1 + wled00/wled00.ino | 2 +- 6 files changed, 132 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68243a3ba..f5caf7b51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ### Development versions after 0.9.1 release +#### Build 2003251 + +- Added Pacifica effect (tentative, doesn't yet support other colors) +- Added Atlantica palette +- Fixed ESP32 build of Espalexa + #### Build 2003222 - Fixed Alexa Whites on non-RGBW lights (bump Espalexa to 2.4.5) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 022b4b232..1e3ec2d98 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -3094,6 +3094,7 @@ uint16_t WS2812FX::mode_plasma(void) { return FRAMETIME; } + /* * Percentage display * Intesity values from 0-100 turn on the leds. @@ -3167,3 +3168,108 @@ uint16_t WS2812FX::mode_heartbeat(void) { return FRAMETIME; } + + +// "Pacifica" +// Gentle, blue-green ocean waves. +// December 2019, Mark Kriegsman and Mary Corey March. +// For Dan. +// +// +// In this animation, there are four "layers" of waves of light. +// +// Each layer moves independently, and each is scaled separately. +// +// All four wave layers are added together on top of each other, and then +// another filter is applied that adds "whitecaps" of brightness where the +// waves line up with each other more. Finally, another pass is taken +// over the led array to 'deepen' (dim) the blues and greens. +// +// The speed and scale and motion each layer varies slowly within independent +// hand-chosen ranges, which is why the code has a lot of low-speed 'beatsin8' functions +// with a lot of oddly specific numeric ranges. +// +// These three custom blue-green color palettes were inspired by the colors found in +// the waters off the southern coast of California, https://goo.gl/maps/QQgd97jjHesHZVxQ7 +// +// Modified for WLED, based on https://github.com/FastLED/FastLED/blob/master/examples/Pacifica/Pacifica.ino +// +uint16_t WS2812FX::mode_pacifica() +{ + CRGBPalette16 pacifica_palette_1 = + { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117, + 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50 }; + CRGBPalette16 pacifica_palette_2 = + { 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117, + 0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F }; + CRGBPalette16 pacifica_palette_3 = + { 0x000208, 0x00030E, 0x000514, 0x00061A, 0x000820, 0x000927, 0x000B2D, 0x000C33, + 0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF }; + // Increment the four "color index start" counters, one for each wave layer. + // Each is incremented at a different speed, and the speeds vary over time. + uint16_t sCIStart1 = SEGENV.aux0, sCIStart2 = SEGENV.aux1, sCIStart3 = SEGENV.step, sCIStart4 = SEGENV.step >> 16; + //static uint16_t sCIStart1, sCIStart2, sCIStart3, sCIStart4; + uint32_t deltams = 26 + (SEGMENT.speed >> 3); + + uint16_t speedfactor1 = beatsin16(3, 179, 269); + uint16_t speedfactor2 = beatsin16(4, 179, 269); + uint32_t deltams1 = (deltams * speedfactor1) / 256; + uint32_t deltams2 = (deltams * speedfactor2) / 256; + uint32_t deltams21 = (deltams1 + deltams2) / 2; + sCIStart1 += (deltams1 * beatsin88(1011,10,13)); + sCIStart2 -= (deltams21 * beatsin88(777,8,11)); + sCIStart3 -= (deltams1 * beatsin88(501,5,7)); + sCIStart4 -= (deltams2 * beatsin88(257,4,6)); + SEGENV.aux0 = sCIStart1; SEGENV.aux1 = sCIStart2; + SEGENV.step = sCIStart4; SEGENV.step = (SEGENV.step << 16) + sCIStart3; + + // Clear out the LED array to a dim background blue-green + //fill(132618); + + uint8_t basethreshold = beatsin8( 9, 55, 65); + uint8_t wave = beat8( 7 ); + + for( uint16_t i = 0; i < SEGLEN; i++) { + CRGB c = CRGB(2, 6, 10); + // Render each of four layers, with different scales and speeds, that vary over time + c += pacifica_one_layer(i, pacifica_palette_1, sCIStart1, beatsin16(3, 11 * 256, 14 * 256), beatsin8(10, 70, 130), 0-beat16(301)); + c += pacifica_one_layer(i, pacifica_palette_2, sCIStart2, beatsin16(4, 6 * 256, 9 * 256), beatsin8(17, 40, 80), beat16(401)); + c += pacifica_one_layer(i, pacifica_palette_3, sCIStart3, 6 * 256 , beatsin8(9, 10,38) , 0-beat16(503)); + c += pacifica_one_layer(i, pacifica_palette_3, sCIStart4, 5 * 256 , beatsin8(8, 10,28) , beat16(601)); + + // Add extra 'white' to areas where the four layers of light have lined up brightly + uint8_t threshold = scale8( sin8( wave), 20) + basethreshold; + wave += 7; + uint8_t l = c.getAverageLight(); + if (l > threshold) { + uint8_t overage = l - threshold; + uint8_t overage2 = qadd8(overage, overage); + c += CRGB(overage, overage2, qadd8(overage2, overage2)); + } + + //deepen the blues and greens + c.blue = scale8(c.blue, 145); + c.green = scale8(c.green, 200); + c |= CRGB( 2, 5, 7); + + setPixelColor(i, c.red, c.green, c.blue); + } + + return FRAMETIME; +} + +// Add one layer of waves into the led array +CRGB WS2812FX::pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff) +{ + uint16_t ci = cistart; + uint16_t waveangle = ioff; + uint16_t wavescale_half = (wavescale >> 1) + 20; + + waveangle += ((120 + SEGMENT.intensity) * i); //original 250 * i + uint16_t s16 = sin16(waveangle) + 32768; + uint16_t cs = scale16(s16, wavescale_half) + wavescale_half; + ci += (cs * i); + uint16_t sindex16 = sin16(ci) + 32768; + uint8_t sindex8 = scale16(sindex16, 240); + return ColorFromPalette(p, sindex8, bri, LINEARBLEND); +} diff --git a/wled00/FX.h b/wled00/FX.h index d24250f9b..b6ed7974c 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -95,7 +95,7 @@ #define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE ) #define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED ) -#define MODE_COUNT 101 +#define MODE_COUNT 102 #define FX_MODE_STATIC 0 #define FX_MODE_BLINK 1 @@ -198,6 +198,7 @@ #define FX_MODE_PERCENT 98 #define FX_MODE_RIPPLE_RAINBOW 99 #define FX_MODE_HEARTBEAT 100 +#define FX_MODE_PACIFICA 101 class WS2812FX { typedef uint16_t (WS2812FX::*mode_ptr)(void); @@ -387,6 +388,7 @@ class WS2812FX { _mode[FX_MODE_PERCENT] = &WS2812FX::mode_percent; _mode[FX_MODE_RIPPLE_RAINBOW] = &WS2812FX::mode_ripple_rainbow; _mode[FX_MODE_HEARTBEAT] = &WS2812FX::mode_heartbeat; + _mode[FX_MODE_PACIFICA] = &WS2812FX::mode_pacifica; _brightness = DEFAULT_BRIGHTNESS; currentPalette = CRGBPalette16(CRGB::Black); @@ -571,7 +573,8 @@ class WS2812FX { mode_plasma(void), mode_percent(void), mode_ripple_rainbow(void), - mode_heartbeat(void); + mode_heartbeat(void), + mode_pacifica(void); private: @@ -621,6 +624,7 @@ class WS2812FX { spots_base(uint16_t); CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat); + CRGB pacifica_one_layer(uint16_t i, CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff); uint32_t _lastPaletteChange = 0; uint32_t _lastShow = 0; @@ -656,7 +660,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([ "Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Meteor Smooth","Railway","Ripple", "Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst", "Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow", -"Heartbeat" +"Heartbeat","Pacifica" ])====="; @@ -666,7 +670,7 @@ const char JSON_palette_names[] PROGMEM = R"=====([ "Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64", "Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn", "Magenta","Magred","Yelmag","Yelblu","Orange & Teal","Tiamat","April Night","Orangery","C9","Sakura", -"Aurora" +"Aurora","Atlantica" ])====="; #endif diff --git a/wled00/palettes.h b/wled00/palettes.h index 293843952..1b95e64b2 100644 --- a/wled00/palettes.h +++ b/wled00/palettes.h @@ -13,7 +13,7 @@ #ifndef PalettesWLED_h #define PalettesWLED_h -#define GRADIENT_PALETTE_COUNT 38 +#define GRADIENT_PALETTE_COUNT 39 const byte ib_jul01_gp[] PROGMEM = { 0, 194, 1, 1, @@ -574,6 +574,14 @@ const byte Aurora_gp[] PROGMEM = { 170, 0,243, 45, 200, 0,135, 7, 255, 1, 5, 45};//deep blue + +const byte Atlantica_gp[] PROGMEM = { + 0, 0, 28,112, //#001C70 + 50, 32, 96,255, //#2060FF + 100, 0,243, 45, + 150, 12, 95, 82, //#0C5F52 + 200, 25,190, 95, //#19BE5F + 255, 40,170, 80};//#28AA50 // Single array of defined cpt-city color palettes. @@ -619,6 +627,7 @@ const byte* const gGradientPalettes[] PROGMEM = { C9_gp, //48-35 C9 Sakura_gp, //49-36 Sakura Aurora_gp, //50-37 Aurora + Atlantica_gp, //51-38 Atlantica }; #endif diff --git a/wled00/src/dependencies/espalexa/EspalexaDevice.h b/wled00/src/dependencies/espalexa/EspalexaDevice.h index 4785591fe..0653a4188 100644 --- a/wled00/src/dependencies/espalexa/EspalexaDevice.h +++ b/wled00/src/dependencies/espalexa/EspalexaDevice.h @@ -2,6 +2,7 @@ #define EspalexaDevice_h #include "Arduino.h" +#include typedef class EspalexaDevice; diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 7c64796d6..a7eeb1f57 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -118,7 +118,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2003222 +#define VERSION 2003251 char versionString[] = "0.9.1"; From c4512b75d9e2b0c64179a7406131061f31d8ad1b Mon Sep 17 00:00:00 2001 From: cschwinne Date: Thu, 26 Mar 2020 01:44:38 +0100 Subject: [PATCH 113/509] Fixed live preview not displaying whole light if over 255 LEDs --- CHANGELOG.md | 30 +++++++++++++++++------------- wled00/wled00.ino | 2 +- wled00/wled19_json.ino | 4 ++-- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5caf7b51..56afa3fff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,34 +2,38 @@ ### Development versions after 0.9.1 release +#### Build 2003261 + +- Fixed live preview not displaying whole light if over 255 LEDs + #### Build 2003251 -- Added Pacifica effect (tentative, doesn't yet support other colors) -- Added Atlantica palette -- Fixed ESP32 build of Espalexa +- Added Pacifica effect (tentative, doesn't yet support other colors) +- Added Atlantica palette +- Fixed ESP32 build of Espalexa #### Build 2003222 -- Fixed Alexa Whites on non-RGBW lights (bump Espalexa to 2.4.5) +- Fixed Alexa Whites on non-RGBW lights (bump Espalexa to 2.4.5) #### Build 2003221 -- Moved Cronixie driver from FX library to drawOverlay handler +- Moved Cronixie driver from FX library to drawOverlay handler #### Build 2003211 -- Added custom mapping compile define to FX_fcn.h -- Merged pull request #784 by @TravisDean: Fixed initialization bug when toggling skip first -- Added link to youtube videos by Room31 to readme +- Added custom mapping compile define to FX_fcn.h +- Merged pull request #784 by @TravisDean: Fixed initialization bug when toggling skip first +- Added link to youtube videos by Room31 to readme #### Build 2003141 -- Fixed color of main segment returned in JSON API during transition not being target color (closes #765) -- Fixed arlsLock() being called after pixels set in E1.31 (closes #772) -- Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment) +- Fixed color of main segment returned in JSON API during transition not being target color (closes #765) +- Fixed arlsLock() being called after pixels set in E1.31 (closes #772) +- Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment) #### Build 2003121 -- Created changelog.md - make tracking changes to code easier -- Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection +- Created changelog.md - make tracking changes to code easier +- Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection diff --git a/wled00/wled00.ino b/wled00/wled00.ino index a7eeb1f57..dc0fbb02b 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -118,7 +118,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2003251 +#define VERSION 2003261 char versionString[] = "0.9.1"; diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index df9bceadc..c0e23b4b5 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -387,8 +387,8 @@ void serveJson(AsyncWebServerRequest* request) void serveLiveLeds(AsyncWebServerRequest* request) { - byte used = ledCount; - byte n = (used -1) /MAX_LIVE_LEDS +1; //only serve every n'th LED if count over MAX_LIVE_LEDS + uint16_t used = ledCount; + uint16_t n = (used -1) /MAX_LIVE_LEDS +1; //only serve every n'th LED if count over MAX_LIVE_LEDS char buffer[2000] = "{\"leds\":["; olen = 9; obuf = buffer; From f2329476ec18578e9acea0f9ebe1f6e332234aaa Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Thu, 26 Mar 2020 04:12:55 -0400 Subject: [PATCH 114/509] Fix linker errors. All global vars declared extern. --- wled00/wled.cpp | 364 +++++++++++++++++++++++++++++++++ wled00/wled.h | 469 +++++++++++++++++++++---------------------- wled00/wled_colors.h | 2 +- wled00/wled_ntp.cpp | 56 ++++++ wled00/wled_ntp.h | 57 ------ 5 files changed, 652 insertions(+), 296 deletions(-) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 97ed38787..a720cb0b4 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -13,6 +13,370 @@ #include "wled_mqtt.h" #include "wled_eeprom.h" #include "wled_server.h" +// Global Variable definitions +char versionString[] = "0.9.1"; + +//AP and OTA default passwords (for maximum change them!) +char apPass[65] = DEFAULT_AP_PASS; +char otaPass[33] = DEFAULT_OTA_PASS; + +//Hardware CONFIG (only changeble HERE, not at runtime) +//LED strip pin, button pin and IR pin changeable in NpbWrapper.h! + +byte auxDefaultState = 0; //0: input 1: high 2: low +byte auxTriggeredState = 0; //0: input 1: high 2: low +char ntpServerName[33] = "0.wled.pool.ntp.org"; //NTP server to use + +//WiFi CONFIG (all these can be changed via web UI, no need to set them here) +char clientSSID[33] = CLIENT_SSID; +char clientPass[65] = CLIENT_PASS; +char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) +char apSSID[33] = ""; //AP off by default (unless setup) +byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) +byte apHide = 0; //hidden AP SSID +byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no connection after boot by default +IPAddress staticIP(0, 0, 0, 0); //static IP of ESP +IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP +IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks +bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues + +//LED CONFIG +uint16_t ledCount = 30; //overcurrent prevented by ABL +bool useRGBW = false; //SK6812 strips can contain an extra White channel +#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit +bool turnOnAtBoot = true; //turn on LEDs at power-up +byte bootPreset = 0; //save preset to load after power-up + +byte col[]{255, 160, 0, 0}; //current RGB(W) primary color. col[] should be updated if you want to change the color. +byte colSec[]{0, 0, 0, 0}; //current RGB(W) secondary color +byte briS = 128; //default brightness + +byte nightlightTargetBri = 0; //brightness after nightlight is over +byte nightlightDelayMins = 60; +bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over +bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. +bool fadeTransition = true; //enable crossfading color transition +uint16_t transitionDelay = 750; //default crossfade duration in ms + +bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) +byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) + +//User Interface CONFIG +char serverDescription[33] = "WLED"; //Name of module +bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise + +//Sync CONFIG +bool buttonEnabled = true; +byte irEnabled = 0; //Infrared receiver + +uint16_t udpPort = 21324; //WLED notifier default port +uint16_t udpRgbPort = 19446; //Hyperion port + +bool receiveNotificationBrightness = true; //apply brightness from incoming notifications +bool receiveNotificationColor = true; //apply color +bool receiveNotificationEffects = true; //apply effects setup +bool notifyDirect = false; //send notification if change via UI or HTTP API +bool notifyButton = false; //send if updated by button or infrared remote +bool notifyAlexa = false; //send notification if updated via Alexa +bool notifyMacro = false; //send notification for macro +bool notifyHue = true; //send notification if Hue light changes +bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably + +bool alexaEnabled = true; //enable device discovery by Amazon Echo +char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand + +char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made + +uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode +int arlsOffset = 0; //realtime LED offset +bool receiveDirect = true; //receive UDP realtime +bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source +bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black + +#define E131_MAX_UNIVERSE_COUNT 9 +uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) +uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) +uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +uint8_t DMXOldDimmer = 0; //only update brightness on change +uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss +bool e131Multicast = false; //multicast or unicast +bool e131SkipOutOfSequence = false; //freeze instead of flickering + +bool mqttEnabled = false; +char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) +char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices) +char mqttServer[33] = ""; //both domains and IPs should work (no SSL) +char mqttUser[41] = ""; //optional: username for MQTT auth +char mqttPass[41] = ""; //optional: password for MQTT auth +char mqttClientID[41] = ""; //override the client ID +uint16_t mqttPort = 1883; + +bool huePollingEnabled = false; //poll hue bridge for light state +uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response +char hueApiKey[47] = "api"; //key token will be obtained from bridge +byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) +IPAddress hueIP = (0, 0, 0, 0); //IP address of the bridge +bool hueApplyOnOff = true; +bool hueApplyBri = true; +bool hueApplyColor = true; + +//Time CONFIG +bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros +bool useAMPM = false; //12h/24h clock format +byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino +int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation + +byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie +byte overlayMin = 0, overlayMax = ledCount - 1; //boundaries of overlay mode + +byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be +bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel +bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position + +char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino +bool cronixieBacklight = true; //Allow digits to be back-illuminated + +bool countdownMode = false; //Clock will count down towards date +byte countdownYear = 20, countdownMonth = 1; //Countdown target date, year is last two digits +byte countdownDay = 1, countdownHour = 0; +byte countdownMin = 0, countdownSec = 0; + +byte macroBoot = 0; //macro loaded after startup +byte macroNl = 0; //after nightlight delay over +byte macroCountdown = 0; +byte macroAlexaOn = 0, macroAlexaOff = 0; +byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; + +//Security CONFIG +bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks +bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled +bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on + +uint16_t userVar0 = 0, userVar1 = 0; + +#ifdef WLED_ENABLE_DMX +//dmx CONFIG +byte DMXChannels = 7; // number of channels per fixture +byte DMXFixtureMap[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +// assigns the different channels to different functions. See wled21_dmx.ino for more information. +uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. +uint16_t DMXStart = 10; // start address of the first fixture +#endif + +//internal global variable declarations +//wifi +bool apActive = false; +bool forceReconnect = false; +uint32_t lastReconnectAttempt = 0; +bool interfacesInited = false; +bool wasConnected = false; + +//color +byte colOld[]{0, 0, 0, 0}; //color before transition +byte colT[]{0, 0, 0, 0}; //color that is currently displayed on the LEDs +byte colIT[]{0, 0, 0, 0}; //color that was last sent to LEDs +byte colSecT[]{0, 0, 0, 0}; +byte colSecOld[]{0, 0, 0, 0}; +byte colSecIT[]{0, 0, 0, 0}; + +byte lastRandomIndex = 0; //used to save last random color so the new one is not the same + +//transitions +bool transitionActive = false; +uint16_t transitionDelayDefault = transitionDelay; +uint16_t transitionDelayTemp = transitionDelay; +unsigned long transitionStartTime; +float tperLast = 0; //crossfade transition progress, 0.0f - 1.0f +bool jsonTransitionOnce = false; + +//nightlight +bool nightlightActive = false; +bool nightlightActiveOld = false; +uint32_t nightlightDelayMs = 10; +uint8_t nightlightDelayMinsDefault = nightlightDelayMins; +unsigned long nightlightStartTime; +byte briNlT = 0; //current nightlight brightness +byte colNlT[]{0, 0, 0, 0}; //current nightlight color + +//brightness +unsigned long lastOnTime = 0; +bool offMode = !turnOnAtBoot; +byte bri = briS; +byte briOld = 0; +byte briT = 0; +byte briIT = 0; +byte briLast = 128; //brightness before turned off. Used for toggle function +byte whiteLast = 128; //white channel before turned off. Used for toggle function + +//button +bool buttonPressedBefore = false; +bool buttonLongPressed = false; +unsigned long buttonPressedTime = 0; +unsigned long buttonWaitTime = 0; + +//notifications +bool notifyDirectDefault = notifyDirect; +bool receiveNotifications = true; +unsigned long notificationSentTime = 0; +byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; +bool notificationTwoRequired = false; + +//effects +byte effectCurrent = 0; +byte effectSpeed = 128; +byte effectIntensity = 128; +byte effectPalette = 0; + +//network +bool udpConnected = false, udpRgbConnected = false; + +//ui style +bool showWelcomePage = false; + +//hue +byte hueError = HUE_ERROR_INACTIVE; +//uint16_t hueFailCount = 0; +float hueXLast = 0, hueYLast = 0; +uint16_t hueHueLast = 0, hueCtLast = 0; +byte hueSatLast = 0, hueBriLast = 0; +unsigned long hueLastRequestSent = 0; +bool hueAuthRequired = false; +bool hueReceived = false; +bool hueStoreAllowed = false, hueNewKey = false; + +//overlays +byte overlayCurrent = overlayDefault; +byte overlaySpeed = 200; +unsigned long overlayRefreshMs = 200; +unsigned long overlayRefreshedTime; + +//cronixie +byte dP[]{0, 0, 0, 0, 0, 0}; +bool cronixieInit = false; + +//countdown +unsigned long countdownTime = 1514764800L; +bool countdownOverTriggered = true; + +//timer +byte lastTimerMinute = 0; +byte timerHours[] = {0, 0, 0, 0, 0, 0, 0, 0}; +byte timerMinutes[] = {0, 0, 0, 0, 0, 0, 0, 0}; +byte timerMacro[] = {0, 0, 0, 0, 0, 0, 0, 0}; +byte timerWeekday[] = {255, 255, 255, 255, 255, 255, 255, 255}; //weekdays to activate on +//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity + +//blynk +bool blynkEnabled = false; + +//preset cycling +bool presetCyclingEnabled = false; +byte presetCycleMin = 1, presetCycleMax = 5; +uint16_t presetCycleTime = 1250; +unsigned long presetCycledTime = 0; +byte presetCycCurr = presetCycleMin; +bool presetApplyBri = true; +bool saveCurrPresetCycConf = false; + +//realtime +byte realtimeMode = REALTIME_MODE_INACTIVE; +IPAddress realtimeIP = (0, 0, 0, 0); +unsigned long realtimeTimeout = 0; + +//mqtt +long lastMqttReconnectAttempt = 0; +long lastInterfaceUpdate = 0; +byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; +char mqttStatusTopic[40] = ""; //this must be global because of async handlers + +#if AUXPIN >= 0 + //auxiliary debug pin +byte auxTime = 0; +unsigned long auxStartTime = 0; +bool auxActive = false, auxActiveBefore = false; +#endif + +//alexa udp +String escapedMac; +#ifndef WLED_DISABLE_ALEXA +Espalexa espalexa; +EspalexaDevice *espalexaDevice; +#endif + +//dns server +DNSServer dnsServer; + +//network time +bool ntpConnected = false; +time_t local = 0; +unsigned long ntpLastSyncTime = 999000000L; +unsigned long ntpPacketSentTime = 999000000L; +IPAddress ntpServerIP; +uint16_t ntpLocalPort = 2390; +#define NTP_PACKET_SIZE 48 + +//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue +#define MAX_LEDS 1500 +#define MAX_LEDS_DMA 500 + +//string temp buffer (now stored in stack locally) +#define OMAX 2048 +char *obuf; +uint16_t olen = 0; + +//presets +uint16_t savedPresets = 0; +int8_t currentPreset = -1; +bool isPreset = false; + +byte errorFlag = 0; + +String messageHead, messageSub; +byte optionType; + +bool doReboot = false; //flag to initiate reboot from async handlers +bool doPublishMqtt = false; + +//server library objects +AsyncWebServer server(80); +AsyncClient *hueClient = NULL; +AsyncMqttClient *mqtt = NULL; + +//function prototypes +void colorFromUint32(uint32_t, bool = false); +void serveMessage(AsyncWebServerRequest *, uint16_t, String, String, byte); +void handleE131Packet(e131_packet_t *, IPAddress); +void arlsLock(uint32_t, byte); +void handleOverlayDraw(); + +//udp interface objects +WiFiUDP notifierUdp, rgbUdp; +WiFiUDP ntpUdp; +ESPAsyncE131 e131(handleE131Packet); +bool e131NewData = false; + +//led fx library object +WS2812FX strip = WS2812FX(); + +#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) +#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) + +//debug macros +#ifdef WLED_DEBUG +#define DEBUG_PRINT(x) Serial.print(x) +#define DEBUG_PRINTLN(x) Serial.println(x) +#define DEBUG_PRINTF(x) Serial.printf(x) +unsigned long debugTime = 0; +int lastWifiState = 3; +unsigned long wifiStateChangedTime = 0; +int loops = 0; +#else +#define DEBUG_PRINT(x) +#define DEBUG_PRINTLN(x) +#define DEBUG_PRINTF(x) +#endif + + WLED::WLED() { diff --git a/wled00/wled.h b/wled00/wled.h index c04dfa87b..043414466 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -123,305 +123,297 @@ extern "C" //version code in format yymmddb (b = daily build) #define VERSION 2003222 -char versionString[] = "0.9.1"; +extern char versionString[]; //AP and OTA default passwords (for maximum change them!) -char apPass[65] = DEFAULT_AP_PASS; -char otaPass[33] = DEFAULT_OTA_PASS; +extern char apPass[65]; +extern char otaPass[33]; //Hardware CONFIG (only changeble HERE, not at runtime) //LED strip pin, button pin and IR pin changeable in NpbWrapper.h! -byte auxDefaultState = 0; //0: input 1: high 2: low -byte auxTriggeredState = 0; //0: input 1: high 2: low -char ntpServerName[33] = "0.wled.pool.ntp.org"; //NTP server to use +extern byte auxDefaultState; //0: input 1: high 2: low +extern byte auxTriggeredState; //0: input 1: high 2: low +extern char ntpServerName[33]; //NTP server to use //WiFi CONFIG (all these can be changed via web UI, no need to set them here) -char clientSSID[33] = CLIENT_SSID; -char clientPass[65] = CLIENT_PASS; -char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) -char apSSID[33] = ""; //AP off by default (unless setup) -byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) -byte apHide = 0; //hidden AP SSID -byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no connection after boot by default -IPAddress staticIP(0, 0, 0, 0); //static IP of ESP -IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP -IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks -bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues +extern char clientSSID[33]; +extern char clientPass[65]; +extern char cmDNS[33]; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) +extern char apSSID[33]; //AP off by default (unless setup) +extern byte apChannel; //2.4GHz WiFi AP channel (1-13) +extern byte apHide; //hidden AP SSID +extern byte apBehavior; //access point opens when no connection after boot by default +extern IPAddress staticIP; //static IP of ESP +extern IPAddress staticGateway; //gateway (router) IP +extern IPAddress staticSubnet; //most common subnet in home networks +extern bool noWifiSleep; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues //LED CONFIG -uint16_t ledCount = 30; //overcurrent prevented by ABL -bool useRGBW = false; //SK6812 strips can contain an extra White channel +extern uint16_t ledCount; //overcurrent prevented by ABL +extern bool useRGBW; //SK6812 strips can contain an extra White channel #define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit -bool turnOnAtBoot = true; //turn on LEDs at power-up -byte bootPreset = 0; //save preset to load after power-up +extern bool turnOnAtBoot; //turn on LEDs at power-up +extern byte bootPreset; //save preset to load after power-up -byte col[]{255, 160, 0, 0}; //current RGB(W) primary color. col[] should be updated if you want to change the color. -byte colSec[]{0, 0, 0, 0}; //current RGB(W) secondary color -byte briS = 128; //default brightness +extern byte col[]; //current RGB(W) primary color. col[] should be updated if you want to change the color. +extern byte colSec[]; //current RGB(W) secondary color +extern byte briS; //default brightness -byte nightlightTargetBri = 0; //brightness after nightlight is over -byte nightlightDelayMins = 60; -bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over -bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. -bool fadeTransition = true; //enable crossfading color transition -uint16_t transitionDelay = 750; //default crossfade duration in ms +extern byte nightlightTargetBri; //brightness after nightlight is over +extern byte nightlightDelayMins; +extern bool nightlightFade; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over +extern bool nightlightColorFade; //if enabled, light will gradually fade color from primary to secondary color. +extern bool fadeTransition; //enable crossfading color transition +extern uint16_t transitionDelay; //default crossfade duration in ms -bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) -byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) +extern bool skipFirstLed; //ignore first LED in strip (useful if you need the LED as signal repeater) +extern byte briMultiplier; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) //User Interface CONFIG -char serverDescription[33] = "WLED"; //Name of module -bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise +extern char serverDescription[33]; //Name of module +extern bool syncToggleReceive; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise //Sync CONFIG -bool buttonEnabled = true; -byte irEnabled = 0; //Infrared receiver +extern bool buttonEnabled; +extern byte irEnabled; //Infrared receiver -uint16_t udpPort = 21324; //WLED notifier default port -uint16_t udpRgbPort = 19446; //Hyperion port +extern uint16_t udpPort; //WLED notifier default port +extern uint16_t udpRgbPort; //Hyperion port -bool receiveNotificationBrightness = true; //apply brightness from incoming notifications -bool receiveNotificationColor = true; //apply color -bool receiveNotificationEffects = true; //apply effects setup -bool notifyDirect = false; //send notification if change via UI or HTTP API -bool notifyButton = false; //send if updated by button or infrared remote -bool notifyAlexa = false; //send notification if updated via Alexa -bool notifyMacro = false; //send notification for macro -bool notifyHue = true; //send notification if Hue light changes -bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably +extern bool receiveNotificationBrightness; //apply brightness from incoming notifications +extern bool receiveNotificationColor; //apply color +extern bool receiveNotificationEffects; //apply effects setup +extern bool notifyDirect; //send notification if change via UI or HTTP API +extern bool notifyButton; //send if updated by button or infrared remote +extern bool notifyAlexa; //send notification if updated via Alexa +extern bool notifyMacro; //send notification for macro +extern bool notifyHue; //send notification if Hue light changes +extern bool notifyTwice; //notifications use UDP: enable if devices don't sync reliably -bool alexaEnabled = true; //enable device discovery by Amazon Echo -char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand +extern bool alexaEnabled; //enable device discovery by Amazon Echo +extern char alexaInvocationName[33]; //speech control name of device. Choose something voice-to-text can understand -char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made +extern char blynkApiKey[36]; //Auth token for Blynk server. If empty, no connection will be made -uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode -int arlsOffset = 0; //realtime LED offset -bool receiveDirect = true; //receive UDP realtime -bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source -bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black +extern uint16_t realtimeTimeoutMs; //ms timeout of realtime mode before returning to normal mode +extern int arlsOffset; //realtime LED offset +extern bool receiveDirect; //receive UDP realtime +extern bool arlsDisableGammaCorrection; //activate if gamma correction is handled by the source +extern bool arlsForceMaxBri; //enable to force max brightness if source has very dark colors that would be black #define E131_MAX_UNIVERSE_COUNT 9 -uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) -uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] -uint8_t DMXOldDimmer = 0; //only update brightness on change -uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss -bool e131Multicast = false; //multicast or unicast -bool e131SkipOutOfSequence = false; //freeze instead of flickering +extern uint16_t e131Universe; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) +extern uint8_t DMXMode; //DMX mode (s.a.) +extern uint16_t DMXAddress; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +extern uint8_t DMXOldDimmer; //only update brightness on change +extern uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss +extern bool e131Multicast; //multicast or unicast +extern bool e131SkipOutOfSequence; //freeze instead of flickering -bool mqttEnabled = false; -char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) -char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices) -char mqttServer[33] = ""; //both domains and IPs should work (no SSL) -char mqttUser[41] = ""; //optional: username for MQTT auth -char mqttPass[41] = ""; //optional: password for MQTT auth -char mqttClientID[41] = ""; //override the client ID -uint16_t mqttPort = 1883; +extern bool mqttEnabled; +extern char mqttDeviceTopic[33]; //main MQTT topic (individual per device, default is wled/mac) +extern char mqttGroupTopic[33]; //second MQTT topic (for example to group devices) +extern char mqttServer[33]; //both domains and IPs should work (no SSL) +extern char mqttUser[41]; //optional: username for MQTT auth +extern char mqttPass[41]; //optional: password for MQTT auth +extern char mqttClientID[41]; //override the client ID +extern uint16_t mqttPort; -bool huePollingEnabled = false; //poll hue bridge for light state -uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response -char hueApiKey[47] = "api"; //key token will be obtained from bridge -byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) -IPAddress hueIP = (0, 0, 0, 0); //IP address of the bridge -bool hueApplyOnOff = true; -bool hueApplyBri = true; -bool hueApplyColor = true; +extern bool huePollingEnabled; //poll hue bridge for light state +extern uint16_t huePollIntervalMs; //low values (< 1sec) may cause lag but offer quicker response +extern char hueApiKey[47]; //key token will be obtained from bridge +extern byte huePollLightId; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) +extern IPAddress hueIP; //IP address of the bridge +extern bool hueApplyOnOff; +extern bool hueApplyBri; +extern bool hueApplyColor; //Time CONFIG -bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros -bool useAMPM = false; //12h/24h clock format -byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino -int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation +extern bool ntpEnabled; //get internet time. Only required if you use clock overlays or time-activated macros +extern bool useAMPM; //12h/24h clock format +extern byte currentTimezone; //Timezone ID. Refer to timezones array in wled_ntp.cpp +extern int utcOffsetSecs; //Seconds to offset from UTC before timzone calculation -byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie -byte overlayMin = 0, overlayMax = ledCount - 1; //boundaries of overlay mode +extern byte overlayDefault; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie +extern byte overlayMin; //boundaries of overlay mode +extern byte overlayMax; -byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be -bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel -bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position +extern byte analogClock12pixel; //The pixel in your strip where "midnight" would be +extern bool analogClockSecondsTrail; //Display seconds as trail of LEDs instead of a single pixel +extern bool analogClock5MinuteMarks; //Light pixels at every 5-minute position -char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino -bool cronixieBacklight = true; //Allow digits to be back-illuminated +extern char cronixieDisplay[7]; //Cronixie Display mask. See wled13_cronixie.ino +extern bool cronixieBacklight; //Allow digits to be back-illuminated -bool countdownMode = false; //Clock will count down towards date -byte countdownYear = 20, countdownMonth = 1; //Countdown target date, year is last two digits -byte countdownDay = 1, countdownHour = 0; -byte countdownMin = 0, countdownSec = 0; +extern bool countdownMode; //Clock will count down towards date +extern byte countdownYear, countdownMonth; //Countdown target date, year is last two digits +extern byte countdownDay, countdownHour; +extern byte countdownMin, countdownSec; -byte macroBoot = 0; //macro loaded after startup -byte macroNl = 0; //after nightlight delay over -byte macroCountdown = 0; -byte macroAlexaOn = 0, macroAlexaOff = 0; -byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; +extern byte macroBoot; //macro loaded after startup +extern byte macroNl; //after nightlight delay over +extern byte macroCountdown; +extern byte macroAlexaOn, macroAlexaOff; +extern byte macroButton, macroLongPress, macroDoublePress; //Security CONFIG -bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks -bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled -bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on +extern bool otaLock; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks +extern bool wifiLock; //prevents access to WiFi settings when OTA lock is enabled +extern bool aOtaEnabled; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on -uint16_t userVar0 = 0, userVar1 = 0; +extern uint16_t userVar0, userVar1; #ifdef WLED_ENABLE_DMX //dmx CONFIG -byte DMXChannels = 7; // number of channels per fixture -byte DMXFixtureMap[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -// assigns the different channels to different functions. See wled21_dmx.ino for more information. -uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. -uint16_t DMXStart = 10; // start address of the first fixture +extern byte DMXChannels; // number of channels per fixture +extern byte DMXFixtureMap[15]; +extern // assigns the different channels to different functions. See wled21_dmx.ino for more information. +extern uint16_t DMXGap; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. +extern uint16_t DMXStart; // start address of the first fixture #endif //internal global variable declarations //wifi -bool apActive = false; -bool forceReconnect = false; -uint32_t lastReconnectAttempt = 0; -bool interfacesInited = false; -bool wasConnected = false; +extern bool apActive; +extern bool forceReconnect; +extern uint32_t lastReconnectAttempt; +extern bool interfacesInited; +extern bool wasConnected; //color -byte colOld[]{0, 0, 0, 0}; //color before transition -byte colT[]{0, 0, 0, 0}; //color that is currently displayed on the LEDs -byte colIT[]{0, 0, 0, 0}; //color that was last sent to LEDs -byte colSecT[]{0, 0, 0, 0}; -byte colSecOld[]{0, 0, 0, 0}; -byte colSecIT[]{0, 0, 0, 0}; +extern byte colOld[]; //color before transition +extern byte colT[]; //color that is currently displayed on the LEDs +extern byte colIT[]; //color that was last sent to LEDs +extern byte colSecT[]; +extern byte colSecOld[]; +extern byte colSecIT[]; -byte lastRandomIndex = 0; //used to save last random color so the new one is not the same +extern byte lastRandomIndex; //used to save last random color so the new one is not the same //transitions -bool transitionActive = false; -uint16_t transitionDelayDefault = transitionDelay; -uint16_t transitionDelayTemp = transitionDelay; -unsigned long transitionStartTime; -float tperLast = 0; //crossfade transition progress, 0.0f - 1.0f -bool jsonTransitionOnce = false; +extern bool transitionActive; +extern uint16_t transitionDelayDefault; +extern uint16_t transitionDelayTemp; +extern unsigned long transitionStartTime; +extern float tperLast; //crossfade transition progress, 0.0f - 1.0f +extern bool jsonTransitionOnce; //nightlight -bool nightlightActive = false; -bool nightlightActiveOld = false; -uint32_t nightlightDelayMs = 10; -uint8_t nightlightDelayMinsDefault = nightlightDelayMins; -unsigned long nightlightStartTime; -byte briNlT = 0; //current nightlight brightness -byte colNlT[]{0, 0, 0, 0}; //current nightlight color +extern bool nightlightActive; +extern bool nightlightActiveOld; +extern uint32_t nightlightDelayMs; +extern uint8_t nightlightDelayMinsDefault; +extern unsigned long nightlightStartTime; +extern byte briNlT; //current nightlight brightness +extern byte colNlT[]; //current nightlight color -//brightness -unsigned long lastOnTime = 0; -bool offMode = !turnOnAtBoot; -byte bri = briS; -byte briOld = 0; -byte briT = 0; -byte briIT = 0; -byte briLast = 128; //brightness before turned off. Used for toggle function -byte whiteLast = 128; //white channel before turned off. Used for toggle function +extern unsigned long lastOnTime; +extern bool offMode; +extern byte bri; +extern byte briOld; +extern byte briT; +extern byte briIT; +extern byte briLast; //brightness before turned off. Used for toggle function +extern byte whiteLast; //white channel before turned off. Used for toggle function -//button -bool buttonPressedBefore = false; -bool buttonLongPressed = false; -unsigned long buttonPressedTime = 0; -unsigned long buttonWaitTime = 0; +extern bool buttonPressedBefore; +extern bool buttonLongPressed; +extern unsigned long buttonPressedTime; +extern unsigned long buttonWaitTime; -//notifications -bool notifyDirectDefault = notifyDirect; -bool receiveNotifications = true; -unsigned long notificationSentTime = 0; -byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; -bool notificationTwoRequired = false; +extern bool notifyDirectDefault; +extern bool receiveNotifications; +extern unsigned long notificationSentTime; +extern byte notificationSentCallMode; +extern bool notificationTwoRequired; -//effects -byte effectCurrent = 0; -byte effectSpeed = 128; -byte effectIntensity = 128; -byte effectPalette = 0; +extern byte effectCurrent; +extern byte effectSpeed; +extern byte effectIntensity; +extern byte effectPalette; -//network -bool udpConnected = false, udpRgbConnected = false; +extern bool udpConnected, udpRgbConnected; -//ui style -bool showWelcomePage = false; +extern bool showWelcomePage; -//hue -byte hueError = HUE_ERROR_INACTIVE; -//uint16_t hueFailCount = 0; -float hueXLast = 0, hueYLast = 0; -uint16_t hueHueLast = 0, hueCtLast = 0; -byte hueSatLast = 0, hueBriLast = 0; -unsigned long hueLastRequestSent = 0; -bool hueAuthRequired = false; -bool hueReceived = false; -bool hueStoreAllowed = false, hueNewKey = false; +extern byte hueError; +//uint16_t hueFailCount; +extern float hueXLast, hueYLast; +extern uint16_t hueHueLast, hueCtLast; +extern byte hueSatLast, hueBriLast; +extern unsigned long hueLastRequestSent; +extern bool hueAuthRequired; +extern bool hueReceived; +extern bool hueStoreAllowed, hueNewKey; -//overlays -byte overlayCurrent = overlayDefault; -byte overlaySpeed = 200; -unsigned long overlayRefreshMs = 200; -unsigned long overlayRefreshedTime; +extern byte overlayCurrent; +extern byte overlaySpeed; +extern unsigned long overlayRefreshMs; +extern unsigned long overlayRefreshedTime; -//cronixie -byte dP[]{0, 0, 0, 0, 0, 0}; -bool cronixieInit = false; +extern byte dP[]; +extern bool cronixieInit; //countdown -unsigned long countdownTime = 1514764800L; -bool countdownOverTriggered = true; +extern unsigned long countdownTime; +extern bool countdownOverTriggered; //timer -byte lastTimerMinute = 0; -byte timerHours[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMinutes[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMacro[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerWeekday[] = {255, 255, 255, 255, 255, 255, 255, 255}; //weekdays to activate on +extern byte lastTimerMinute; +extern byte timerHours[]; +extern byte timerMinutes[]; +extern byte timerMacro[]; +extern byte timerWeekday[]; //weekdays to activate on //bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity //blynk -bool blynkEnabled = false; +extern bool blynkEnabled; //preset cycling -bool presetCyclingEnabled = false; -byte presetCycleMin = 1, presetCycleMax = 5; -uint16_t presetCycleTime = 1250; -unsigned long presetCycledTime = 0; -byte presetCycCurr = presetCycleMin; -bool presetApplyBri = true; -bool saveCurrPresetCycConf = false; +extern bool presetCyclingEnabled; +extern byte presetCycleMin, presetCycleMax; +extern uint16_t presetCycleTime; +extern unsigned long presetCycledTime; +extern byte presetCycCurr; +extern bool presetApplyBri; +extern bool saveCurrPresetCycConf; //realtime -byte realtimeMode = REALTIME_MODE_INACTIVE; -IPAddress realtimeIP = (0, 0, 0, 0); -unsigned long realtimeTimeout = 0; +extern byte realtimeMode; +extern IPAddress realtimeIP; +extern unsigned long realtimeTimeout; //mqtt -long lastMqttReconnectAttempt = 0; -long lastInterfaceUpdate = 0; -byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; -char mqttStatusTopic[40] = ""; //this must be global because of async handlers +extern long lastMqttReconnectAttempt; +extern long lastInterfaceUpdate; +extern byte interfaceUpdateCallMode; +extern char mqttStatusTopic[40]; //this must be global because of async handlers #if AUXPIN >= 0 - //auxiliary debug pin -byte auxTime = 0; -unsigned long auxStartTime = 0; -bool auxActive = false, auxActiveBefore = false; +//auxiliary debug pin +extern byte auxTime; +extern unsigned long auxStartTime; +extern bool auxActive; #endif //alexa udp -String escapedMac; +extern String escapedMac; #ifndef WLED_DISABLE_ALEXA -Espalexa espalexa; -EspalexaDevice *espalexaDevice; +extern Espalexa espalexa; +extern EspalexaDevice *espalexaDevice; #endif //dns server -DNSServer dnsServer; +extern DNSServer dnsServer; //network time -bool ntpConnected = false; -time_t local = 0; -unsigned long ntpLastSyncTime = 999000000L; -unsigned long ntpPacketSentTime = 999000000L; -IPAddress ntpServerIP; -uint16_t ntpLocalPort = 2390; +extern bool ntpConnected; +extern time_t local; +extern unsigned long ntpLastSyncTime; +extern unsigned long ntpPacketSentTime; +extern IPAddress ntpServerIP; +extern uint16_t ntpLocalPort; #define NTP_PACKET_SIZE 48 //maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue @@ -430,42 +422,43 @@ uint16_t ntpLocalPort = 2390; //string temp buffer (now stored in stack locally) #define OMAX 2048 -char *obuf; -uint16_t olen = 0; +extern char *obuf; +extern uint16_t olen; //presets -uint16_t savedPresets = 0; -int8_t currentPreset = -1; -bool isPreset = false; +extern uint16_t savedPresets; +extern int8_t currentPreset; +extern bool isPreset; -byte errorFlag = 0; +extern byte errorFlag; -String messageHead, messageSub; -byte optionType; +extern String messageHead, messageSub; +extern byte optionType; -bool doReboot = false; //flag to initiate reboot from async handlers -bool doPublishMqtt = false; +extern bool doReboot; //flag to initiate reboot from async handlers +extern bool doPublishMqtt; //server library objects -AsyncWebServer server(80); -AsyncClient *hueClient = NULL; -AsyncMqttClient *mqtt = NULL; +extern AsyncWebServer server; +extern AsyncClient *hueClient; +extern AsyncMqttClient *mqtt; //function prototypes -void colorFromUint32(uint32_t, bool = false); -void serveMessage(AsyncWebServerRequest *, uint16_t, String, String, byte); -void handleE131Packet(e131_packet_t *, IPAddress); -void arlsLock(uint32_t, byte); -void handleOverlayDraw(); +extern void colorFromUint32(uint32_t, bool); +extern void serveMessage(AsyncWebServerRequest *, uint16_t, String, String, byte); +extern void handleE131Packet(e131_packet_t *, IPAddress); +extern void arlsLock(uint32_t, byte); +extern void handleOverlayDraw(); //udp interface objects -WiFiUDP notifierUdp, rgbUdp; -WiFiUDP ntpUdp; -ESPAsyncE131 e131(handleE131Packet); -bool e131NewData = false; +extern WiFiUDP notifierUdp, rgbUdp; +extern WiFiUDP ntpUdp; +extern ESPAsyncE131 e131; +extern bool e131NewData; //led fx library object -WS2812FX strip = WS2812FX(); +extern WS2812FX strip; + #define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) #define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) diff --git a/wled00/wled_colors.h b/wled00/wled_colors.h index 2b3ff32c5..917311e78 100644 --- a/wled00/wled_colors.h +++ b/wled00/wled_colors.h @@ -5,7 +5,7 @@ * Color conversion methods */ -void colorFromUint32(uint32_t in, bool secondary); +void colorFromUint32(uint32_t in, bool secondary = false); void colorFromUint24(uint32_t in, bool secondary = false); void relativeChangeWhite(int8_t amount, byte lowerBoundary = 0); void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb diff --git a/wled00/wled_ntp.cpp b/wled00/wled_ntp.cpp index 82b99f963..d8d9c38a2 100644 --- a/wled00/wled_ntp.cpp +++ b/wled00/wled_ntp.cpp @@ -1,7 +1,63 @@ #include "wled_ntp.h" #include "wled.h" #include "wled_eeprom.h" +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); + +Timezone tzCASaskatchewan(CST, CST); //Central without DST + +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); + +TimeChangeRule NKST = {Last, Sun, Mar, 1, 510}; //Pyongyang Time = UTC + 8.5 hours +Timezone tzNK(NKST, NKST); + +TimeChangeRule IST = {Last, Sun, Mar, 1, 330}; // India Standard Time = UTC + 5.5 hours +Timezone tzIndia(IST, IST); + +// Pick your timezone from here. +Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia, &tzCASaskatchewan}; void handleNetworkTime() { diff --git a/wled00/wled_ntp.h b/wled00/wled_ntp.h index 142933421..be683d143 100644 --- a/wled00/wled_ntp.h +++ b/wled00/wled_ntp.h @@ -2,66 +2,9 @@ #define WLED_NTP_H #include #include "timezone/Timezone.h" - /* * 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); - -Timezone tzCASaskatchewan(CST, CST); //Central without DST - -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); - -TimeChangeRule NKST = {Last, Sun, Mar, 1, 510}; //Pyongyang Time = UTC + 8.5 hours -Timezone tzNK(NKST, NKST); - -TimeChangeRule IST = {Last, Sun, Mar, 1, 330}; // India Standard Time = UTC + 5.5 hours -Timezone tzIndia(IST, IST); - -Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia, &tzCASaskatchewan}; void handleNetworkTime(); void sendNTPPacket(); From c6ea2dff8a87dd4f3fedfa754218f23a1bd13016 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Thu, 26 Mar 2020 04:49:35 -0400 Subject: [PATCH 115/509] Add further includes. --- wled00/wled.cpp | 1 + wled00/wled_blynk.cpp | 3 +++ wled00/wled_ir.cpp | 5 ++++- wled00/wled_ir.h | 15 +++++++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index a720cb0b4..3b3d6936d 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -1,4 +1,5 @@ #include "wled.h" +#include #include "wled_led.h" #include "wled_ir.h" #include "wled_notify.h" diff --git a/wled00/wled_blynk.cpp b/wled00/wled_blynk.cpp index c6754a231..2e3d9f7bb 100644 --- a/wled00/wled_blynk.cpp +++ b/wled00/wled_blynk.cpp @@ -1,6 +1,9 @@ #include "wled_blynk.h" +#include "const.h" #include "wled.h" #include "src/dependencies/blynk/Blynk/BlynkHandlers.h" +#include "wled_led.h" +#include "wled_colors.h" uint16_t blHue = 0; byte blSat = 255; diff --git a/wled00/wled_ir.cpp b/wled00/wled_ir.cpp index 53f0d23f9..f625148eb 100644 --- a/wled00/wled_ir.cpp +++ b/wled00/wled_ir.cpp @@ -1,5 +1,8 @@ #include "wled_ir.h" #include "wled.h" +#include "wled_led.h" +#include "wled_colors.h" +#include "wled_eeprom.h" #if defined(WLED_DISABLE_INFRARED) void handleIR(){} @@ -34,7 +37,7 @@ bool decodeIRCustom(uint32_t code) //relatively change brightness, minumum A=5 -void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF) +void relativeChange(byte* property, int8_t amount, byte lowerBoundary, byte higherBoundary) { int16_t new_val = (int16_t) *property + amount; if (new_val > higherBoundary) new_val = higherBoundary; diff --git a/wled00/wled_ir.h b/wled00/wled_ir.h index 3479f410b..3f819da01 100644 --- a/wled00/wled_ir.h +++ b/wled00/wled_ir.h @@ -1,9 +1,24 @@ #ifndef WLED_IR_H #define WLED_IR_H +#include /* * Infrared sensor support for generic 24/40/44 key RGB remotes */ +bool decodeIRCustom(uint32_t code); +void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF); +void changeEffectSpeed(int8_t amount); +void changeEffectIntensity(int8_t amount); +void decodeIR(uint32_t code); +void decodeIR24(uint32_t code); +void decodeIR24OLD(uint32_t code); +void decodeIR24CT(uint32_t code); +void decodeIR40(uint32_t code); +void decodeIR44(uint32_t code); +void decodeIR21(uint32_t code); +void decodeIR6(uint32_t code); + +void initIR(); void handleIR(); #endif //WLED_IR_H \ No newline at end of file From 7bf1c35dcfac940c9b048c67537a2d7fb5b35f83 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Thu, 26 Mar 2020 04:56:19 -0400 Subject: [PATCH 116/509] Change interface of BlynkSimpleEsp. --- wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp | 5 +++++ wled00/src/dependencies/blynk/BlynkSimpleEsp.h | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp diff --git a/wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp b/wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp new file mode 100644 index 000000000..a15d2c1bb --- /dev/null +++ b/wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp @@ -0,0 +1,5 @@ +#include "BlynkSimpleEsp.h" + +WiFiClient _blynkWifiClient; +BlynkArduinoClient _blynkTransport(_blynkWifiClient); +BlynkWifi Blynk(_blynkTransport); \ No newline at end of file diff --git a/wled00/src/dependencies/blynk/BlynkSimpleEsp.h b/wled00/src/dependencies/blynk/BlynkSimpleEsp.h index f6b2a0f1c..6697686fa 100644 --- a/wled00/src/dependencies/blynk/BlynkSimpleEsp.h +++ b/wled00/src/dependencies/blynk/BlynkSimpleEsp.h @@ -89,8 +89,6 @@ public: }; -static WiFiClient _blynkWifiClient; -static BlynkArduinoClient _blynkTransport(_blynkWifiClient); -BlynkWifi Blynk(_blynkTransport); +extern BlynkWifi Blynk; #endif From 30e3bbd0e8e226bc707c9e0e4b0777dcd87b0727 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Thu, 26 Mar 2020 05:18:19 -0400 Subject: [PATCH 117/509] Renamed min/max macros to fix potential std::min/max conflict (depending on include order). --- wled00/FX.cpp | 66 +++++++++++++++++++++++------------------------ wled00/FX.h | 4 +-- wled00/FX_fcn.cpp | 10 +++---- wled00/wled.h | 8 +++--- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 022b4b232..a57e9ddac 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -268,7 +268,7 @@ uint16_t WS2812FX::mode_breath(void) { counter = (counter >> 2) + (counter >> 4); //0-16384 + 0-2048 if (counter < 16384) { if (counter > 8192) counter = 8192 - (counter - 8192); - var = sin16(counter) / 103; //close to parabolic in range 0-8192, max val. 23170 + var = sin16(counter) / 103; //close to parabolic in range 0-8192, MAX val. 23170 } uint8_t lum = 30 + var; @@ -475,8 +475,8 @@ uint16_t WS2812FX::mode_twinkle(void) { uint32_t it = now / cycleTime; if (it != SEGENV.step) { - uint16_t maxOn = map(SEGMENT.intensity, 0, 255, 1, SEGLEN); // make sure at least one LED is on - if (SEGENV.aux0 >= maxOn) + uint16_t MAXOn = map(SEGMENT.intensity, 0, 255, 1, SEGLEN); // make sure at least one LED is on + if (SEGENV.aux0 >= MAXOn) { SEGENV.aux0 = 0; SEGENV.aux1 = random16(); //new seed for our PRNG @@ -601,7 +601,7 @@ uint16_t WS2812FX::mode_hyper_sparkle(void) { } if(random8(5) < 2) { - for(uint16_t i = 0; i < max(1, SEGLEN/3); i++) { + for(uint16_t i = 0; i < MAX(1, SEGLEN/3); i++) { setPixelColor(random16(SEGLEN), SEGCOLOR(1)); } return 20; @@ -1115,7 +1115,7 @@ uint16_t WS2812FX::mode_fireworks() { if (valid1) setPixelColor(SEGENV.aux0 , sv1); if (valid2) setPixelColor(SEGENV.aux1, sv2); - for(uint16_t i=0; i> 1)) == 0) { uint16_t index = random(SEGLEN); setPixelColor(index, color_from_palette(random8(), false, false, 0)); @@ -1162,12 +1162,12 @@ uint16_t WS2812FX::mode_fire_flicker(void) { byte r = (SEGCOLOR(0) >> 16) & 0xFF; byte g = (SEGCOLOR(0) >> 8) & 0xFF; byte b = (SEGCOLOR(0) & 0xFF); - byte lum = (SEGMENT.palette == 0) ? max(w, max(r, max(g, b))) : 255; + byte lum = (SEGMENT.palette == 0) ? MAX(w, MAX(r, MAX(g, b))) : 255; lum /= (((256-SEGMENT.intensity)/16)+1); for(uint16_t i = 0; i < SEGLEN; i++) { byte flicker = random8(lum); if (SEGMENT.palette == 0) { - setPixelColor(i, max(r - flicker, 0), max(g - flicker, 0), max(b - flicker, 0), max(w - flicker, 0)); + setPixelColor(i, MAX(r - flicker, 0), MAX(g - flicker, 0), MAX(b - flicker, 0), MAX(w - flicker, 0)); } else { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, 255 - flicker)); } @@ -1197,7 +1197,7 @@ uint16_t WS2812FX::gradient_base(bool loading) { { val = abs(((i>pp) ? p2:pp) -i); } else { - val = min(abs(pp-i),min(abs(p1-i),abs(p2-i))); + val = MIN(abs(pp-i),MIN(abs(p1-i),abs(p2-i))); } val = (brd > val) ? val/brd * 255 : 255; setPixelColor(i, color_blend(SEGCOLOR(0), color_from_palette(i, true, PALETTE_SOLID_WRAP, 1), val)); @@ -1597,8 +1597,8 @@ uint16_t WS2812FX::mode_oscillate(void) uint16_t WS2812FX::mode_lightning(void) { - uint16_t ledstart = random16(SEGLEN); // Determine starting location of flash - uint16_t ledlen = random16(SEGLEN -1 -ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1) + uint16_t ledstart = random16(SEGLEN); // DeterMINe starting location of flash + uint16_t ledlen = random16(SEGLEN -1 -ledstart); // DeterMINe length of flash (not to go beyond NUM_LEDS-1) uint8_t bri = 255/random8(1, 3); if (SEGENV.step == 0) @@ -1778,7 +1778,7 @@ uint16_t WS2812FX::mode_fire_2012() // Step 4. Map from heat cells to LED colors for (uint16_t j = 0; j < SEGLEN; j++) { - CRGB color = ColorFromPalette(currentPalette, min(heat[j],240), 255, LINEARBLEND); + CRGB color = ColorFromPalette(currentPalette, MIN(heat[j],240), 255, LINEARBLEND); setPixelColor(j, color.red, color.green, color.blue); } return FRAMETIME; @@ -2153,9 +2153,9 @@ typedef struct Ripple { uint16_t WS2812FX::ripple_base(bool rainbow) { - uint16_t maxRipples = 1 + (SEGLEN >> 2); - if (maxRipples > 100) maxRipples = 100; - uint16_t dataSize = sizeof(ripple) * maxRipples; + uint16_t MAXRipples = 1 + (SEGLEN >> 2); + if (MAXRipples > 100) MAXRipples = 100; + uint16_t dataSize = sizeof(ripple) * MAXRipples; if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -2181,7 +2181,7 @@ uint16_t WS2812FX::ripple_base(bool rainbow) } //draw wave - for (uint16_t i = 0; i < maxRipples; i++) + for (uint16_t i = 0; i < MAXRipples; i++) { uint16_t ripplestate = ripples[i].state; if (ripplestate) @@ -2480,8 +2480,8 @@ uint16_t WS2812FX::spots_base(uint16_t threshold) { fill(SEGCOLOR(1)); - uint16_t maxZones = SEGLEN >> 2; - uint16_t zones = 1 + ((SEGMENT.intensity * maxZones) >> 8); + uint16_t MAXZones = SEGLEN >> 2; + uint16_t zones = 1 + ((SEGMENT.intensity * MAXZones) >> 8); uint16_t zoneLen = SEGLEN / zones; uint16_t offset = (SEGLEN - zones * zoneLen) >> 1; @@ -2533,15 +2533,15 @@ typedef struct Ball { */ uint16_t WS2812FX::mode_bouncing_balls(void) { //allocate segment data - uint16_t maxNumBalls = 16; - uint16_t dataSize = sizeof(ball) * maxNumBalls; + uint16_t MAXNumBalls = 16; + uint16_t dataSize = sizeof(ball) * MAXNumBalls; if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed Ball* balls = reinterpret_cast(SEGENV.data); - // number of balls based on intensity setting to max of 7 (cycles colors) + // number of balls based on intensity setting to MAX of 7 (cycles colors) // non-chosen color is a random color - uint8_t numBalls = int(((SEGMENT.intensity * (maxNumBalls - 0.8f)) / 255) + 1); + uint8_t numBalls = int(((SEGMENT.intensity * (MAXNumBalls - 0.8f)) / 255) + 1); float gravity = -9.81; // standard value of gravity float impactVelocityStart = sqrt( -2 * gravity); @@ -2549,7 +2549,7 @@ uint16_t WS2812FX::mode_bouncing_balls(void) { unsigned long time = millis(); if (SEGENV.call == 0) { - for (uint8_t i = 0; i < maxNumBalls; i++) balls[i].lastBounceTime = time; + for (uint8_t i = 0; i < MAXNumBalls; i++) balls[i].lastBounceTime = time; } bool hasCol2 = SEGCOLOR(2); @@ -2573,7 +2573,7 @@ uint16_t WS2812FX::mode_bouncing_balls(void) { uint32_t color = SEGCOLOR(0); if (SEGMENT.palette) { - color = color_wheel(i*(256/max(numBalls, 8))); + color = color_wheel(i*(256/MAX(numBalls, 8))); } else if (hasCol2) { color = SEGCOLOR(i % NUM_COLORS); } @@ -2665,8 +2665,8 @@ typedef struct Spark { */ uint16_t WS2812FX::mode_popcorn(void) { //allocate segment data - uint16_t maxNumPopcorn = 24; - uint16_t dataSize = sizeof(spark) * maxNumPopcorn; + uint16_t MAXNumPopcorn = 24; + uint16_t dataSize = sizeof(spark) * MAXNumPopcorn; if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed Spark* popcorn = reinterpret_cast(SEGENV.data); @@ -2677,7 +2677,7 @@ uint16_t WS2812FX::mode_popcorn(void) { bool hasCol2 = SEGCOLOR(2); fill(hasCol2 ? BLACK : SEGCOLOR(1)); - uint8_t numPopcorn = SEGMENT.intensity*maxNumPopcorn/255; + uint8_t numPopcorn = SEGMENT.intensity*MAXNumPopcorn/255; if (numPopcorn == 0) numPopcorn = 1; for(uint8_t i = 0; i < numPopcorn; i++) { @@ -2792,13 +2792,13 @@ uint16_t WS2812FX::mode_starburst(void) { star* stars = reinterpret_cast(SEGENV.data); - float maxSpeed = 375.0f; // Max velocity + float MAXSpeed = 375.0f; // Max velocity float particleIgnition = 250.0f; // How long to "flash" float particleFadeTime = 1500.0f; // Fade out time for (int j = 0; j < numStars; j++) { - // speed to adjust chance of a burst, max is nearly always. + // speed to adjust chance of a burst, MAX is nearly always. if (random8((144-(SEGMENT.speed >> 1))) == 0 && stars[j].birth == 0) { // Pick a random color and location. @@ -2807,7 +2807,7 @@ uint16_t WS2812FX::mode_starburst(void) { stars[j].color = col_to_crgb(color_wheel(random8())); stars[j].pos = startPos; - stars[j].vel = maxSpeed * (float)(random8())/255.0 * multiplier; + stars[j].vel = MAXSpeed * (float)(random8())/255.0 * multiplier; stars[j].birth = it; stars[j].last = it; // more fragments means larger burst effect @@ -3026,7 +3026,7 @@ uint16_t WS2812FX::mode_drip(void) drops[j].pos = SEGLEN-1; // start at end drops[j].vel = 0; // speed drops[j].col = sourcedrop; // brightness - drops[j].colIndex = 1; // drop state (0 init, 1 forming, 2 falling, 5 bouncing) + drops[j].colIndex = 1; // drop state (0 init, 1 forMINg, 2 falling, 5 bouncing) } setPixelColor(SEGLEN-1,color_blend(BLACK,SEGCOLOR(0), sourcedrop));// water source @@ -3047,7 +3047,7 @@ uint16_t WS2812FX::mode_drip(void) if (drops[j].pos < 0) drops[j].pos = 0; drops[j].vel += gravity; - for (int i=1;i<7-drops[j].colIndex;i++) { // some minor math so we don't expand bouncing droplets + for (int i=1;i<7-drops[j].colIndex;i++) { // some MINor math so we don't expand bouncing droplets setPixelColor(int(drops[j].pos)+i,color_blend(BLACK,SEGCOLOR(0),drops[j].col/i)); //spread pixel with fade while falling } @@ -3055,7 +3055,7 @@ uint16_t WS2812FX::mode_drip(void) setPixelColor(0,color_blend(SEGCOLOR(0),BLACK,drops[j].col)); } } else { // we hit bottom - if (drops[j].colIndex > 2) { // already hit once, so back to forming + if (drops[j].colIndex > 2) { // already hit once, so back to forMINg drops[j].colIndex = 0; drops[j].col = sourcedrop; @@ -3100,7 +3100,7 @@ uint16_t WS2812FX::mode_plasma(void) { */ uint16_t WS2812FX::mode_percent(void) { - uint8_t percent = max(0, min(200, SEGMENT.intensity)); + uint8_t percent = MAX(0, MIN(200, SEGMENT.intensity)); uint16_t active_leds = (percent < 100) ? SEGLEN * percent / 100.0 : SEGLEN * (200 - percent) / 100.0; diff --git a/wled00/FX.h b/wled00/FX.h index d24250f9b..210039ef4 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -38,8 +38,8 @@ #define DEFAULT_SPEED (uint8_t)128 #define DEFAULT_COLOR (uint32_t)0xFFAA00 -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)>(b)?(a):(b)) +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX(a,b) ((a)>(b)?(a):(b)) /* Not used in all effects yet */ #define WLED_FPS 42 diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 055686237..75ec65101 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -224,7 +224,7 @@ void WS2812FX::show(void) { if(useWackyWS2815PowerModel) { // ignore white component on WS2815 power calculation - powerSum += (max(max(c.R,c.G),c.B)) * 3; + powerSum += (MAX(MAX(c.R,c.G),c.B)) * 3; } else { @@ -638,7 +638,7 @@ uint32_t WS2812FX::color_wheel(uint8_t pos) { } /* - * Returns a new, random wheel index with a minimum distance of 42 from pos. + * Returns a new, random wheel index with a MINimum distance of 42 from pos. */ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) { uint8_t r = 0, x = 0, y = 0, d = 0; @@ -647,7 +647,7 @@ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) { r = random8(); x = abs(pos - r); y = 255 - x; - d = min(x, y); + d = MIN(x, y); } return r; } @@ -730,8 +730,8 @@ void WS2812FX::handle_palette(void) CHSV prim_hsv = rgb2hsv_approximate(prim); targetPalette = CRGBPalette16( CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v), //color itself - CHSV(prim_hsv.h, max(prim_hsv.s - 50,0), prim_hsv.v), //less saturated - CHSV(prim_hsv.h, prim_hsv.s, max(prim_hsv.v - 50,0)), //darker + CHSV(prim_hsv.h, MAX(prim_hsv.s - 50,0), prim_hsv.v), //less saturated + CHSV(prim_hsv.h, prim_hsv.s, MAX(prim_hsv.v - 50,0)), //darker CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v)); //color itself break;} case 4: {//primary + secondary diff --git a/wled00/wled.h b/wled00/wled.h index 043414466..3b744bcd4 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -468,10 +468,10 @@ extern WS2812FX strip; #define DEBUG_PRINT(x) Serial.print(x) #define DEBUG_PRINTLN(x) Serial.println(x) #define DEBUG_PRINTF(x) Serial.printf(x) -unsigned long debugTime = 0; -int lastWifiState = 3; -unsigned long wifiStateChangedTime = 0; -int loops = 0; +extern unsigned long debugTime; +extern int lastWifiState; +extern unsigned long wifiStateChangedTime; +extern int loops; #else #define DEBUG_PRINT(x) #define DEBUG_PRINTLN(x) From ef125ff1095bd0525da6ca5ba9a398d0d06971a2 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Thu, 26 Mar 2020 19:43:23 +0100 Subject: [PATCH 118/509] Fixed compilation for Analog LEDs Fixed sync settings network port fields too small --- CHANGELOG.md | 33 +++++++++++++++++++-------------- wled00/FX.h | 2 +- wled00/html_settings.h | 6 +++--- wled00/wled00.ino | 2 +- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56afa3fff..7d3a466c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,38 +2,43 @@ ### Development versions after 0.9.1 release +#### Build 2003262 + + - Fixed compilation for Analog LEDs + - Fixed sync settings network port fields too small + #### Build 2003261 -- Fixed live preview not displaying whole light if over 255 LEDs + - Fixed live preview not displaying whole light if over 255 LEDs #### Build 2003251 -- Added Pacifica effect (tentative, doesn't yet support other colors) -- Added Atlantica palette -- Fixed ESP32 build of Espalexa + - Added Pacifica effect (tentative, doesn't yet support other colors) + - Added Atlantica palette + - Fixed ESP32 build of Espalexa #### Build 2003222 -- Fixed Alexa Whites on non-RGBW lights (bump Espalexa to 2.4.5) + - Fixed Alexa Whites on non-RGBW lights (bump Espalexa to 2.4.5) #### Build 2003221 -- Moved Cronixie driver from FX library to drawOverlay handler + - Moved Cronixie driver from FX library to drawOverlay handler #### Build 2003211 -- Added custom mapping compile define to FX_fcn.h -- Merged pull request #784 by @TravisDean: Fixed initialization bug when toggling skip first -- Added link to youtube videos by Room31 to readme + - Added custom mapping compile define to FX_fcn.h + - Merged pull request #784 by @TravisDean: Fixed initialization bug when toggling skip first + - Added link to youtube videos by Room31 to readme #### Build 2003141 -- Fixed color of main segment returned in JSON API during transition not being target color (closes #765) -- Fixed arlsLock() being called after pixels set in E1.31 (closes #772) -- Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment) + - Fixed color of main segment returned in JSON API during transition not being target color (closes #765) + - Fixed arlsLock() being called after pixels set in E1.31 (closes #772) + - Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment) #### Build 2003121 -- Created changelog.md - make tracking changes to code easier -- Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection + - Created changelog.md - make tracking changes to code easier + - Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection diff --git a/wled00/FX.h b/wled00/FX.h index b6ed7974c..a87da8e25 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -631,7 +631,7 @@ class WS2812FX { #ifdef WLED_USE_ANALOG_LEDS uint32_t _analogLastShow = 0; - uint32_t _analogLastColor = 0; + RgbwColor _analogLastColor = 0; uint8_t _analogLastBri = 0; #endif diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 266016959..284d9b30f 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -3,7 +3,7 @@ */ //common CSS of settings pages -const char PAGE_settingsCss[] PROGMEM = R"=====()====="; +const char PAGE_settingsCss[] PROGMEM = R"=====()====="; //settings menu const char PAGE_settings[] PROGMEM = R"=====( @@ -273,7 +273,7 @@ Infrared remote:
IR info

WLED Broadcast

-UDP Port:
+UDP Port:
Receive Brightness, Color, and Effects
Send notifications on direct change:
Send notifications on button press:
@@ -316,7 +316,7 @@ Device Auth token:

MQTT

Enable MQTT:
Broker: -Port:
+Port:
The MQTT credentials are sent over an unsecured connection.
Never use the MQTT password for another service!

Username:
diff --git a/wled00/wled00.ino b/wled00/wled00.ino index dc0fbb02b..728c5ef66 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -118,7 +118,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2003261 +#define VERSION 2003262 char versionString[] = "0.9.1"; From 77ce67d68588a2e31e811b6219ad7fcf591c293f Mon Sep 17 00:00:00 2001 From: feindsender Date: Fri, 27 Mar 2020 10:03:23 +0100 Subject: [PATCH 119/509] Add P9813 LED driver support Adds support for the P9813 LED driver --- wled00/NpbWrapper.h | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 673d82492..6e58b7197 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -9,6 +9,7 @@ //#define USE_APA102 // Uncomment for using APA102 LEDs. //#define USE_WS2801 // Uncomment for using WS2801 LEDs (make sure you have NeoPixelBus v2.5.6 or newer) //#define USE_LPD8806 // Uncomment for using LPD8806 +//#define USE_P9813 // Uncomment for using P9813 LEDs (make sure you have NeoPixelBus v2.5.8 or newer) //#define WLED_USE_ANALOG_LEDS //Uncomment for using "dumb" PWM controlled LEDs (see pins below, default R: gpio5, G: 12, B: 15, W: 13) //#define WLED_USE_H801 //H801 controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well //#define WLED_USE_5CH_LEDS //5 Channel H801 for cold and warm white @@ -35,7 +36,7 @@ //END CONFIGURATION -#if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) +#if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) #define CLKPIN 0 #define DATAPIN 2 #if BTNPIN == CLKPIN || BTNPIN == DATAPIN @@ -73,6 +74,8 @@ #define PIXELMETHOD NeoWs2801Method #elif defined(USE_LPD8806) #define PIXELMETHOD Lpd8806Method + #elif defined(USE_P9813) + #define PIXELMETHOD P9813Method #else #define PIXELMETHOD NeoEsp32Rmt0Ws2812xMethod #endif @@ -84,6 +87,8 @@ #define PIXELMETHOD NeoWs2801Method #elif defined(USE_LPD8806) #define PIXELMETHOD Lpd8806Method + #elif defined(USE_P9813) + #define PIXELMETHOD P9813Method #elif LEDPIN == 2 #define PIXELMETHOD NeoEsp8266Uart1Ws2813Method //if you get an error here, try to change to NeoEsp8266UartWs2813Method or update Neopixelbus #elif LEDPIN == 3 @@ -101,7 +106,10 @@ #define PIXELFEATURE4 DotStarLbgrFeature #elif defined(USE_LPD8806) #define PIXELFEATURE3 Lpd8806GrbFeature - #define PIXELFEATURE4 Lpd8806GrbFeature + #define PIXELFEATURE4 Lpd8806GrbFeature +#elif defined(USE_P9813) + #define PIXELFEATURE3 P9813BgrFeature + #define PIXELFEATURE4 NeoGrbwFeature #else #define PIXELFEATURE3 NeoGrbFeature #define PIXELFEATURE4 NeoGrbwFeature @@ -143,7 +151,7 @@ public: switch (_type) { case NeoPixelType_Grb: - #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) + #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) _pGrb = new NeoPixelBrightnessBus(countPixels, CLKPIN, DATAPIN); #else _pGrb = new NeoPixelBrightnessBus(countPixels, LEDPIN); @@ -152,7 +160,7 @@ public: break; case NeoPixelType_Grbw: - #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) + #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) _pGrbw = new NeoPixelBrightnessBus(countPixels, CLKPIN, DATAPIN); #else _pGrbw = new NeoPixelBrightnessBus(countPixels, LEDPIN); From 0ce77bbc59b560d68ba74c332ef354fbfa438e4b Mon Sep 17 00:00:00 2001 From: Rares Serban Date: Sat, 28 Mar 2020 13:07:02 +0200 Subject: [PATCH 120/509] Add ability to set DMX fixtures to a segment and from what LED they should start. --- wled00/html_settings.h | 8 +++++++- wled00/wled00.ino | 4 +++- wled00/wled01_eeprom.ino | 5 +++++ wled00/wled02_xml.ino | 2 ++ wled00/wled03_set.ino | 8 ++++++++ wled00/wled21_dmx.ino | 15 +++++++++++---- 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 284d9b30f..7def2314d 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -218,7 +218,13 @@ channels per fixture (15 max):
spacing between start channels: [ info ]
- +
+ +If wanting to use DMX together with LEDs. Number of fixtures will also depend on the segment and start LED settings below
+Using these settings, you can position your fixtures anywhere you want on the LED strip
+which segment should DMX use:
+start LED from the above channel from which DMX fixtures should start:
+

channel functions


diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 728c5ef66..851a9c45d 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -23,7 +23,7 @@ //#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 12kb #define WLED_ENABLE_MQTT //saves 12kb #define WLED_ENABLE_ADALIGHT //saves 500b only -//#define WLED_ENABLE_DMX //uses 3.5kb +//#define WLED_ENABLE_DMX //uses 3.5kb, if wanting to use DMX together with LEDs, you should change the LEDPIN to something other than 2 in NpbWrapper.h #define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet //#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version @@ -277,6 +277,8 @@ uint16_t userVar0 = 0, userVar1 = 0; // assigns the different channels to different functions. See wled21_dmx.ino for more information. uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. uint16_t DMXStart = 10; // start address of the first fixture + uint16_t DMXSegment = 0; // segment which DMX fixtures use + uint16_t DMXStartLED = 0; // start LED from which DMX fixtures should start #endif diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index 1f0e8426f..c741d4e3f 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -270,6 +270,9 @@ void saveSettingsToEEPROM() for (int i=0; i<15; i++) { EEPROM.write(2535+i, DMXFixtureMap[i]); } // last used: 2549. maybe leave a few bytes for future expansion and go on with 2600 kthxbye. + + EEPROM.write(2550, DMXSegment); + EEPROM.write(2551, DMXStartLED); #endif commit(); @@ -551,6 +554,8 @@ void loadSettingsFromEEPROM(bool first) DMXChannels = EEPROM.read(2530); DMXGap = EEPROM.read(2531) + ((EEPROM.read(2532) << 8) & 0xFF00); DMXStart = EEPROM.read(2533) + ((EEPROM.read(2534) << 8) & 0xFF00); + DMXSegment = EEPROM.read(2550); + DMXStartLED = EEPROM.read(2551); for (int i=0;i<15;i++) { DMXFixtureMap[i] = EEPROM.read(2535+i); diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index 100be4822..a05c1e97b 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -455,6 +455,8 @@ void getSettingsJS(byte subPage, char* dest) sappend('v',"CN",DMXChannels); sappend('v',"CG",DMXGap); sappend('v',"CS",DMXStart); + sappend('v',"SEG",DMXSegment); + sappend('v',"SL",DMXStartLED); sappend('i',"CH1",DMXFixtureMap[0]); sappend('i',"CH2",DMXFixtureMap[1]); diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index fc82256d2..088f31ad3 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -310,6 +310,14 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) t = request->arg(argname).toInt(); DMXFixtureMap[i] = t; } + t = request->arg("SEG").toInt(); + if (t>=0 && t<10) { + DMXSegment = t; + } + t = request->arg("SL").toInt(); + if (t>=0 && t<1500) { + DMXStartLED = t; + } } #endif diff --git a/wled00/wled21_dmx.ino b/wled00/wled21_dmx.ino index 4230f07d8..e48b051a0 100644 --- a/wled00/wled21_dmx.ino +++ b/wled00/wled21_dmx.ino @@ -5,20 +5,27 @@ */ #ifdef WLED_ENABLE_DMX -void handleDMX() { +void handleDMX() { + WS2812FX::Segment& seg = strip.getSegment(DMXSegment); + + if (!seg.isActive()) { + return; + } + // TODO: calculate brightness manually if no shutter channel is set - uint8_t brightness = strip.getBrightness(); - for (int i = 0; i < ledCount; i++) { // uses the amount of LEDs as fixture count + // Calculate the start LED depending on segment and DMXStartLED config + uint8_t startLed = seg.start + DMXStartLED; + for (int i = startLed; i < seg.stop; i++) { uint32_t in = strip.getPixelColor(i); // time to get the colors for the individual fixtures as suggested by AirCookie at issue #462 byte w = in >> 24 & 0xFF; byte r = in >> 16 & 0xFF; byte g = in >> 8 & 0xFF; byte b = in & 0xFF; - int DMXFixtureStart = DMXStart + (DMXGap * i); + int DMXFixtureStart = DMXStart + (DMXGap * (i - startLed)); for (int j = 0; j < DMXChannels; j++) { int DMXAddr = DMXFixtureStart + j; switch (DMXFixtureMap[j]) { From b8342f1c9cde82c15bfed4728130451a5487d6f3 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Sat, 28 Mar 2020 07:32:02 -0400 Subject: [PATCH 121/509] actually call the setup function. --- wled00/wled00.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wled00/wled00.ino b/wled00/wled00.ino index ac993bf62..522447d0a 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -3,9 +3,10 @@ */ #include "wled.h" -WLED wled; +WLED& wled; void setup() { - wled.instance(); // Force creation of static instance + wled = WLED::instance(); + wled.setup(); } void loop() { From f35ab125eccb3fca86d27fb4dd7728bb5812e65d Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Sat, 28 Mar 2020 08:30:51 -0400 Subject: [PATCH 122/509] Rename files to remove wled_ --- wled00/{wled_alexa.cpp => alexa.cpp} | 8 +- wled00/{wled_alexa.h => alexa.h} | 32 +- wled00/{wled_blynk.cpp => blynk.cpp} | 6 +- wled00/{wled_blynk.h => blynk.h} | 24 +- wled00/{wled_button.cpp => button.cpp} | 8 +- wled00/{wled_button.h => button.h} | 22 +- wled00/{wled_colors.cpp => colors.cpp} | 2 +- wled00/{wled_colors.h => colors.h} | 38 +- wled00/{wled_cronixie.cpp => cronixie.cpp} | 2 +- wled00/{wled_cronixie.h => cronixie.h} | 24 +- wled00/{wled_dmx.cpp => dmx.cpp} | 2 +- wled00/{wled_dmx.h => dmx.h} | 20 +- wled00/{wled_eeprom.cpp => eeprom.cpp} | 10 +- wled00/{wled_eeprom.h => eeprom.h} | 46 +- wled00/{wled_file.cpp => file.cpp} | 6 +- wled00/{wled_file.h => file.h} | 22 +- wled00/{wled_hue.cpp => hue.cpp} | 10 +- wled00/{wled_hue.h => hue.h} | 30 +- wled00/{wled_ir.cpp => ir.cpp} | 8 +- wled00/{wled_ir.h => ir.h} | 46 +- wled00/{wled_json.cpp => json.cpp} | 6 +- wled00/{wled_json.h => json.h} | 40 +- wled00/{wled_led.cpp => led.cpp} | 12 +- wled00/{wled_led.h => led.h} | 36 +- wled00/{wled_mqtt.cpp => mqtt.cpp} | 12 +- wled00/{wled_mqtt.h => mqtt.h} | 16 +- wled00/{wled_notify.cpp => notify.cpp} | 4 +- wled00/{wled_notify.h => notify.h} | 34 +- wled00/{wled_ntp.cpp => ntp.cpp} | 4 +- wled00/{wled_ntp.h => ntp.h} | 35 +- wled00/{wled_overlay.cpp => overlay.cpp} | 6 +- wled00/{wled_overlay.h => overlay.h} | 26 +- wled00/{wled_server.cpp => server.cpp} | 10 +- wled00/{wled_server.h => server.h} | 40 +- wled00/{wled_set.cpp => set.cpp} | 18 +- wled00/{wled_set.h => set.h} | 30 +- wled00/{wled_usermod.cpp => usermod.cpp} | 0 wled00/{wled_usermod.h => usermod.h} | 14 +- wled00/wled.cpp | 1763 ++++++++++---------- wled00/wled.h | 1038 ++++++------ wled00/{wled_xml.cpp => xml.cpp} | 6 +- wled00/{wled_xml.h => xml.h} | 28 +- 42 files changed, 1772 insertions(+), 1772 deletions(-) rename wled00/{wled_alexa.cpp => alexa.cpp} (95%) rename wled00/{wled_alexa.h => alexa.h} (96%) rename wled00/{wled_blynk.cpp => blynk.cpp} (96%) rename wled00/{wled_blynk.h => blynk.h} (96%) rename wled00/{wled_button.cpp => button.cpp} (96%) rename wled00/{wled_button.h => button.h} (94%) rename wled00/{wled_colors.cpp => colors.cpp} (99%) rename wled00/{wled_colors.h => colors.h} (97%) rename wled00/{wled_cronixie.cpp => cronixie.cpp} (99%) rename wled00/{wled_cronixie.h => cronixie.h} (96%) rename wled00/{wled_dmx.cpp => dmx.cpp} (98%) rename wled00/{wled_dmx.h => dmx.h} (96%) rename wled00/{wled_eeprom.cpp => eeprom.cpp} (99%) rename wled00/{wled_eeprom.h => eeprom.h} (97%) rename wled00/{wled_file.cpp => file.cpp} (98%) rename wled00/{wled_file.h => file.h} (95%) rename wled00/{wled_hue.cpp => hue.cpp} (97%) rename wled00/{wled_hue.h => hue.h} (96%) rename wled00/{wled_ir.cpp => ir.cpp} (99%) rename wled00/{wled_ir.h => ir.h} (96%) rename wled00/{wled_json.cpp => json.cpp} (99%) rename wled00/{wled_json.h => json.h} (97%) rename wled00/{wled_led.cpp => led.cpp} (97%) rename wled00/{wled_led.h => led.h} (95%) rename wled00/{wled_mqtt.cpp => mqtt.cpp} (96%) rename wled00/{wled_mqtt.h => mqtt.h} (95%) rename wled00/{wled_notify.cpp => notify.cpp} (99%) rename wled00/{wled_notify.h => notify.h} (96%) rename wled00/{wled_ntp.cpp => ntp.cpp} (99%) rename wled00/{wled_ntp.h => ntp.h} (87%) rename wled00/{wled_overlay.cpp => overlay.cpp} (98%) rename wled00/{wled_overlay.h => overlay.h} (95%) rename wled00/{wled_server.cpp => server.cpp} (99%) rename wled00/{wled_server.h => server.h} (96%) rename wled00/{wled_set.cpp => set.cpp} (98%) rename wled00/{wled_set.h => set.h} (97%) rename wled00/{wled_usermod.cpp => usermod.cpp} (100%) rename wled00/{wled_usermod.h => usermod.h} (94%) rename wled00/{wled_xml.cpp => xml.cpp} (99%) rename wled00/{wled_xml.h => xml.h} (96%) diff --git a/wled00/wled_alexa.cpp b/wled00/alexa.cpp similarity index 95% rename from wled00/wled_alexa.cpp rename to wled00/alexa.cpp index 1eb33e71d..621480d0c 100644 --- a/wled00/wled_alexa.cpp +++ b/wled00/alexa.cpp @@ -1,9 +1,9 @@ -#include "wled_alexa.h" +#include "alexa.h" #include "wled.h" #include "const.h" -#include "wled_led.h" -#include "wled_eeprom.h" -#include "wled_colors.h" +#include "led.h" +#include "eeprom.h" +#include "colors.h" #ifndef WLED_DISABLE_ALEXA void onAlexaChange(EspalexaDevice* dev); diff --git a/wled00/wled_alexa.h b/wled00/alexa.h similarity index 96% rename from wled00/wled_alexa.h rename to wled00/alexa.h index 94ad0342b..c2adfebe3 100644 --- a/wled00/wled_alexa.h +++ b/wled00/alexa.h @@ -1,17 +1,17 @@ -#ifndef WLED_ALEXA_H -#define WLED_ALEXA_H -/* - * Alexa Voice On/Off/Brightness Control. Emulates a Philips Hue bridge to Alexa. - * - * This was put together from these two excellent projects: - * https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch - * https://github.com/probonopd/ESP8266HueEmulator - */ -#include "src/dependencies/espalexa/EspalexaDevice.h" - -void onAlexaChange(EspalexaDevice* dev); -void alexaInit(); -void handleAlexa(); -void onAlexaChange(EspalexaDevice* dev); - +#ifndef WLED_ALEXA_H +#define WLED_ALEXA_H +/* + * Alexa Voice On/Off/Brightness Control. Emulates a Philips Hue bridge to Alexa. + * + * This was put together from these two excellent projects: + * https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch + * https://github.com/probonopd/ESP8266HueEmulator + */ +#include "src/dependencies/espalexa/EspalexaDevice.h" + +void onAlexaChange(EspalexaDevice* dev); +void alexaInit(); +void handleAlexa(); +void onAlexaChange(EspalexaDevice* dev); + #endif // WLED_ALEXA_H \ No newline at end of file diff --git a/wled00/wled_blynk.cpp b/wled00/blynk.cpp similarity index 96% rename from wled00/wled_blynk.cpp rename to wled00/blynk.cpp index 2e3d9f7bb..2307a6942 100644 --- a/wled00/wled_blynk.cpp +++ b/wled00/blynk.cpp @@ -1,9 +1,9 @@ -#include "wled_blynk.h" +#include "blynk.h" #include "const.h" #include "wled.h" #include "src/dependencies/blynk/Blynk/BlynkHandlers.h" -#include "wled_led.h" -#include "wled_colors.h" +#include "led.h" +#include "colors.h" uint16_t blHue = 0; byte blSat = 255; diff --git a/wled00/wled_blynk.h b/wled00/blynk.h similarity index 96% rename from wled00/wled_blynk.h rename to wled00/blynk.h index e8c8341b5..cf3a2e225 100644 --- a/wled00/wled_blynk.h +++ b/wled00/blynk.h @@ -1,13 +1,13 @@ -#ifndef WLED_BLYNK_H -#define WLED_BLYNK_H -#include -/* - * Remote light control with the free Blynk app - */ - -void initBlynk(const char* auth); -void handleBlynk(); -void updateBlynk(); -// Unsure if the macro expansions need to accessed through the declaration... TODO - +#ifndef WLED_BLYNK_H +#define WLED_BLYNK_H +#include +/* + * Remote light control with the free Blynk app + */ + +void initBlynk(const char* auth); +void handleBlynk(); +void updateBlynk(); +// Unsure if the macro expansions need to accessed through the declaration... TODO + #endif //WLED_BLYNK_H \ No newline at end of file diff --git a/wled00/wled_button.cpp b/wled00/button.cpp similarity index 96% rename from wled00/wled_button.cpp rename to wled00/button.cpp index 3825cc846..1afb54d57 100644 --- a/wled00/wled_button.cpp +++ b/wled00/button.cpp @@ -1,8 +1,8 @@ -#include "wled_button.h" +#include "button.h" #include "wled.h" -#include "wled_led.h" -#include "wled_eeprom.h" -#include "wled_set.h" +#include "led.h" +#include "eeprom.h" +#include "set.h" /* * Physical IO diff --git a/wled00/wled_button.h b/wled00/button.h similarity index 94% rename from wled00/wled_button.h rename to wled00/button.h index 5f8944773..f974888e7 100644 --- a/wled00/wled_button.h +++ b/wled00/button.h @@ -1,12 +1,12 @@ -#ifndef WLED_BUTTON_H -#define WLED_BUTTON_H -#include -/* - * Physical IO - */ - -void shortPressAction(); -void handleButton(); -void handleIO(); - +#ifndef WLED_BUTTON_H +#define WLED_BUTTON_H +#include +/* + * Physical IO + */ + +void shortPressAction(); +void handleButton(); +void handleIO(); + #endif // WLED_BUTTON_H \ No newline at end of file diff --git a/wled00/wled_colors.cpp b/wled00/colors.cpp similarity index 99% rename from wled00/wled_colors.cpp rename to wled00/colors.cpp index dcd32e574..6f2477574 100644 --- a/wled00/wled_colors.cpp +++ b/wled00/colors.cpp @@ -1,4 +1,4 @@ -#include "wled_colors.h" +#include "colors.h" #include "wled.h" void colorFromUint32(uint32_t in, bool secondary) diff --git a/wled00/wled_colors.h b/wled00/colors.h similarity index 97% rename from wled00/wled_colors.h rename to wled00/colors.h index 917311e78..85e0adb50 100644 --- a/wled00/wled_colors.h +++ b/wled00/colors.h @@ -1,20 +1,20 @@ -#ifndef WLED_COLORS_H -#define WLED_COLORS_H -#include -/* - * Color conversion methods - */ - -void colorFromUint32(uint32_t in, bool secondary = false); -void colorFromUint24(uint32_t in, bool secondary = false); -void relativeChangeWhite(int8_t amount, byte lowerBoundary = 0); -void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb -void colorCTtoRGB(uint16_t mired, byte* rgb); //white spectrum to rgb - -void colorXYtoRGB(float x, float y, byte* rgb); // only defined if huesync disabled TODO -void colorRGBtoXY(byte* rgb, float* xy); // only defined if huesync disabled TODO - -void colorFromDecOrHexString(byte* rgb, char* in); -void colorRGBtoRGBW(byte* rgb); //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY) - +#ifndef WLED_COLORS_H +#define WLED_COLORS_H +#include +/* + * Color conversion methods + */ + +void colorFromUint32(uint32_t in, bool secondary = false); +void colorFromUint24(uint32_t in, bool secondary = false); +void relativeChangeWhite(int8_t amount, byte lowerBoundary = 0); +void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb +void colorCTtoRGB(uint16_t mired, byte* rgb); //white spectrum to rgb + +void colorXYtoRGB(float x, float y, byte* rgb); // only defined if huesync disabled TODO +void colorRGBtoXY(byte* rgb, float* xy); // only defined if huesync disabled TODO + +void colorFromDecOrHexString(byte* rgb, char* in); +void colorRGBtoRGBW(byte* rgb); //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY) + #endif //WLED_COLORS_H \ No newline at end of file diff --git a/wled00/wled_cronixie.cpp b/wled00/cronixie.cpp similarity index 99% rename from wled00/wled_cronixie.cpp rename to wled00/cronixie.cpp index 107af752a..e3b951b86 100644 --- a/wled00/wled_cronixie.cpp +++ b/wled00/cronixie.cpp @@ -1,4 +1,4 @@ -#include "wled_cronixie.h" +#include "cronixie.h" #include "wled.h" #ifndef WLED_DISABLE_CRONIXIE diff --git a/wled00/wled_cronixie.h b/wled00/cronixie.h similarity index 96% rename from wled00/wled_cronixie.h rename to wled00/cronixie.h index 9dea69b33..f6eea6b43 100644 --- a/wled00/wled_cronixie.h +++ b/wled00/cronixie.h @@ -1,13 +1,13 @@ -#ifndef WLED_CRONIXIE_H -#define WLED_CRONIXIE_H -#include -/* - * Support for the Cronixie clock - */ - -byte getSameCodeLength(char code, int index, char const cronixieDisplay[]); -void setCronixie(); -void _overlayCronixie(); -void _drawOverlayCronixie(); - +#ifndef WLED_CRONIXIE_H +#define WLED_CRONIXIE_H +#include +/* + * Support for the Cronixie clock + */ + +byte getSameCodeLength(char code, int index, char const cronixieDisplay[]); +void setCronixie(); +void _overlayCronixie(); +void _drawOverlayCronixie(); + #endif // WLED_CRONIXIE_H \ No newline at end of file diff --git a/wled00/wled_dmx.cpp b/wled00/dmx.cpp similarity index 98% rename from wled00/wled_dmx.cpp rename to wled00/dmx.cpp index f620f7779..d024ac713 100644 --- a/wled00/wled_dmx.cpp +++ b/wled00/dmx.cpp @@ -1,4 +1,4 @@ -#include "wled_dmx.h" +#include "dmx.h" #include "wled.h" #ifdef WLED_ENABLE_DMX diff --git a/wled00/wled_dmx.h b/wled00/dmx.h similarity index 96% rename from wled00/wled_dmx.h rename to wled00/dmx.h index 94cbb0d25..707dec915 100644 --- a/wled00/wled_dmx.h +++ b/wled00/dmx.h @@ -1,11 +1,11 @@ -#ifndef WLED_DMX_H -#define WLED_DMX_H -/* - * Support for DMX via MAX485. - * Needs the espdmx library. You might have to change the output pin within the library. Sketchy, i know. - * https://github.com/Rickgg/ESP-Dmx - */ - -void handleDMX(); - +#ifndef WLED_DMX_H +#define WLED_DMX_H +/* + * Support for DMX via MAX485. + * Needs the espdmx library. You might have to change the output pin within the library. Sketchy, i know. + * https://github.com/Rickgg/ESP-Dmx + */ + +void handleDMX(); + #endif //WLED_DMX_H \ No newline at end of file diff --git a/wled00/wled_eeprom.cpp b/wled00/eeprom.cpp similarity index 99% rename from wled00/wled_eeprom.cpp rename to wled00/eeprom.cpp index 04b86289a..68b8c35f9 100644 --- a/wled00/wled_eeprom.cpp +++ b/wled00/eeprom.cpp @@ -1,9 +1,9 @@ -#include "wled_eeprom.h" +#include "eeprom.h" #include "wled.h" -#include "wled_cronixie.h" -#include "wled_ntp.h" -#include "wled_set.h" -#include "wled_led.h" +#include "cronixie.h" +#include "ntp.h" +#include "set.h" +#include "led.h" //eeprom Version code, enables default settings instead of 0 init on update diff --git a/wled00/wled_eeprom.h b/wled00/eeprom.h similarity index 97% rename from wled00/wled_eeprom.h rename to wled00/eeprom.h index 19f61925a..eae52b128 100644 --- a/wled00/wled_eeprom.h +++ b/wled00/eeprom.h @@ -1,23 +1,23 @@ -#ifndef WLED_EPPROM_H -#define WLED_EPPROM_H -#include -/* - * Methods to handle saving and loading to non-volatile memory - * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map - */ -#define EEPSIZE 2560 //Maximum is 4096 - -void commit(); -void clearEEPROM(); -void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len); -void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len); -void saveSettingsToEEPROM(); -void loadSettingsFromEEPROM(bool first); -void savedToPresets(); -bool applyPreset(byte index, bool loadBri = true); -void savePreset(byte index, bool persist = true); -void loadMacro(byte index, char* m); -void applyMacro(byte index); -void saveMacro(byte index, String mc, bool persist = true); //only commit on single save, not in settings - -#endif //WLED_EPPROM_H +#ifndef WLED_EPPROM_H +#define WLED_EPPROM_H +#include +/* + * Methods to handle saving and loading to non-volatile memory + * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map + */ +#define EEPSIZE 2560 //Maximum is 4096 + +void commit(); +void clearEEPROM(); +void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len); +void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len); +void saveSettingsToEEPROM(); +void loadSettingsFromEEPROM(bool first); +void savedToPresets(); +bool applyPreset(byte index, bool loadBri = true); +void savePreset(byte index, bool persist = true); +void loadMacro(byte index, char* m); +void applyMacro(byte index); +void saveMacro(byte index, String mc, bool persist = true); //only commit on single save, not in settings + +#endif //WLED_EPPROM_H diff --git a/wled00/wled_file.cpp b/wled00/file.cpp similarity index 98% rename from wled00/wled_file.cpp rename to wled00/file.cpp index 81b86d6d3..dba27d4fe 100644 --- a/wled00/wled_file.cpp +++ b/wled00/file.cpp @@ -1,7 +1,7 @@ -#include "wled_file.h" +#include "file.h" #include "wled.h" -#include "wled_led.h" -#include "wled_notify.h" +#include "led.h" +#include "notify.h" //filesystem #ifndef WLED_DISABLE_FILESYSTEM diff --git a/wled00/wled_file.h b/wled00/file.h similarity index 95% rename from wled00/wled_file.h rename to wled00/file.h index 7457ec4cd..90731db67 100644 --- a/wled00/wled_file.h +++ b/wled00/file.h @@ -1,12 +1,12 @@ -#ifndef WLED_FILE_H -#define WLED_FILE_H -#include -#include -/* - * Utility for SPIFFS filesystem & Serial console - */ - -void handleSerial(); -bool handleFileRead(AsyncWebServerRequest*, String path); - +#ifndef WLED_FILE_H +#define WLED_FILE_H +#include +#include +/* + * Utility for SPIFFS filesystem & Serial console + */ + +void handleSerial(); +bool handleFileRead(AsyncWebServerRequest*, String path); + #endif // WLED_FILE_H \ No newline at end of file diff --git a/wled00/wled_hue.cpp b/wled00/hue.cpp similarity index 97% rename from wled00/wled_hue.cpp rename to wled00/hue.cpp index 61756ec0e..484f2bd84 100644 --- a/wled00/wled_hue.cpp +++ b/wled00/hue.cpp @@ -1,9 +1,9 @@ -#include "wled_hue.h" +#include "hue.h" #include "wled.h" -#include "wled_colors.h" -#include "wled_eeprom.h" -#include "wled_notify.h" -#include "wled_led.h" +#include "colors.h" +#include "eeprom.h" +#include "notify.h" +#include "led.h" #ifndef WLED_DISABLE_HUESYNC diff --git a/wled00/wled_hue.h b/wled00/hue.h similarity index 96% rename from wled00/wled_hue.h rename to wled00/hue.h index 8b26f8b6f..7ce629fbe 100644 --- a/wled00/wled_hue.h +++ b/wled00/hue.h @@ -1,16 +1,16 @@ -#ifndef WLED_HUE_H -#define WLED_HUE_H -/* - * Sync to Philips hue lights - */ -#include -class AsyncClient; - -void handleHue(); -void reconnectHue(); -void onHueError(void* arg, AsyncClient* client, int8_t error); -void onHueConnect(void* arg, AsyncClient* client); -void sendHuePoll(); -void onHueData(void* arg, AsyncClient* client, void *data, size_t len); - +#ifndef WLED_HUE_H +#define WLED_HUE_H +/* + * Sync to Philips hue lights + */ +#include +class AsyncClient; + +void handleHue(); +void reconnectHue(); +void onHueError(void* arg, AsyncClient* client, int8_t error); +void onHueConnect(void* arg, AsyncClient* client); +void sendHuePoll(); +void onHueData(void* arg, AsyncClient* client, void *data, size_t len); + #endif //WLED_HUE_H \ No newline at end of file diff --git a/wled00/wled_ir.cpp b/wled00/ir.cpp similarity index 99% rename from wled00/wled_ir.cpp rename to wled00/ir.cpp index f625148eb..fcc0f5dda 100644 --- a/wled00/wled_ir.cpp +++ b/wled00/ir.cpp @@ -1,8 +1,8 @@ -#include "wled_ir.h" +#include "ir.h" #include "wled.h" -#include "wled_led.h" -#include "wled_colors.h" -#include "wled_eeprom.h" +#include "led.h" +#include "colors.h" +#include "eeprom.h" #if defined(WLED_DISABLE_INFRARED) void handleIR(){} diff --git a/wled00/wled_ir.h b/wled00/ir.h similarity index 96% rename from wled00/wled_ir.h rename to wled00/ir.h index 3f819da01..e6ecb9668 100644 --- a/wled00/wled_ir.h +++ b/wled00/ir.h @@ -1,24 +1,24 @@ -#ifndef WLED_IR_H -#define WLED_IR_H -#include -/* - * Infrared sensor support for generic 24/40/44 key RGB remotes - */ - -bool decodeIRCustom(uint32_t code); -void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF); -void changeEffectSpeed(int8_t amount); -void changeEffectIntensity(int8_t amount); -void decodeIR(uint32_t code); -void decodeIR24(uint32_t code); -void decodeIR24OLD(uint32_t code); -void decodeIR24CT(uint32_t code); -void decodeIR40(uint32_t code); -void decodeIR44(uint32_t code); -void decodeIR21(uint32_t code); -void decodeIR6(uint32_t code); - -void initIR(); -void handleIR(); - +#ifndef WLED_IR_H +#define WLED_IR_H +#include +/* + * Infrared sensor support for generic 24/40/44 key RGB remotes + */ + +bool decodeIRCustom(uint32_t code); +void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF); +void changeEffectSpeed(int8_t amount); +void changeEffectIntensity(int8_t amount); +void decodeIR(uint32_t code); +void decodeIR24(uint32_t code); +void decodeIR24OLD(uint32_t code); +void decodeIR24CT(uint32_t code); +void decodeIR40(uint32_t code); +void decodeIR44(uint32_t code); +void decodeIR21(uint32_t code); +void decodeIR6(uint32_t code); + +void initIR(); +void handleIR(); + #endif //WLED_IR_H \ No newline at end of file diff --git a/wled00/wled_json.cpp b/wled00/json.cpp similarity index 99% rename from wled00/wled_json.cpp rename to wled00/json.cpp index 17359462d..73659e7ed 100644 --- a/wled00/wled_json.cpp +++ b/wled00/json.cpp @@ -1,7 +1,7 @@ -#include "wled_json.h" +#include "json.h" #include "wled.h" -#include "wled_eeprom.h" -#include "wled_led.h" +#include "eeprom.h" +#include "led.h" void deserializeSegment(JsonObject elem, byte it) { diff --git a/wled00/wled_json.h b/wled00/json.h similarity index 97% rename from wled00/wled_json.h rename to wled00/json.h index a7c2473aa..77d1b616f 100644 --- a/wled00/wled_json.h +++ b/wled00/json.h @@ -1,21 +1,21 @@ -#ifndef WLED_JSON_H -#define WLED_JSON_H -/* - * JSON API (De)serialization - */ -#include -#include "ESPAsyncWebServer.h" -#include "src/dependencies/json/ArduinoJson-v6.h" -#include "src/dependencies/json/AsyncJson-v6.h" -#include "fx.h" -// TODO: AsynicWebServerRequest conflict? - -void deserializeSegment(JsonObject elem, byte it); -bool deserializeState(JsonObject root); -void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id); -void serializeState(JsonObject root); -void serializeInfo(JsonObject root); -void serveJson(AsyncWebServerRequest* request); -void serveLiveLeds(AsyncWebServerRequest* request); - +#ifndef WLED_JSON_H +#define WLED_JSON_H +/* + * JSON API (De)serialization + */ +#include +#include "ESPAsyncWebServer.h" +#include "src/dependencies/json/ArduinoJson-v6.h" +#include "src/dependencies/json/AsyncJson-v6.h" +#include "fx.h" +// TODO: AsynicWebServerRequest conflict? + +void deserializeSegment(JsonObject elem, byte it); +bool deserializeState(JsonObject root); +void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id); +void serializeState(JsonObject root); +void serializeInfo(JsonObject root); +void serveJson(AsyncWebServerRequest* request); +void serveLiveLeds(AsyncWebServerRequest* request); + #endif //WLED_JSON_H \ No newline at end of file diff --git a/wled00/wled_led.cpp b/wled00/led.cpp similarity index 97% rename from wled00/wled_led.cpp rename to wled00/led.cpp index bd657a53b..4a16dcff8 100644 --- a/wled00/wled_led.cpp +++ b/wled00/led.cpp @@ -1,10 +1,10 @@ -#include "wled_led.h" +#include "led.h" #include "wled.h" -#include "wled_notify.h" -#include "wled_blynk.h" -#include "wled_eeprom.h" -#include "wled_mqtt.h" -#include "wled_colors.h" +#include "notify.h" +#include "blynk.h" +#include "eeprom.h" +#include "mqtt.h" +#include "colors.h" void setValuesFromMainSeg() { diff --git a/wled00/wled_led.h b/wled00/led.h similarity index 95% rename from wled00/wled_led.h rename to wled00/led.h index aebe95e48..d5eb97a8d 100644 --- a/wled00/wled_led.h +++ b/wled00/led.h @@ -1,19 +1,19 @@ -#ifndef WLED_LED_H -#define WLED_LED_H -#include -/* - * LED methods - */ - -void setValuesFromMainSeg(); -void resetTimebase(); -void toggleOnOff(); -void setAllLeds(); -void setLedsStandard(bool justColors = false); -bool colorChanged(); -void colorUpdated(int callMode); -void updateInterfaces(uint8_t callMode); -void handleTransitions(); -void handleNightlight(); - +#ifndef WLED_LED_H +#define WLED_LED_H +#include +/* + * LED methods + */ + +void setValuesFromMainSeg(); +void resetTimebase(); +void toggleOnOff(); +void setAllLeds(); +void setLedsStandard(bool justColors = false); +bool colorChanged(); +void colorUpdated(int callMode); +void updateInterfaces(uint8_t callMode); +void handleTransitions(); +void handleNightlight(); + #endif \ No newline at end of file diff --git a/wled00/wled_mqtt.cpp b/wled00/mqtt.cpp similarity index 96% rename from wled00/wled_mqtt.cpp rename to wled00/mqtt.cpp index 5e96a18f2..b84184af0 100644 --- a/wled00/wled_mqtt.cpp +++ b/wled00/mqtt.cpp @@ -1,10 +1,10 @@ -#include "wled_mqtt.h" +#include "mqtt.h" #include "wled.h" -#include "wled_notify.h" -#include "wled_led.h" -#include "wled_colors.h" -#include "wled_xml.h" -#include "wled_set.h" +#include "notify.h" +#include "led.h" +#include "colors.h" +#include "xml.h" +#include "set.h" #ifdef WLED_ENABLE_MQTT #define MQTT_KEEP_ALIVE_TIME 60 // contact the MQTT broker every 60 seconds diff --git a/wled00/wled_mqtt.h b/wled00/mqtt.h similarity index 95% rename from wled00/wled_mqtt.h rename to wled00/mqtt.h index f1c7160e5..de602b981 100644 --- a/wled00/wled_mqtt.h +++ b/wled00/mqtt.h @@ -1,9 +1,9 @@ -#ifndef WLED_MQTT_H -#define WLED_MQTT_H -/* - * MQTT communication protocol for home automation - */ -bool initMqtt(); -void publishMqtt(); - +#ifndef WLED_MQTT_H +#define WLED_MQTT_H +/* + * MQTT communication protocol for home automation + */ +bool initMqtt(); +void publishMqtt(); + #endif //WLED_MQTT_H \ No newline at end of file diff --git a/wled00/wled_notify.cpp b/wled00/notify.cpp similarity index 99% rename from wled00/wled_notify.cpp rename to wled00/notify.cpp index 7913b4525..30adfee01 100644 --- a/wled00/wled_notify.cpp +++ b/wled00/notify.cpp @@ -1,7 +1,7 @@ -#include "wled_notify.h" +#include "notify.h" #include "wled.h" #include "src/dependencies/e131/ESPAsyncE131.h" -#include "wled_led.h" +#include "led.h" #define WLEDPACKETSIZE 29 #define UDP_IN_MAXSIZE 1472 diff --git a/wled00/wled_notify.h b/wled00/notify.h similarity index 96% rename from wled00/wled_notify.h rename to wled00/notify.h index 04c65aa43..a0fbfde2c 100644 --- a/wled00/wled_notify.h +++ b/wled00/notify.h @@ -1,18 +1,18 @@ -#ifndef WLED_NOTIFY_H -#define WLED_NOTIFY_H -#include -#include "src/dependencies/e131/ESPAsyncE131.h" -#include "const.h" -/* - * UDP notifier - */ -//union e131_packet_t; // Will this compile? -class IPAddress; - -void notify(byte callMode, bool followUp=false); -void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC); -void handleE131Packet(e131_packet_t* p, IPAddress clientIP); -void handleNotifications(); -void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w); - +#ifndef WLED_NOTIFY_H +#define WLED_NOTIFY_H +#include +#include "src/dependencies/e131/ESPAsyncE131.h" +#include "const.h" +/* + * UDP notifier + */ +//union e131_packet_t; // Will this compile? +class IPAddress; + +void notify(byte callMode, bool followUp=false); +void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC); +void handleE131Packet(e131_packet_t* p, IPAddress clientIP); +void handleNotifications(); +void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w); + #endif // WLED_NOTIFY_H \ No newline at end of file diff --git a/wled00/wled_ntp.cpp b/wled00/ntp.cpp similarity index 99% rename from wled00/wled_ntp.cpp rename to wled00/ntp.cpp index d8d9c38a2..3435760b7 100644 --- a/wled00/wled_ntp.cpp +++ b/wled00/ntp.cpp @@ -1,6 +1,6 @@ -#include "wled_ntp.h" +#include "ntp.h" #include "wled.h" -#include "wled_eeprom.h" +#include "eeprom.h" TimeChangeRule UTCr = {Last, Sun, Mar, 1, 0}; // UTC Timezone tzUTC(UTCr, UTCr); diff --git a/wled00/wled_ntp.h b/wled00/ntp.h similarity index 87% rename from wled00/wled_ntp.h rename to wled00/ntp.h index be683d143..9029661dd 100644 --- a/wled00/wled_ntp.h +++ b/wled00/ntp.h @@ -1,19 +1,18 @@ -#ifndef WLED_NTP_H -#define WLED_NTP_H -#include -#include "timezone/Timezone.h" -/* - * Acquires time from NTP server - */ - -void handleNetworkTime(); -void sendNTPPacket(); -bool checkNTPResponse(); -void updateLocalTime(); -void getTimeString(char* out); -bool checkCountdown(); -void setCountdown(); -byte weekdayMondayFirst(); -void checkTimers(); - +#ifndef WLED_NTP_H +#define WLED_NTP_H +#include +/* + * Acquires time from NTP server + */ + +void handleNetworkTime(); +void sendNTPPacket(); +bool checkNTPResponse(); +void updateLocalTime(); +void getTimeString(char* out); +bool checkCountdown(); +void setCountdown(); +byte weekdayMondayFirst(); +void checkTimers(); + #endif // WLED_NTP_H \ No newline at end of file diff --git a/wled00/wled_overlay.cpp b/wled00/overlay.cpp similarity index 98% rename from wled00/wled_overlay.cpp rename to wled00/overlay.cpp index 8cb707866..ccdd3d0cd 100644 --- a/wled00/wled_overlay.cpp +++ b/wled00/overlay.cpp @@ -1,7 +1,7 @@ -#include "wled_overlay.h" +#include "overlay.h" #include "wled.h" -#include "wled_cronixie.h" -#include "wled_ntp.h" +#include "cronixie.h" +#include "ntp.h" void initCronixie() { diff --git a/wled00/wled_overlay.h b/wled00/overlay.h similarity index 95% rename from wled00/wled_overlay.h rename to wled00/overlay.h index ec18f45b4..b403a6e23 100644 --- a/wled00/wled_overlay.h +++ b/wled00/overlay.h @@ -1,14 +1,14 @@ -#ifndef WLED_OVERLAYS_H -#define WLED_OVERLAYS_H -#include -/* - * Used to draw clock overlays over the strip - */ - -void initCronixie(); -void handleOverlays(); -void handleOverlayDraw(); -void _overlayAnalogCountdown(); -void _overlayAnalogClock(); - +#ifndef WLED_OVERLAYS_H +#define WLED_OVERLAYS_H +#include +/* + * Used to draw clock overlays over the strip + */ + +void initCronixie(); +void handleOverlays(); +void handleOverlayDraw(); +void _overlayAnalogCountdown(); +void _overlayAnalogClock(); + #endif // WLED_OVERLAY_H \ No newline at end of file diff --git a/wled00/wled_server.cpp b/wled00/server.cpp similarity index 99% rename from wled00/wled_server.cpp rename to wled00/server.cpp index 542abea4c..3249466cf 100644 --- a/wled00/wled_server.cpp +++ b/wled00/server.cpp @@ -1,9 +1,9 @@ -#include "wled_server.h" +#include "server.h" #include "wled.h" -#include "wled_file.h" -#include "wled_set.h" -#include "wled_json.h" -#include "wled_xml.h" +#include "file.h" +#include "set.h" +#include "json.h" +#include "xml.h" //Is this an IP? diff --git a/wled00/wled_server.h b/wled00/server.h similarity index 96% rename from wled00/wled_server.h rename to wled00/server.h index 46adc9629..ff7133d63 100644 --- a/wled00/wled_server.h +++ b/wled00/server.h @@ -1,21 +1,21 @@ -#ifndef WLED_SERVER_H -#define WLED_SERVER_H -#include -/* - * Server page declarations - */ -class AsyncWebServerRequest; - - -bool isIp(String str); -bool captivePortal(AsyncWebServerRequest *request); -void initServer(); -void serveIndexOrWelcome(AsyncWebServerRequest *request); -void serveIndex(AsyncWebServerRequest* request); -String msgProcessor(const String& var); -void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255); -String settingsProcessor(const String& var); -String dmxProcessor(const String& var); -void serveSettings(AsyncWebServerRequest* request); - +#ifndef WLED_SERVER_H +#define WLED_SERVER_H +#include +/* + * Server page declarations + */ +class AsyncWebServerRequest; + + +bool isIp(String str); +bool captivePortal(AsyncWebServerRequest *request); +void initServer(); +void serveIndexOrWelcome(AsyncWebServerRequest *request); +void serveIndex(AsyncWebServerRequest* request); +String msgProcessor(const String& var); +void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255); +String settingsProcessor(const String& var); +String dmxProcessor(const String& var); +void serveSettings(AsyncWebServerRequest* request); + #endif //WLED_SERVER_H \ No newline at end of file diff --git a/wled00/wled_set.cpp b/wled00/set.cpp similarity index 98% rename from wled00/wled_set.cpp rename to wled00/set.cpp index 66d9ff1ec..1dfeb19d0 100644 --- a/wled00/wled_set.cpp +++ b/wled00/set.cpp @@ -1,13 +1,13 @@ -#include "wled_set.h" +#include "set.h" #include "wled.h" -#include "wled_colors.h" -#include "wled_hue.h" -#include "wled_led.h" -#include "wled_blynk.h" -#include "wled_eeprom.h" -#include "wled_alexa.h" -#include "wled_cronixie.h" -#include "wled_xml.h" +#include "colors.h" +#include "hue.h" +#include "led.h" +#include "blynk.h" +#include "eeprom.h" +#include "alexa.h" +#include "cronixie.h" +#include "xml.h" void _setRandomColor(bool _sec,bool fromButton) { diff --git a/wled00/wled_set.h b/wled00/set.h similarity index 97% rename from wled00/wled_set.h rename to wled00/set.h index ebee8c928..6bc7dbd6c 100644 --- a/wled00/wled_set.h +++ b/wled00/set.h @@ -1,16 +1,16 @@ -#ifndef WLED_SET_H -#define WLED_SET_H -#include -#include -/* - * Receives client input - */ - -void _setRandomColor(bool _sec,bool fromButton=false); -bool isAsterisksOnly(const char* str, byte maxLen); -void handleSettingsSet(AsyncWebServerRequest *request, byte subPage); -bool handleSet(AsyncWebServerRequest *request, const String& req); -int getNumVal(const String* req, uint16_t pos); -bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255); - +#ifndef WLED_SET_H +#define WLED_SET_H +#include +#include +/* + * Receives client input + */ + +void _setRandomColor(bool _sec,bool fromButton=false); +bool isAsterisksOnly(const char* str, byte maxLen); +void handleSettingsSet(AsyncWebServerRequest *request, byte subPage); +bool handleSet(AsyncWebServerRequest *request, const String& req); +int getNumVal(const String* req, uint16_t pos); +bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255); + #endif // WLED_SET_H \ No newline at end of file diff --git a/wled00/wled_usermod.cpp b/wled00/usermod.cpp similarity index 100% rename from wled00/wled_usermod.cpp rename to wled00/usermod.cpp diff --git a/wled00/wled_usermod.h b/wled00/usermod.h similarity index 94% rename from wled00/wled_usermod.h rename to wled00/usermod.h index 61ef6b785..8269c6e92 100644 --- a/wled00/wled_usermod.h +++ b/wled00/usermod.h @@ -1,8 +1,8 @@ -#ifndef WLED_USERMOD_H -#define WLED_USERMOD_H - -void userSetup(); -void userConnected(); -void userLoop(); - +#ifndef WLED_USERMOD_H +#define WLED_USERMOD_H + +void userSetup(); +void userConnected(); +void userLoop(); + #endif // WLED_USERMOD_H \ No newline at end of file diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 3b3d6936d..106f503b2 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -1,882 +1,883 @@ -#include "wled.h" -#include -#include "wled_led.h" -#include "wled_ir.h" -#include "wled_notify.h" -#include "wled_alexa.h" -#include "wled_overlay.h" -#include "wled_file.h" -#include "wled_button.h" -#include "wled_ntp.h" -#include "wled_usermod.h" -#include "wled_blynk.h" -#include "wled_hue.h" -#include "wled_mqtt.h" -#include "wled_eeprom.h" -#include "wled_server.h" -// Global Variable definitions -char versionString[] = "0.9.1"; - -//AP and OTA default passwords (for maximum change them!) -char apPass[65] = DEFAULT_AP_PASS; -char otaPass[33] = DEFAULT_OTA_PASS; - -//Hardware CONFIG (only changeble HERE, not at runtime) -//LED strip pin, button pin and IR pin changeable in NpbWrapper.h! - -byte auxDefaultState = 0; //0: input 1: high 2: low -byte auxTriggeredState = 0; //0: input 1: high 2: low -char ntpServerName[33] = "0.wled.pool.ntp.org"; //NTP server to use - -//WiFi CONFIG (all these can be changed via web UI, no need to set them here) -char clientSSID[33] = CLIENT_SSID; -char clientPass[65] = CLIENT_PASS; -char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) -char apSSID[33] = ""; //AP off by default (unless setup) -byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) -byte apHide = 0; //hidden AP SSID -byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no connection after boot by default -IPAddress staticIP(0, 0, 0, 0); //static IP of ESP -IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP -IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks -bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues - -//LED CONFIG -uint16_t ledCount = 30; //overcurrent prevented by ABL -bool useRGBW = false; //SK6812 strips can contain an extra White channel -#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit -bool turnOnAtBoot = true; //turn on LEDs at power-up -byte bootPreset = 0; //save preset to load after power-up - -byte col[]{255, 160, 0, 0}; //current RGB(W) primary color. col[] should be updated if you want to change the color. -byte colSec[]{0, 0, 0, 0}; //current RGB(W) secondary color -byte briS = 128; //default brightness - -byte nightlightTargetBri = 0; //brightness after nightlight is over -byte nightlightDelayMins = 60; -bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over -bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. -bool fadeTransition = true; //enable crossfading color transition -uint16_t transitionDelay = 750; //default crossfade duration in ms - -bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) -byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) - -//User Interface CONFIG -char serverDescription[33] = "WLED"; //Name of module -bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise - -//Sync CONFIG -bool buttonEnabled = true; -byte irEnabled = 0; //Infrared receiver - -uint16_t udpPort = 21324; //WLED notifier default port -uint16_t udpRgbPort = 19446; //Hyperion port - -bool receiveNotificationBrightness = true; //apply brightness from incoming notifications -bool receiveNotificationColor = true; //apply color -bool receiveNotificationEffects = true; //apply effects setup -bool notifyDirect = false; //send notification if change via UI or HTTP API -bool notifyButton = false; //send if updated by button or infrared remote -bool notifyAlexa = false; //send notification if updated via Alexa -bool notifyMacro = false; //send notification for macro -bool notifyHue = true; //send notification if Hue light changes -bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably - -bool alexaEnabled = true; //enable device discovery by Amazon Echo -char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand - -char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made - -uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode -int arlsOffset = 0; //realtime LED offset -bool receiveDirect = true; //receive UDP realtime -bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source -bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black - -#define E131_MAX_UNIVERSE_COUNT 9 -uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) -uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] -uint8_t DMXOldDimmer = 0; //only update brightness on change -uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss -bool e131Multicast = false; //multicast or unicast -bool e131SkipOutOfSequence = false; //freeze instead of flickering - -bool mqttEnabled = false; -char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) -char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices) -char mqttServer[33] = ""; //both domains and IPs should work (no SSL) -char mqttUser[41] = ""; //optional: username for MQTT auth -char mqttPass[41] = ""; //optional: password for MQTT auth -char mqttClientID[41] = ""; //override the client ID -uint16_t mqttPort = 1883; - -bool huePollingEnabled = false; //poll hue bridge for light state -uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response -char hueApiKey[47] = "api"; //key token will be obtained from bridge -byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) -IPAddress hueIP = (0, 0, 0, 0); //IP address of the bridge -bool hueApplyOnOff = true; -bool hueApplyBri = true; -bool hueApplyColor = true; - -//Time CONFIG -bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros -bool useAMPM = false; //12h/24h clock format -byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino -int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation - -byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie -byte overlayMin = 0, overlayMax = ledCount - 1; //boundaries of overlay mode - -byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be -bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel -bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position - -char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino -bool cronixieBacklight = true; //Allow digits to be back-illuminated - -bool countdownMode = false; //Clock will count down towards date -byte countdownYear = 20, countdownMonth = 1; //Countdown target date, year is last two digits -byte countdownDay = 1, countdownHour = 0; -byte countdownMin = 0, countdownSec = 0; - -byte macroBoot = 0; //macro loaded after startup -byte macroNl = 0; //after nightlight delay over -byte macroCountdown = 0; -byte macroAlexaOn = 0, macroAlexaOff = 0; -byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; - -//Security CONFIG -bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks -bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled -bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on - -uint16_t userVar0 = 0, userVar1 = 0; - -#ifdef WLED_ENABLE_DMX -//dmx CONFIG -byte DMXChannels = 7; // number of channels per fixture -byte DMXFixtureMap[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -// assigns the different channels to different functions. See wled21_dmx.ino for more information. -uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. -uint16_t DMXStart = 10; // start address of the first fixture -#endif - -//internal global variable declarations -//wifi -bool apActive = false; -bool forceReconnect = false; -uint32_t lastReconnectAttempt = 0; -bool interfacesInited = false; -bool wasConnected = false; - -//color -byte colOld[]{0, 0, 0, 0}; //color before transition -byte colT[]{0, 0, 0, 0}; //color that is currently displayed on the LEDs -byte colIT[]{0, 0, 0, 0}; //color that was last sent to LEDs -byte colSecT[]{0, 0, 0, 0}; -byte colSecOld[]{0, 0, 0, 0}; -byte colSecIT[]{0, 0, 0, 0}; - -byte lastRandomIndex = 0; //used to save last random color so the new one is not the same - -//transitions -bool transitionActive = false; -uint16_t transitionDelayDefault = transitionDelay; -uint16_t transitionDelayTemp = transitionDelay; -unsigned long transitionStartTime; -float tperLast = 0; //crossfade transition progress, 0.0f - 1.0f -bool jsonTransitionOnce = false; - -//nightlight -bool nightlightActive = false; -bool nightlightActiveOld = false; -uint32_t nightlightDelayMs = 10; -uint8_t nightlightDelayMinsDefault = nightlightDelayMins; -unsigned long nightlightStartTime; -byte briNlT = 0; //current nightlight brightness -byte colNlT[]{0, 0, 0, 0}; //current nightlight color - -//brightness -unsigned long lastOnTime = 0; -bool offMode = !turnOnAtBoot; -byte bri = briS; -byte briOld = 0; -byte briT = 0; -byte briIT = 0; -byte briLast = 128; //brightness before turned off. Used for toggle function -byte whiteLast = 128; //white channel before turned off. Used for toggle function - -//button -bool buttonPressedBefore = false; -bool buttonLongPressed = false; -unsigned long buttonPressedTime = 0; -unsigned long buttonWaitTime = 0; - -//notifications -bool notifyDirectDefault = notifyDirect; -bool receiveNotifications = true; -unsigned long notificationSentTime = 0; -byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; -bool notificationTwoRequired = false; - -//effects -byte effectCurrent = 0; -byte effectSpeed = 128; -byte effectIntensity = 128; -byte effectPalette = 0; - -//network -bool udpConnected = false, udpRgbConnected = false; - -//ui style -bool showWelcomePage = false; - -//hue -byte hueError = HUE_ERROR_INACTIVE; -//uint16_t hueFailCount = 0; -float hueXLast = 0, hueYLast = 0; -uint16_t hueHueLast = 0, hueCtLast = 0; -byte hueSatLast = 0, hueBriLast = 0; -unsigned long hueLastRequestSent = 0; -bool hueAuthRequired = false; -bool hueReceived = false; -bool hueStoreAllowed = false, hueNewKey = false; - -//overlays -byte overlayCurrent = overlayDefault; -byte overlaySpeed = 200; -unsigned long overlayRefreshMs = 200; -unsigned long overlayRefreshedTime; - -//cronixie -byte dP[]{0, 0, 0, 0, 0, 0}; -bool cronixieInit = false; - -//countdown -unsigned long countdownTime = 1514764800L; -bool countdownOverTriggered = true; - -//timer -byte lastTimerMinute = 0; -byte timerHours[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMinutes[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMacro[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerWeekday[] = {255, 255, 255, 255, 255, 255, 255, 255}; //weekdays to activate on -//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity - -//blynk -bool blynkEnabled = false; - -//preset cycling -bool presetCyclingEnabled = false; -byte presetCycleMin = 1, presetCycleMax = 5; -uint16_t presetCycleTime = 1250; -unsigned long presetCycledTime = 0; -byte presetCycCurr = presetCycleMin; -bool presetApplyBri = true; -bool saveCurrPresetCycConf = false; - -//realtime -byte realtimeMode = REALTIME_MODE_INACTIVE; -IPAddress realtimeIP = (0, 0, 0, 0); -unsigned long realtimeTimeout = 0; - -//mqtt -long lastMqttReconnectAttempt = 0; -long lastInterfaceUpdate = 0; -byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; -char mqttStatusTopic[40] = ""; //this must be global because of async handlers - -#if AUXPIN >= 0 - //auxiliary debug pin -byte auxTime = 0; -unsigned long auxStartTime = 0; -bool auxActive = false, auxActiveBefore = false; -#endif - -//alexa udp -String escapedMac; -#ifndef WLED_DISABLE_ALEXA -Espalexa espalexa; -EspalexaDevice *espalexaDevice; -#endif - -//dns server -DNSServer dnsServer; - -//network time -bool ntpConnected = false; -time_t local = 0; -unsigned long ntpLastSyncTime = 999000000L; -unsigned long ntpPacketSentTime = 999000000L; -IPAddress ntpServerIP; -uint16_t ntpLocalPort = 2390; -#define NTP_PACKET_SIZE 48 - -//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue -#define MAX_LEDS 1500 -#define MAX_LEDS_DMA 500 - -//string temp buffer (now stored in stack locally) -#define OMAX 2048 -char *obuf; -uint16_t olen = 0; - -//presets -uint16_t savedPresets = 0; -int8_t currentPreset = -1; -bool isPreset = false; - -byte errorFlag = 0; - -String messageHead, messageSub; -byte optionType; - -bool doReboot = false; //flag to initiate reboot from async handlers -bool doPublishMqtt = false; - -//server library objects -AsyncWebServer server(80); -AsyncClient *hueClient = NULL; -AsyncMqttClient *mqtt = NULL; - -//function prototypes -void colorFromUint32(uint32_t, bool = false); -void serveMessage(AsyncWebServerRequest *, uint16_t, String, String, byte); -void handleE131Packet(e131_packet_t *, IPAddress); -void arlsLock(uint32_t, byte); -void handleOverlayDraw(); - -//udp interface objects -WiFiUDP notifierUdp, rgbUdp; -WiFiUDP ntpUdp; -ESPAsyncE131 e131(handleE131Packet); -bool e131NewData = false; - -//led fx library object -WS2812FX strip = WS2812FX(); - -#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) -#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) - -//debug macros -#ifdef WLED_DEBUG -#define DEBUG_PRINT(x) Serial.print(x) -#define DEBUG_PRINTLN(x) Serial.println(x) -#define DEBUG_PRINTF(x) Serial.printf(x) -unsigned long debugTime = 0; -int lastWifiState = 3; -unsigned long wifiStateChangedTime = 0; -int loops = 0; -#else -#define DEBUG_PRINT(x) -#define DEBUG_PRINTLN(x) -#define DEBUG_PRINTF(x) -#endif - - - -WLED::WLED() { - -} - -//turns all LEDs off and restarts ESP -void WLED::reset() -{ - briT = 0; - long dly = millis(); - while (millis() - dly < 250) - { - yield(); //enough time to send response to client - } - setAllLeds(); - DEBUG_PRINTLN("MODULE RESET"); - ESP.restart(); -} - -bool oappendi(int i) -{ - char s[11]; - sprintf(s, "%ld", i); - return oappend(s); -} - -bool oappend(const char *txt) -{ - uint16_t len = strlen(txt); - if (olen + len >= OMAX) - return false; //buffer full - strcpy(obuf + olen, txt); - olen += len; - return true; -} - -void WLED::loop() -{ - handleIR(); //2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too - handleConnection(); - handleSerial(); - handleNotifications(); - handleTransitions(); -#ifdef WLED_ENABLE_DMX - handleDMX(); -#endif - userLoop(); - - yield(); - handleIO(); - handleIR(); - handleNetworkTime(); - handleAlexa(); - - handleOverlays(); - yield(); -#ifdef WLED_USE_ANALOG_LEDS - strip.setRgbwPwm(); -#endif - - if (doReboot) - reset(); - - if (!realtimeMode) //block stuff if WARLS/Adalight is enabled - { - if (apActive) - dnsServer.processNextRequest(); -#ifndef WLED_DISABLE_OTA - if (WLED_CONNECTED && aOtaEnabled) - ArduinoOTA.handle(); -#endif - handleNightlight(); - yield(); - - handleHue(); - handleBlynk(); - - yield(); - if (!offMode) - strip.service(); - } - yield(); -#ifdef ESP8266 - MDNS.update(); -#endif - if (millis() - lastMqttReconnectAttempt > 30000) - initMqtt(); - -//DEBUG serial logging -#ifdef WLED_DEBUG - if (millis() - debugTime > 9999) - { - DEBUG_PRINTLN("---DEBUG INFO---"); - DEBUG_PRINT("Runtime: "); - DEBUG_PRINTLN(millis()); - DEBUG_PRINT("Unix time: "); - DEBUG_PRINTLN(now()); - DEBUG_PRINT("Free heap: "); - DEBUG_PRINTLN(ESP.getFreeHeap()); - DEBUG_PRINT("Wifi state: "); - DEBUG_PRINTLN(WiFi.status()); - if (WiFi.status() != lastWifiState) - { - wifiStateChangedTime = millis(); - } - lastWifiState = WiFi.status(); - DEBUG_PRINT("State time: "); - DEBUG_PRINTLN(wifiStateChangedTime); - DEBUG_PRINT("NTP last sync: "); - DEBUG_PRINTLN(ntpLastSyncTime); - DEBUG_PRINT("Client IP: "); - DEBUG_PRINTLN(WiFi.localIP()); - DEBUG_PRINT("Loops/sec: "); - DEBUG_PRINTLN(loops / 10); - loops = 0; - debugTime = millis(); - } - loops++; -#endif // WLED_DEBU -} - -void WLED::wledInit() -{ - EEPROM.begin(EEPSIZE); - ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); - if (ledCount > MAX_LEDS || ledCount == 0) - ledCount = 30; - -#ifdef ESP8266 -#if LEDPIN == 3 - if (ledCount > MAX_LEDS_DMA) - ledCount = MAX_LEDS_DMA; //DMA method uses too much ram -#endif -#endif - Serial.begin(115200); - Serial.setTimeout(50); - DEBUG_PRINTLN(); - DEBUG_PRINT("---WLED "); - DEBUG_PRINT(versionString); - DEBUG_PRINT(" "); - DEBUG_PRINT(VERSION); - DEBUG_PRINTLN(" INIT---"); -#ifdef ARDUINO_ARCH_ESP32 - DEBUG_PRINT("esp32 "); - DEBUG_PRINTLN(ESP.getSdkVersion()); -#else - DEBUG_PRINT("esp8266 "); - DEBUG_PRINTLN(ESP.getCoreVersion()); -#endif - int heapPreAlloc = ESP.getFreeHeap(); - DEBUG_PRINT("heap "); - DEBUG_PRINTLN(ESP.getFreeHeap()); - - strip.init(EEPROM.read(372), ledCount, EEPROM.read(2204)); //init LEDs quickly - strip.setBrightness(0); - - DEBUG_PRINT("LEDs inited. heap usage ~"); - DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap()); - -#ifndef WLED_DISABLE_FILESYSTEM -#ifdef ARDUINO_ARCH_ESP32 - SPIFFS.begin(true); -#endif - SPIFFS.begin(); -#endif - - DEBUG_PRINTLN("Load EEPROM"); - loadSettingsFromEEPROM(true); - beginStrip(); - userSetup(); - if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0) - showWelcomePage = true; - WiFi.persistent(false); - - if (macroBoot > 0) - applyMacro(macroBoot); - Serial.println("Ada"); - - //generate module IDs - escapedMac = WiFi.macAddress(); - escapedMac.replace(":", ""); - escapedMac.toLowerCase(); - if (strcmp(cmDNS, "x") == 0) //fill in unique mdns default - { - strcpy(cmDNS, "wled-"); - sprintf(cmDNS + 5, "%*s", 6, escapedMac.c_str() + 6); - } - if (mqttDeviceTopic[0] == 0) - { - strcpy(mqttDeviceTopic, "wled/"); - sprintf(mqttDeviceTopic + 5, "%*s", 6, escapedMac.c_str() + 6); - } - if (mqttClientID[0] == 0) - { - strcpy(mqttClientID, "WLED-"); - sprintf(mqttClientID + 5, "%*s", 6, escapedMac.c_str() + 6); - } - - strip.service(); - -#ifndef WLED_DISABLE_OTA - if (aOtaEnabled) - { - ArduinoOTA.onStart([]() { -#ifdef ESP8266 - wifi_set_sleep_type(NONE_SLEEP_T); -#endif - DEBUG_PRINTLN("Start ArduinoOTA"); - }); - if (strlen(cmDNS) > 0) - ArduinoOTA.setHostname(cmDNS); - } -#endif -#ifdef WLED_ENABLE_DMX - dmx.init(512); // initialize with bus length -#endif - //HTTP server page init - initServer(); -} - -void WLED::beginStrip() -{ - // Initialize NeoPixel Strip and button - strip.setShowCallback(handleOverlayDraw); - -#ifdef BTNPIN - pinMode(BTNPIN, INPUT_PULLUP); -#endif - - if (bootPreset > 0) - applyPreset(bootPreset, turnOnAtBoot); - colorUpdated(NOTIFIER_CALL_MODE_INIT); - -//init relay pin -#if RLYPIN >= 0 - pinMode(RLYPIN, OUTPUT); -#if RLYMDE - digitalWrite(RLYPIN, bri); -#else - digitalWrite(RLYPIN, !bri); -#endif -#endif - - //disable button if it is "pressed" unintentionally -#ifdef BTNPIN - if (digitalRead(BTNPIN) == LOW) - buttonEnabled = false; -#else - buttonEnabled = false; -#endif -} - -void WLED::initAP(bool resetAP) -{ - if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) - return; - - if (!apSSID[0] || resetAP) - strcpy(apSSID, "WLED-AP"); - if (resetAP) - strcpy(apPass, DEFAULT_AP_PASS); - DEBUG_PRINT("Opening access point "); - DEBUG_PRINTLN(apSSID); - WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0)); - WiFi.softAP(apSSID, apPass, apChannel, apHide); - - if (!apActive) //start captive portal if AP active - { - DEBUG_PRINTLN("Init AP interfaces"); - server.begin(); - if (udpPort > 0 && udpPort != ntpLocalPort) - { - udpConnected = notifierUdp.begin(udpPort); - } - if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) - { - udpRgbConnected = rgbUdp.begin(udpRgbPort); - } - - dnsServer.setErrorReplyCode(DNSReplyCode::NoError); - dnsServer.start(53, "*", WiFi.softAPIP()); - } - apActive = true; -} - -void WLED::initConnection() -{ - WiFi.disconnect(); //close old connections -#ifdef ESP8266 - WiFi.setPhyMode(WIFI_PHY_MODE_11N); -#endif - - if (staticIP[0] != 0 && staticGateway[0] != 0) - { - WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8, 8, 8, 8)); - } - else - { - WiFi.config(0U, 0U, 0U); - } - - lastReconnectAttempt = millis(); - - if (!WLED_WIFI_CONFIGURED) - { - DEBUG_PRINT("No connection configured. "); - if (!apActive) - initAP(); //instantly go to ap mode - return; - } - else if (!apActive) - { - if (apBehavior == AP_BEHAVIOR_ALWAYS) - { - initAP(); - } - else - { - DEBUG_PRINTLN("Access point disabled."); - WiFi.softAPdisconnect(true); - } - } - showWelcomePage = false; - - DEBUG_PRINT("Connecting to "); - DEBUG_PRINT(clientSSID); - DEBUG_PRINTLN("..."); - -#ifdef ESP8266 - WiFi.hostname(serverDescription); -#endif - - WiFi.begin(clientSSID, clientPass); - -#ifdef ARDUINO_ARCH_ESP32 - WiFi.setSleep(!noWifiSleep); - WiFi.setHostname(serverDescription); -#else - wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); -#endif -} - -void WLED::initInterfaces() -{ - DEBUG_PRINTLN("Init STA interfaces"); - - if (hueIP[0] == 0) - { - hueIP[0] = WiFi.localIP()[0]; - hueIP[1] = WiFi.localIP()[1]; - hueIP[2] = WiFi.localIP()[2]; - } - - //init Alexa hue emulation - if (alexaEnabled) - alexaInit(); - -#ifndef WLED_DISABLE_OTA - if (aOtaEnabled) - ArduinoOTA.begin(); -#endif - - strip.service(); - // Set up mDNS responder: - if (strlen(cmDNS) > 0) - { - if (!aOtaEnabled) - MDNS.begin(cmDNS); - - DEBUG_PRINTLN("mDNS started"); - MDNS.addService("http", "tcp", 80); - MDNS.addService("wled", "tcp", 80); - MDNS.addServiceTxt("wled", "tcp", "mac", escapedMac.c_str()); - } - server.begin(); - - if (udpPort > 0 && udpPort != ntpLocalPort) - { - udpConnected = notifierUdp.begin(udpPort); - if (udpConnected && udpRgbPort != udpPort) - udpRgbConnected = rgbUdp.begin(udpRgbPort); - } - if (ntpEnabled) - ntpConnected = ntpUdp.begin(ntpLocalPort); - - initBlynk(blynkApiKey); - e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST, e131Universe, E131_MAX_UNIVERSE_COUNT); - reconnectHue(); - initMqtt(); - interfacesInited = true; - wasConnected = true; -} - -byte stacO = 0; -uint32_t lastHeap; -unsigned long heapTime = 0; - -void WLED::handleConnection() -{ - if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) - return; - if (lastReconnectAttempt == 0) - initConnection(); - - //reconnect WiFi to clear stale allocations if heap gets too low - if (millis() - heapTime > 5000) - { - uint32_t heap = ESP.getFreeHeap(); - if (heap < 9000 && lastHeap < 9000) - { - DEBUG_PRINT("Heap too low! "); - DEBUG_PRINTLN(heap); - forceReconnect = true; - } - lastHeap = heap; - heapTime = millis(); - } - - byte stac = 0; - if (apActive) - { -#ifdef ESP8266 - stac = wifi_softap_get_station_num(); -#else - wifi_sta_list_t stationList; - esp_wifi_ap_get_sta_list(&stationList); - stac = stationList.num; -#endif - if (stac != stacO) - { - stacO = stac; - DEBUG_PRINT("Connected AP clients: "); - DEBUG_PRINTLN(stac); - if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) - { //trying to connect, but not connected - if (stac) - WiFi.disconnect(); //disable search so that AP can work - else - initConnection(); //restart search - } - } - } - if (forceReconnect) - { - DEBUG_PRINTLN("Forcing reconnect."); - initConnection(); - interfacesInited = false; - forceReconnect = false; - wasConnected = false; - return; - } - if (!WLED_CONNECTED) - { - if (interfacesInited) - { - DEBUG_PRINTLN("Disconnected!"); - interfacesInited = false; - initConnection(); - } - if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) - initConnection(); - if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) - initAP(); - } - else if (!interfacesInited) - { //newly connected - DEBUG_PRINTLN(""); - DEBUG_PRINT("Connected! IP address: "); - DEBUG_PRINTLN(WiFi.localIP()); - initInterfaces(); - userConnected(); - - //shut down AP - if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) - { - dnsServer.stop(); - WiFi.softAPdisconnect(true); - apActive = false; - DEBUG_PRINTLN("Access point disabled."); - } - } -} - -//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp -int getSignalQuality(int rssi) -{ - int quality = 0; - - if (rssi <= -100) - { - quality = 0; - } - else if (rssi >= -50) - { - quality = 100; - } - else - { - quality = 2 * (rssi + 100); - } - return quality; +#include "wled.h" +#include +#include "led.h" +#include "ir.h" +#include "notify.h" +#include "alexa.h" +#include "overlay.h" +#include "file.h" +#include "button.h" +#include "ntp.h" +#include "usermod.h" +#include "blynk.h" +#include "hue.h" +#include "mqtt.h" +#include "eeprom.h" +#include "server.h" +// replaced +// Global Variable definitions +char versionString[] = "0.9.1"; + +//AP and OTA default passwords (for maximum change them!) +char apPass[65] = DEFAULT_AP_PASS; +char otaPass[33] = DEFAULT_OTA_PASS; + +//Hardware CONFIG (only changeble HERE, not at runtime) +//LED strip pin, button pin and IR pin changeable in NpbWrapper.h! + +byte auxDefaultState = 0; //0: input 1: high 2: low +byte auxTriggeredState = 0; //0: input 1: high 2: low +char ntpServerName[33] = "0.wled.pool.ntp.org"; //NTP server to use + +//WiFi CONFIG (all these can be changed via web UI, no need to set them here) +char clientSSID[33] = CLIENT_SSID; +char clientPass[65] = CLIENT_PASS; +char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) +char apSSID[33] = ""; //AP off by default (unless setup) +byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) +byte apHide = 0; //hidden AP SSID +byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no connection after boot by default +IPAddress staticIP(0, 0, 0, 0); //static IP of ESP +IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP +IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks +bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues + +//LED CONFIG +uint16_t ledCount = 30; //overcurrent prevented by ABL +bool useRGBW = false; //SK6812 strips can contain an extra White channel +#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit +bool turnOnAtBoot = true; //turn on LEDs at power-up +byte bootPreset = 0; //save preset to load after power-up + +byte col[]{255, 160, 0, 0}; //current RGB(W) primary color. col[] should be updated if you want to change the color. +byte colSec[]{0, 0, 0, 0}; //current RGB(W) secondary color +byte briS = 128; //default brightness + +byte nightlightTargetBri = 0; //brightness after nightlight is over +byte nightlightDelayMins = 60; +bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over +bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. +bool fadeTransition = true; //enable crossfading color transition +uint16_t transitionDelay = 750; //default crossfade duration in ms + +bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) +byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) + +//User Interface CONFIG +char serverDescription[33] = "WLED"; //Name of module +bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise + +//Sync CONFIG +bool buttonEnabled = true; +byte irEnabled = 0; //Infrared receiver + +uint16_t udpPort = 21324; //WLED notifier default port +uint16_t udpRgbPort = 19446; //Hyperion port + +bool receiveNotificationBrightness = true; //apply brightness from incoming notifications +bool receiveNotificationColor = true; //apply color +bool receiveNotificationEffects = true; //apply effects setup +bool notifyDirect = false; //send notification if change via UI or HTTP API +bool notifyButton = false; //send if updated by button or infrared remote +bool notifyAlexa = false; //send notification if updated via Alexa +bool notifyMacro = false; //send notification for macro +bool notifyHue = true; //send notification if Hue light changes +bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably + +bool alexaEnabled = true; //enable device discovery by Amazon Echo +char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand + +char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made + +uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode +int arlsOffset = 0; //realtime LED offset +bool receiveDirect = true; //receive UDP realtime +bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source +bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black + +#define E131_MAX_UNIVERSE_COUNT 9 +uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) +uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) +uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +uint8_t DMXOldDimmer = 0; //only update brightness on change +uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss +bool e131Multicast = false; //multicast or unicast +bool e131SkipOutOfSequence = false; //freeze instead of flickering + +bool mqttEnabled = false; +char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) +char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices) +char mqttServer[33] = ""; //both domains and IPs should work (no SSL) +char mqttUser[41] = ""; //optional: username for MQTT auth +char mqttPass[41] = ""; //optional: password for MQTT auth +char mqttClientID[41] = ""; //override the client ID +uint16_t mqttPort = 1883; + +bool huePollingEnabled = false; //poll hue bridge for light state +uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response +char hueApiKey[47] = "api"; //key token will be obtained from bridge +byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) +IPAddress hueIP = (0, 0, 0, 0); //IP address of the bridge +bool hueApplyOnOff = true; +bool hueApplyBri = true; +bool hueApplyColor = true; + +//Time CONFIG +bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros +bool useAMPM = false; //12h/24h clock format +byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino +int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation + +byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie +byte overlayMin = 0, overlayMax = ledCount - 1; //boundaries of overlay mode + +byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be +bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel +bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position + +char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino +bool cronixieBacklight = true; //Allow digits to be back-illuminated + +bool countdownMode = false; //Clock will count down towards date +byte countdownYear = 20, countdownMonth = 1; //Countdown target date, year is last two digits +byte countdownDay = 1, countdownHour = 0; +byte countdownMin = 0, countdownSec = 0; + +byte macroBoot = 0; //macro loaded after startup +byte macroNl = 0; //after nightlight delay over +byte macroCountdown = 0; +byte macroAlexaOn = 0, macroAlexaOff = 0; +byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; + +//Security CONFIG +bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks +bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled +bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on + +uint16_t userVar0 = 0, userVar1 = 0; + +#ifdef WLED_ENABLE_DMX +//dmx CONFIG +byte DMXChannels = 7; // number of channels per fixture +byte DMXFixtureMap[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +// assigns the different channels to different functions. See wled21_dmx.ino for more information. +uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. +uint16_t DMXStart = 10; // start address of the first fixture +#endif + +//internal global variable declarations +//wifi +bool apActive = false; +bool forceReconnect = false; +uint32_t lastReconnectAttempt = 0; +bool interfacesInited = false; +bool wasConnected = false; + +//color +byte colOld[]{0, 0, 0, 0}; //color before transition +byte colT[]{0, 0, 0, 0}; //color that is currently displayed on the LEDs +byte colIT[]{0, 0, 0, 0}; //color that was last sent to LEDs +byte colSecT[]{0, 0, 0, 0}; +byte colSecOld[]{0, 0, 0, 0}; +byte colSecIT[]{0, 0, 0, 0}; + +byte lastRandomIndex = 0; //used to save last random color so the new one is not the same + +//transitions +bool transitionActive = false; +uint16_t transitionDelayDefault = transitionDelay; +uint16_t transitionDelayTemp = transitionDelay; +unsigned long transitionStartTime; +float tperLast = 0; //crossfade transition progress, 0.0f - 1.0f +bool jsonTransitionOnce = false; + +//nightlight +bool nightlightActive = false; +bool nightlightActiveOld = false; +uint32_t nightlightDelayMs = 10; +uint8_t nightlightDelayMinsDefault = nightlightDelayMins; +unsigned long nightlightStartTime; +byte briNlT = 0; //current nightlight brightness +byte colNlT[]{0, 0, 0, 0}; //current nightlight color + +//brightness +unsigned long lastOnTime = 0; +bool offMode = !turnOnAtBoot; +byte bri = briS; +byte briOld = 0; +byte briT = 0; +byte briIT = 0; +byte briLast = 128; //brightness before turned off. Used for toggle function +byte whiteLast = 128; //white channel before turned off. Used for toggle function + +//button +bool buttonPressedBefore = false; +bool buttonLongPressed = false; +unsigned long buttonPressedTime = 0; +unsigned long buttonWaitTime = 0; + +//notifications +bool notifyDirectDefault = notifyDirect; +bool receiveNotifications = true; +unsigned long notificationSentTime = 0; +byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; +bool notificationTwoRequired = false; + +//effects +byte effectCurrent = 0; +byte effectSpeed = 128; +byte effectIntensity = 128; +byte effectPalette = 0; + +//network +bool udpConnected = false, udpRgbConnected = false; + +//ui style +bool showWelcomePage = false; + +//hue +byte hueError = HUE_ERROR_INACTIVE; +//uint16_t hueFailCount = 0; +float hueXLast = 0, hueYLast = 0; +uint16_t hueHueLast = 0, hueCtLast = 0; +byte hueSatLast = 0, hueBriLast = 0; +unsigned long hueLastRequestSent = 0; +bool hueAuthRequired = false; +bool hueReceived = false; +bool hueStoreAllowed = false, hueNewKey = false; + +//overlays +byte overlayCurrent = overlayDefault; +byte overlaySpeed = 200; +unsigned long overlayRefreshMs = 200; +unsigned long overlayRefreshedTime; + +//cronixie +byte dP[]{0, 0, 0, 0, 0, 0}; +bool cronixieInit = false; + +//countdown +unsigned long countdownTime = 1514764800L; +bool countdownOverTriggered = true; + +//timer +byte lastTimerMinute = 0; +byte timerHours[] = {0, 0, 0, 0, 0, 0, 0, 0}; +byte timerMinutes[] = {0, 0, 0, 0, 0, 0, 0, 0}; +byte timerMacro[] = {0, 0, 0, 0, 0, 0, 0, 0}; +byte timerWeekday[] = {255, 255, 255, 255, 255, 255, 255, 255}; //weekdays to activate on +//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity + +//blynk +bool blynkEnabled = false; + +//preset cycling +bool presetCyclingEnabled = false; +byte presetCycleMin = 1, presetCycleMax = 5; +uint16_t presetCycleTime = 1250; +unsigned long presetCycledTime = 0; +byte presetCycCurr = presetCycleMin; +bool presetApplyBri = true; +bool saveCurrPresetCycConf = false; + +//realtime +byte realtimeMode = REALTIME_MODE_INACTIVE; +IPAddress realtimeIP = (0, 0, 0, 0); +unsigned long realtimeTimeout = 0; + +//mqtt +long lastMqttReconnectAttempt = 0; +long lastInterfaceUpdate = 0; +byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; +char mqttStatusTopic[40] = ""; //this must be global because of async handlers + +#if AUXPIN >= 0 + //auxiliary debug pin +byte auxTime = 0; +unsigned long auxStartTime = 0; +bool auxActive = false, auxActiveBefore = false; +#endif + +//alexa udp +String escapedMac; +#ifndef WLED_DISABLE_ALEXA +Espalexa espalexa; +EspalexaDevice *espalexaDevice; +#endif + +//dns server +DNSServer dnsServer; + +//network time +bool ntpConnected = false; +time_t local = 0; +unsigned long ntpLastSyncTime = 999000000L; +unsigned long ntpPacketSentTime = 999000000L; +IPAddress ntpServerIP; +uint16_t ntpLocalPort = 2390; +#define NTP_PACKET_SIZE 48 + +//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue +#define MAX_LEDS 1500 +#define MAX_LEDS_DMA 500 + +//string temp buffer (now stored in stack locally) +#define OMAX 2048 +char *obuf; +uint16_t olen = 0; + +//presets +uint16_t savedPresets = 0; +int8_t currentPreset = -1; +bool isPreset = false; + +byte errorFlag = 0; + +String messageHead, messageSub; +byte optionType; + +bool doReboot = false; //flag to initiate reboot from async handlers +bool doPublishMqtt = false; + +//server library objects +AsyncWebServer server(80); +AsyncClient *hueClient = NULL; +AsyncMqttClient *mqtt = NULL; + +//function prototypes +void colorFromUint32(uint32_t, bool = false); +void serveMessage(AsyncWebServerRequest *, uint16_t, String, String, byte); +void handleE131Packet(e131_packet_t *, IPAddress); +void arlsLock(uint32_t, byte); +void handleOverlayDraw(); + +//udp interface objects +WiFiUDP notifierUdp, rgbUdp; +WiFiUDP ntpUdp; +ESPAsyncE131 e131(handleE131Packet); +bool e131NewData = false; + +//led fx library object +WS2812FX strip = WS2812FX(); + +#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) +#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) + +//debug macros +#ifdef WLED_DEBUG +#define DEBUG_PRINT(x) Serial.print(x) +#define DEBUG_PRINTLN(x) Serial.println(x) +#define DEBUG_PRINTF(x) Serial.printf(x) +unsigned long debugTime = 0; +int lastWifiState = 3; +unsigned long wifiStateChangedTime = 0; +int loops = 0; +#else +#define DEBUG_PRINT(x) +#define DEBUG_PRINTLN(x) +#define DEBUG_PRINTF(x) +#endif + + + +WLED::WLED() { + +} + +//turns all LEDs off and restarts ESP +void WLED::reset() +{ + briT = 0; + long dly = millis(); + while (millis() - dly < 250) + { + yield(); //enough time to send response to client + } + setAllLeds(); + DEBUG_PRINTLN("MODULE RESET"); + ESP.restart(); +} + +bool oappendi(int i) +{ + char s[11]; + sprintf(s, "%ld", i); + return oappend(s); +} + +bool oappend(const char *txt) +{ + uint16_t len = strlen(txt); + if (olen + len >= OMAX) + return false; //buffer full + strcpy(obuf + olen, txt); + olen += len; + return true; +} + +void WLED::loop() +{ + handleIR(); //2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too + handleConnection(); + handleSerial(); + handleNotifications(); + handleTransitions(); +#ifdef WLED_ENABLE_DMX + handleDMX(); +#endif + userLoop(); + + yield(); + handleIO(); + handleIR(); + handleNetworkTime(); + handleAlexa(); + + handleOverlays(); + yield(); +#ifdef WLED_USE_ANALOG_LEDS + strip.setRgbwPwm(); +#endif + + if (doReboot) + reset(); + + if (!realtimeMode) //block stuff if WARLS/Adalight is enabled + { + if (apActive) + dnsServer.processNextRequest(); +#ifndef WLED_DISABLE_OTA + if (WLED_CONNECTED && aOtaEnabled) + ArduinoOTA.handle(); +#endif + handleNightlight(); + yield(); + + handleHue(); + handleBlynk(); + + yield(); + if (!offMode) + strip.service(); + } + yield(); +#ifdef ESP8266 + MDNS.update(); +#endif + if (millis() - lastMqttReconnectAttempt > 30000) + initMqtt(); + +//DEBUG serial logging +#ifdef WLED_DEBUG + if (millis() - debugTime > 9999) + { + DEBUG_PRINTLN("---DEBUG INFO---"); + DEBUG_PRINT("Runtime: "); + DEBUG_PRINTLN(millis()); + DEBUG_PRINT("Unix time: "); + DEBUG_PRINTLN(now()); + DEBUG_PRINT("Free heap: "); + DEBUG_PRINTLN(ESP.getFreeHeap()); + DEBUG_PRINT("Wifi state: "); + DEBUG_PRINTLN(WiFi.status()); + if (WiFi.status() != lastWifiState) + { + wifiStateChangedTime = millis(); + } + lastWifiState = WiFi.status(); + DEBUG_PRINT("State time: "); + DEBUG_PRINTLN(wifiStateChangedTime); + DEBUG_PRINT("NTP last sync: "); + DEBUG_PRINTLN(ntpLastSyncTime); + DEBUG_PRINT("Client IP: "); + DEBUG_PRINTLN(WiFi.localIP()); + DEBUG_PRINT("Loops/sec: "); + DEBUG_PRINTLN(loops / 10); + loops = 0; + debugTime = millis(); + } + loops++; +#endif // WLED_DEBU +} + +void WLED::wledInit() +{ + EEPROM.begin(EEPSIZE); + ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); + if (ledCount > MAX_LEDS || ledCount == 0) + ledCount = 30; + +#ifdef ESP8266 +#if LEDPIN == 3 + if (ledCount > MAX_LEDS_DMA) + ledCount = MAX_LEDS_DMA; //DMA method uses too much ram +#endif +#endif + Serial.begin(115200); + Serial.setTimeout(50); + DEBUG_PRINTLN(); + DEBUG_PRINT("---WLED "); + DEBUG_PRINT(versionString); + DEBUG_PRINT(" "); + DEBUG_PRINT(VERSION); + DEBUG_PRINTLN(" INIT---"); +#ifdef ARDUINO_ARCH_ESP32 + DEBUG_PRINT("esp32 "); + DEBUG_PRINTLN(ESP.getSdkVersion()); +#else + DEBUG_PRINT("esp8266 "); + DEBUG_PRINTLN(ESP.getCoreVersion()); +#endif + int heapPreAlloc = ESP.getFreeHeap(); + DEBUG_PRINT("heap "); + DEBUG_PRINTLN(ESP.getFreeHeap()); + + strip.init(EEPROM.read(372), ledCount, EEPROM.read(2204)); //init LEDs quickly + strip.setBrightness(0); + + DEBUG_PRINT("LEDs inited. heap usage ~"); + DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap()); + +#ifndef WLED_DISABLE_FILESYSTEM +#ifdef ARDUINO_ARCH_ESP32 + SPIFFS.begin(true); +#endif + SPIFFS.begin(); +#endif + + DEBUG_PRINTLN("Load EEPROM"); + loadSettingsFromEEPROM(true); + beginStrip(); + userSetup(); + if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0) + showWelcomePage = true; + WiFi.persistent(false); + + if (macroBoot > 0) + applyMacro(macroBoot); + Serial.println("Ada"); + + //generate module IDs + escapedMac = WiFi.macAddress(); + escapedMac.replace(":", ""); + escapedMac.toLowerCase(); + if (strcmp(cmDNS, "x") == 0) //fill in unique mdns default + { + strcpy(cmDNS, "wled-"); + sprintf(cmDNS + 5, "%*s", 6, escapedMac.c_str() + 6); + } + if (mqttDeviceTopic[0] == 0) + { + strcpy(mqttDeviceTopic, "wled/"); + sprintf(mqttDeviceTopic + 5, "%*s", 6, escapedMac.c_str() + 6); + } + if (mqttClientID[0] == 0) + { + strcpy(mqttClientID, "WLED-"); + sprintf(mqttClientID + 5, "%*s", 6, escapedMac.c_str() + 6); + } + + strip.service(); + +#ifndef WLED_DISABLE_OTA + if (aOtaEnabled) + { + ArduinoOTA.onStart([]() { +#ifdef ESP8266 + wifi_set_sleep_type(NONE_SLEEP_T); +#endif + DEBUG_PRINTLN("Start ArduinoOTA"); + }); + if (strlen(cmDNS) > 0) + ArduinoOTA.setHostname(cmDNS); + } +#endif +#ifdef WLED_ENABLE_DMX + dmx.init(512); // initialize with bus length +#endif + //HTTP server page init + initServer(); +} + +void WLED::beginStrip() +{ + // Initialize NeoPixel Strip and button + strip.setShowCallback(handleOverlayDraw); + +#ifdef BTNPIN + pinMode(BTNPIN, INPUT_PULLUP); +#endif + + if (bootPreset > 0) + applyPreset(bootPreset, turnOnAtBoot); + colorUpdated(NOTIFIER_CALL_MODE_INIT); + +//init relay pin +#if RLYPIN >= 0 + pinMode(RLYPIN, OUTPUT); +#if RLYMDE + digitalWrite(RLYPIN, bri); +#else + digitalWrite(RLYPIN, !bri); +#endif +#endif + + //disable button if it is "pressed" unintentionally +#ifdef BTNPIN + if (digitalRead(BTNPIN) == LOW) + buttonEnabled = false; +#else + buttonEnabled = false; +#endif +} + +void WLED::initAP(bool resetAP) +{ + if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) + return; + + if (!apSSID[0] || resetAP) + strcpy(apSSID, "WLED-AP"); + if (resetAP) + strcpy(apPass, DEFAULT_AP_PASS); + DEBUG_PRINT("Opening access point "); + DEBUG_PRINTLN(apSSID); + WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0)); + WiFi.softAP(apSSID, apPass, apChannel, apHide); + + if (!apActive) //start captive portal if AP active + { + DEBUG_PRINTLN("Init AP interfaces"); + server.begin(); + if (udpPort > 0 && udpPort != ntpLocalPort) + { + udpConnected = notifierUdp.begin(udpPort); + } + if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) + { + udpRgbConnected = rgbUdp.begin(udpRgbPort); + } + + dnsServer.setErrorReplyCode(DNSReplyCode::NoError); + dnsServer.start(53, "*", WiFi.softAPIP()); + } + apActive = true; +} + +void WLED::initConnection() +{ + WiFi.disconnect(); //close old connections +#ifdef ESP8266 + WiFi.setPhyMode(WIFI_PHY_MODE_11N); +#endif + + if (staticIP[0] != 0 && staticGateway[0] != 0) + { + WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8, 8, 8, 8)); + } + else + { + WiFi.config(0U, 0U, 0U); + } + + lastReconnectAttempt = millis(); + + if (!WLED_WIFI_CONFIGURED) + { + DEBUG_PRINT("No connection configured. "); + if (!apActive) + initAP(); //instantly go to ap mode + return; + } + else if (!apActive) + { + if (apBehavior == AP_BEHAVIOR_ALWAYS) + { + initAP(); + } + else + { + DEBUG_PRINTLN("Access point disabled."); + WiFi.softAPdisconnect(true); + } + } + showWelcomePage = false; + + DEBUG_PRINT("Connecting to "); + DEBUG_PRINT(clientSSID); + DEBUG_PRINTLN("..."); + +#ifdef ESP8266 + WiFi.hostname(serverDescription); +#endif + + WiFi.begin(clientSSID, clientPass); + +#ifdef ARDUINO_ARCH_ESP32 + WiFi.setSleep(!noWifiSleep); + WiFi.setHostname(serverDescription); +#else + wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); +#endif +} + +void WLED::initInterfaces() +{ + DEBUG_PRINTLN("Init STA interfaces"); + + if (hueIP[0] == 0) + { + hueIP[0] = WiFi.localIP()[0]; + hueIP[1] = WiFi.localIP()[1]; + hueIP[2] = WiFi.localIP()[2]; + } + + //init Alexa hue emulation + if (alexaEnabled) + alexaInit(); + +#ifndef WLED_DISABLE_OTA + if (aOtaEnabled) + ArduinoOTA.begin(); +#endif + + strip.service(); + // Set up mDNS responder: + if (strlen(cmDNS) > 0) + { + if (!aOtaEnabled) + MDNS.begin(cmDNS); + + DEBUG_PRINTLN("mDNS started"); + MDNS.addService("http", "tcp", 80); + MDNS.addService("wled", "tcp", 80); + MDNS.addServiceTxt("wled", "tcp", "mac", escapedMac.c_str()); + } + server.begin(); + + if (udpPort > 0 && udpPort != ntpLocalPort) + { + udpConnected = notifierUdp.begin(udpPort); + if (udpConnected && udpRgbPort != udpPort) + udpRgbConnected = rgbUdp.begin(udpRgbPort); + } + if (ntpEnabled) + ntpConnected = ntpUdp.begin(ntpLocalPort); + + initBlynk(blynkApiKey); + e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST, e131Universe, E131_MAX_UNIVERSE_COUNT); + reconnectHue(); + initMqtt(); + interfacesInited = true; + wasConnected = true; +} + +byte stacO = 0; +uint32_t lastHeap; +unsigned long heapTime = 0; + +void WLED::handleConnection() +{ + if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) + return; + if (lastReconnectAttempt == 0) + initConnection(); + + //reconnect WiFi to clear stale allocations if heap gets too low + if (millis() - heapTime > 5000) + { + uint32_t heap = ESP.getFreeHeap(); + if (heap < 9000 && lastHeap < 9000) + { + DEBUG_PRINT("Heap too low! "); + DEBUG_PRINTLN(heap); + forceReconnect = true; + } + lastHeap = heap; + heapTime = millis(); + } + + byte stac = 0; + if (apActive) + { +#ifdef ESP8266 + stac = wifi_softap_get_station_num(); +#else + wifi_sta_list_t stationList; + esp_wifi_ap_get_sta_list(&stationList); + stac = stationList.num; +#endif + if (stac != stacO) + { + stacO = stac; + DEBUG_PRINT("Connected AP clients: "); + DEBUG_PRINTLN(stac); + if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) + { //trying to connect, but not connected + if (stac) + WiFi.disconnect(); //disable search so that AP can work + else + initConnection(); //restart search + } + } + } + if (forceReconnect) + { + DEBUG_PRINTLN("Forcing reconnect."); + initConnection(); + interfacesInited = false; + forceReconnect = false; + wasConnected = false; + return; + } + if (!WLED_CONNECTED) + { + if (interfacesInited) + { + DEBUG_PRINTLN("Disconnected!"); + interfacesInited = false; + initConnection(); + } + if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) + initConnection(); + if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) + initAP(); + } + else if (!interfacesInited) + { //newly connected + DEBUG_PRINTLN(""); + DEBUG_PRINT("Connected! IP address: "); + DEBUG_PRINTLN(WiFi.localIP()); + initInterfaces(); + userConnected(); + + //shut down AP + if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) + { + dnsServer.stop(); + WiFi.softAPdisconnect(true); + apActive = false; + DEBUG_PRINTLN("Access point disabled."); + } + } +} + +//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp +int getSignalQuality(int rssi) +{ + int quality = 0; + + if (rssi <= -100) + { + quality = 0; + } + else if (rssi >= -50) + { + quality = 100; + } + else + { + quality = 2 * (rssi + 100); + } + return quality; } \ No newline at end of file diff --git a/wled00/wled.h b/wled00/wled.h index 3b744bcd4..c6f791cd4 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -1,519 +1,519 @@ -#ifndef WLED_H -#define WLED_H - -/* - Main sketch, global variable declarations -*/ -/* - * @title WLED project sketch - * @version 0.9.1 - * @author Christian Schwinne - */ - -//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). - -//ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). -//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): - -//You are required to disable over-the-air updates: -//#define WLED_DISABLE_OTA //saves 14kb - -//You need to choose some of these features to disable: -//#define WLED_DISABLE_ALEXA //saves 11kb -//#define WLED_DISABLE_BLYNK //saves 6kb -//#define WLED_DISABLE_CRONIXIE //saves 3kb -//#define WLED_DISABLE_HUESYNC //saves 4kb -//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 12kb -#define WLED_ENABLE_MQTT //saves 12kb -#define WLED_ENABLE_ADALIGHT //saves 500b only -//#define WLED_ENABLE_DMX //uses 3.5kb - -#define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet -//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version -//#define WLED_ENABLE_FS_EDITOR //enable /edit page for editing SPIFFS content. Will also be disabled with OTA lock - -//to toggle usb serial debug (un)comment the following line -//#define WLED_DEBUG - -//library inclusions -#include -#ifdef WLED_ENABLE_DMX -#include -DMXESPSerial dmx; -#endif -#ifdef ESP8266 -#include -#include -#include -extern "C" -{ -#include -} -#else //ESP32 -#include -#include "esp_wifi.h" -#include -#include -#include "SPIFFS.h" -#endif - -#include -#include -#include -#include -#ifndef WLED_DISABLE_OTA -#include -#endif -#include -#include "src/dependencies/time/TimeLib.h" -#include "src/dependencies/timezone/Timezone.h" -#ifndef WLED_DISABLE_ALEXA -#define ESPALEXA_ASYNC -#define ESPALEXA_NO_SUBPAGE -#define ESPALEXA_MAXDEVICES 1 -// #define ESPALEXA_DEBUG -#include "src/dependencies/espalexa/Espalexa.h" -#endif -#ifndef WLED_DISABLE_BLYNK -#include "src/dependencies/blynk/BlynkSimpleEsp.h" -#endif -#include "src/dependencies/e131/ESPAsyncE131.h" -#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h" -#include "src/dependencies/json/AsyncJson-v6.h" -#include "src/dependencies/json/ArduinoJson-v6.h" -#include "html_ui.h" -#include "html_settings.h" -#include "html_other.h" -#include "FX.h" -#include "ir_codes.h" -#include "const.h" - -#ifndef CLIENT_SSID -#define CLIENT_SSID DEFAULT_CLIENT_SSID -#endif - -#ifndef CLIENT_PASS -#define CLIENT_PASS "" -#endif - -#if IR_PIN < 0 -#ifndef WLED_DISABLE_INFRARED -#define WLED_DISABLE_INFRARED -#endif -#endif - -#ifndef WLED_DISABLE_INFRARED -#include -#include -#include -#endif - -// remove flicker because PWM signal of RGB channels can become out of phase -#if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266) -#include "src/dependencies/arduino/core_esp8266_waveform.h" -#endif - -// enable additional debug output -#ifdef WLED_DEBUG -#ifndef ESP8266 -#include -#endif -#endif - -//version code in format yymmddb (b = daily build) -#define VERSION 2003222 - -extern char versionString[]; - -//AP and OTA default passwords (for maximum change them!) -extern char apPass[65]; -extern char otaPass[33]; - -//Hardware CONFIG (only changeble HERE, not at runtime) -//LED strip pin, button pin and IR pin changeable in NpbWrapper.h! - -extern byte auxDefaultState; //0: input 1: high 2: low -extern byte auxTriggeredState; //0: input 1: high 2: low -extern char ntpServerName[33]; //NTP server to use - -//WiFi CONFIG (all these can be changed via web UI, no need to set them here) -extern char clientSSID[33]; -extern char clientPass[65]; -extern char cmDNS[33]; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) -extern char apSSID[33]; //AP off by default (unless setup) -extern byte apChannel; //2.4GHz WiFi AP channel (1-13) -extern byte apHide; //hidden AP SSID -extern byte apBehavior; //access point opens when no connection after boot by default -extern IPAddress staticIP; //static IP of ESP -extern IPAddress staticGateway; //gateway (router) IP -extern IPAddress staticSubnet; //most common subnet in home networks -extern bool noWifiSleep; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues - -//LED CONFIG -extern uint16_t ledCount; //overcurrent prevented by ABL -extern bool useRGBW; //SK6812 strips can contain an extra White channel -#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit -extern bool turnOnAtBoot; //turn on LEDs at power-up -extern byte bootPreset; //save preset to load after power-up - -extern byte col[]; //current RGB(W) primary color. col[] should be updated if you want to change the color. -extern byte colSec[]; //current RGB(W) secondary color -extern byte briS; //default brightness - -extern byte nightlightTargetBri; //brightness after nightlight is over -extern byte nightlightDelayMins; -extern bool nightlightFade; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over -extern bool nightlightColorFade; //if enabled, light will gradually fade color from primary to secondary color. -extern bool fadeTransition; //enable crossfading color transition -extern uint16_t transitionDelay; //default crossfade duration in ms - -extern bool skipFirstLed; //ignore first LED in strip (useful if you need the LED as signal repeater) -extern byte briMultiplier; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) - -//User Interface CONFIG -extern char serverDescription[33]; //Name of module -extern bool syncToggleReceive; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise - -//Sync CONFIG -extern bool buttonEnabled; -extern byte irEnabled; //Infrared receiver - -extern uint16_t udpPort; //WLED notifier default port -extern uint16_t udpRgbPort; //Hyperion port - -extern bool receiveNotificationBrightness; //apply brightness from incoming notifications -extern bool receiveNotificationColor; //apply color -extern bool receiveNotificationEffects; //apply effects setup -extern bool notifyDirect; //send notification if change via UI or HTTP API -extern bool notifyButton; //send if updated by button or infrared remote -extern bool notifyAlexa; //send notification if updated via Alexa -extern bool notifyMacro; //send notification for macro -extern bool notifyHue; //send notification if Hue light changes -extern bool notifyTwice; //notifications use UDP: enable if devices don't sync reliably - -extern bool alexaEnabled; //enable device discovery by Amazon Echo -extern char alexaInvocationName[33]; //speech control name of device. Choose something voice-to-text can understand - -extern char blynkApiKey[36]; //Auth token for Blynk server. If empty, no connection will be made - -extern uint16_t realtimeTimeoutMs; //ms timeout of realtime mode before returning to normal mode -extern int arlsOffset; //realtime LED offset -extern bool receiveDirect; //receive UDP realtime -extern bool arlsDisableGammaCorrection; //activate if gamma correction is handled by the source -extern bool arlsForceMaxBri; //enable to force max brightness if source has very dark colors that would be black - -#define E131_MAX_UNIVERSE_COUNT 9 -extern uint16_t e131Universe; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -extern uint8_t DMXMode; //DMX mode (s.a.) -extern uint16_t DMXAddress; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] -extern uint8_t DMXOldDimmer; //only update brightness on change -extern uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss -extern bool e131Multicast; //multicast or unicast -extern bool e131SkipOutOfSequence; //freeze instead of flickering - -extern bool mqttEnabled; -extern char mqttDeviceTopic[33]; //main MQTT topic (individual per device, default is wled/mac) -extern char mqttGroupTopic[33]; //second MQTT topic (for example to group devices) -extern char mqttServer[33]; //both domains and IPs should work (no SSL) -extern char mqttUser[41]; //optional: username for MQTT auth -extern char mqttPass[41]; //optional: password for MQTT auth -extern char mqttClientID[41]; //override the client ID -extern uint16_t mqttPort; - -extern bool huePollingEnabled; //poll hue bridge for light state -extern uint16_t huePollIntervalMs; //low values (< 1sec) may cause lag but offer quicker response -extern char hueApiKey[47]; //key token will be obtained from bridge -extern byte huePollLightId; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) -extern IPAddress hueIP; //IP address of the bridge -extern bool hueApplyOnOff; -extern bool hueApplyBri; -extern bool hueApplyColor; - -//Time CONFIG -extern bool ntpEnabled; //get internet time. Only required if you use clock overlays or time-activated macros -extern bool useAMPM; //12h/24h clock format -extern byte currentTimezone; //Timezone ID. Refer to timezones array in wled_ntp.cpp -extern int utcOffsetSecs; //Seconds to offset from UTC before timzone calculation - -extern byte overlayDefault; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie -extern byte overlayMin; //boundaries of overlay mode -extern byte overlayMax; - -extern byte analogClock12pixel; //The pixel in your strip where "midnight" would be -extern bool analogClockSecondsTrail; //Display seconds as trail of LEDs instead of a single pixel -extern bool analogClock5MinuteMarks; //Light pixels at every 5-minute position - -extern char cronixieDisplay[7]; //Cronixie Display mask. See wled13_cronixie.ino -extern bool cronixieBacklight; //Allow digits to be back-illuminated - -extern bool countdownMode; //Clock will count down towards date -extern byte countdownYear, countdownMonth; //Countdown target date, year is last two digits -extern byte countdownDay, countdownHour; -extern byte countdownMin, countdownSec; - -extern byte macroBoot; //macro loaded after startup -extern byte macroNl; //after nightlight delay over -extern byte macroCountdown; -extern byte macroAlexaOn, macroAlexaOff; -extern byte macroButton, macroLongPress, macroDoublePress; - -//Security CONFIG -extern bool otaLock; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks -extern bool wifiLock; //prevents access to WiFi settings when OTA lock is enabled -extern bool aOtaEnabled; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on - -extern uint16_t userVar0, userVar1; - -#ifdef WLED_ENABLE_DMX -//dmx CONFIG -extern byte DMXChannels; // number of channels per fixture -extern byte DMXFixtureMap[15]; -extern // assigns the different channels to different functions. See wled21_dmx.ino for more information. -extern uint16_t DMXGap; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. -extern uint16_t DMXStart; // start address of the first fixture -#endif - -//internal global variable declarations -//wifi -extern bool apActive; -extern bool forceReconnect; -extern uint32_t lastReconnectAttempt; -extern bool interfacesInited; -extern bool wasConnected; - -//color -extern byte colOld[]; //color before transition -extern byte colT[]; //color that is currently displayed on the LEDs -extern byte colIT[]; //color that was last sent to LEDs -extern byte colSecT[]; -extern byte colSecOld[]; -extern byte colSecIT[]; - -extern byte lastRandomIndex; //used to save last random color so the new one is not the same - -//transitions -extern bool transitionActive; -extern uint16_t transitionDelayDefault; -extern uint16_t transitionDelayTemp; -extern unsigned long transitionStartTime; -extern float tperLast; //crossfade transition progress, 0.0f - 1.0f -extern bool jsonTransitionOnce; - -//nightlight -extern bool nightlightActive; -extern bool nightlightActiveOld; -extern uint32_t nightlightDelayMs; -extern uint8_t nightlightDelayMinsDefault; -extern unsigned long nightlightStartTime; -extern byte briNlT; //current nightlight brightness -extern byte colNlT[]; //current nightlight color - -extern unsigned long lastOnTime; -extern bool offMode; -extern byte bri; -extern byte briOld; -extern byte briT; -extern byte briIT; -extern byte briLast; //brightness before turned off. Used for toggle function -extern byte whiteLast; //white channel before turned off. Used for toggle function - -extern bool buttonPressedBefore; -extern bool buttonLongPressed; -extern unsigned long buttonPressedTime; -extern unsigned long buttonWaitTime; - -extern bool notifyDirectDefault; -extern bool receiveNotifications; -extern unsigned long notificationSentTime; -extern byte notificationSentCallMode; -extern bool notificationTwoRequired; - -extern byte effectCurrent; -extern byte effectSpeed; -extern byte effectIntensity; -extern byte effectPalette; - -extern bool udpConnected, udpRgbConnected; - -extern bool showWelcomePage; - -extern byte hueError; -//uint16_t hueFailCount; -extern float hueXLast, hueYLast; -extern uint16_t hueHueLast, hueCtLast; -extern byte hueSatLast, hueBriLast; -extern unsigned long hueLastRequestSent; -extern bool hueAuthRequired; -extern bool hueReceived; -extern bool hueStoreAllowed, hueNewKey; - -extern byte overlayCurrent; -extern byte overlaySpeed; -extern unsigned long overlayRefreshMs; -extern unsigned long overlayRefreshedTime; - -extern byte dP[]; -extern bool cronixieInit; - -//countdown -extern unsigned long countdownTime; -extern bool countdownOverTriggered; - -//timer -extern byte lastTimerMinute; -extern byte timerHours[]; -extern byte timerMinutes[]; -extern byte timerMacro[]; -extern byte timerWeekday[]; //weekdays to activate on -//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity - -//blynk -extern bool blynkEnabled; - -//preset cycling -extern bool presetCyclingEnabled; -extern byte presetCycleMin, presetCycleMax; -extern uint16_t presetCycleTime; -extern unsigned long presetCycledTime; -extern byte presetCycCurr; -extern bool presetApplyBri; -extern bool saveCurrPresetCycConf; - -//realtime -extern byte realtimeMode; -extern IPAddress realtimeIP; -extern unsigned long realtimeTimeout; - -//mqtt -extern long lastMqttReconnectAttempt; -extern long lastInterfaceUpdate; -extern byte interfaceUpdateCallMode; -extern char mqttStatusTopic[40]; //this must be global because of async handlers - -#if AUXPIN >= 0 -//auxiliary debug pin -extern byte auxTime; -extern unsigned long auxStartTime; -extern bool auxActive; -#endif - -//alexa udp -extern String escapedMac; -#ifndef WLED_DISABLE_ALEXA -extern Espalexa espalexa; -extern EspalexaDevice *espalexaDevice; -#endif - -//dns server -extern DNSServer dnsServer; - -//network time -extern bool ntpConnected; -extern time_t local; -extern unsigned long ntpLastSyncTime; -extern unsigned long ntpPacketSentTime; -extern IPAddress ntpServerIP; -extern uint16_t ntpLocalPort; -#define NTP_PACKET_SIZE 48 - -//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue -#define MAX_LEDS 1500 -#define MAX_LEDS_DMA 500 - -//string temp buffer (now stored in stack locally) -#define OMAX 2048 -extern char *obuf; -extern uint16_t olen; - -//presets -extern uint16_t savedPresets; -extern int8_t currentPreset; -extern bool isPreset; - -extern byte errorFlag; - -extern String messageHead, messageSub; -extern byte optionType; - -extern bool doReboot; //flag to initiate reboot from async handlers -extern bool doPublishMqtt; - -//server library objects -extern AsyncWebServer server; -extern AsyncClient *hueClient; -extern AsyncMqttClient *mqtt; - -//function prototypes -extern void colorFromUint32(uint32_t, bool); -extern void serveMessage(AsyncWebServerRequest *, uint16_t, String, String, byte); -extern void handleE131Packet(e131_packet_t *, IPAddress); -extern void arlsLock(uint32_t, byte); -extern void handleOverlayDraw(); - -//udp interface objects -extern WiFiUDP notifierUdp, rgbUdp; -extern WiFiUDP ntpUdp; -extern ESPAsyncE131 e131; -extern bool e131NewData; - -//led fx library object -extern WS2812FX strip; - - -#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) -#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) - -//debug macros -#ifdef WLED_DEBUG -#define DEBUG_PRINT(x) Serial.print(x) -#define DEBUG_PRINTLN(x) Serial.println(x) -#define DEBUG_PRINTF(x) Serial.printf(x) -extern unsigned long debugTime; -extern int lastWifiState; -extern unsigned long wifiStateChangedTime; -extern int loops; -#else -#define DEBUG_PRINT(x) -#define DEBUG_PRINTLN(x) -#define DEBUG_PRINTF(x) -#endif - - -// TODO: Inline? -//append new c string to temp buffer efficiently -bool oappend(const char *txt); -//append new number to temp buffer efficiently -bool oappendi(int i); -int getSignalQuality(int rssi); - -class WLED -{ -public: - static WLED &instance() - { - static WLED instance; - return instance; - } - - WLED(); - - void reset(); - void loop(); - - - //boot starts here - void setup() - { - wledInit(); - } - -public: // TODO: privacy - void wledInit(); - void beginStrip(); - - void handleConnection(); - void initAP(bool resetAP = false); - void initConnection(); - void initInterfaces(); -}; -#endif // WLED_H +#ifndef WLED_H +#define WLED_H + +/* + Main sketch, global variable declarations +*/ +/* + * @title WLED project sketch + * @version 0.9.1 + * @author Christian Schwinne + */ + +//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). + +//ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). +//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): + +//You are required to disable over-the-air updates: +//#define WLED_DISABLE_OTA //saves 14kb + +//You need to choose some of these features to disable: +//#define WLED_DISABLE_ALEXA //saves 11kb +//#define WLED_DISABLE_BLYNK //saves 6kb +//#define WLED_DISABLE_CRONIXIE //saves 3kb +//#define WLED_DISABLE_HUESYNC //saves 4kb +//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 12kb +#define WLED_ENABLE_MQTT //saves 12kb +#define WLED_ENABLE_ADALIGHT //saves 500b only +//#define WLED_ENABLE_DMX //uses 3.5kb + +#define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet +//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version +//#define WLED_ENABLE_FS_EDITOR //enable /edit page for editing SPIFFS content. Will also be disabled with OTA lock + +//to toggle usb serial debug (un)comment the following line +//#define WLED_DEBUG + +//library inclusions +#include +#ifdef WLED_ENABLE_DMX +#include +DMXESPSerial dmx; +#endif +#ifdef ESP8266 +#include +#include +#include +extern "C" +{ +#include +} +#else //ESP32 +#include +#include "esp_wifi.h" +#include +#include +#include "SPIFFS.h" +#endif + +#include +#include +#include +#include +#ifndef WLED_DISABLE_OTA +#include +#endif +#include +#include "src/dependencies/time/TimeLib.h" +#include "src/dependencies/timezone/Timezone.h" +#ifndef WLED_DISABLE_ALEXA +#define ESPALEXA_ASYNC +#define ESPALEXA_NO_SUBPAGE +#define ESPALEXA_MAXDEVICES 1 +// #define ESPALEXA_DEBUG +#include "src/dependencies/espalexa/Espalexa.h" +#endif +#ifndef WLED_DISABLE_BLYNK +#include "src/dependencies/blynk/BlynkSimpleEsp.h" +#endif +#include "src/dependencies/e131/ESPAsyncE131.h" +#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h" +#include "src/dependencies/json/AsyncJson-v6.h" +#include "src/dependencies/json/ArduinoJson-v6.h" +#include "html_ui.h" +#include "html_settings.h" +#include "html_other.h" +#include "FX.h" +#include "ir_codes.h" +#include "const.h" + +#ifndef CLIENT_SSID +#define CLIENT_SSID DEFAULT_CLIENT_SSID +#endif + +#ifndef CLIENT_PASS +#define CLIENT_PASS "" +#endif + +#if IR_PIN < 0 +#ifndef WLED_DISABLE_INFRARED +#define WLED_DISABLE_INFRARED +#endif +#endif + +#ifndef WLED_DISABLE_INFRARED +#include +#include +#include +#endif + +// remove flicker because PWM signal of RGB channels can become out of phase +#if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266) +#include "src/dependencies/arduino/core_esp8266_waveform.h" +#endif + +// enable additional debug output +#ifdef WLED_DEBUG +#ifndef ESP8266 +#include +#endif +#endif + +//version code in format yymmddb (b = daily build) +#define VERSION 2003222 + +extern char versionString[]; + +//AP and OTA default passwords (for maximum change them!) +extern char apPass[65]; +extern char otaPass[33]; + +//Hardware CONFIG (only changeble HERE, not at runtime) +//LED strip pin, button pin and IR pin changeable in NpbWrapper.h! + +extern byte auxDefaultState; //0: input 1: high 2: low +extern byte auxTriggeredState; //0: input 1: high 2: low +extern char ntpServerName[33]; //NTP server to use + +//WiFi CONFIG (all these can be changed via web UI, no need to set them here) +extern char clientSSID[33]; +extern char clientPass[65]; +extern char cmDNS[33]; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) +extern char apSSID[33]; //AP off by default (unless setup) +extern byte apChannel; //2.4GHz WiFi AP channel (1-13) +extern byte apHide; //hidden AP SSID +extern byte apBehavior; //access point opens when no connection after boot by default +extern IPAddress staticIP; //static IP of ESP +extern IPAddress staticGateway; //gateway (router) IP +extern IPAddress staticSubnet; //most common subnet in home networks +extern bool noWifiSleep; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues + +//LED CONFIG +extern uint16_t ledCount; //overcurrent prevented by ABL +extern bool useRGBW; //SK6812 strips can contain an extra White channel +#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit +extern bool turnOnAtBoot; //turn on LEDs at power-up +extern byte bootPreset; //save preset to load after power-up + +extern byte col[]; //current RGB(W) primary color. col[] should be updated if you want to change the color. +extern byte colSec[]; //current RGB(W) secondary color +extern byte briS; //default brightness + +extern byte nightlightTargetBri; //brightness after nightlight is over +extern byte nightlightDelayMins; +extern bool nightlightFade; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over +extern bool nightlightColorFade; //if enabled, light will gradually fade color from primary to secondary color. +extern bool fadeTransition; //enable crossfading color transition +extern uint16_t transitionDelay; //default crossfade duration in ms + +extern bool skipFirstLed; //ignore first LED in strip (useful if you need the LED as signal repeater) +extern byte briMultiplier; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) + +//User Interface CONFIG +extern char serverDescription[33]; //Name of module +extern bool syncToggleReceive; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise + +//Sync CONFIG +extern bool buttonEnabled; +extern byte irEnabled; //Infrared receiver + +extern uint16_t udpPort; //WLED notifier default port +extern uint16_t udpRgbPort; //Hyperion port + +extern bool receiveNotificationBrightness; //apply brightness from incoming notifications +extern bool receiveNotificationColor; //apply color +extern bool receiveNotificationEffects; //apply effects setup +extern bool notifyDirect; //send notification if change via UI or HTTP API +extern bool notifyButton; //send if updated by button or infrared remote +extern bool notifyAlexa; //send notification if updated via Alexa +extern bool notifyMacro; //send notification for macro +extern bool notifyHue; //send notification if Hue light changes +extern bool notifyTwice; //notifications use UDP: enable if devices don't sync reliably + +extern bool alexaEnabled; //enable device discovery by Amazon Echo +extern char alexaInvocationName[33]; //speech control name of device. Choose something voice-to-text can understand + +extern char blynkApiKey[36]; //Auth token for Blynk server. If empty, no connection will be made + +extern uint16_t realtimeTimeoutMs; //ms timeout of realtime mode before returning to normal mode +extern int arlsOffset; //realtime LED offset +extern bool receiveDirect; //receive UDP realtime +extern bool arlsDisableGammaCorrection; //activate if gamma correction is handled by the source +extern bool arlsForceMaxBri; //enable to force max brightness if source has very dark colors that would be black + +#define E131_MAX_UNIVERSE_COUNT 9 +extern uint16_t e131Universe; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) +extern uint8_t DMXMode; //DMX mode (s.a.) +extern uint16_t DMXAddress; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +extern uint8_t DMXOldDimmer; //only update brightness on change +extern uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss +extern bool e131Multicast; //multicast or unicast +extern bool e131SkipOutOfSequence; //freeze instead of flickering + +extern bool mqttEnabled; +extern char mqttDeviceTopic[33]; //main MQTT topic (individual per device, default is wled/mac) +extern char mqttGroupTopic[33]; //second MQTT topic (for example to group devices) +extern char mqttServer[33]; //both domains and IPs should work (no SSL) +extern char mqttUser[41]; //optional: username for MQTT auth +extern char mqttPass[41]; //optional: password for MQTT auth +extern char mqttClientID[41]; //override the client ID +extern uint16_t mqttPort; + +extern bool huePollingEnabled; //poll hue bridge for light state +extern uint16_t huePollIntervalMs; //low values (< 1sec) may cause lag but offer quicker response +extern char hueApiKey[47]; //key token will be obtained from bridge +extern byte huePollLightId; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) +extern IPAddress hueIP; //IP address of the bridge +extern bool hueApplyOnOff; +extern bool hueApplyBri; +extern bool hueApplyColor; + +//Time CONFIG +extern bool ntpEnabled; //get internet time. Only required if you use clock overlays or time-activated macros +extern bool useAMPM; //12h/24h clock format +extern byte currentTimezone; //Timezone ID. Refer to timezones array in wled_ntp.cpp +extern int utcOffsetSecs; //Seconds to offset from UTC before timzone calculation + +extern byte overlayDefault; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie +extern byte overlayMin; //boundaries of overlay mode +extern byte overlayMax; + +extern byte analogClock12pixel; //The pixel in your strip where "midnight" would be +extern bool analogClockSecondsTrail; //Display seconds as trail of LEDs instead of a single pixel +extern bool analogClock5MinuteMarks; //Light pixels at every 5-minute position + +extern char cronixieDisplay[7]; //Cronixie Display mask. See wled13_cronixie.ino +extern bool cronixieBacklight; //Allow digits to be back-illuminated + +extern bool countdownMode; //Clock will count down towards date +extern byte countdownYear, countdownMonth; //Countdown target date, year is last two digits +extern byte countdownDay, countdownHour; +extern byte countdownMin, countdownSec; + +extern byte macroBoot; //macro loaded after startup +extern byte macroNl; //after nightlight delay over +extern byte macroCountdown; +extern byte macroAlexaOn, macroAlexaOff; +extern byte macroButton, macroLongPress, macroDoublePress; + +//Security CONFIG +extern bool otaLock; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks +extern bool wifiLock; //prevents access to WiFi settings when OTA lock is enabled +extern bool aOtaEnabled; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on + +extern uint16_t userVar0, userVar1; + +#ifdef WLED_ENABLE_DMX +//dmx CONFIG +extern byte DMXChannels; // number of channels per fixture +extern byte DMXFixtureMap[15]; +extern // assigns the different channels to different functions. See wled21_dmx.ino for more information. +extern uint16_t DMXGap; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. +extern uint16_t DMXStart; // start address of the first fixture +#endif + +//internal global variable declarations +//wifi +extern bool apActive; +extern bool forceReconnect; +extern uint32_t lastReconnectAttempt; +extern bool interfacesInited; +extern bool wasConnected; + +//color +extern byte colOld[]; //color before transition +extern byte colT[]; //color that is currently displayed on the LEDs +extern byte colIT[]; //color that was last sent to LEDs +extern byte colSecT[]; +extern byte colSecOld[]; +extern byte colSecIT[]; + +extern byte lastRandomIndex; //used to save last random color so the new one is not the same + +//transitions +extern bool transitionActive; +extern uint16_t transitionDelayDefault; +extern uint16_t transitionDelayTemp; +extern unsigned long transitionStartTime; +extern float tperLast; //crossfade transition progress, 0.0f - 1.0f +extern bool jsonTransitionOnce; + +//nightlight +extern bool nightlightActive; +extern bool nightlightActiveOld; +extern uint32_t nightlightDelayMs; +extern uint8_t nightlightDelayMinsDefault; +extern unsigned long nightlightStartTime; +extern byte briNlT; //current nightlight brightness +extern byte colNlT[]; //current nightlight color + +extern unsigned long lastOnTime; +extern bool offMode; +extern byte bri; +extern byte briOld; +extern byte briT; +extern byte briIT; +extern byte briLast; //brightness before turned off. Used for toggle function +extern byte whiteLast; //white channel before turned off. Used for toggle function + +extern bool buttonPressedBefore; +extern bool buttonLongPressed; +extern unsigned long buttonPressedTime; +extern unsigned long buttonWaitTime; + +extern bool notifyDirectDefault; +extern bool receiveNotifications; +extern unsigned long notificationSentTime; +extern byte notificationSentCallMode; +extern bool notificationTwoRequired; + +extern byte effectCurrent; +extern byte effectSpeed; +extern byte effectIntensity; +extern byte effectPalette; + +extern bool udpConnected, udpRgbConnected; + +extern bool showWelcomePage; + +extern byte hueError; +//uint16_t hueFailCount; +extern float hueXLast, hueYLast; +extern uint16_t hueHueLast, hueCtLast; +extern byte hueSatLast, hueBriLast; +extern unsigned long hueLastRequestSent; +extern bool hueAuthRequired; +extern bool hueReceived; +extern bool hueStoreAllowed, hueNewKey; + +extern byte overlayCurrent; +extern byte overlaySpeed; +extern unsigned long overlayRefreshMs; +extern unsigned long overlayRefreshedTime; + +extern byte dP[]; +extern bool cronixieInit; + +//countdown +extern unsigned long countdownTime; +extern bool countdownOverTriggered; + +//timer +extern byte lastTimerMinute; +extern byte timerHours[]; +extern byte timerMinutes[]; +extern byte timerMacro[]; +extern byte timerWeekday[]; //weekdays to activate on +//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity + +//blynk +extern bool blynkEnabled; + +//preset cycling +extern bool presetCyclingEnabled; +extern byte presetCycleMin, presetCycleMax; +extern uint16_t presetCycleTime; +extern unsigned long presetCycledTime; +extern byte presetCycCurr; +extern bool presetApplyBri; +extern bool saveCurrPresetCycConf; + +//realtime +extern byte realtimeMode; +extern IPAddress realtimeIP; +extern unsigned long realtimeTimeout; + +//mqtt +extern long lastMqttReconnectAttempt; +extern long lastInterfaceUpdate; +extern byte interfaceUpdateCallMode; +extern char mqttStatusTopic[40]; //this must be global because of async handlers + +#if AUXPIN >= 0 +//auxiliary debug pin +extern byte auxTime; +extern unsigned long auxStartTime; +extern bool auxActive; +#endif + +//alexa udp +extern String escapedMac; +#ifndef WLED_DISABLE_ALEXA +extern Espalexa espalexa; +extern EspalexaDevice *espalexaDevice; +#endif + +//dns server +extern DNSServer dnsServer; + +//network time +extern bool ntpConnected; +extern time_t local; +extern unsigned long ntpLastSyncTime; +extern unsigned long ntpPacketSentTime; +extern IPAddress ntpServerIP; +extern uint16_t ntpLocalPort; +#define NTP_PACKET_SIZE 48 + +//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue +#define MAX_LEDS 1500 +#define MAX_LEDS_DMA 500 + +//string temp buffer (now stored in stack locally) +#define OMAX 2048 +extern char *obuf; +extern uint16_t olen; + +//presets +extern uint16_t savedPresets; +extern int8_t currentPreset; +extern bool isPreset; + +extern byte errorFlag; + +extern String messageHead, messageSub; +extern byte optionType; + +extern bool doReboot; //flag to initiate reboot from async handlers +extern bool doPublishMqtt; + +//server library objects +extern AsyncWebServer server; +extern AsyncClient *hueClient; +extern AsyncMqttClient *mqtt; + +//function prototypes +extern void colorFromUint32(uint32_t, bool); +extern void serveMessage(AsyncWebServerRequest *, uint16_t, String, String, byte); +extern void handleE131Packet(e131_packet_t *, IPAddress); +extern void arlsLock(uint32_t, byte); +extern void handleOverlayDraw(); + +//udp interface objects +extern WiFiUDP notifierUdp, rgbUdp; +extern WiFiUDP ntpUdp; +extern ESPAsyncE131 e131; +extern bool e131NewData; + +//led fx library object +extern WS2812FX strip; + + +#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) +#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) + +//debug macros +#ifdef WLED_DEBUG +#define DEBUG_PRINT(x) Serial.print(x) +#define DEBUG_PRINTLN(x) Serial.println(x) +#define DEBUG_PRINTF(x) Serial.printf(x) +extern unsigned long debugTime; +extern int lastWifiState; +extern unsigned long wifiStateChangedTime; +extern int loops; +#else +#define DEBUG_PRINT(x) +#define DEBUG_PRINTLN(x) +#define DEBUG_PRINTF(x) +#endif + + +// TODO: Inline? +//append new c string to temp buffer efficiently +bool oappend(const char *txt); +//append new number to temp buffer efficiently +bool oappendi(int i); +int getSignalQuality(int rssi); + +class WLED +{ +public: + static WLED &instance() + { + static WLED instance; + return instance; + } + + WLED(); + + void reset(); + void loop(); + + + //boot starts here + void setup() + { + wledInit(); + } + +public: // TODO: privacy + void wledInit(); + void beginStrip(); + + void handleConnection(); + void initAP(bool resetAP = false); + void initConnection(); + void initInterfaces(); +}; +#endif // WLED_H diff --git a/wled00/wled_xml.cpp b/wled00/xml.cpp similarity index 99% rename from wled00/wled_xml.cpp rename to wled00/xml.cpp index 4f2b3f45b..930ab4b0d 100644 --- a/wled00/wled_xml.cpp +++ b/wled00/xml.cpp @@ -1,7 +1,7 @@ -#include "wled_xml.h" +#include "xml.h" #include "wled.h" -#include "wled_eeprom.h" -#include "wled_ntp.h" +#include "eeprom.h" +#include "ntp.h" //build XML response to HTTP /win API request diff --git a/wled00/wled_xml.h b/wled00/xml.h similarity index 96% rename from wled00/wled_xml.h rename to wled00/xml.h index 5cfb1dbb7..022982959 100644 --- a/wled00/wled_xml.h +++ b/wled00/xml.h @@ -1,15 +1,15 @@ -#ifndef WLED_XML_H -#define WLED_XML_H -#include -#include - -/* - * Sending XML status files to client - */ -char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr); -char* URL_response(AsyncWebServerRequest *request); -void sappend(char stype, const char* key, int val); -void sappends(char stype, const char* key, char* val); -void getSettingsJS(byte subPage, char* dest); - +#ifndef WLED_XML_H +#define WLED_XML_H +#include +#include + +/* + * Sending XML status files to client + */ +char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr); +char* URL_response(AsyncWebServerRequest *request); +void sappend(char stype, const char* key, int val); +void sappends(char stype, const char* key, char* val); +void getSettingsJS(byte subPage, char* dest); + #endif // WLED_XML_H \ No newline at end of file From f99f13a090581ea037850b167edbe15d3d0daf98 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Sat, 28 Mar 2020 08:45:20 -0400 Subject: [PATCH 123/509] Avoid name collision. Fix wled instance access in ino. --- usermods/blynk_relay_control/wled06_usermod.ino | 2 +- usermods/stairway_wipe_basic/wled06_usermod.ino | 2 +- wled00/alexa.cpp | 2 +- wled00/button.cpp | 2 +- wled00/hue.cpp | 2 +- wled00/ir.cpp | 2 +- wled00/json.cpp | 2 +- wled00/led.cpp | 2 +- wled00/ntp.cpp | 4 +++- wled00/set.cpp | 2 +- wled00/usermod.cpp | 2 +- wled00/wled.cpp | 3 +-- wled00/wled00.ino | 6 ++---- wled00/{eeprom.cpp => wled_eeprom.cpp} | 3 ++- wled00/{eeprom.h => wled_eeprom.h} | 0 wled00/xml.cpp | 2 +- 16 files changed, 19 insertions(+), 19 deletions(-) rename wled00/{eeprom.cpp => wled_eeprom.cpp} (99%) rename wled00/{eeprom.h => wled_eeprom.h} (100%) diff --git a/usermods/blynk_relay_control/wled06_usermod.ino b/usermods/blynk_relay_control/wled06_usermod.ino index 1004b1ed3..d4028ea5d 100644 --- a/usermods/blynk_relay_control/wled06_usermod.ino +++ b/usermods/blynk_relay_control/wled06_usermod.ino @@ -1,7 +1,7 @@ /* * This file allows you to add own functionality to WLED more easily * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality - * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled01_eeprom.h) + * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled_eeprom.h) * bytes 2400+ are currently ununsed, but might be used for future wled features */ diff --git a/usermods/stairway_wipe_basic/wled06_usermod.ino b/usermods/stairway_wipe_basic/wled06_usermod.ino index 3d493cc1d..0cc85df74 100644 --- a/usermods/stairway_wipe_basic/wled06_usermod.ino +++ b/usermods/stairway_wipe_basic/wled06_usermod.ino @@ -1,7 +1,7 @@ /* * This file allows you to add own functionality to WLED more easily * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality - * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled01_eeprom.h) + * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled_eeprom.h) * bytes 2400+ are currently ununsed, but might be used for future wled features */ diff --git a/wled00/alexa.cpp b/wled00/alexa.cpp index 621480d0c..e35f5b358 100644 --- a/wled00/alexa.cpp +++ b/wled00/alexa.cpp @@ -2,7 +2,7 @@ #include "wled.h" #include "const.h" #include "led.h" -#include "eeprom.h" +#include "wled_eeprom.h" #include "colors.h" #ifndef WLED_DISABLE_ALEXA diff --git a/wled00/button.cpp b/wled00/button.cpp index 1afb54d57..a80061eeb 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -1,7 +1,7 @@ #include "button.h" #include "wled.h" #include "led.h" -#include "eeprom.h" +#include "wled_eeprom.h" #include "set.h" /* diff --git a/wled00/hue.cpp b/wled00/hue.cpp index 484f2bd84..a186a3144 100644 --- a/wled00/hue.cpp +++ b/wled00/hue.cpp @@ -1,7 +1,7 @@ #include "hue.h" #include "wled.h" #include "colors.h" -#include "eeprom.h" +#include "wled_eeprom.h" #include "notify.h" #include "led.h" diff --git a/wled00/ir.cpp b/wled00/ir.cpp index fcc0f5dda..32b0ee937 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -2,7 +2,7 @@ #include "wled.h" #include "led.h" #include "colors.h" -#include "eeprom.h" +#include "wled_eeprom.h" #if defined(WLED_DISABLE_INFRARED) void handleIR(){} diff --git a/wled00/json.cpp b/wled00/json.cpp index 73659e7ed..6d71e4141 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -1,6 +1,6 @@ #include "json.h" #include "wled.h" -#include "eeprom.h" +#include "wled_eeprom.h" #include "led.h" void deserializeSegment(JsonObject elem, byte it) diff --git a/wled00/led.cpp b/wled00/led.cpp index 4a16dcff8..7f4d63095 100644 --- a/wled00/led.cpp +++ b/wled00/led.cpp @@ -2,7 +2,7 @@ #include "wled.h" #include "notify.h" #include "blynk.h" -#include "eeprom.h" +#include "wled_eeprom.h" #include "mqtt.h" #include "colors.h" diff --git a/wled00/ntp.cpp b/wled00/ntp.cpp index 3435760b7..206631097 100644 --- a/wled00/ntp.cpp +++ b/wled00/ntp.cpp @@ -1,6 +1,8 @@ #include "ntp.h" +#include "src/dependencies/timezone/Timezone.h" #include "wled.h" -#include "eeprom.h" +#include "wled_eeprom.h" + TimeChangeRule UTCr = {Last, Sun, Mar, 1, 0}; // UTC Timezone tzUTC(UTCr, UTCr); diff --git a/wled00/set.cpp b/wled00/set.cpp index 1dfeb19d0..0a7a4ff4f 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -4,7 +4,7 @@ #include "hue.h" #include "led.h" #include "blynk.h" -#include "eeprom.h" +#include "wled_eeprom.h" #include "alexa.h" #include "cronixie.h" #include "xml.h" diff --git a/wled00/usermod.cpp b/wled00/usermod.cpp index c780ffeeb..6589c07c8 100644 --- a/wled00/usermod.cpp +++ b/wled00/usermod.cpp @@ -2,7 +2,7 @@ /* * This file allows you to add own functionality to WLED more easily * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality - * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled01_eeprom.h) + * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled01_wled_eeprom.h) * bytes 2400+ are currently ununsed, but might be used for future wled features */ diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 106f503b2..2d474eb3b 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -12,9 +12,8 @@ #include "blynk.h" #include "hue.h" #include "mqtt.h" -#include "eeprom.h" +#include "wled_eeprom.h" #include "server.h" -// replaced // Global Variable definitions char versionString[] = "0.9.1"; diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 522447d0a..e33348379 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -3,12 +3,10 @@ */ #include "wled.h" -WLED& wled; void setup() { - wled = WLED::instance(); - wled.setup(); + WLED::instance().setup(); } void loop() { - wled.loop(); + WLED::instance().loop(); } \ No newline at end of file diff --git a/wled00/eeprom.cpp b/wled00/wled_eeprom.cpp similarity index 99% rename from wled00/eeprom.cpp rename to wled00/wled_eeprom.cpp index 68b8c35f9..0087641aa 100644 --- a/wled00/eeprom.cpp +++ b/wled00/wled_eeprom.cpp @@ -1,4 +1,5 @@ -#include "eeprom.h" +#include "wled_eeprom.h" +#include #include "wled.h" #include "cronixie.h" #include "ntp.h" diff --git a/wled00/eeprom.h b/wled00/wled_eeprom.h similarity index 100% rename from wled00/eeprom.h rename to wled00/wled_eeprom.h diff --git a/wled00/xml.cpp b/wled00/xml.cpp index 930ab4b0d..09e42011d 100644 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -1,6 +1,6 @@ #include "xml.h" #include "wled.h" -#include "eeprom.h" +#include "wled_eeprom.h" #include "ntp.h" From cc2de04f6b3c912291bbf57d15a06f40ccf99620 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Sat, 28 Mar 2020 09:24:07 -0400 Subject: [PATCH 124/509] Avoid name collision. --- wled00/wled.cpp | 2 +- wled00/{server.cpp => wled_server.cpp} | 2 +- wled00/{server.h => wled_server.h} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename wled00/{server.cpp => wled_server.cpp} (99%) rename wled00/{server.h => wled_server.h} (100%) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 2d474eb3b..4945ffb78 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -13,7 +13,7 @@ #include "hue.h" #include "mqtt.h" #include "wled_eeprom.h" -#include "server.h" +#include "wled_server.h" // Global Variable definitions char versionString[] = "0.9.1"; diff --git a/wled00/server.cpp b/wled00/wled_server.cpp similarity index 99% rename from wled00/server.cpp rename to wled00/wled_server.cpp index 3249466cf..d5b4eebce 100644 --- a/wled00/server.cpp +++ b/wled00/wled_server.cpp @@ -1,4 +1,4 @@ -#include "server.h" +#include "wled_server.h" #include "wled.h" #include "file.h" #include "set.h" diff --git a/wled00/server.h b/wled00/wled_server.h similarity index 100% rename from wled00/server.h rename to wled00/wled_server.h From 8264ca4e9e283f71a95ea5c1e84e03d9d1717d49 Mon Sep 17 00:00:00 2001 From: Aircoookie Date: Sat, 28 Mar 2020 21:30:32 +0100 Subject: [PATCH 125/509] Create stale.yml (to reduce older open issues) --- .github/stale.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 000000000..811db619a --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,20 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 120 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - keep + - enhancement + - confirmed +# Label to use when marking an issue as stale +staleLabel: stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + Hey! This issue has been open for quite some time without any new comments now. + It will be closed automatically in a week if no further activity occurs. + + Thank you for using WLED! +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false From d2f55e1064a1188f0b831979c4e9ddde96c29a53 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 03:55:44 -0400 Subject: [PATCH 126/509] Make dmx.h header only. --- wled00/dmx.cpp | 52 ----------------------------------------------- wled00/dmx.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++++- wled00/wled.h | 4 ---- 3 files changed, 54 insertions(+), 57 deletions(-) delete mode 100644 wled00/dmx.cpp diff --git a/wled00/dmx.cpp b/wled00/dmx.cpp deleted file mode 100644 index d024ac713..000000000 --- a/wled00/dmx.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "dmx.h" -#include "wled.h" - -#ifdef WLED_ENABLE_DMX -void handleDMX() { - // TODO: calculate brightness manually if no shutter channel is set - - uint8_t brightness = strip.getBrightness(); - - for (int i = 0; i < ledCount; i++) { // uses the amount of LEDs as fixture count - - uint32_t in = strip.getPixelColor(i); // time to get the colors for the individual fixtures as suggested by AirCookie at issue #462 - byte w = in >> 24 & 0xFF; - byte r = in >> 16 & 0xFF; - byte g = in >> 8 & 0xFF; - byte b = in & 0xFF; - - int DMXFixtureStart = DMXStart + (DMXGap * i); - for (int j = 0; j < DMXChannels; j++) { - int DMXAddr = DMXFixtureStart + j; - switch (DMXFixtureMap[j]) { - case 0: // Set this channel to 0. Good way to tell strobe- and fade-functions to fuck right off. - dmx.write(DMXAddr, 0); - break; - case 1: // Red - dmx.write(DMXAddr, r); - break; - case 2: // Green - dmx.write(DMXAddr, g); - break; - case 3: // Blue - dmx.write(DMXAddr, b); - break; - case 4: // White - dmx.write(DMXAddr, w); - break; - case 5: // Shutter channel. Controls the brightness. - dmx.write(DMXAddr, brightness); - break; - case 6:// Sets this channel to 255. Like 0, but more wholesome. - dmx.write(DMXAddr, 255); - break; - } - } - } - - dmx.update(); // update the DMX bus -} - -#else -void handleDMX() {} -#endif diff --git a/wled00/dmx.h b/wled00/dmx.h index 707dec915..76aab4849 100644 --- a/wled00/dmx.h +++ b/wled00/dmx.h @@ -1,11 +1,64 @@ #ifndef WLED_DMX_H #define WLED_DMX_H +#include "wled.h" /* * Support for DMX via MAX485. * Needs the espdmx library. You might have to change the output pin within the library. Sketchy, i know. * https://github.com/Rickgg/ESP-Dmx */ -void handleDMX(); +#ifdef WLED_ENABLE_DMX +#include +DMXESPSerial dmx; + +#ifdef WLED_ENABLE_DMX +void handleDMX() { + // TODO: calculate brightness manually if no shutter channel is set + + uint8_t brightness = strip.getBrightness(); + + for (int i = 0; i < ledCount; i++) { // uses the amount of LEDs as fixture count + + uint32_t in = strip.getPixelColor(i); // time to get the colors for the individual fixtures as suggested by AirCookie at issue #462 + byte w = in >> 24 & 0xFF; + byte r = in >> 16 & 0xFF; + byte g = in >> 8 & 0xFF; + byte b = in & 0xFF; + + int DMXFixtureStart = DMXStart + (DMXGap * i); + for (int j = 0; j < DMXChannels; j++) { + int DMXAddr = DMXFixtureStart + j; + switch (DMXFixtureMap[j]) { + case 0: // Set this channel to 0. Good way to tell strobe- and fade-functions to fuck right off. + dmx.write(DMXAddr, 0); + break; + case 1: // Red + dmx.write(DMXAddr, r); + break; + case 2: // Green + dmx.write(DMXAddr, g); + break; + case 3: // Blue + dmx.write(DMXAddr, b); + break; + case 4: // White + dmx.write(DMXAddr, w); + break; + case 5: // Shutter channel. Controls the brightness. + dmx.write(DMXAddr, brightness); + break; + case 6:// Sets this channel to 255. Like 0, but more wholesome. + dmx.write(DMXAddr, 255); + break; + } + } + } + + dmx.update(); // update the DMX bus +} + +#else +void handleDMX() {} +#endif #endif //WLED_DMX_H \ No newline at end of file diff --git a/wled00/wled.h b/wled00/wled.h index c6f791cd4..e5c4f493b 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -37,10 +37,6 @@ //library inclusions #include -#ifdef WLED_ENABLE_DMX -#include -DMXESPSerial dmx; -#endif #ifdef ESP8266 #include #include From 3e1eb02f54b674cbe74064f81b4eca987394e97f Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 04:21:47 -0400 Subject: [PATCH 127/509] Comment cleanup and line reduction. --- wled00/wled.h | 345 ++++++++++++++++++-------------------------------- 1 file changed, 124 insertions(+), 221 deletions(-) diff --git a/wled00/wled.h b/wled00/wled.h index e5c4f493b..9e373216f 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -1,41 +1,39 @@ #ifndef WLED_H #define WLED_H - /* Main sketch, global variable declarations -*/ -/* - * @title WLED project sketch - * @version 0.9.1 - * @author Christian Schwinne + @title WLED project sketch + @version 0.9.1 + @author Christian Schwinne */ -//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). +// ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). -//ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). -//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): +// ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). +// Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): +// Alternatively, with platformio pass your chosen flags to your custom build target in platformio.ini.override -//You are required to disable over-the-air updates: +// You are required to disable over-the-air updates: //#define WLED_DISABLE_OTA //saves 14kb -//You need to choose some of these features to disable: +// You need to choose some of these features to disable: //#define WLED_DISABLE_ALEXA //saves 11kb //#define WLED_DISABLE_BLYNK //saves 6kb //#define WLED_DISABLE_CRONIXIE //saves 3kb //#define WLED_DISABLE_HUESYNC //saves 4kb //#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 12kb -#define WLED_ENABLE_MQTT //saves 12kb -#define WLED_ENABLE_ADALIGHT //saves 500b only +#define WLED_ENABLE_MQTT //saves 12kb +#define WLED_ENABLE_ADALIGHT //saves 500b only //#define WLED_ENABLE_DMX //uses 3.5kb #define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet //#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version //#define WLED_ENABLE_FS_EDITOR //enable /edit page for editing SPIFFS content. Will also be disabled with OTA lock -//to toggle usb serial debug (un)comment the following line +// to toggle usb serial debug (un)comment the following line //#define WLED_DEBUG -//library inclusions +// Library inclusions. #include #ifdef ESP8266 #include @@ -116,225 +114,171 @@ extern "C" #endif #endif -//version code in format yymmddb (b = daily build) +// version code in format yymmddb (b = daily build) #define VERSION 2003222 +// Global external variable declaration. See wled.cpp for definitions and comments. extern char versionString[]; - -//AP and OTA default passwords (for maximum change them!) extern char apPass[65]; extern char otaPass[33]; - -//Hardware CONFIG (only changeble HERE, not at runtime) -//LED strip pin, button pin and IR pin changeable in NpbWrapper.h! - -extern byte auxDefaultState; //0: input 1: high 2: low -extern byte auxTriggeredState; //0: input 1: high 2: low -extern char ntpServerName[33]; //NTP server to use - -//WiFi CONFIG (all these can be changed via web UI, no need to set them here) +extern byte auxDefaultState; +extern byte auxTriggeredState; +extern char ntpServerName[33]; extern char clientSSID[33]; extern char clientPass[65]; -extern char cmDNS[33]; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) -extern char apSSID[33]; //AP off by default (unless setup) -extern byte apChannel; //2.4GHz WiFi AP channel (1-13) -extern byte apHide; //hidden AP SSID -extern byte apBehavior; //access point opens when no connection after boot by default -extern IPAddress staticIP; //static IP of ESP -extern IPAddress staticGateway; //gateway (router) IP -extern IPAddress staticSubnet; //most common subnet in home networks -extern bool noWifiSleep; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues - -//LED CONFIG -extern uint16_t ledCount; //overcurrent prevented by ABL -extern bool useRGBW; //SK6812 strips can contain an extra White channel -#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit -extern bool turnOnAtBoot; //turn on LEDs at power-up -extern byte bootPreset; //save preset to load after power-up - -extern byte col[]; //current RGB(W) primary color. col[] should be updated if you want to change the color. -extern byte colSec[]; //current RGB(W) secondary color -extern byte briS; //default brightness - -extern byte nightlightTargetBri; //brightness after nightlight is over +extern char cmDNS[33]; +extern char apSSID[33]; +extern byte apChannel; +extern byte apHide; +extern byte apBehavior; +extern IPAddress staticIP; +extern IPAddress staticGateway; +extern IPAddress staticSubnet; +extern bool noWifiSleep; +extern uint16_t ledCount; +extern bool useRGBW; +#define ABL_MILLIAMPS_DEFAULT 850; +extern bool turnOnAtBoot; +extern byte bootPreset; +extern byte col[]; +extern byte colSec[]; +extern byte briS; +extern byte nightlightTargetBri; extern byte nightlightDelayMins; -extern bool nightlightFade; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over -extern bool nightlightColorFade; //if enabled, light will gradually fade color from primary to secondary color. -extern bool fadeTransition; //enable crossfading color transition -extern uint16_t transitionDelay; //default crossfade duration in ms - -extern bool skipFirstLed; //ignore first LED in strip (useful if you need the LED as signal repeater) -extern byte briMultiplier; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) - -//User Interface CONFIG -extern char serverDescription[33]; //Name of module -extern bool syncToggleReceive; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise - -//Sync CONFIG +extern bool nightlightFade; +extern bool nightlightColorFade; +extern bool fadeTransition; +extern uint16_t transitionDelay; +extern bool skipFirstLed; +extern byte briMultiplier; +extern char serverDescription[33]; +extern bool syncToggleReceive; extern bool buttonEnabled; -extern byte irEnabled; //Infrared receiver - -extern uint16_t udpPort; //WLED notifier default port -extern uint16_t udpRgbPort; //Hyperion port - -extern bool receiveNotificationBrightness; //apply brightness from incoming notifications -extern bool receiveNotificationColor; //apply color -extern bool receiveNotificationEffects; //apply effects setup -extern bool notifyDirect; //send notification if change via UI or HTTP API -extern bool notifyButton; //send if updated by button or infrared remote -extern bool notifyAlexa; //send notification if updated via Alexa -extern bool notifyMacro; //send notification for macro -extern bool notifyHue; //send notification if Hue light changes -extern bool notifyTwice; //notifications use UDP: enable if devices don't sync reliably - -extern bool alexaEnabled; //enable device discovery by Amazon Echo -extern char alexaInvocationName[33]; //speech control name of device. Choose something voice-to-text can understand - -extern char blynkApiKey[36]; //Auth token for Blynk server. If empty, no connection will be made - -extern uint16_t realtimeTimeoutMs; //ms timeout of realtime mode before returning to normal mode -extern int arlsOffset; //realtime LED offset -extern bool receiveDirect; //receive UDP realtime -extern bool arlsDisableGammaCorrection; //activate if gamma correction is handled by the source -extern bool arlsForceMaxBri; //enable to force max brightness if source has very dark colors that would be black - +extern byte irEnabled; +extern uint16_t udpPort; +extern uint16_t udpRgbPort; +extern bool receiveNotificationBrightness; +extern bool receiveNotificationColor; +extern bool receiveNotificationEffects; +extern bool notifyDirect; +extern bool notifyButton; +extern bool notifyAlexa; +extern bool notifyMacro; +extern bool notifyHue; +extern bool notifyTwice; +extern bool alexaEnabled; +extern char alexaInvocationName[33]; +extern char blynkApiKey[36]; +extern uint16_t realtimeTimeoutMs; +extern int arlsOffset; +extern bool receiveDirect; +extern bool arlsDisableGammaCorrection; +extern bool arlsForceMaxBri; #define E131_MAX_UNIVERSE_COUNT 9 -extern uint16_t e131Universe; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -extern uint8_t DMXMode; //DMX mode (s.a.) -extern uint16_t DMXAddress; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] -extern uint8_t DMXOldDimmer; //only update brightness on change -extern uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss -extern bool e131Multicast; //multicast or unicast -extern bool e131SkipOutOfSequence; //freeze instead of flickering - +extern uint16_t e131Universe; +extern uint8_t DMXMode; +extern uint16_t DMXAddress; +extern uint8_t DMXOldDimmer; +extern uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; +extern bool e131Multicast; +extern bool e131SkipOutOfSequence; extern bool mqttEnabled; -extern char mqttDeviceTopic[33]; //main MQTT topic (individual per device, default is wled/mac) -extern char mqttGroupTopic[33]; //second MQTT topic (for example to group devices) -extern char mqttServer[33]; //both domains and IPs should work (no SSL) -extern char mqttUser[41]; //optional: username for MQTT auth -extern char mqttPass[41]; //optional: password for MQTT auth -extern char mqttClientID[41]; //override the client ID +extern char mqttDeviceTopic[33]; +extern char mqttGroupTopic[33]; +extern char mqttServer[33]; +extern char mqttUser[41]; +extern char mqttPass[41]; +extern char mqttClientID[41]; extern uint16_t mqttPort; - -extern bool huePollingEnabled; //poll hue bridge for light state -extern uint16_t huePollIntervalMs; //low values (< 1sec) may cause lag but offer quicker response -extern char hueApiKey[47]; //key token will be obtained from bridge -extern byte huePollLightId; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) -extern IPAddress hueIP; //IP address of the bridge +extern bool huePollingEnabled; +extern uint16_t huePollIntervalMs; +extern char hueApiKey[47]; +extern byte huePollLightId; +extern IPAddress hueIP; extern bool hueApplyOnOff; extern bool hueApplyBri; extern bool hueApplyColor; - -//Time CONFIG -extern bool ntpEnabled; //get internet time. Only required if you use clock overlays or time-activated macros -extern bool useAMPM; //12h/24h clock format -extern byte currentTimezone; //Timezone ID. Refer to timezones array in wled_ntp.cpp -extern int utcOffsetSecs; //Seconds to offset from UTC before timzone calculation - -extern byte overlayDefault; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie -extern byte overlayMin; //boundaries of overlay mode +extern bool ntpEnabled; +extern bool useAMPM; +extern byte currentTimezone; +extern int utcOffsetSecs; +extern byte overlayDefault; +extern byte overlayMin; extern byte overlayMax; - -extern byte analogClock12pixel; //The pixel in your strip where "midnight" would be -extern bool analogClockSecondsTrail; //Display seconds as trail of LEDs instead of a single pixel -extern bool analogClock5MinuteMarks; //Light pixels at every 5-minute position - -extern char cronixieDisplay[7]; //Cronixie Display mask. See wled13_cronixie.ino -extern bool cronixieBacklight; //Allow digits to be back-illuminated - -extern bool countdownMode; //Clock will count down towards date -extern byte countdownYear, countdownMonth; //Countdown target date, year is last two digits +extern byte analogClock12pixel; +extern bool analogClockSecondsTrail; +extern bool analogClock5MinuteMarks; +extern char cronixieDisplay[7]; +extern bool cronixieBacklight; +extern bool countdownMode; +extern byte countdownYear, countdownMonth; extern byte countdownDay, countdownHour; extern byte countdownMin, countdownSec; - -extern byte macroBoot; //macro loaded after startup -extern byte macroNl; //after nightlight delay over +extern byte macroBoot; +extern byte macroNl; extern byte macroCountdown; extern byte macroAlexaOn, macroAlexaOff; extern byte macroButton, macroLongPress, macroDoublePress; - -//Security CONFIG -extern bool otaLock; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks -extern bool wifiLock; //prevents access to WiFi settings when OTA lock is enabled -extern bool aOtaEnabled; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on - +extern bool otaLock; +extern bool wifiLock; +extern bool aOtaEnabled; extern uint16_t userVar0, userVar1; - #ifdef WLED_ENABLE_DMX -//dmx CONFIG -extern byte DMXChannels; // number of channels per fixture +extern byte DMXChannels; extern byte DMXFixtureMap[15]; -extern // assigns the different channels to different functions. See wled21_dmx.ino for more information. -extern uint16_t DMXGap; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. -extern uint16_t DMXStart; // start address of the first fixture +extern +extern uint16_t DMXGap; +extern uint16_t DMXStart; #endif - -//internal global variable declarations -//wifi extern bool apActive; extern bool forceReconnect; extern uint32_t lastReconnectAttempt; extern bool interfacesInited; extern bool wasConnected; - -//color -extern byte colOld[]; //color before transition -extern byte colT[]; //color that is currently displayed on the LEDs -extern byte colIT[]; //color that was last sent to LEDs +extern byte colOld[]; +extern byte colT[]; +extern byte colIT[]; extern byte colSecT[]; extern byte colSecOld[]; extern byte colSecIT[]; - -extern byte lastRandomIndex; //used to save last random color so the new one is not the same - -//transitions +extern byte lastRandomIndex; extern bool transitionActive; extern uint16_t transitionDelayDefault; extern uint16_t transitionDelayTemp; extern unsigned long transitionStartTime; -extern float tperLast; //crossfade transition progress, 0.0f - 1.0f +extern float tperLast; extern bool jsonTransitionOnce; - -//nightlight extern bool nightlightActive; extern bool nightlightActiveOld; extern uint32_t nightlightDelayMs; extern uint8_t nightlightDelayMinsDefault; extern unsigned long nightlightStartTime; -extern byte briNlT; //current nightlight brightness -extern byte colNlT[]; //current nightlight color - +extern byte briNlT; +extern byte colNlT[]; extern unsigned long lastOnTime; extern bool offMode; extern byte bri; extern byte briOld; extern byte briT; extern byte briIT; -extern byte briLast; //brightness before turned off. Used for toggle function -extern byte whiteLast; //white channel before turned off. Used for toggle function - +extern byte briLast; +extern byte whiteLast; extern bool buttonPressedBefore; extern bool buttonLongPressed; extern unsigned long buttonPressedTime; extern unsigned long buttonWaitTime; - extern bool notifyDirectDefault; extern bool receiveNotifications; extern unsigned long notificationSentTime; extern byte notificationSentCallMode; extern bool notificationTwoRequired; - extern byte effectCurrent; extern byte effectSpeed; extern byte effectIntensity; extern byte effectPalette; - extern bool udpConnected, udpRgbConnected; - extern bool showWelcomePage; - extern byte hueError; -//uint16_t hueFailCount; extern float hueXLast, hueYLast; extern uint16_t hueHueLast, hueCtLast; extern byte hueSatLast, hueBriLast; @@ -342,31 +286,20 @@ extern unsigned long hueLastRequestSent; extern bool hueAuthRequired; extern bool hueReceived; extern bool hueStoreAllowed, hueNewKey; - extern byte overlayCurrent; extern byte overlaySpeed; extern unsigned long overlayRefreshMs; extern unsigned long overlayRefreshedTime; - extern byte dP[]; extern bool cronixieInit; - -//countdown extern unsigned long countdownTime; extern bool countdownOverTriggered; - -//timer extern byte lastTimerMinute; extern byte timerHours[]; extern byte timerMinutes[]; extern byte timerMacro[]; -extern byte timerWeekday[]; //weekdays to activate on -//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity - -//blynk +extern byte timerWeekday[]; extern bool blynkEnabled; - -//preset cycling extern bool presetCyclingEnabled; extern byte presetCycleMin, presetCycleMax; extern uint16_t presetCycleTime; @@ -374,36 +307,24 @@ extern unsigned long presetCycledTime; extern byte presetCycCurr; extern bool presetApplyBri; extern bool saveCurrPresetCycConf; - -//realtime extern byte realtimeMode; extern IPAddress realtimeIP; extern unsigned long realtimeTimeout; - -//mqtt extern long lastMqttReconnectAttempt; extern long lastInterfaceUpdate; extern byte interfaceUpdateCallMode; -extern char mqttStatusTopic[40]; //this must be global because of async handlers - +extern char mqttStatusTopic[40]; #if AUXPIN >= 0 -//auxiliary debug pin extern byte auxTime; extern unsigned long auxStartTime; extern bool auxActive; #endif - -//alexa udp extern String escapedMac; #ifndef WLED_DISABLE_ALEXA extern Espalexa espalexa; extern EspalexaDevice *espalexaDevice; #endif - -//dns server extern DNSServer dnsServer; - -//network time extern bool ntpConnected; extern time_t local; extern unsigned long ntpLastSyncTime; @@ -411,51 +332,35 @@ extern unsigned long ntpPacketSentTime; extern IPAddress ntpServerIP; extern uint16_t ntpLocalPort; #define NTP_PACKET_SIZE 48 - -//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue #define MAX_LEDS 1500 #define MAX_LEDS_DMA 500 - -//string temp buffer (now stored in stack locally) #define OMAX 2048 extern char *obuf; extern uint16_t olen; - -//presets extern uint16_t savedPresets; extern int8_t currentPreset; extern bool isPreset; - extern byte errorFlag; - extern String messageHead, messageSub; extern byte optionType; - -extern bool doReboot; //flag to initiate reboot from async handlers +extern bool doReboot; extern bool doPublishMqtt; - -//server library objects extern AsyncWebServer server; extern AsyncClient *hueClient; extern AsyncMqttClient *mqtt; +extern WiFiUDP notifierUdp, rgbUdp; +extern WiFiUDP ntpUdp; +extern ESPAsyncE131 e131; +extern bool e131NewData; +extern WS2812FX strip; -//function prototypes +// Function prototypes extern void colorFromUint32(uint32_t, bool); extern void serveMessage(AsyncWebServerRequest *, uint16_t, String, String, byte); extern void handleE131Packet(e131_packet_t *, IPAddress); extern void arlsLock(uint32_t, byte); extern void handleOverlayDraw(); -//udp interface objects -extern WiFiUDP notifierUdp, rgbUdp; -extern WiFiUDP ntpUdp; -extern ESPAsyncE131 e131; -extern bool e131NewData; - -//led fx library object -extern WS2812FX strip; - - #define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) #define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) @@ -474,11 +379,9 @@ extern int loops; #define DEBUG_PRINTF(x) #endif - -// TODO: Inline? -//append new c string to temp buffer efficiently +// append new c string to temp buffer efficiently bool oappend(const char *txt); -//append new number to temp buffer efficiently +// append new number to temp buffer efficiently bool oappendi(int i); int getSignalQuality(int rssi); From 408d63825a5176f370fd04b6ea4662c6a3d27286 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 04:26:41 -0400 Subject: [PATCH 128/509] Function prototype cleanup. --- wled00/set.cpp | 1 + wled00/wled.cpp | 8 +------- wled00/wled.h | 7 ------- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/wled00/set.cpp b/wled00/set.cpp index 0a7a4ff4f..f26795c8e 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -8,6 +8,7 @@ #include "alexa.h" #include "cronixie.h" #include "xml.h" +#include "wled_server.h" void _setRandomColor(bool _sec,bool fromButton) { diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 4945ffb78..c6dac0d22 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -14,6 +14,7 @@ #include "mqtt.h" #include "wled_eeprom.h" #include "wled_server.h" + // Global Variable definitions char versionString[] = "0.9.1"; @@ -343,13 +344,6 @@ AsyncWebServer server(80); AsyncClient *hueClient = NULL; AsyncMqttClient *mqtt = NULL; -//function prototypes -void colorFromUint32(uint32_t, bool = false); -void serveMessage(AsyncWebServerRequest *, uint16_t, String, String, byte); -void handleE131Packet(e131_packet_t *, IPAddress); -void arlsLock(uint32_t, byte); -void handleOverlayDraw(); - //udp interface objects WiFiUDP notifierUdp, rgbUdp; WiFiUDP ntpUdp; diff --git a/wled00/wled.h b/wled00/wled.h index 9e373216f..e825668e6 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -354,13 +354,6 @@ extern ESPAsyncE131 e131; extern bool e131NewData; extern WS2812FX strip; -// Function prototypes -extern void colorFromUint32(uint32_t, bool); -extern void serveMessage(AsyncWebServerRequest *, uint16_t, String, String, byte); -extern void handleE131Packet(e131_packet_t *, IPAddress); -extern void arlsLock(uint32_t, byte); -extern void handleOverlayDraw(); - #define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) #define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) From de63bdac3951707f781691afd788d8e8a4319bc3 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 04:35:52 -0400 Subject: [PATCH 129/509] Code reorg. --- wled00/wled.cpp | 11 +---------- wled00/wled.h | 11 +++-------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index c6dac0d22..6edd58e2b 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -356,23 +356,14 @@ WS2812FX strip = WS2812FX(); #define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) #define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) -//debug macros +//debug macro variable definitions #ifdef WLED_DEBUG -#define DEBUG_PRINT(x) Serial.print(x) -#define DEBUG_PRINTLN(x) Serial.println(x) -#define DEBUG_PRINTF(x) Serial.printf(x) unsigned long debugTime = 0; int lastWifiState = 3; unsigned long wifiStateChangedTime = 0; int loops = 0; -#else -#define DEBUG_PRINT(x) -#define DEBUG_PRINTLN(x) -#define DEBUG_PRINTF(x) #endif - - WLED::WLED() { } diff --git a/wled00/wled.h b/wled00/wled.h index e825668e6..abcffac16 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -381,28 +381,23 @@ int getSignalQuality(int rssi); class WLED { public: + WLED(); static WLED &instance() { static WLED instance; return instance; } - WLED(); - - void reset(); - void loop(); - - //boot starts here void setup() { wledInit(); } + void loop(); + void reset(); -public: // TODO: privacy void wledInit(); void beginStrip(); - void handleConnection(); void initAP(bool resetAP = false); void initConnection(); From 40ac760285425a6c1d7f6c2b8c9d0bee49f7e342 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 04:41:42 -0400 Subject: [PATCH 130/509] Move getSignalQuality to json.cpp --- wled00/json.cpp | 20 ++++++++++++++++++++ wled00/wled.cpp | 20 -------------------- wled00/wled.h | 1 - 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/wled00/json.cpp b/wled00/json.cpp index 6d71e4141..782dc8f68 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -249,6 +249,26 @@ void serializeState(JsonObject root) } } +//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp +int getSignalQuality(int rssi) +{ + int quality = 0; + + if (rssi <= -100) + { + quality = 0; + } + else if (rssi >= -50) + { + quality = 100; + } + else + { + quality = 2 * (rssi + 100); + } + return quality; +} + void serializeInfo(JsonObject root) { root["ver"] = versionString; diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 6edd58e2b..18bc4fca5 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -845,23 +845,3 @@ void WLED::handleConnection() } } } - -//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp -int getSignalQuality(int rssi) -{ - int quality = 0; - - if (rssi <= -100) - { - quality = 0; - } - else if (rssi >= -50) - { - quality = 100; - } - else - { - quality = 2 * (rssi + 100); - } - return quality; -} \ No newline at end of file diff --git a/wled00/wled.h b/wled00/wled.h index abcffac16..076066769 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -376,7 +376,6 @@ extern int loops; bool oappend(const char *txt); // append new number to temp buffer efficiently bool oappendi(int i); -int getSignalQuality(int rssi); class WLED { From 7e21955211282daa581ee912da9d426c7f46aba8 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 04:43:37 -0400 Subject: [PATCH 131/509] wledInit -> setup --- wled00/wled.cpp | 2 +- wled00/wled.h | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 18bc4fca5..fe3d7bd99 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -484,7 +484,7 @@ void WLED::loop() #endif // WLED_DEBU } -void WLED::wledInit() +void WLED::setup() { EEPROM.begin(EEPSIZE); ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); diff --git a/wled00/wled.h b/wled00/wled.h index 076066769..9262c6f17 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -388,14 +388,11 @@ public: } //boot starts here - void setup() - { - wledInit(); - } + void setup(); + void loop(); void reset(); - void wledInit(); void beginStrip(); void handleConnection(); void initAP(bool resetAP = false); From c54092c932ee84ca3a385f38ceb28bbc40b83967 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 05:04:20 -0400 Subject: [PATCH 132/509] Remove redundant defines. --- wled00/wled.cpp | 13 +------------ wled00/wled.h | 7 ++++++- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/wled00/wled.cpp b/wled00/wled.cpp index fe3d7bd99..670868e61 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -45,7 +45,6 @@ bool noWifiSleep = false; //disabling modem sleep modes will i //LED CONFIG uint16_t ledCount = 30; //overcurrent prevented by ABL bool useRGBW = false; //SK6812 strips can contain an extra White channel -#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit bool turnOnAtBoot = true; //turn on LEDs at power-up byte bootPreset = 0; //save preset to load after power-up @@ -95,7 +94,6 @@ bool receiveDirect = true; //receive UDP realtime bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black -#define E131_MAX_UNIVERSE_COUNT 9 uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] @@ -315,14 +313,8 @@ unsigned long ntpLastSyncTime = 999000000L; unsigned long ntpPacketSentTime = 999000000L; IPAddress ntpServerIP; uint16_t ntpLocalPort = 2390; -#define NTP_PACKET_SIZE 48 -//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue -#define MAX_LEDS 1500 -#define MAX_LEDS_DMA 500 - -//string temp buffer (now stored in stack locally) -#define OMAX 2048 +// Temp buffer char *obuf; uint16_t olen = 0; @@ -353,9 +345,6 @@ bool e131NewData = false; //led fx library object WS2812FX strip = WS2812FX(); -#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) -#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) - //debug macro variable definitions #ifdef WLED_DEBUG unsigned long debugTime = 0; diff --git a/wled00/wled.h b/wled00/wled.h index 4eebead2f..3e6c11be1 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -137,7 +137,7 @@ extern IPAddress staticSubnet; extern bool noWifiSleep; extern uint16_t ledCount; extern bool useRGBW; -#define ABL_MILLIAMPS_DEFAULT 850; +#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit extern bool turnOnAtBoot; extern byte bootPreset; extern byte col[]; @@ -332,11 +332,16 @@ extern unsigned long ntpPacketSentTime; extern IPAddress ntpServerIP; extern uint16_t ntpLocalPort; #define NTP_PACKET_SIZE 48 + +//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue #define MAX_LEDS 1500 #define MAX_LEDS_DMA 500 + +//string temp buffer (now stored in stack locally) #define OMAX 2048 extern char *obuf; extern uint16_t olen; + extern uint16_t savedPresets; extern int8_t currentPreset; extern bool isPreset; From a47d48c9735eaef7bd96d84a15c83cafc2c1e5bc Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 05:19:09 -0400 Subject: [PATCH 133/509] Add clang format. --- .clang-format | 4 + wled00/wled.cpp | 829 +++++++++++++++++++++++------------------------- 2 files changed, 403 insertions(+), 430 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..56df2b76f --- /dev/null +++ b/.clang-format @@ -0,0 +1,4 @@ +--- + BasedOnStyle: Webkit + IndentWidth: 2 + \ No newline at end of file diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 670868e61..fd47592f7 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -1,19 +1,19 @@ #include "wled.h" -#include -#include "led.h" -#include "ir.h" -#include "notify.h" #include "alexa.h" -#include "overlay.h" -#include "file.h" -#include "button.h" -#include "ntp.h" -#include "usermod.h" #include "blynk.h" +#include "button.h" +#include "file.h" #include "hue.h" +#include "ir.h" +#include "led.h" #include "mqtt.h" +#include "notify.h" +#include "ntp.h" +#include "overlay.h" +#include "usermod.h" #include "wled_eeprom.h" #include "wled_server.h" +#include // Global Variable definitions char versionString[] = "0.9.1"; @@ -25,131 +25,131 @@ char otaPass[33] = DEFAULT_OTA_PASS; //Hardware CONFIG (only changeble HERE, not at runtime) //LED strip pin, button pin and IR pin changeable in NpbWrapper.h! -byte auxDefaultState = 0; //0: input 1: high 2: low -byte auxTriggeredState = 0; //0: input 1: high 2: low +byte auxDefaultState = 0; //0: input 1: high 2: low +byte auxTriggeredState = 0; //0: input 1: high 2: low char ntpServerName[33] = "0.wled.pool.ntp.org"; //NTP server to use //WiFi CONFIG (all these can be changed via web UI, no need to set them here) char clientSSID[33] = CLIENT_SSID; char clientPass[65] = CLIENT_PASS; -char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) -char apSSID[33] = ""; //AP off by default (unless setup) -byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) -byte apHide = 0; //hidden AP SSID +char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) +char apSSID[33] = ""; //AP off by default (unless setup) +byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) +byte apHide = 0; //hidden AP SSID byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no connection after boot by default -IPAddress staticIP(0, 0, 0, 0); //static IP of ESP -IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP -IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks -bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues +IPAddress staticIP(0, 0, 0, 0); //static IP of ESP +IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP +IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks +bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues //LED CONFIG -uint16_t ledCount = 30; //overcurrent prevented by ABL -bool useRGBW = false; //SK6812 strips can contain an extra White channel -bool turnOnAtBoot = true; //turn on LEDs at power-up -byte bootPreset = 0; //save preset to load after power-up +uint16_t ledCount = 30; //overcurrent prevented by ABL +bool useRGBW = false; //SK6812 strips can contain an extra White channel +bool turnOnAtBoot = true; //turn on LEDs at power-up +byte bootPreset = 0; //save preset to load after power-up -byte col[]{255, 160, 0, 0}; //current RGB(W) primary color. col[] should be updated if you want to change the color. -byte colSec[]{0, 0, 0, 0}; //current RGB(W) secondary color -byte briS = 128; //default brightness +byte col[] { 255, 160, 0, 0 }; //current RGB(W) primary color. col[] should be updated if you want to change the color. +byte colSec[] { 0, 0, 0, 0 }; //current RGB(W) secondary color +byte briS = 128; //default brightness byte nightlightTargetBri = 0; //brightness after nightlight is over byte nightlightDelayMins = 60; -bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over +bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. -bool fadeTransition = true; //enable crossfading color transition -uint16_t transitionDelay = 750; //default crossfade duration in ms +bool fadeTransition = true; //enable crossfading color transition +uint16_t transitionDelay = 750; //default crossfade duration in ms bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) -byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) +byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) //User Interface CONFIG char serverDescription[33] = "WLED"; //Name of module -bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise +bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise //Sync CONFIG bool buttonEnabled = true; byte irEnabled = 0; //Infrared receiver -uint16_t udpPort = 21324; //WLED notifier default port +uint16_t udpPort = 21324; //WLED notifier default port uint16_t udpRgbPort = 19446; //Hyperion port bool receiveNotificationBrightness = true; //apply brightness from incoming notifications -bool receiveNotificationColor = true; //apply color -bool receiveNotificationEffects = true; //apply effects setup -bool notifyDirect = false; //send notification if change via UI or HTTP API -bool notifyButton = false; //send if updated by button or infrared remote -bool notifyAlexa = false; //send notification if updated via Alexa -bool notifyMacro = false; //send notification for macro -bool notifyHue = true; //send notification if Hue light changes -bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably +bool receiveNotificationColor = true; //apply color +bool receiveNotificationEffects = true; //apply effects setup +bool notifyDirect = false; //send notification if change via UI or HTTP API +bool notifyButton = false; //send if updated by button or infrared remote +bool notifyAlexa = false; //send notification if updated via Alexa +bool notifyMacro = false; //send notification for macro +bool notifyHue = true; //send notification if Hue light changes +bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably -bool alexaEnabled = true; //enable device discovery by Amazon Echo +bool alexaEnabled = true; //enable device discovery by Amazon Echo char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made -uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode -int arlsOffset = 0; //realtime LED offset -bool receiveDirect = true; //receive UDP realtime +uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode +int arlsOffset = 0; //realtime LED offset +bool receiveDirect = true; //receive UDP realtime bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source -bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black +bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black -uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) -uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] -uint8_t DMXOldDimmer = 0; //only update brightness on change +uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) +uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) +uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +uint8_t DMXOldDimmer = 0; //only update brightness on change uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss -bool e131Multicast = false; //multicast or unicast -bool e131SkipOutOfSequence = false; //freeze instead of flickering +bool e131Multicast = false; //multicast or unicast +bool e131SkipOutOfSequence = false; //freeze instead of flickering bool mqttEnabled = false; -char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) +char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices) -char mqttServer[33] = ""; //both domains and IPs should work (no SSL) -char mqttUser[41] = ""; //optional: username for MQTT auth -char mqttPass[41] = ""; //optional: password for MQTT auth -char mqttClientID[41] = ""; //override the client ID +char mqttServer[33] = ""; //both domains and IPs should work (no SSL) +char mqttUser[41] = ""; //optional: username for MQTT auth +char mqttPass[41] = ""; //optional: password for MQTT auth +char mqttClientID[41] = ""; //override the client ID uint16_t mqttPort = 1883; -bool huePollingEnabled = false; //poll hue bridge for light state +bool huePollingEnabled = false; //poll hue bridge for light state uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response -char hueApiKey[47] = "api"; //key token will be obtained from bridge -byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) -IPAddress hueIP = (0, 0, 0, 0); //IP address of the bridge +char hueApiKey[47] = "api"; //key token will be obtained from bridge +byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) +IPAddress hueIP = (0, 0, 0, 0); //IP address of the bridge bool hueApplyOnOff = true; bool hueApplyBri = true; bool hueApplyColor = true; //Time CONFIG -bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros -bool useAMPM = false; //12h/24h clock format +bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros +bool useAMPM = false; //12h/24h clock format byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino -int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation +int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation -byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie +byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie byte overlayMin = 0, overlayMax = ledCount - 1; //boundaries of overlay mode -byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be +byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino -bool cronixieBacklight = true; //Allow digits to be back-illuminated +bool cronixieBacklight = true; //Allow digits to be back-illuminated -bool countdownMode = false; //Clock will count down towards date +bool countdownMode = false; //Clock will count down towards date byte countdownYear = 20, countdownMonth = 1; //Countdown target date, year is last two digits byte countdownDay = 1, countdownHour = 0; byte countdownMin = 0, countdownSec = 0; byte macroBoot = 0; //macro loaded after startup -byte macroNl = 0; //after nightlight delay over +byte macroNl = 0; //after nightlight delay over byte macroCountdown = 0; byte macroAlexaOn = 0, macroAlexaOff = 0; byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; //Security CONFIG -bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks -bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled +bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks +bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on uint16_t userVar0 = 0, userVar1 = 0; @@ -157,9 +157,9 @@ uint16_t userVar0 = 0, userVar1 = 0; #ifdef WLED_ENABLE_DMX //dmx CONFIG byte DMXChannels = 7; // number of channels per fixture -byte DMXFixtureMap[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +byte DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // assigns the different channels to different functions. See wled21_dmx.ino for more information. -uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. +uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. uint16_t DMXStart = 10; // start address of the first fixture #endif @@ -172,12 +172,12 @@ bool interfacesInited = false; bool wasConnected = false; //color -byte colOld[]{0, 0, 0, 0}; //color before transition -byte colT[]{0, 0, 0, 0}; //color that is currently displayed on the LEDs -byte colIT[]{0, 0, 0, 0}; //color that was last sent to LEDs -byte colSecT[]{0, 0, 0, 0}; -byte colSecOld[]{0, 0, 0, 0}; -byte colSecIT[]{0, 0, 0, 0}; +byte colOld[] { 0, 0, 0, 0 }; //color before transition +byte colT[] { 0, 0, 0, 0 }; //color that is currently displayed on the LEDs +byte colIT[] { 0, 0, 0, 0 }; //color that was last sent to LEDs +byte colSecT[] { 0, 0, 0, 0 }; +byte colSecOld[] { 0, 0, 0, 0 }; +byte colSecIT[] { 0, 0, 0, 0 }; byte lastRandomIndex = 0; //used to save last random color so the new one is not the same @@ -195,8 +195,8 @@ bool nightlightActiveOld = false; uint32_t nightlightDelayMs = 10; uint8_t nightlightDelayMinsDefault = nightlightDelayMins; unsigned long nightlightStartTime; -byte briNlT = 0; //current nightlight brightness -byte colNlT[]{0, 0, 0, 0}; //current nightlight color +byte briNlT = 0; //current nightlight brightness +byte colNlT[] { 0, 0, 0, 0 }; //current nightlight color //brightness unsigned long lastOnTime = 0; @@ -205,7 +205,7 @@ byte bri = briS; byte briOld = 0; byte briT = 0; byte briIT = 0; -byte briLast = 128; //brightness before turned off. Used for toggle function +byte briLast = 128; //brightness before turned off. Used for toggle function byte whiteLast = 128; //white channel before turned off. Used for toggle function //button @@ -251,7 +251,7 @@ unsigned long overlayRefreshMs = 200; unsigned long overlayRefreshedTime; //cronixie -byte dP[]{0, 0, 0, 0, 0, 0}; +byte dP[] { 0, 0, 0, 0, 0, 0 }; bool cronixieInit = false; //countdown @@ -260,10 +260,10 @@ bool countdownOverTriggered = true; //timer byte lastTimerMinute = 0; -byte timerHours[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMinutes[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMacro[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerWeekday[] = {255, 255, 255, 255, 255, 255, 255, 255}; //weekdays to activate on +byte timerHours[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +byte timerMinutes[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +byte timerMacro[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +byte timerWeekday[] = { 255, 255, 255, 255, 255, 255, 255, 255 }; //weekdays to activate on //bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity //blynk @@ -300,7 +300,7 @@ bool auxActive = false, auxActiveBefore = false; String escapedMac; #ifndef WLED_DISABLE_ALEXA Espalexa espalexa; -EspalexaDevice *espalexaDevice; +EspalexaDevice* espalexaDevice; #endif //dns server @@ -315,7 +315,7 @@ IPAddress ntpServerIP; uint16_t ntpLocalPort = 2390; // Temp buffer -char *obuf; +char* obuf; uint16_t olen = 0; //presets @@ -333,8 +333,8 @@ bool doPublishMqtt = false; //server library objects AsyncWebServer server(80); -AsyncClient *hueClient = NULL; -AsyncMqttClient *mqtt = NULL; +AsyncClient* hueClient = NULL; +AsyncMqttClient* mqtt = NULL; //udp interface objects WiFiUDP notifierUdp, rgbUdp; @@ -353,396 +353,376 @@ unsigned long wifiStateChangedTime = 0; int loops = 0; #endif -WLED::WLED() { - +WLED::WLED() +{ } //turns all LEDs off and restarts ESP void WLED::reset() { - briT = 0; - long dly = millis(); - while (millis() - dly < 250) - { - yield(); //enough time to send response to client - } - setAllLeds(); - DEBUG_PRINTLN("MODULE RESET"); - ESP.restart(); + briT = 0; + long dly = millis(); + while (millis() - dly < 250) { + yield(); //enough time to send response to client + } + setAllLeds(); + DEBUG_PRINTLN("MODULE RESET"); + ESP.restart(); } bool oappendi(int i) { - char s[11]; - sprintf(s, "%ld", i); - return oappend(s); + char s[11]; + sprintf(s, "%ld", i); + return oappend(s); } -bool oappend(const char *txt) +bool oappend(const char* txt) { - uint16_t len = strlen(txt); - if (olen + len >= OMAX) - return false; //buffer full - strcpy(obuf + olen, txt); - olen += len; - return true; + uint16_t len = strlen(txt); + if (olen + len >= OMAX) + return false; //buffer full + strcpy(obuf + olen, txt); + olen += len; + return true; } void WLED::loop() { - handleIR(); //2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too - handleConnection(); - handleSerial(); - handleNotifications(); - handleTransitions(); + handleIR(); //2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too + handleConnection(); + handleSerial(); + handleNotifications(); + handleTransitions(); #ifdef WLED_ENABLE_DMX - handleDMX(); + handleDMX(); #endif - userLoop(); + userLoop(); - yield(); - handleIO(); - handleIR(); - handleNetworkTime(); - handleAlexa(); + yield(); + handleIO(); + handleIR(); + handleNetworkTime(); + handleAlexa(); - handleOverlays(); - yield(); + handleOverlays(); + yield(); #ifdef WLED_USE_ANALOG_LEDS - strip.setRgbwPwm(); + strip.setRgbwPwm(); #endif - if (doReboot) - reset(); + if (doReboot) + reset(); - if (!realtimeMode) //block stuff if WARLS/Adalight is enabled - { - if (apActive) - dnsServer.processNextRequest(); + if (!realtimeMode) //block stuff if WARLS/Adalight is enabled + { + if (apActive) + dnsServer.processNextRequest(); #ifndef WLED_DISABLE_OTA - if (WLED_CONNECTED && aOtaEnabled) - ArduinoOTA.handle(); + if (WLED_CONNECTED && aOtaEnabled) + ArduinoOTA.handle(); #endif - handleNightlight(); - yield(); - - handleHue(); - handleBlynk(); - - yield(); - if (!offMode) - strip.service(); - } + handleNightlight(); yield(); + + handleHue(); + handleBlynk(); + + yield(); + if (!offMode) + strip.service(); + } + yield(); #ifdef ESP8266 - MDNS.update(); + MDNS.update(); #endif - if (millis() - lastMqttReconnectAttempt > 30000) - initMqtt(); + if (millis() - lastMqttReconnectAttempt > 30000) + initMqtt(); //DEBUG serial logging #ifdef WLED_DEBUG - if (millis() - debugTime > 9999) - { - DEBUG_PRINTLN("---DEBUG INFO---"); - DEBUG_PRINT("Runtime: "); - DEBUG_PRINTLN(millis()); - DEBUG_PRINT("Unix time: "); - DEBUG_PRINTLN(now()); - DEBUG_PRINT("Free heap: "); - DEBUG_PRINTLN(ESP.getFreeHeap()); - DEBUG_PRINT("Wifi state: "); - DEBUG_PRINTLN(WiFi.status()); - if (WiFi.status() != lastWifiState) - { - wifiStateChangedTime = millis(); - } - lastWifiState = WiFi.status(); - DEBUG_PRINT("State time: "); - DEBUG_PRINTLN(wifiStateChangedTime); - DEBUG_PRINT("NTP last sync: "); - DEBUG_PRINTLN(ntpLastSyncTime); - DEBUG_PRINT("Client IP: "); - DEBUG_PRINTLN(WiFi.localIP()); - DEBUG_PRINT("Loops/sec: "); - DEBUG_PRINTLN(loops / 10); - loops = 0; - debugTime = millis(); + if (millis() - debugTime > 9999) { + DEBUG_PRINTLN("---DEBUG INFO---"); + DEBUG_PRINT("Runtime: "); + DEBUG_PRINTLN(millis()); + DEBUG_PRINT("Unix time: "); + DEBUG_PRINTLN(now()); + DEBUG_PRINT("Free heap: "); + DEBUG_PRINTLN(ESP.getFreeHeap()); + DEBUG_PRINT("Wifi state: "); + DEBUG_PRINTLN(WiFi.status()); + if (WiFi.status() != lastWifiState) { + wifiStateChangedTime = millis(); } - loops++; + lastWifiState = WiFi.status(); + DEBUG_PRINT("State time: "); + DEBUG_PRINTLN(wifiStateChangedTime); + DEBUG_PRINT("NTP last sync: "); + DEBUG_PRINTLN(ntpLastSyncTime); + DEBUG_PRINT("Client IP: "); + DEBUG_PRINTLN(WiFi.localIP()); + DEBUG_PRINT("Loops/sec: "); + DEBUG_PRINTLN(loops / 10); + loops = 0; + debugTime = millis(); + } + loops++; #endif // WLED_DEBU } void WLED::setup() { - EEPROM.begin(EEPSIZE); - ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); - if (ledCount > MAX_LEDS || ledCount == 0) - ledCount = 30; + EEPROM.begin(EEPSIZE); + ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); + if (ledCount > MAX_LEDS || ledCount == 0) + ledCount = 30; #ifdef ESP8266 #if LEDPIN == 3 - if (ledCount > MAX_LEDS_DMA) - ledCount = MAX_LEDS_DMA; //DMA method uses too much ram + if (ledCount > MAX_LEDS_DMA) + ledCount = MAX_LEDS_DMA; //DMA method uses too much ram #endif #endif - Serial.begin(115200); - Serial.setTimeout(50); - DEBUG_PRINTLN(); - DEBUG_PRINT("---WLED "); - DEBUG_PRINT(versionString); - DEBUG_PRINT(" "); - DEBUG_PRINT(VERSION); - DEBUG_PRINTLN(" INIT---"); + Serial.begin(115200); + Serial.setTimeout(50); + DEBUG_PRINTLN(); + DEBUG_PRINT("---WLED "); + DEBUG_PRINT(versionString); + DEBUG_PRINT(" "); + DEBUG_PRINT(VERSION); + DEBUG_PRINTLN(" INIT---"); #ifdef ARDUINO_ARCH_ESP32 - DEBUG_PRINT("esp32 "); - DEBUG_PRINTLN(ESP.getSdkVersion()); + DEBUG_PRINT("esp32 "); + DEBUG_PRINTLN(ESP.getSdkVersion()); #else - DEBUG_PRINT("esp8266 "); - DEBUG_PRINTLN(ESP.getCoreVersion()); + DEBUG_PRINT("esp8266 "); + DEBUG_PRINTLN(ESP.getCoreVersion()); #endif - int heapPreAlloc = ESP.getFreeHeap(); - DEBUG_PRINT("heap "); - DEBUG_PRINTLN(ESP.getFreeHeap()); + int heapPreAlloc = ESP.getFreeHeap(); + DEBUG_PRINT("heap "); + DEBUG_PRINTLN(ESP.getFreeHeap()); - strip.init(EEPROM.read(372), ledCount, EEPROM.read(2204)); //init LEDs quickly - strip.setBrightness(0); + strip.init(EEPROM.read(372), ledCount, EEPROM.read(2204)); //init LEDs quickly + strip.setBrightness(0); - DEBUG_PRINT("LEDs inited. heap usage ~"); - DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap()); + DEBUG_PRINT("LEDs inited. heap usage ~"); + DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap()); #ifndef WLED_DISABLE_FILESYSTEM #ifdef ARDUINO_ARCH_ESP32 - SPIFFS.begin(true); + SPIFFS.begin(true); #endif - SPIFFS.begin(); + SPIFFS.begin(); #endif - DEBUG_PRINTLN("Load EEPROM"); - loadSettingsFromEEPROM(true); - beginStrip(); - userSetup(); - if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0) - showWelcomePage = true; - WiFi.persistent(false); + DEBUG_PRINTLN("Load EEPROM"); + loadSettingsFromEEPROM(true); + beginStrip(); + userSetup(); + if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0) + showWelcomePage = true; + WiFi.persistent(false); - if (macroBoot > 0) - applyMacro(macroBoot); - Serial.println("Ada"); + if (macroBoot > 0) + applyMacro(macroBoot); + Serial.println("Ada"); - //generate module IDs - escapedMac = WiFi.macAddress(); - escapedMac.replace(":", ""); - escapedMac.toLowerCase(); - if (strcmp(cmDNS, "x") == 0) //fill in unique mdns default - { - strcpy(cmDNS, "wled-"); - sprintf(cmDNS + 5, "%*s", 6, escapedMac.c_str() + 6); - } - if (mqttDeviceTopic[0] == 0) - { - strcpy(mqttDeviceTopic, "wled/"); - sprintf(mqttDeviceTopic + 5, "%*s", 6, escapedMac.c_str() + 6); - } - if (mqttClientID[0] == 0) - { - strcpy(mqttClientID, "WLED-"); - sprintf(mqttClientID + 5, "%*s", 6, escapedMac.c_str() + 6); - } + //generate module IDs + escapedMac = WiFi.macAddress(); + escapedMac.replace(":", ""); + escapedMac.toLowerCase(); + if (strcmp(cmDNS, "x") == 0) //fill in unique mdns default + { + strcpy(cmDNS, "wled-"); + sprintf(cmDNS + 5, "%*s", 6, escapedMac.c_str() + 6); + } + if (mqttDeviceTopic[0] == 0) { + strcpy(mqttDeviceTopic, "wled/"); + sprintf(mqttDeviceTopic + 5, "%*s", 6, escapedMac.c_str() + 6); + } + if (mqttClientID[0] == 0) { + strcpy(mqttClientID, "WLED-"); + sprintf(mqttClientID + 5, "%*s", 6, escapedMac.c_str() + 6); + } - strip.service(); + strip.service(); #ifndef WLED_DISABLE_OTA - if (aOtaEnabled) - { - ArduinoOTA.onStart([]() { + if (aOtaEnabled) { + ArduinoOTA.onStart([]() { #ifdef ESP8266 - wifi_set_sleep_type(NONE_SLEEP_T); + wifi_set_sleep_type(NONE_SLEEP_T); #endif - DEBUG_PRINTLN("Start ArduinoOTA"); - }); - if (strlen(cmDNS) > 0) - ArduinoOTA.setHostname(cmDNS); - } + DEBUG_PRINTLN("Start ArduinoOTA"); + }); + if (strlen(cmDNS) > 0) + ArduinoOTA.setHostname(cmDNS); + } #endif #ifdef WLED_ENABLE_DMX - dmx.init(512); // initialize with bus length + dmx.init(512); // initialize with bus length #endif - //HTTP server page init - initServer(); + //HTTP server page init + initServer(); } void WLED::beginStrip() { - // Initialize NeoPixel Strip and button - strip.setShowCallback(handleOverlayDraw); + // Initialize NeoPixel Strip and button + strip.setShowCallback(handleOverlayDraw); #ifdef BTNPIN - pinMode(BTNPIN, INPUT_PULLUP); + pinMode(BTNPIN, INPUT_PULLUP); #endif - if (bootPreset > 0) - applyPreset(bootPreset, turnOnAtBoot); - colorUpdated(NOTIFIER_CALL_MODE_INIT); + if (bootPreset > 0) + applyPreset(bootPreset, turnOnAtBoot); + colorUpdated(NOTIFIER_CALL_MODE_INIT); //init relay pin #if RLYPIN >= 0 - pinMode(RLYPIN, OUTPUT); + pinMode(RLYPIN, OUTPUT); #if RLYMDE - digitalWrite(RLYPIN, bri); + digitalWrite(RLYPIN, bri); #else - digitalWrite(RLYPIN, !bri); + digitalWrite(RLYPIN, !bri); #endif #endif - //disable button if it is "pressed" unintentionally + //disable button if it is "pressed" unintentionally #ifdef BTNPIN - if (digitalRead(BTNPIN) == LOW) - buttonEnabled = false; -#else + if (digitalRead(BTNPIN) == LOW) buttonEnabled = false; +#else + buttonEnabled = false; #endif } void WLED::initAP(bool resetAP) { - if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) - return; + if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) + return; - if (!apSSID[0] || resetAP) - strcpy(apSSID, "WLED-AP"); - if (resetAP) - strcpy(apPass, DEFAULT_AP_PASS); - DEBUG_PRINT("Opening access point "); - DEBUG_PRINTLN(apSSID); - WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0)); - WiFi.softAP(apSSID, apPass, apChannel, apHide); + if (!apSSID[0] || resetAP) + strcpy(apSSID, "WLED-AP"); + if (resetAP) + strcpy(apPass, DEFAULT_AP_PASS); + DEBUG_PRINT("Opening access point "); + DEBUG_PRINTLN(apSSID); + WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0)); + WiFi.softAP(apSSID, apPass, apChannel, apHide); - if (!apActive) //start captive portal if AP active - { - DEBUG_PRINTLN("Init AP interfaces"); - server.begin(); - if (udpPort > 0 && udpPort != ntpLocalPort) - { - udpConnected = notifierUdp.begin(udpPort); - } - if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) - { - udpRgbConnected = rgbUdp.begin(udpRgbPort); - } - - dnsServer.setErrorReplyCode(DNSReplyCode::NoError); - dnsServer.start(53, "*", WiFi.softAPIP()); + if (!apActive) //start captive portal if AP active + { + DEBUG_PRINTLN("Init AP interfaces"); + server.begin(); + if (udpPort > 0 && udpPort != ntpLocalPort) { + udpConnected = notifierUdp.begin(udpPort); } - apActive = true; + if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) { + udpRgbConnected = rgbUdp.begin(udpRgbPort); + } + + dnsServer.setErrorReplyCode(DNSReplyCode::NoError); + dnsServer.start(53, "*", WiFi.softAPIP()); + } + apActive = true; } void WLED::initConnection() { - WiFi.disconnect(); //close old connections + WiFi.disconnect(); //close old connections #ifdef ESP8266 - WiFi.setPhyMode(WIFI_PHY_MODE_11N); + WiFi.setPhyMode(WIFI_PHY_MODE_11N); #endif - if (staticIP[0] != 0 && staticGateway[0] != 0) - { - WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8, 8, 8, 8)); - } - else - { - WiFi.config(0U, 0U, 0U); - } + if (staticIP[0] != 0 && staticGateway[0] != 0) { + WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8, 8, 8, 8)); + } else { + WiFi.config(0U, 0U, 0U); + } - lastReconnectAttempt = millis(); + lastReconnectAttempt = millis(); - if (!WLED_WIFI_CONFIGURED) - { - DEBUG_PRINT("No connection configured. "); - if (!apActive) - initAP(); //instantly go to ap mode - return; + if (!WLED_WIFI_CONFIGURED) { + DEBUG_PRINT("No connection configured. "); + if (!apActive) + initAP(); //instantly go to ap mode + return; + } else if (!apActive) { + if (apBehavior == AP_BEHAVIOR_ALWAYS) { + initAP(); + } else { + DEBUG_PRINTLN("Access point disabled."); + WiFi.softAPdisconnect(true); } - else if (!apActive) - { - if (apBehavior == AP_BEHAVIOR_ALWAYS) - { - initAP(); - } - else - { - DEBUG_PRINTLN("Access point disabled."); - WiFi.softAPdisconnect(true); - } - } - showWelcomePage = false; + } + showWelcomePage = false; - DEBUG_PRINT("Connecting to "); - DEBUG_PRINT(clientSSID); - DEBUG_PRINTLN("..."); + DEBUG_PRINT("Connecting to "); + DEBUG_PRINT(clientSSID); + DEBUG_PRINTLN("..."); #ifdef ESP8266 - WiFi.hostname(serverDescription); + WiFi.hostname(serverDescription); #endif - WiFi.begin(clientSSID, clientPass); + WiFi.begin(clientSSID, clientPass); #ifdef ARDUINO_ARCH_ESP32 - WiFi.setSleep(!noWifiSleep); - WiFi.setHostname(serverDescription); + WiFi.setSleep(!noWifiSleep); + WiFi.setHostname(serverDescription); #else - wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); + wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); #endif } void WLED::initInterfaces() { - DEBUG_PRINTLN("Init STA interfaces"); + DEBUG_PRINTLN("Init STA interfaces"); - if (hueIP[0] == 0) - { - hueIP[0] = WiFi.localIP()[0]; - hueIP[1] = WiFi.localIP()[1]; - hueIP[2] = WiFi.localIP()[2]; - } + if (hueIP[0] == 0) { + hueIP[0] = WiFi.localIP()[0]; + hueIP[1] = WiFi.localIP()[1]; + hueIP[2] = WiFi.localIP()[2]; + } - //init Alexa hue emulation - if (alexaEnabled) - alexaInit(); + //init Alexa hue emulation + if (alexaEnabled) + alexaInit(); #ifndef WLED_DISABLE_OTA - if (aOtaEnabled) - ArduinoOTA.begin(); + if (aOtaEnabled) + ArduinoOTA.begin(); #endif - strip.service(); - // Set up mDNS responder: - if (strlen(cmDNS) > 0) - { - if (!aOtaEnabled) - MDNS.begin(cmDNS); + strip.service(); + // Set up mDNS responder: + if (strlen(cmDNS) > 0) { + if (!aOtaEnabled) + MDNS.begin(cmDNS); - DEBUG_PRINTLN("mDNS started"); - MDNS.addService("http", "tcp", 80); - MDNS.addService("wled", "tcp", 80); - MDNS.addServiceTxt("wled", "tcp", "mac", escapedMac.c_str()); - } - server.begin(); + DEBUG_PRINTLN("mDNS started"); + MDNS.addService("http", "tcp", 80); + MDNS.addService("wled", "tcp", 80); + MDNS.addServiceTxt("wled", "tcp", "mac", escapedMac.c_str()); + } + server.begin(); - if (udpPort > 0 && udpPort != ntpLocalPort) - { - udpConnected = notifierUdp.begin(udpPort); - if (udpConnected && udpRgbPort != udpPort) - udpRgbConnected = rgbUdp.begin(udpRgbPort); - } - if (ntpEnabled) - ntpConnected = ntpUdp.begin(ntpLocalPort); + if (udpPort > 0 && udpPort != ntpLocalPort) { + udpConnected = notifierUdp.begin(udpPort); + if (udpConnected && udpRgbPort != udpPort) + udpRgbConnected = rgbUdp.begin(udpRgbPort); + } + if (ntpEnabled) + ntpConnected = ntpUdp.begin(ntpLocalPort); - initBlynk(blynkApiKey); - e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST, e131Universe, E131_MAX_UNIVERSE_COUNT); - reconnectHue(); - initMqtt(); - interfacesInited = true; - wasConnected = true; + initBlynk(blynkApiKey); + e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST, e131Universe, E131_MAX_UNIVERSE_COUNT); + reconnectHue(); + initMqtt(); + interfacesInited = true; + wasConnected = true; } byte stacO = 0; @@ -751,86 +731,75 @@ unsigned long heapTime = 0; void WLED::handleConnection() { - if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) - return; - if (lastReconnectAttempt == 0) - initConnection(); + if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) + return; + if (lastReconnectAttempt == 0) + initConnection(); - //reconnect WiFi to clear stale allocations if heap gets too low - if (millis() - heapTime > 5000) - { - uint32_t heap = ESP.getFreeHeap(); - if (heap < 9000 && lastHeap < 9000) - { - DEBUG_PRINT("Heap too low! "); - DEBUG_PRINTLN(heap); - forceReconnect = true; - } - lastHeap = heap; - heapTime = millis(); + //reconnect WiFi to clear stale allocations if heap gets too low + if (millis() - heapTime > 5000) { + uint32_t heap = ESP.getFreeHeap(); + if (heap < 9000 && lastHeap < 9000) { + DEBUG_PRINT("Heap too low! "); + DEBUG_PRINTLN(heap); + forceReconnect = true; } + lastHeap = heap; + heapTime = millis(); + } - byte stac = 0; - if (apActive) - { + byte stac = 0; + if (apActive) { #ifdef ESP8266 - stac = wifi_softap_get_station_num(); + stac = wifi_softap_get_station_num(); #else - wifi_sta_list_t stationList; - esp_wifi_ap_get_sta_list(&stationList); - stac = stationList.num; + wifi_sta_list_t stationList; + esp_wifi_ap_get_sta_list(&stationList); + stac = stationList.num; #endif - if (stac != stacO) - { - stacO = stac; - DEBUG_PRINT("Connected AP clients: "); - DEBUG_PRINTLN(stac); - if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) - { //trying to connect, but not connected - if (stac) - WiFi.disconnect(); //disable search so that AP can work - else - initConnection(); //restart search - } - } + if (stac != stacO) { + stacO = stac; + DEBUG_PRINT("Connected AP clients: "); + DEBUG_PRINTLN(stac); + if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { //trying to connect, but not connected + if (stac) + WiFi.disconnect(); //disable search so that AP can work + else + initConnection(); //restart search + } } - if (forceReconnect) - { - DEBUG_PRINTLN("Forcing reconnect."); - initConnection(); - interfacesInited = false; - forceReconnect = false; - wasConnected = false; - return; + } + if (forceReconnect) { + DEBUG_PRINTLN("Forcing reconnect."); + initConnection(); + interfacesInited = false; + forceReconnect = false; + wasConnected = false; + return; + } + if (!WLED_CONNECTED) { + if (interfacesInited) { + DEBUG_PRINTLN("Disconnected!"); + interfacesInited = false; + initConnection(); } - if (!WLED_CONNECTED) - { - if (interfacesInited) - { - DEBUG_PRINTLN("Disconnected!"); - interfacesInited = false; - initConnection(); - } - if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) - initConnection(); - if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) - initAP(); - } - else if (!interfacesInited) - { //newly connected - DEBUG_PRINTLN(""); - DEBUG_PRINT("Connected! IP address: "); - DEBUG_PRINTLN(WiFi.localIP()); - initInterfaces(); - userConnected(); + if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) + initConnection(); + if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) + initAP(); + } else if (!interfacesInited) { //newly connected + DEBUG_PRINTLN(""); + DEBUG_PRINT("Connected! IP address: "); + DEBUG_PRINTLN(WiFi.localIP()); + initInterfaces(); + userConnected(); - //shut down AP - if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) - { - dnsServer.stop(); - WiFi.softAPdisconnect(true); - apActive = false; - DEBUG_PRINTLN("Access point disabled."); - } + //shut down AP + if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) { + dnsServer.stop(); + WiFi.softAPdisconnect(true); + apActive = false; + DEBUG_PRINTLN("Access point disabled."); } + } } From ffbedbc1e62dd25c4a4e798182a831666fe3e3d2 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 06:27:36 -0400 Subject: [PATCH 134/509] Add clang format to git ignore. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ea49cb51f..5e61e1565 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /wled00/Release /wled00/extLibs /platformio_override.ini +.clang-format From 8d75c06852e44e3b87b3b2002a40cee4796af7d0 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 06:42:21 -0400 Subject: [PATCH 135/509] Format changes. --- .clang-format | 10 +- wled00/wled.cpp | 366 ++++++++++++++++++++++++------------------------ wled00/wled.h | 188 +++++++++++++------------ 3 files changed, 287 insertions(+), 277 deletions(-) diff --git a/.clang-format b/.clang-format index 56df2b76f..aedd2246f 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,12 @@ --- BasedOnStyle: Webkit IndentWidth: 2 - \ No newline at end of file + AlignTrailingComments: true + SpacesBeforeTrailingComments: 8 + AllowShortIfStatementsOnASingleLine: Always + AllowShortLoopsOnASingleLine: true + AllowShortLambdasOnASingleLine: true + AllowShortCaseLabelsOnASingleLine: true + AllowShortFunctionsOnASingleLine: All + AllowShortBlocksOnASingleLine: true + IndentCaseLabels: true \ No newline at end of file diff --git a/wled00/wled.cpp b/wled00/wled.cpp index fd47592f7..48231599d 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -18,224 +18,224 @@ // Global Variable definitions char versionString[] = "0.9.1"; -//AP and OTA default passwords (for maximum change them!) +// AP and OTA default passwords (for maximum change them!) char apPass[65] = DEFAULT_AP_PASS; char otaPass[33] = DEFAULT_OTA_PASS; -//Hardware CONFIG (only changeble HERE, not at runtime) -//LED strip pin, button pin and IR pin changeable in NpbWrapper.h! +// Hardware CONFIG (only changeble HERE, not at runtime) +// LED strip pin, button pin and IR pin changeable in NpbWrapper.h! -byte auxDefaultState = 0; //0: input 1: high 2: low -byte auxTriggeredState = 0; //0: input 1: high 2: low -char ntpServerName[33] = "0.wled.pool.ntp.org"; //NTP server to use +byte auxDefaultState = 0; // 0: input 1: high 2: low +byte auxTriggeredState = 0; // 0: input 1: high 2: low +char ntpServerName[33] = "0.wled.pool.ntp.org"; // NTP server to use -//WiFi CONFIG (all these can be changed via web UI, no need to set them here) +// WiFi CONFIG (all these can be changed via web UI, no need to set them here) char clientSSID[33] = CLIENT_SSID; char clientPass[65] = CLIENT_PASS; -char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) -char apSSID[33] = ""; //AP off by default (unless setup) -byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) -byte apHide = 0; //hidden AP SSID -byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no connection after boot by default -IPAddress staticIP(0, 0, 0, 0); //static IP of ESP -IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP -IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks -bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues +char cmDNS[33] = "x"; // mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) +char apSSID[33] = ""; // AP off by default (unless setup) +byte apChannel = 1; // 2.4GHz WiFi AP channel (1-13) +byte apHide = 0; // hidden AP SSID +byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; // access point opens when no connection after boot by default +IPAddress staticIP(0, 0, 0, 0); // static IP of ESP +IPAddress staticGateway(0, 0, 0, 0); // gateway (router) IP +IPAddress staticSubnet(255, 255, 255, 0); // most common subnet in home networks +bool noWifiSleep = false; // disabling modem sleep modes will increase heat output and power usage, but may help with connection issues -//LED CONFIG -uint16_t ledCount = 30; //overcurrent prevented by ABL -bool useRGBW = false; //SK6812 strips can contain an extra White channel -bool turnOnAtBoot = true; //turn on LEDs at power-up -byte bootPreset = 0; //save preset to load after power-up +// LED CONFIG +uint16_t ledCount = 30; // overcurrent prevented by ABL +bool useRGBW = false; // SK6812 strips can contain an extra White channel +bool turnOnAtBoot = true; // turn on LEDs at power-up +byte bootPreset = 0; // save preset to load after power-up -byte col[] { 255, 160, 0, 0 }; //current RGB(W) primary color. col[] should be updated if you want to change the color. -byte colSec[] { 0, 0, 0, 0 }; //current RGB(W) secondary color -byte briS = 128; //default brightness +byte col[] { 255, 160, 0, 0 }; // current RGB(W) primary color. col[] should be updated if you want to change the color. +byte colSec[] { 0, 0, 0, 0 }; // current RGB(W) secondary color +byte briS = 128; // default brightness -byte nightlightTargetBri = 0; //brightness after nightlight is over +byte nightlightTargetBri = 0; // brightness after nightlight is over byte nightlightDelayMins = 60; -bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over -bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. -bool fadeTransition = true; //enable crossfading color transition -uint16_t transitionDelay = 750; //default crossfade duration in ms +bool nightlightFade = true; // if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over +bool nightlightColorFade = false; // if enabled, light will gradually fade color from primary to secondary color. +bool fadeTransition = true; // enable crossfading color transition +uint16_t transitionDelay = 750; // default crossfade duration in ms -bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) -byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) +bool skipFirstLed = false; // ignore first LED in strip (useful if you need the LED as signal repeater) +byte briMultiplier = 100; // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) -//User Interface CONFIG -char serverDescription[33] = "WLED"; //Name of module -bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise +// User Interface CONFIG +char serverDescription[33] = "WLED"; // Name of module +bool syncToggleReceive = false; // UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise -//Sync CONFIG +// Sync CONFIG bool buttonEnabled = true; -byte irEnabled = 0; //Infrared receiver +byte irEnabled = 0; // Infrared receiver -uint16_t udpPort = 21324; //WLED notifier default port -uint16_t udpRgbPort = 19446; //Hyperion port +uint16_t udpPort = 21324; // WLED notifier default port +uint16_t udpRgbPort = 19446; // Hyperion port -bool receiveNotificationBrightness = true; //apply brightness from incoming notifications -bool receiveNotificationColor = true; //apply color -bool receiveNotificationEffects = true; //apply effects setup -bool notifyDirect = false; //send notification if change via UI or HTTP API -bool notifyButton = false; //send if updated by button or infrared remote -bool notifyAlexa = false; //send notification if updated via Alexa -bool notifyMacro = false; //send notification for macro -bool notifyHue = true; //send notification if Hue light changes -bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably +bool receiveNotificationBrightness = true; // apply brightness from incoming notifications +bool receiveNotificationColor = true; // apply color +bool receiveNotificationEffects = true; // apply effects setup +bool notifyDirect = false; // send notification if change via UI or HTTP API +bool notifyButton = false; // send if updated by button or infrared remote +bool notifyAlexa = false; // send notification if updated via Alexa +bool notifyMacro = false; // send notification for macro +bool notifyHue = true; // send notification if Hue light changes +bool notifyTwice = false; // notifications use UDP: enable if devices don't sync reliably -bool alexaEnabled = true; //enable device discovery by Amazon Echo -char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand +bool alexaEnabled = true; // enable device discovery by Amazon Echo +char alexaInvocationName[33] = "Light"; // speech control name of device. Choose something voice-to-text can understand -char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made +char blynkApiKey[36] = ""; // Auth token for Blynk server. If empty, no connection will be made -uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode -int arlsOffset = 0; //realtime LED offset -bool receiveDirect = true; //receive UDP realtime -bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source -bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black +uint16_t realtimeTimeoutMs = 2500; // ms timeout of realtime mode before returning to normal mode +int arlsOffset = 0; // realtime LED offset +bool receiveDirect = true; // receive UDP realtime +bool arlsDisableGammaCorrection = true; // activate if gamma correction is handled by the source +bool arlsForceMaxBri = false; // enable to force max brightness if source has very dark colors that would be black -uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) -uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] -uint8_t DMXOldDimmer = 0; //only update brightness on change -uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss -bool e131Multicast = false; //multicast or unicast -bool e131SkipOutOfSequence = false; //freeze instead of flickering +uint16_t e131Universe = 1; // settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) +uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; // DMX mode (s.a.) +uint16_t DMXAddress = 1; // DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +uint8_t DMXOldDimmer = 0; // only update brightness on change +uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; // to detect packet loss +bool e131Multicast = false; // multicast or unicast +bool e131SkipOutOfSequence = false; // freeze instead of flickering bool mqttEnabled = false; -char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) -char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices) -char mqttServer[33] = ""; //both domains and IPs should work (no SSL) -char mqttUser[41] = ""; //optional: username for MQTT auth -char mqttPass[41] = ""; //optional: password for MQTT auth -char mqttClientID[41] = ""; //override the client ID +char mqttDeviceTopic[33] = ""; // main MQTT topic (individual per device, default is wled/mac) +char mqttGroupTopic[33] = "wled/all"; // second MQTT topic (for example to group devices) +char mqttServer[33] = ""; // both domains and IPs should work (no SSL) +char mqttUser[41] = ""; // optional: username for MQTT auth +char mqttPass[41] = ""; // optional: password for MQTT auth +char mqttClientID[41] = ""; // override the client ID uint16_t mqttPort = 1883; -bool huePollingEnabled = false; //poll hue bridge for light state -uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response -char hueApiKey[47] = "api"; //key token will be obtained from bridge -byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) -IPAddress hueIP = (0, 0, 0, 0); //IP address of the bridge +bool huePollingEnabled = false; // poll hue bridge for light state +uint16_t huePollIntervalMs = 2500; // low values (< 1sec) may cause lag but offer quicker response +char hueApiKey[47] = "api"; // key token will be obtained from bridge +byte huePollLightId = 1; // ID of hue lamp to sync to. Find the ID in the hue app ("about" section) +IPAddress hueIP = (0, 0, 0, 0); // IP address of the bridge bool hueApplyOnOff = true; bool hueApplyBri = true; bool hueApplyColor = true; -//Time CONFIG -bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros -bool useAMPM = false; //12h/24h clock format -byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino -int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation +// Time CONFIG +bool ntpEnabled = false; // get internet time. Only required if you use clock overlays or time-activated macros +bool useAMPM = false; // 12h/24h clock format +byte currentTimezone = 0; // Timezone ID. Refer to timezones array in wled10_ntp.ino +int utcOffsetSecs = 0; // Seconds to offset from UTC before timzone calculation -byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie -byte overlayMin = 0, overlayMax = ledCount - 1; //boundaries of overlay mode +byte overlayDefault = 0; // 0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie +byte overlayMin = 0, overlayMax = ledCount - 1; // boundaries of overlay mode -byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be -bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel -bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position +byte analogClock12pixel = 0; // The pixel in your strip where "midnight" would be +bool analogClockSecondsTrail = false; // Display seconds as trail of LEDs instead of a single pixel +bool analogClock5MinuteMarks = false; // Light pixels at every 5-minute position -char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino -bool cronixieBacklight = true; //Allow digits to be back-illuminated +char cronixieDisplay[7] = "HHMMSS"; // Cronixie Display mask. See wled13_cronixie.ino +bool cronixieBacklight = true; // Allow digits to be back-illuminated -bool countdownMode = false; //Clock will count down towards date -byte countdownYear = 20, countdownMonth = 1; //Countdown target date, year is last two digits +bool countdownMode = false; // Clock will count down towards date +byte countdownYear = 20, countdownMonth = 1; // Countdown target date, year is last two digits byte countdownDay = 1, countdownHour = 0; byte countdownMin = 0, countdownSec = 0; -byte macroBoot = 0; //macro loaded after startup -byte macroNl = 0; //after nightlight delay over +byte macroBoot = 0; // macro loaded after startup +byte macroNl = 0; // after nightlight delay over byte macroCountdown = 0; byte macroAlexaOn = 0, macroAlexaOff = 0; byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; -//Security CONFIG -bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks -bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled -bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on +// Security CONFIG +bool otaLock = false; // prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks +bool wifiLock = false; // prevents access to WiFi settings when OTA lock is enabled +bool aOtaEnabled = true; // ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on uint16_t userVar0 = 0, userVar1 = 0; #ifdef WLED_ENABLE_DMX -//dmx CONFIG -byte DMXChannels = 7; // number of channels per fixture -byte DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -// assigns the different channels to different functions. See wled21_dmx.ino for more information. -uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. -uint16_t DMXStart = 10; // start address of the first fixture + // dmx CONFIG + byte DMXChannels = 7; // number of channels per fixture + byte DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + // assigns the different channels to different functions. See wled21_dmx.ino for more information. + uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. + uint16_t DMXStart = 10; // start address of the first fixture #endif -//internal global variable declarations -//wifi +// internal global variable declarations +// wifi bool apActive = false; bool forceReconnect = false; uint32_t lastReconnectAttempt = 0; bool interfacesInited = false; bool wasConnected = false; -//color -byte colOld[] { 0, 0, 0, 0 }; //color before transition -byte colT[] { 0, 0, 0, 0 }; //color that is currently displayed on the LEDs -byte colIT[] { 0, 0, 0, 0 }; //color that was last sent to LEDs +// color +byte colOld[] { 0, 0, 0, 0 }; // color before transition +byte colT[] { 0, 0, 0, 0 }; // color that is currently displayed on the LEDs +byte colIT[] { 0, 0, 0, 0 }; // color that was last sent to LEDs byte colSecT[] { 0, 0, 0, 0 }; byte colSecOld[] { 0, 0, 0, 0 }; byte colSecIT[] { 0, 0, 0, 0 }; -byte lastRandomIndex = 0; //used to save last random color so the new one is not the same +byte lastRandomIndex = 0; // used to save last random color so the new one is not the same -//transitions +// transitions bool transitionActive = false; uint16_t transitionDelayDefault = transitionDelay; uint16_t transitionDelayTemp = transitionDelay; unsigned long transitionStartTime; -float tperLast = 0; //crossfade transition progress, 0.0f - 1.0f +float tperLast = 0; // crossfade transition progress, 0.0f - 1.0f bool jsonTransitionOnce = false; -//nightlight +// nightlight bool nightlightActive = false; bool nightlightActiveOld = false; uint32_t nightlightDelayMs = 10; uint8_t nightlightDelayMinsDefault = nightlightDelayMins; unsigned long nightlightStartTime; -byte briNlT = 0; //current nightlight brightness -byte colNlT[] { 0, 0, 0, 0 }; //current nightlight color +byte briNlT = 0; // current nightlight brightness +byte colNlT[] { 0, 0, 0, 0 }; // current nightlight color -//brightness +// brightness unsigned long lastOnTime = 0; bool offMode = !turnOnAtBoot; byte bri = briS; byte briOld = 0; byte briT = 0; byte briIT = 0; -byte briLast = 128; //brightness before turned off. Used for toggle function -byte whiteLast = 128; //white channel before turned off. Used for toggle function +byte briLast = 128; // brightness before turned off. Used for toggle function +byte whiteLast = 128; // white channel before turned off. Used for toggle function -//button +// button bool buttonPressedBefore = false; bool buttonLongPressed = false; unsigned long buttonPressedTime = 0; unsigned long buttonWaitTime = 0; -//notifications +// notifications bool notifyDirectDefault = notifyDirect; bool receiveNotifications = true; unsigned long notificationSentTime = 0; byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; bool notificationTwoRequired = false; -//effects +// effects byte effectCurrent = 0; byte effectSpeed = 128; byte effectIntensity = 128; byte effectPalette = 0; -//network +// network bool udpConnected = false, udpRgbConnected = false; -//ui style +// ui style bool showWelcomePage = false; -//hue +// hue byte hueError = HUE_ERROR_INACTIVE; -//uint16_t hueFailCount = 0; +// uint16_t hueFailCount = 0; float hueXLast = 0, hueYLast = 0; uint16_t hueHueLast = 0, hueCtLast = 0; byte hueSatLast = 0, hueBriLast = 0; @@ -244,32 +244,32 @@ bool hueAuthRequired = false; bool hueReceived = false; bool hueStoreAllowed = false, hueNewKey = false; -//overlays +// overlays byte overlayCurrent = overlayDefault; byte overlaySpeed = 200; unsigned long overlayRefreshMs = 200; unsigned long overlayRefreshedTime; -//cronixie +// cronixie byte dP[] { 0, 0, 0, 0, 0, 0 }; bool cronixieInit = false; -//countdown +// countdown unsigned long countdownTime = 1514764800L; bool countdownOverTriggered = true; -//timer +// timer byte lastTimerMinute = 0; byte timerHours[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; byte timerMinutes[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; byte timerMacro[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -byte timerWeekday[] = { 255, 255, 255, 255, 255, 255, 255, 255 }; //weekdays to activate on -//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity +byte timerWeekday[] = { 255, 255, 255, 255, 255, 255, 255, 255 }; // weekdays to activate on +// bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity -//blynk +// blynk bool blynkEnabled = false; -//preset cycling +// preset cycling bool presetCyclingEnabled = false; byte presetCycleMin = 1, presetCycleMax = 5; uint16_t presetCycleTime = 1250; @@ -278,35 +278,35 @@ byte presetCycCurr = presetCycleMin; bool presetApplyBri = true; bool saveCurrPresetCycConf = false; -//realtime +// realtime byte realtimeMode = REALTIME_MODE_INACTIVE; IPAddress realtimeIP = (0, 0, 0, 0); unsigned long realtimeTimeout = 0; -//mqtt +// mqtt long lastMqttReconnectAttempt = 0; long lastInterfaceUpdate = 0; byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; -char mqttStatusTopic[40] = ""; //this must be global because of async handlers +char mqttStatusTopic[40] = ""; // this must be global because of async handlers #if AUXPIN >= 0 - //auxiliary debug pin -byte auxTime = 0; -unsigned long auxStartTime = 0; -bool auxActive = false, auxActiveBefore = false; + // auxiliary debug pin + byte auxTime = 0; + unsigned long auxStartTime = 0; + bool auxActive = false, auxActiveBefore = false; #endif -//alexa udp +// alexa udp String escapedMac; #ifndef WLED_DISABLE_ALEXA -Espalexa espalexa; -EspalexaDevice* espalexaDevice; + Espalexa espalexa; + EspalexaDevice* espalexaDevice; #endif -//dns server +// dns server DNSServer dnsServer; -//network time +// network time bool ntpConnected = false; time_t local = 0; unsigned long ntpLastSyncTime = 999000000L; @@ -318,7 +318,7 @@ uint16_t ntpLocalPort = 2390; char* obuf; uint16_t olen = 0; -//presets +// presets uint16_t savedPresets = 0; int8_t currentPreset = -1; bool isPreset = false; @@ -328,42 +328,42 @@ byte errorFlag = 0; String messageHead, messageSub; byte optionType; -bool doReboot = false; //flag to initiate reboot from async handlers +bool doReboot = false; // flag to initiate reboot from async handlers bool doPublishMqtt = false; -//server library objects +// server library objects AsyncWebServer server(80); AsyncClient* hueClient = NULL; AsyncMqttClient* mqtt = NULL; -//udp interface objects +// udp interface objects WiFiUDP notifierUdp, rgbUdp; WiFiUDP ntpUdp; ESPAsyncE131 e131(handleE131Packet); bool e131NewData = false; -//led fx library object +// led fx library object WS2812FX strip = WS2812FX(); -//debug macro variable definitions +// debug macro variable definitions #ifdef WLED_DEBUG -unsigned long debugTime = 0; -int lastWifiState = 3; -unsigned long wifiStateChangedTime = 0; -int loops = 0; + unsigned long debugTime = 0; + int lastWifiState = 3; + unsigned long wifiStateChangedTime = 0; + int loops = 0; #endif WLED::WLED() { } -//turns all LEDs off and restarts ESP +// turns all LEDs off and restarts ESP void WLED::reset() { briT = 0; long dly = millis(); while (millis() - dly < 250) { - yield(); //enough time to send response to client + yield(); // enough time to send response to client } setAllLeds(); DEBUG_PRINTLN("MODULE RESET"); @@ -381,7 +381,7 @@ bool oappend(const char* txt) { uint16_t len = strlen(txt); if (olen + len >= OMAX) - return false; //buffer full + return false; // buffer full strcpy(obuf + olen, txt); olen += len; return true; @@ -389,7 +389,7 @@ bool oappend(const char* txt) void WLED::loop() { - handleIR(); //2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too + handleIR(); // 2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too handleConnection(); handleSerial(); handleNotifications(); @@ -414,7 +414,7 @@ void WLED::loop() if (doReboot) reset(); - if (!realtimeMode) //block stuff if WARLS/Adalight is enabled + if (!realtimeMode) // block stuff if WARLS/Adalight is enabled { if (apActive) dnsServer.processNextRequest(); @@ -439,7 +439,7 @@ void WLED::loop() if (millis() - lastMqttReconnectAttempt > 30000) initMqtt(); -//DEBUG serial logging +// DEBUG serial logging #ifdef WLED_DEBUG if (millis() - debugTime > 9999) { DEBUG_PRINTLN("---DEBUG INFO---"); @@ -467,7 +467,7 @@ void WLED::loop() debugTime = millis(); } loops++; -#endif // WLED_DEBU +#endif // WLED_DEBU } void WLED::setup() @@ -478,10 +478,10 @@ void WLED::setup() ledCount = 30; #ifdef ESP8266 -#if LEDPIN == 3 - if (ledCount > MAX_LEDS_DMA) - ledCount = MAX_LEDS_DMA; //DMA method uses too much ram -#endif + #if LEDPIN == 3 + if (ledCount > MAX_LEDS_DMA) + ledCount = MAX_LEDS_DMA; // DMA method uses too much ram + #endif #endif Serial.begin(115200); Serial.setTimeout(50); @@ -502,17 +502,17 @@ void WLED::setup() DEBUG_PRINT("heap "); DEBUG_PRINTLN(ESP.getFreeHeap()); - strip.init(EEPROM.read(372), ledCount, EEPROM.read(2204)); //init LEDs quickly + strip.init(EEPROM.read(372), ledCount, EEPROM.read(2204)); // init LEDs quickly strip.setBrightness(0); DEBUG_PRINT("LEDs inited. heap usage ~"); DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap()); #ifndef WLED_DISABLE_FILESYSTEM -#ifdef ARDUINO_ARCH_ESP32 - SPIFFS.begin(true); -#endif - SPIFFS.begin(); + #ifdef ARDUINO_ARCH_ESP32 + SPIFFS.begin(true); + #endif + SPIFFS.begin(); #endif DEBUG_PRINTLN("Load EEPROM"); @@ -527,11 +527,11 @@ void WLED::setup() applyMacro(macroBoot); Serial.println("Ada"); - //generate module IDs + // generate module IDs escapedMac = WiFi.macAddress(); escapedMac.replace(":", ""); escapedMac.toLowerCase(); - if (strcmp(cmDNS, "x") == 0) //fill in unique mdns default + if (strcmp(cmDNS, "x") == 0) // fill in unique mdns default { strcpy(cmDNS, "wled-"); sprintf(cmDNS + 5, "%*s", 6, escapedMac.c_str() + 6); @@ -560,9 +560,9 @@ void WLED::setup() } #endif #ifdef WLED_ENABLE_DMX - dmx.init(512); // initialize with bus length + dmx.init(512); // initialize with bus length #endif - //HTTP server page init + // HTTP server page init initServer(); } @@ -579,7 +579,7 @@ void WLED::beginStrip() applyPreset(bootPreset, turnOnAtBoot); colorUpdated(NOTIFIER_CALL_MODE_INIT); -//init relay pin +// init relay pin #if RLYPIN >= 0 pinMode(RLYPIN, OUTPUT); #if RLYMDE @@ -589,7 +589,7 @@ void WLED::beginStrip() #endif #endif - //disable button if it is "pressed" unintentionally + // disable button if it is "pressed" unintentionally #ifdef BTNPIN if (digitalRead(BTNPIN) == LOW) buttonEnabled = false; @@ -612,7 +612,7 @@ void WLED::initAP(bool resetAP) WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0)); WiFi.softAP(apSSID, apPass, apChannel, apHide); - if (!apActive) //start captive portal if AP active + if (!apActive) // start captive portal if AP active { DEBUG_PRINTLN("Init AP interfaces"); server.begin(); @@ -631,7 +631,7 @@ void WLED::initAP(bool resetAP) void WLED::initConnection() { - WiFi.disconnect(); //close old connections + WiFi.disconnect(); // close old connections #ifdef ESP8266 WiFi.setPhyMode(WIFI_PHY_MODE_11N); #endif @@ -647,7 +647,7 @@ void WLED::initConnection() if (!WLED_WIFI_CONFIGURED) { DEBUG_PRINT("No connection configured. "); if (!apActive) - initAP(); //instantly go to ap mode + initAP(); // instantly go to ap mode return; } else if (!apActive) { if (apBehavior == AP_BEHAVIOR_ALWAYS) { @@ -687,7 +687,7 @@ void WLED::initInterfaces() hueIP[2] = WiFi.localIP()[2]; } - //init Alexa hue emulation + // init Alexa hue emulation if (alexaEnabled) alexaInit(); @@ -736,7 +736,7 @@ void WLED::handleConnection() if (lastReconnectAttempt == 0) initConnection(); - //reconnect WiFi to clear stale allocations if heap gets too low + // reconnect WiFi to clear stale allocations if heap gets too low if (millis() - heapTime > 5000) { uint32_t heap = ESP.getFreeHeap(); if (heap < 9000 && lastHeap < 9000) { @@ -761,11 +761,11 @@ void WLED::handleConnection() stacO = stac; DEBUG_PRINT("Connected AP clients: "); DEBUG_PRINTLN(stac); - if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { //trying to connect, but not connected + if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { // trying to connect, but not connected if (stac) - WiFi.disconnect(); //disable search so that AP can work + WiFi.disconnect(); // disable search so that AP can work else - initConnection(); //restart search + initConnection(); // restart search } } } @@ -787,14 +787,14 @@ void WLED::handleConnection() initConnection(); if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) initAP(); - } else if (!interfacesInited) { //newly connected + } else if (!interfacesInited) { // newly connected DEBUG_PRINTLN(""); DEBUG_PRINT("Connected! IP address: "); DEBUG_PRINTLN(WiFi.localIP()); initInterfaces(); userConnected(); - //shut down AP + // shut down AP if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) { dnsServer.stop(); WiFi.softAPdisconnect(true); diff --git a/wled00/wled.h b/wled00/wled.h index 3e6c11be1..72686a000 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -14,41 +14,41 @@ // Alternatively, with platformio pass your chosen flags to your custom build target in platformio.ini.override // You are required to disable over-the-air updates: -//#define WLED_DISABLE_OTA //saves 14kb +//#define WLED_DISABLE_OTA // saves 14kb // You need to choose some of these features to disable: -//#define WLED_DISABLE_ALEXA //saves 11kb -//#define WLED_DISABLE_BLYNK //saves 6kb -//#define WLED_DISABLE_CRONIXIE //saves 3kb -//#define WLED_DISABLE_HUESYNC //saves 4kb -//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 12kb -#define WLED_ENABLE_MQTT //saves 12kb -#define WLED_ENABLE_ADALIGHT //saves 500b only -//#define WLED_ENABLE_DMX //uses 3.5kb +//#define WLED_DISABLE_ALEXA // saves 11kb +//#define WLED_DISABLE_BLYNK // saves 6kb +//#define WLED_DISABLE_CRONIXIE // saves 3kb +//#define WLED_DISABLE_HUESYNC // saves 4kb +//#define WLED_DISABLE_INFRARED // there is no pin left for this on ESP8266-01, saves 12kb +#define WLED_ENABLE_MQTT // saves 12kb +#define WLED_ENABLE_ADALIGHT // saves 500b only +//#define WLED_ENABLE_DMX // uses 3.5kb -#define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet -//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version -//#define WLED_ENABLE_FS_EDITOR //enable /edit page for editing SPIFFS content. Will also be disabled with OTA lock +#define WLED_DISABLE_FILESYSTEM // SPIFFS is not used by any WLED feature yet +//#define WLED_ENABLE_FS_SERVING // Enable sending html file from SPIFFS before serving progmem version +//#define WLED_ENABLE_FS_EDITOR // enable /edit page for editing SPIFFS content. Will also be disabled with OTA lock // to toggle usb serial debug (un)comment the following line //#define WLED_DEBUG // Library inclusions. #include -#ifdef ESP8266 -#include -#include -#include -extern "C" -{ -#include -} -#else //ESP32 -#include -#include "esp_wifi.h" -#include -#include -#include "SPIFFS.h" + #ifdef ESP8266 + #include + #include + #include + extern "C" + { + #include + } +#else // ESP32 + #include + #include "esp_wifi.h" + #include + #include + #include "SPIFFS.h" #endif #include @@ -56,25 +56,28 @@ extern "C" #include #include #ifndef WLED_DISABLE_OTA -#include + #include #endif #include #include "src/dependencies/time/TimeLib.h" #include "src/dependencies/timezone/Timezone.h" + #ifndef WLED_DISABLE_ALEXA -#define ESPALEXA_ASYNC -#define ESPALEXA_NO_SUBPAGE -#define ESPALEXA_MAXDEVICES 1 -// #define ESPALEXA_DEBUG -#include "src/dependencies/espalexa/Espalexa.h" + #define ESPALEXA_ASYNC + #define ESPALEXA_NO_SUBPAGE + #define ESPALEXA_MAXDEVICES 1 + // #define ESPALEXA_DEBUG + #include "src/dependencies/espalexa/Espalexa.h" #endif #ifndef WLED_DISABLE_BLYNK -#include "src/dependencies/blynk/BlynkSimpleEsp.h" + #include "src/dependencies/blynk/BlynkSimpleEsp.h" #endif + #include "src/dependencies/e131/ESPAsyncE131.h" #include "src/dependencies/async-mqtt-client/AsyncMqttClient.h" #include "src/dependencies/json/AsyncJson-v6.h" #include "src/dependencies/json/ArduinoJson-v6.h" + #include "html_ui.h" #include "html_settings.h" #include "html_other.h" @@ -83,35 +86,35 @@ extern "C" #include "const.h" #ifndef CLIENT_SSID -#define CLIENT_SSID DEFAULT_CLIENT_SSID + #define CLIENT_SSID DEFAULT_CLIENT_SSID #endif #ifndef CLIENT_PASS -#define CLIENT_PASS "" + #define CLIENT_PASS "" #endif #if IR_PIN < 0 -#ifndef WLED_DISABLE_INFRARED -#define WLED_DISABLE_INFRARED -#endif + #ifndef WLED_DISABLE_INFRARED + #define WLED_DISABLE_INFRARED + #endif #endif #ifndef WLED_DISABLE_INFRARED -#include -#include -#include + #include + #include + #include #endif // remove flicker because PWM signal of RGB channels can become out of phase #if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266) -#include "src/dependencies/arduino/core_esp8266_waveform.h" + #include "src/dependencies/arduino/core_esp8266_waveform.h" #endif // enable additional debug output #ifdef WLED_DEBUG -#ifndef ESP8266 -#include -#endif + #ifndef ESP8266 + #include + #endif #endif // version code in format yymmddb (b = daily build) @@ -137,7 +140,7 @@ extern IPAddress staticSubnet; extern bool noWifiSleep; extern uint16_t ledCount; extern bool useRGBW; -#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit +#define ABL_MILLIAMPS_DEFAULT 850; // auto lower brightness to stay close to milliampere limit extern bool turnOnAtBoot; extern byte bootPreset; extern byte col[]; @@ -224,11 +227,10 @@ extern bool wifiLock; extern bool aOtaEnabled; extern uint16_t userVar0, userVar1; #ifdef WLED_ENABLE_DMX -extern byte DMXChannels; -extern byte DMXFixtureMap[15]; -extern -extern uint16_t DMXGap; -extern uint16_t DMXStart; + extern byte DMXChannels; + extern byte DMXFixtureMap[15]; + extern uint16_t DMXGap; + extern uint16_t DMXStart; #endif extern bool apActive; extern bool forceReconnect; @@ -315,15 +317,17 @@ extern long lastInterfaceUpdate; extern byte interfaceUpdateCallMode; extern char mqttStatusTopic[40]; #if AUXPIN >= 0 -extern byte auxTime; -extern unsigned long auxStartTime; -extern bool auxActive; + extern byte auxTime; + extern unsigned long auxStartTime; + extern bool auxActive; #endif extern String escapedMac; #ifndef WLED_DISABLE_ALEXA -extern Espalexa espalexa; -extern EspalexaDevice *espalexaDevice; + extern Espalexa espalexa; + extern EspalexaDevice *espalexaDevice; #endif + +#define NTP_PACKET_SIZE 48 extern DNSServer dnsServer; extern bool ntpConnected; extern time_t local; @@ -331,15 +335,14 @@ extern unsigned long ntpLastSyncTime; extern unsigned long ntpPacketSentTime; extern IPAddress ntpServerIP; extern uint16_t ntpLocalPort; -#define NTP_PACKET_SIZE 48 -//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue +// maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue #define MAX_LEDS 1500 #define MAX_LEDS_DMA 500 -//string temp buffer (now stored in stack locally) +// string temp buffer (now stored in stack locally) #define OMAX 2048 -extern char *obuf; +extern char* obuf; extern uint16_t olen; extern uint16_t savedPresets; @@ -348,11 +351,11 @@ extern bool isPreset; extern byte errorFlag; extern String messageHead, messageSub; extern byte optionType; -extern bool doReboot; +extern bool doReboot; extern bool doPublishMqtt; extern AsyncWebServer server; -extern AsyncClient *hueClient; -extern AsyncMqttClient *mqtt; +extern AsyncClient* hueClient; +extern AsyncMqttClient* mqtt; extern WiFiUDP notifierUdp, rgbUdp; extern WiFiUDP ntpUdp; extern ESPAsyncE131 e131; @@ -362,46 +365,45 @@ extern WS2812FX strip; #define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) #define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) -//debug macros +// debug macros #ifdef WLED_DEBUG -#define DEBUG_PRINT(x) Serial.print(x) -#define DEBUG_PRINTLN(x) Serial.println(x) -#define DEBUG_PRINTF(x) Serial.printf(x) -extern unsigned long debugTime; -extern int lastWifiState; -extern unsigned long wifiStateChangedTime; -extern int loops; + #define DEBUG_PRINT(x) Serial.print(x) + #define DEBUG_PRINTLN(x) Serial.println(x) + #define DEBUG_PRINTF(x) Serial.printf(x) + extern unsigned long debugTime; + extern int lastWifiState; + extern unsigned long wifiStateChangedTime; + extern int loops; #else -#define DEBUG_PRINT(x) -#define DEBUG_PRINTLN(x) -#define DEBUG_PRINTF(x) + #define DEBUG_PRINT(x) + #define DEBUG_PRINTLN(x) + #define DEBUG_PRINTF(x) #endif // append new c string to temp buffer efficiently -bool oappend(const char *txt); +bool oappend(const char* txt); // append new number to temp buffer efficiently bool oappendi(int i); -class WLED -{ +class WLED { public: - WLED(); - static WLED &instance() - { - static WLED instance; - return instance; - } + WLED(); + static WLED& instance() + { + static WLED instance; + return instance; + } - //boot starts here - void setup(); + // boot starts here + void setup(); - void loop(); - void reset(); + void loop(); + void reset(); - void beginStrip(); - void handleConnection(); - void initAP(bool resetAP = false); - void initConnection(); - void initInterfaces(); + void beginStrip(); + void handleConnection(); + void initAP(bool resetAP = false); + void initConnection(); + void initInterfaces(); }; -#endif // WLED_H +#endif // WLED_H From aea07f42d1a55155d79269ec775959a41c8e38fd Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 06:56:51 -0400 Subject: [PATCH 136/509] Fix mistaken substitute. --- wled00/FX.cpp | 50 +++++++++++++++++++++++------------------------ wled00/FX_fcn.cpp | 2 +- wled00/blynk.h | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index e5408a424..7230a9b3e 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -268,7 +268,7 @@ uint16_t WS2812FX::mode_breath(void) { counter = (counter >> 2) + (counter >> 4); //0-16384 + 0-2048 if (counter < 16384) { if (counter > 8192) counter = 8192 - (counter - 8192); - var = sin16(counter) / 103; //close to parabolic in range 0-8192, MAX val. 23170 + var = sin16(counter) / 103; //close to parabolic in range 0-8192, max val. 23170 } uint8_t lum = 30 + var; @@ -475,8 +475,8 @@ uint16_t WS2812FX::mode_twinkle(void) { uint32_t it = now / cycleTime; if (it != SEGENV.step) { - uint16_t MAXOn = map(SEGMENT.intensity, 0, 255, 1, SEGLEN); // make sure at least one LED is on - if (SEGENV.aux0 >= MAXOn) + uint16_t maxOn = map(SEGMENT.intensity, 0, 255, 1, SEGLEN); // make sure at least one LED is on + if (SEGENV.aux0 >= maxOn) { SEGENV.aux0 = 0; SEGENV.aux1 = random16(); //new seed for our PRNG @@ -1597,8 +1597,8 @@ uint16_t WS2812FX::mode_oscillate(void) uint16_t WS2812FX::mode_lightning(void) { - uint16_t ledstart = random16(SEGLEN); // DeterMINe starting location of flash - uint16_t ledlen = random16(SEGLEN -1 -ledstart); // DeterMINe length of flash (not to go beyond NUM_LEDS-1) + uint16_t ledstart = random16(SEGLEN); // Determine starting location of flash + uint16_t ledlen = random16(SEGLEN -1 -ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1) uint8_t bri = 255/random8(1, 3); if (SEGENV.step == 0) @@ -2153,9 +2153,9 @@ typedef struct Ripple { uint16_t WS2812FX::ripple_base(bool rainbow) { - uint16_t MAXRipples = 1 + (SEGLEN >> 2); - if (MAXRipples > 100) MAXRipples = 100; - uint16_t dataSize = sizeof(ripple) * MAXRipples; + uint16_t maxRipples = 1 + (SEGLEN >> 2); + if (maxRipples > 100) maxRipples = 100; + uint16_t dataSize = sizeof(ripple) * maxRipples; if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -2181,7 +2181,7 @@ uint16_t WS2812FX::ripple_base(bool rainbow) } //draw wave - for (uint16_t i = 0; i < MAXRipples; i++) + for (uint16_t i = 0; i < maxRipples; i++) { uint16_t ripplestate = ripples[i].state; if (ripplestate) @@ -2480,8 +2480,8 @@ uint16_t WS2812FX::spots_base(uint16_t threshold) { fill(SEGCOLOR(1)); - uint16_t MAXZones = SEGLEN >> 2; - uint16_t zones = 1 + ((SEGMENT.intensity * MAXZones) >> 8); + uint16_t maxZones = SEGLEN >> 2; + uint16_t zones = 1 + ((SEGMENT.intensity * maxZones) >> 8); uint16_t zoneLen = SEGLEN / zones; uint16_t offset = (SEGLEN - zones * zoneLen) >> 1; @@ -2533,15 +2533,15 @@ typedef struct Ball { */ uint16_t WS2812FX::mode_bouncing_balls(void) { //allocate segment data - uint16_t MAXNumBalls = 16; - uint16_t dataSize = sizeof(ball) * MAXNumBalls; + uint16_t maxNumBalls = 16; + uint16_t dataSize = sizeof(ball) * maxNumBalls; if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed Ball* balls = reinterpret_cast(SEGENV.data); - // number of balls based on intensity setting to MAX of 7 (cycles colors) + // number of balls based on intensity setting to max of 7 (cycles colors) // non-chosen color is a random color - uint8_t numBalls = int(((SEGMENT.intensity * (MAXNumBalls - 0.8f)) / 255) + 1); + uint8_t numBalls = int(((SEGMENT.intensity * (maxNumBalls - 0.8f)) / 255) + 1); float gravity = -9.81; // standard value of gravity float impactVelocityStart = sqrt( -2 * gravity); @@ -2549,7 +2549,7 @@ uint16_t WS2812FX::mode_bouncing_balls(void) { unsigned long time = millis(); if (SEGENV.call == 0) { - for (uint8_t i = 0; i < MAXNumBalls; i++) balls[i].lastBounceTime = time; + for (uint8_t i = 0; i < maxNumBalls; i++) balls[i].lastBounceTime = time; } bool hasCol2 = SEGCOLOR(2); @@ -2665,8 +2665,8 @@ typedef struct Spark { */ uint16_t WS2812FX::mode_popcorn(void) { //allocate segment data - uint16_t MAXNumPopcorn = 24; - uint16_t dataSize = sizeof(spark) * MAXNumPopcorn; + uint16_t maxNumPopcorn = 24; + uint16_t dataSize = sizeof(spark) * maxNumPopcorn; if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed Spark* popcorn = reinterpret_cast(SEGENV.data); @@ -2677,7 +2677,7 @@ uint16_t WS2812FX::mode_popcorn(void) { bool hasCol2 = SEGCOLOR(2); fill(hasCol2 ? BLACK : SEGCOLOR(1)); - uint8_t numPopcorn = SEGMENT.intensity*MAXNumPopcorn/255; + uint8_t numPopcorn = SEGMENT.intensity*maxNumPopcorn/255; if (numPopcorn == 0) numPopcorn = 1; for(uint8_t i = 0; i < numPopcorn; i++) { @@ -2792,13 +2792,13 @@ uint16_t WS2812FX::mode_starburst(void) { star* stars = reinterpret_cast(SEGENV.data); - float MAXSpeed = 375.0f; // Max velocity + float maxSpeed = 375.0f; // Max velocity float particleIgnition = 250.0f; // How long to "flash" float particleFadeTime = 1500.0f; // Fade out time for (int j = 0; j < numStars; j++) { - // speed to adjust chance of a burst, MAX is nearly always. + // speed to adjust chance of a burst, max is nearly always. if (random8((144-(SEGMENT.speed >> 1))) == 0 && stars[j].birth == 0) { // Pick a random color and location. @@ -2807,7 +2807,7 @@ uint16_t WS2812FX::mode_starburst(void) { stars[j].color = col_to_crgb(color_wheel(random8())); stars[j].pos = startPos; - stars[j].vel = MAXSpeed * (float)(random8())/255.0 * multiplier; + stars[j].vel = maxSpeed * (float)(random8())/255.0 * multiplier; stars[j].birth = it; stars[j].last = it; // more fragments means larger burst effect @@ -3026,7 +3026,7 @@ uint16_t WS2812FX::mode_drip(void) drops[j].pos = SEGLEN-1; // start at end drops[j].vel = 0; // speed drops[j].col = sourcedrop; // brightness - drops[j].colIndex = 1; // drop state (0 init, 1 forMINg, 2 falling, 5 bouncing) + drops[j].colIndex = 1; // drop state (0 init, 1 forming, 2 falling, 5 bouncing) } setPixelColor(SEGLEN-1,color_blend(BLACK,SEGCOLOR(0), sourcedrop));// water source @@ -3047,7 +3047,7 @@ uint16_t WS2812FX::mode_drip(void) if (drops[j].pos < 0) drops[j].pos = 0; drops[j].vel += gravity; - for (int i=1;i<7-drops[j].colIndex;i++) { // some MINor math so we don't expand bouncing droplets + for (int i=1;i<7-drops[j].colIndex;i++) { // some minor math so we don't expand bouncing droplets setPixelColor(int(drops[j].pos)+i,color_blend(BLACK,SEGCOLOR(0),drops[j].col/i)); //spread pixel with fade while falling } @@ -3055,7 +3055,7 @@ uint16_t WS2812FX::mode_drip(void) setPixelColor(0,color_blend(SEGCOLOR(0),BLACK,drops[j].col)); } } else { // we hit bottom - if (drops[j].colIndex > 2) { // already hit once, so back to forMINg + if (drops[j].colIndex > 2) { // already hit once, so back to forming drops[j].colIndex = 0; drops[j].col = sourcedrop; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 75ec65101..de89a430e 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -638,7 +638,7 @@ uint32_t WS2812FX::color_wheel(uint8_t pos) { } /* - * Returns a new, random wheel index with a MINimum distance of 42 from pos. + * Returns a new, random wheel index with a minimum distance of 42 from pos. */ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) { uint8_t r = 0, x = 0, y = 0, d = 0; diff --git a/wled00/blynk.h b/wled00/blynk.h index cf3a2e225..f17f774a0 100644 --- a/wled00/blynk.h +++ b/wled00/blynk.h @@ -8,6 +8,6 @@ void initBlynk(const char* auth); void handleBlynk(); void updateBlynk(); -// Unsure if the macro expansions need to accessed through the declaration... TODO +// TODO: Make sure that the macro expansions are handled correctly. #endif //WLED_BLYNK_H \ No newline at end of file From 8ff4f50f79aa0f663f25408c621d235225734272 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 07:24:45 -0400 Subject: [PATCH 137/509] Fix visual studio project files and organize. --- wled00/wled00.vcxproj | 317 +++++----------- wled00/wled00.vcxproj.filters | 657 ++++++++++++++++++++-------------- 2 files changed, 483 insertions(+), 491 deletions(-) diff --git a/wled00/wled00.vcxproj b/wled00/wled00.vcxproj index 2183ad262..e095b8f76 100644 --- a/wled00/wled00.vcxproj +++ b/wled00/wled00.vcxproj @@ -104,231 +104,103 @@ CppCode - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -350,6 +222,11 @@ + + + + + VisualMicroDebugger @@ -362,4 +239,4 @@ - \ No newline at end of file + diff --git a/wled00/wled00.vcxproj.filters b/wled00/wled00.vcxproj.filters index e2c2b219c..ef1f47bdf 100644 --- a/wled00/wled00.vcxproj.filters +++ b/wled00/wled00.vcxproj.filters @@ -1,272 +1,387 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - - - - - - - - - - - - - - - - - - - - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {72fe60da-ba26-45b4-82c1-bdff809975da} + + + {8880888d-efea-4189-a25a-834b7b3bb756} + + + + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + \ No newline at end of file From a9a7720a1158dc5b7a2c95c430bcebbc14c4ae3f Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 07:45:33 -0400 Subject: [PATCH 138/509] Import dmx output library into project. --- wled00/dmx.h | 39 ++++----- wled00/src/dependencies/dmx/ESPDMX.cpp | 106 +++++++++++++++++++++++++ wled00/src/dependencies/dmx/ESPDMX.h | 31 ++++++++ wled00/wled.cpp | 1 + 4 files changed, 158 insertions(+), 19 deletions(-) create mode 100644 wled00/src/dependencies/dmx/ESPDMX.cpp create mode 100644 wled00/src/dependencies/dmx/ESPDMX.h diff --git a/wled00/dmx.h b/wled00/dmx.h index 76aab4849..0ab2a4a20 100644 --- a/wled00/dmx.h +++ b/wled00/dmx.h @@ -1,64 +1,65 @@ #ifndef WLED_DMX_H #define WLED_DMX_H -#include "wled.h" +#include "wled.h" /* * Support for DMX via MAX485. - * Needs the espdmx library. You might have to change the output pin within the library. Sketchy, i know. + * Change the output pin in src/dependencies/ESPDMX.cpp if needed. + * Library from: * https://github.com/Rickgg/ESP-Dmx */ #ifdef WLED_ENABLE_DMX -#include +#include "src/dependencies/dmx/ESPDMX.h" DMXESPSerial dmx; -#ifdef WLED_ENABLE_DMX -void handleDMX() { +void handleDMX() +{ // TODO: calculate brightness manually if no shutter channel is set - + uint8_t brightness = strip.getBrightness(); - for (int i = 0; i < ledCount; i++) { // uses the amount of LEDs as fixture count + for (int i = 0; i < ledCount; i++) { // uses the amount of LEDs as fixture count - uint32_t in = strip.getPixelColor(i); // time to get the colors for the individual fixtures as suggested by AirCookie at issue #462 + uint32_t in = strip.getPixelColor(i); // time to get the colors for the individual fixtures as suggested by AirCookie at issue #462 byte w = in >> 24 & 0xFF; byte r = in >> 16 & 0xFF; - byte g = in >> 8 & 0xFF; - byte b = in & 0xFF; + byte g = in >> 8 & 0xFF; + byte b = in & 0xFF; int DMXFixtureStart = DMXStart + (DMXGap * i); for (int j = 0; j < DMXChannels; j++) { int DMXAddr = DMXFixtureStart + j; switch (DMXFixtureMap[j]) { - case 0: // Set this channel to 0. Good way to tell strobe- and fade-functions to fuck right off. + case 0: // Set this channel to 0. Good way to tell strobe- and fade-functions to fuck right off. dmx.write(DMXAddr, 0); break; - case 1: // Red + case 1: // Red dmx.write(DMXAddr, r); break; - case 2: // Green + case 2: // Green dmx.write(DMXAddr, g); break; - case 3: // Blue + case 3: // Blue dmx.write(DMXAddr, b); break; - case 4: // White + case 4: // White dmx.write(DMXAddr, w); break; - case 5: // Shutter channel. Controls the brightness. + case 5: // Shutter channel. Controls the brightness. dmx.write(DMXAddr, brightness); break; - case 6:// Sets this channel to 255. Like 0, but more wholesome. + case 6: // Sets this channel to 255. Like 0, but more wholesome. dmx.write(DMXAddr, 255); break; } } } - dmx.update(); // update the DMX bus + dmx.update(); // update the DMX bus } #else void handleDMX() {} #endif -#endif //WLED_DMX_H \ No newline at end of file +#endif //WLED_DMX_H \ No newline at end of file diff --git a/wled00/src/dependencies/dmx/ESPDMX.cpp b/wled00/src/dependencies/dmx/ESPDMX.cpp new file mode 100644 index 000000000..f3ece1c8e --- /dev/null +++ b/wled00/src/dependencies/dmx/ESPDMX.cpp @@ -0,0 +1,106 @@ +// - - - - - +// ESPDMX - A Arduino library for sending and receiving DMX using the builtin serial hardware port. +// ESPDMX.cpp: Library implementation file +// +// Copyright (C) 2015 Rick +// This work is licensed under a GNU style license. +// +// Last change: Marcel Seerig +// +// Documentation and samples are available at https://github.com/Rickgg/ESP-Dmx +// - - - - - + +/* ----- LIBRARIES ----- */ +#include + +#include "ESPDMX.h" + + + +#define dmxMaxChannel 512 +#define defaultMax 32 + +#define DMXSPEED 250000 +#define DMXFORMAT SERIAL_8N2 +#define BREAKSPEED 83333 +#define BREAKFORMAT SERIAL_8N1 + +bool dmxStarted = false; +int sendPin = 2; //dafault on ESP8266 + +//DMX value array and size. Entry 0 will hold startbyte +uint8_t dmxData[dmxMaxChannel] = {}; +int chanSize; + + +void DMXESPSerial::init() { + chanSize = defaultMax; + + Serial1.begin(DMXSPEED); + pinMode(sendPin, OUTPUT); + dmxStarted = true; +} + +// Set up the DMX-Protocol +void DMXESPSerial::init(int chanQuant) { + + if (chanQuant > dmxMaxChannel || chanQuant <= 0) { + chanQuant = defaultMax; + } + + chanSize = chanQuant; + + Serial1.begin(DMXSPEED); + pinMode(sendPin, OUTPUT); + dmxStarted = true; +} + +// Function to read DMX data +uint8_t DMXESPSerial::read(int Channel) { + if (dmxStarted == false) init(); + + if (Channel < 1) Channel = 1; + if (Channel > dmxMaxChannel) Channel = dmxMaxChannel; + return(dmxData[Channel]); +} + +// Function to send DMX data +void DMXESPSerial::write(int Channel, uint8_t value) { + if (dmxStarted == false) init(); + + if (Channel < 1) Channel = 1; + if (Channel > chanSize) Channel = chanSize; + if (value < 0) value = 0; + if (value > 255) value = 255; + + dmxData[Channel] = value; +} + +void DMXESPSerial::end() { + delete dmxData; + chanSize = 0; + Serial1.end(); + dmxStarted == false; +} + +void DMXESPSerial::update() { + if (dmxStarted == false) init(); + + //Send break + digitalWrite(sendPin, HIGH); + Serial1.begin(BREAKSPEED, BREAKFORMAT); + Serial1.write(0); + Serial1.flush(); + delay(1); + Serial1.end(); + + //send data + Serial1.begin(DMXSPEED, DMXFORMAT); + digitalWrite(sendPin, LOW); + Serial1.write(dmxData, chanSize); + Serial1.flush(); + delay(1); + Serial1.end(); +} + +// Function to update the DMX bus diff --git a/wled00/src/dependencies/dmx/ESPDMX.h b/wled00/src/dependencies/dmx/ESPDMX.h new file mode 100644 index 000000000..4585bdd26 --- /dev/null +++ b/wled00/src/dependencies/dmx/ESPDMX.h @@ -0,0 +1,31 @@ +// - - - - - +// ESPDMX - A Arduino library for sending and receiving DMX using the builtin serial hardware port. +// ESPDMX.cpp: Library implementation file +// +// Copyright (C) 2015 Rick +// This work is licensed under a GNU style license. +// +// Last change: Marcel Seerig +// +// Documentation and samples are available at https://github.com/Rickgg/ESP-Dmx +// - - - - - + +#include + + +#ifndef ESPDMX_h +#define ESPDMX_h + +// ---- Methods ---- + +class DMXESPSerial { +public: + void init(); + void init(int MaxChan); + uint8_t read(int Channel); + void write(int channel, uint8_t value); + void update(); + void end(); +}; + +#endif diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 48231599d..fdb607765 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -2,6 +2,7 @@ #include "alexa.h" #include "blynk.h" #include "button.h" +#include "dmx.h" #include "file.h" #include "hue.h" #include "ir.h" From ad70fcba7fc2dbda16ec78b27a1ad443378a5ef4 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 08:00:58 -0400 Subject: [PATCH 139/509] Typo fix. --- wled00/overlay.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wled00/overlay.h b/wled00/overlay.h index b403a6e23..f7b54d5db 100644 --- a/wled00/overlay.h +++ b/wled00/overlay.h @@ -1,5 +1,5 @@ -#ifndef WLED_OVERLAYS_H -#define WLED_OVERLAYS_H +#ifndef WLED_OVERLAY_H +#define WLED_OVERLAY_H #include /* * Used to draw clock overlays over the strip From cf29ddc8d0d25a240648f044d798eb4ebd59f710 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 08:03:55 -0400 Subject: [PATCH 140/509] Typo fix. --- wled00/usermod.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/usermod.cpp b/wled00/usermod.cpp index 6589c07c8..96c1f8a6c 100644 --- a/wled00/usermod.cpp +++ b/wled00/usermod.cpp @@ -2,7 +2,7 @@ /* * This file allows you to add own functionality to WLED more easily * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality - * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled01_wled_eeprom.h) + * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled_eeprom.h) * bytes 2400+ are currently ununsed, but might be used for future wled features */ From 9875fbef0aa2c159eec8496dfd77fda80e8cd930 Mon Sep 17 00:00:00 2001 From: Travis J Dean Date: Mon, 30 Mar 2020 08:34:20 -0400 Subject: [PATCH 141/509] Layout changes. --- wled00/wled.h | 2 +- wled00/wled00.vcxproj.filters | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/wled00/wled.h b/wled00/wled.h index 72686a000..70b197c8e 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -35,7 +35,7 @@ // Library inclusions. #include - #ifdef ESP8266 +#ifdef ESP8266 #include #include #include diff --git a/wled00/wled00.vcxproj.filters b/wled00/wled00.vcxproj.filters index ef1f47bdf..39fe509e9 100644 --- a/wled00/wled00.vcxproj.filters +++ b/wled00/wled00.vcxproj.filters @@ -135,9 +135,6 @@ Header Files\Dependencies - - Header Files\Dependencies - Header Files\Dependencies @@ -147,9 +144,6 @@ Header Files\Dependencies - - Header Files\Dependencies - Header Files\Dependencies @@ -258,6 +252,12 @@ Header Files + + Header Files + + + Header Files + From a88ae2ca56a277d070906832a534960f1eecc26c Mon Sep 17 00:00:00 2001 From: Travis Dean Date: Mon, 30 Mar 2020 08:48:01 -0400 Subject: [PATCH 142/509] Delete .clang-format --- .clang-format | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 .clang-format diff --git a/.clang-format b/.clang-format deleted file mode 100644 index aedd2246f..000000000 --- a/.clang-format +++ /dev/null @@ -1,12 +0,0 @@ ---- - BasedOnStyle: Webkit - IndentWidth: 2 - AlignTrailingComments: true - SpacesBeforeTrailingComments: 8 - AllowShortIfStatementsOnASingleLine: Always - AllowShortLoopsOnASingleLine: true - AllowShortLambdasOnASingleLine: true - AllowShortCaseLabelsOnASingleLine: true - AllowShortFunctionsOnASingleLine: All - AllowShortBlocksOnASingleLine: true - IndentCaseLabels: true \ No newline at end of file From 6268cadc950db2e58d1837361ebe2e64db9f27f5 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 31 Mar 2020 02:38:08 +0200 Subject: [PATCH 143/509] Function definitions in func_declare.h Significantly reducing number of header files --- CHANGELOG.md | 36 ++--- wled00/alexa.cpp | 14 +- wled00/alexa.h | 17 --- wled00/blynk.cpp | 8 +- wled00/blynk.h | 13 -- wled00/button.cpp | 4 - wled00/button.h | 12 -- wled00/colors.cpp | 5 +- wled00/colors.h | 20 --- wled00/const.h | 7 +- wled00/cronixie.cpp | 243 ------------------------------- wled00/cronixie.h | 13 -- wled00/{dmx.h => dmx.cpp} | 5 +- wled00/e131.cpp | 144 +++++++++++++++++++ wled00/file.cpp | 86 +---------- wled00/file.h | 12 -- wled00/func_declare.h | 183 ++++++++++++++++++++++++ wled00/hue.cpp | 9 +- wled00/hue.h | 16 --- wled00/ir.cpp | 8 +- wled00/ir.h | 24 ---- wled00/json.cpp | 7 +- wled00/json.h | 21 --- wled00/led.cpp | 10 +- wled00/led.h | 19 --- wled00/mqtt.cpp | 10 +- wled00/mqtt.h | 9 -- wled00/notify.h | 18 --- wled00/ntp.cpp | 6 +- wled00/ntp.h | 18 --- wled00/overlay.cpp | 253 ++++++++++++++++++++++++++++++++- wled00/overlay.h | 14 -- wled00/set.cpp | 14 +- wled00/set.h | 16 --- wled00/{notify.cpp => udp.cpp} | 148 +------------------ wled00/usermod.cpp | 2 +- wled00/usermod.h | 8 -- wled00/wled.cpp | 17 +-- wled00/wled.h | 9 +- wled00/wled00.ino | 6 +- wled00/wled_eeprom.cpp | 9 +- wled00/wled_eeprom.h | 23 --- wled00/wled_serial.cpp | 83 +++++++++++ wled00/wled_server.cpp | 8 +- wled00/wled_server.h | 21 --- wled00/xml.cpp | 6 +- wled00/xml.h | 15 -- 47 files changed, 759 insertions(+), 890 deletions(-) delete mode 100644 wled00/alexa.h delete mode 100644 wled00/blynk.h delete mode 100644 wled00/button.h delete mode 100644 wled00/colors.h delete mode 100644 wled00/cronixie.cpp delete mode 100644 wled00/cronixie.h rename wled00/{dmx.h => dmx.cpp} (96%) create mode 100644 wled00/e131.cpp delete mode 100644 wled00/file.h create mode 100644 wled00/func_declare.h delete mode 100644 wled00/hue.h delete mode 100644 wled00/ir.h delete mode 100644 wled00/json.h delete mode 100644 wled00/led.h delete mode 100644 wled00/mqtt.h delete mode 100644 wled00/notify.h delete mode 100644 wled00/ntp.h delete mode 100644 wled00/overlay.h delete mode 100644 wled00/set.h rename wled00/{notify.cpp => udp.cpp} (55%) delete mode 100644 wled00/usermod.h delete mode 100644 wled00/wled_eeprom.h create mode 100644 wled00/wled_serial.cpp delete mode 100644 wled00/wled_server.h delete mode 100644 wled00/xml.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d3a466c4..a9804b1f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,43 +2,47 @@ ### Development versions after 0.9.1 release +#### Build 2003300 + +- Major change of project structure from .ino to .cpp and func_declare.h + #### Build 2003262 - - Fixed compilation for Analog LEDs - - Fixed sync settings network port fields too small +- Fixed compilation for Analog LEDs +- Fixed sync settings network port fields too small #### Build 2003261 - - Fixed live preview not displaying whole light if over 255 LEDs +- Fixed live preview not displaying whole light if over 255 LEDs #### Build 2003251 - - Added Pacifica effect (tentative, doesn't yet support other colors) - - Added Atlantica palette - - Fixed ESP32 build of Espalexa +- Added Pacifica effect (tentative, doesn't yet support other colors) +- Added Atlantica palette +- Fixed ESP32 build of Espalexa #### Build 2003222 - - Fixed Alexa Whites on non-RGBW lights (bump Espalexa to 2.4.5) +- Fixed Alexa Whites on non-RGBW lights (bump Espalexa to 2.4.5) #### Build 2003221 - - Moved Cronixie driver from FX library to drawOverlay handler +- Moved Cronixie driver from FX library to drawOverlay handler #### Build 2003211 - - Added custom mapping compile define to FX_fcn.h - - Merged pull request #784 by @TravisDean: Fixed initialization bug when toggling skip first - - Added link to youtube videos by Room31 to readme +- Added custom mapping compile define to FX_fcn.h +- Merged pull request #784 by @TravisDean: Fixed initialization bug when toggling skip first +- Added link to youtube videos by Room31 to readme #### Build 2003141 - - Fixed color of main segment returned in JSON API during transition not being target color (closes #765) - - Fixed arlsLock() being called after pixels set in E1.31 (closes #772) - - Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment) +- Fixed color of main segment returned in JSON API during transition not being target color (closes #765) +- Fixed arlsLock() being called after pixels set in E1.31 (closes #772) +- Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment) #### Build 2003121 - - Created changelog.md - make tracking changes to code easier - - Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection +- Created changelog.md - make tracking changes to code easier +- Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection diff --git a/wled00/alexa.cpp b/wled00/alexa.cpp index e35f5b358..c9f61ff23 100644 --- a/wled00/alexa.cpp +++ b/wled00/alexa.cpp @@ -1,9 +1,13 @@ -#include "alexa.h" #include "wled.h" -#include "const.h" -#include "led.h" -#include "wled_eeprom.h" -#include "colors.h" + +/* + * Alexa Voice On/Off/Brightness/Color Control. Emulates a Philips Hue bridge to Alexa. + * + * This was put together from these two excellent projects: + * https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch + * https://github.com/probonopd/ESP8266HueEmulator + */ +#include "src/dependencies/espalexa/EspalexaDevice.h" #ifndef WLED_DISABLE_ALEXA void onAlexaChange(EspalexaDevice* dev); diff --git a/wled00/alexa.h b/wled00/alexa.h deleted file mode 100644 index c2adfebe3..000000000 --- a/wled00/alexa.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef WLED_ALEXA_H -#define WLED_ALEXA_H -/* - * Alexa Voice On/Off/Brightness Control. Emulates a Philips Hue bridge to Alexa. - * - * This was put together from these two excellent projects: - * https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch - * https://github.com/probonopd/ESP8266HueEmulator - */ -#include "src/dependencies/espalexa/EspalexaDevice.h" - -void onAlexaChange(EspalexaDevice* dev); -void alexaInit(); -void handleAlexa(); -void onAlexaChange(EspalexaDevice* dev); - -#endif // WLED_ALEXA_H \ No newline at end of file diff --git a/wled00/blynk.cpp b/wled00/blynk.cpp index 2307a6942..39b43ba80 100644 --- a/wled00/blynk.cpp +++ b/wled00/blynk.cpp @@ -1,9 +1,9 @@ -#include "blynk.h" -#include "const.h" #include "wled.h" #include "src/dependencies/blynk/Blynk/BlynkHandlers.h" -#include "led.h" -#include "colors.h" + +/* + * Remote light control with the free Blynk app + */ uint16_t blHue = 0; byte blSat = 255; diff --git a/wled00/blynk.h b/wled00/blynk.h deleted file mode 100644 index f17f774a0..000000000 --- a/wled00/blynk.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef WLED_BLYNK_H -#define WLED_BLYNK_H -#include -/* - * Remote light control with the free Blynk app - */ - -void initBlynk(const char* auth); -void handleBlynk(); -void updateBlynk(); -// TODO: Make sure that the macro expansions are handled correctly. - -#endif //WLED_BLYNK_H \ No newline at end of file diff --git a/wled00/button.cpp b/wled00/button.cpp index a80061eeb..e71cce965 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -1,8 +1,4 @@ -#include "button.h" #include "wled.h" -#include "led.h" -#include "wled_eeprom.h" -#include "set.h" /* * Physical IO diff --git a/wled00/button.h b/wled00/button.h deleted file mode 100644 index f974888e7..000000000 --- a/wled00/button.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef WLED_BUTTON_H -#define WLED_BUTTON_H -#include -/* - * Physical IO - */ - -void shortPressAction(); -void handleButton(); -void handleIO(); - -#endif // WLED_BUTTON_H \ No newline at end of file diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 6f2477574..f76499a01 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -1,6 +1,9 @@ -#include "colors.h" #include "wled.h" +/* + * Color conversion methods + */ + void colorFromUint32(uint32_t in, bool secondary) { if (secondary) { diff --git a/wled00/colors.h b/wled00/colors.h deleted file mode 100644 index 85e0adb50..000000000 --- a/wled00/colors.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef WLED_COLORS_H -#define WLED_COLORS_H -#include -/* - * Color conversion methods - */ - -void colorFromUint32(uint32_t in, bool secondary = false); -void colorFromUint24(uint32_t in, bool secondary = false); -void relativeChangeWhite(int8_t amount, byte lowerBoundary = 0); -void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb -void colorCTtoRGB(uint16_t mired, byte* rgb); //white spectrum to rgb - -void colorXYtoRGB(float x, float y, byte* rgb); // only defined if huesync disabled TODO -void colorRGBtoXY(byte* rgb, float* xy); // only defined if huesync disabled TODO - -void colorFromDecOrHexString(byte* rgb, char* in); -void colorRGBtoRGBW(byte* rgb); //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY) - -#endif //WLED_COLORS_H \ No newline at end of file diff --git a/wled00/const.h b/wled00/const.h index 21be19536..535a59870 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -1,5 +1,5 @@ -#ifndef wled_const_h -#define wled_const_h +#ifndef WLED_CONST_H +#define WLED_CONST_H //Defaults #define DEFAULT_CLIENT_SSID "Your_Network" @@ -72,4 +72,7 @@ #define HUE_ERROR_TIMEOUT 251 #define HUE_ERROR_ACTIVE 255 +//EEPROM size +#define EEPSIZE 2560 //Maximum is 4096 + #endif diff --git a/wled00/cronixie.cpp b/wled00/cronixie.cpp deleted file mode 100644 index e3b951b86..000000000 --- a/wled00/cronixie.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include "cronixie.h" -#include "wled.h" - -#ifndef WLED_DISABLE_CRONIXIE -byte _digitOut[6] = {10,10,10,10,10,10}; - -byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) -{ - byte counter = 0; - - for (int i = index+1; i < 6; i++) - { - if (cronixieDisplay[i] == code) - { - counter++; - } else { - return counter; - } - } - return counter; -} - -void setCronixie() -{ - /* - * digit purpose index - * 0-9 | 0-9 (incl. random) - * 10 | blank - * 11 | blank, bg off - * 12 | test upw. - * 13 | test dnw. - * 14 | binary AM/PM - * 15 | BB upper +50 for no trailing 0 - * 16 | BBB - * 17 | BBBB - * 18 | BBBBB - * 19 | BBBBBB - * 20 | H - * 21 | HH - * 22 | HHH - * 23 | HHHH - * 24 | M - * 25 | MM - * 26 | MMM - * 27 | MMMM - * 28 | MMMMM - * 29 | MMMMMM - * 30 | S - * 31 | SS - * 32 | SSS - * 33 | SSSS - * 34 | SSSSS - * 35 | SSSSSS - * 36 | Y - * 37 | YY - * 38 | YYYY - * 39 | I - * 40 | II - * 41 | W - * 42 | WW - * 43 | D - * 44 | DD - * 45 | DDD - * 46 | V - * 47 | VV - * 48 | VVV - * 49 | VVVV - * 50 | VVVVV - * 51 | VVVVVV - * 52 | v - * 53 | vv - * 54 | vvv - * 55 | vvvv - * 56 | vvvvv - * 57 | vvvvvv - */ - - //H HourLower | HH - Hour 24. | AH - Hour 12. | HHH Hour of Month | HHHH Hour of Year - //M MinuteUpper | MM Minute of Hour | MMM Minute of 12h | MMMM Minute of Day | MMMMM Minute of Month | MMMMMM Minute of Year - //S SecondUpper | SS Second of Minute | SSS Second of 10 Minute | SSSS Second of Hour | SSSSS Second of Day | SSSSSS Second of Week - //B AM/PM | BB 0-6/6-12/12-18/18-24 | BBB 0-3... | BBBB 0-1.5... | BBBBB 0-1 | BBBBBB 0-0.5 - - //Y YearLower | YY - Year LU | YYYY - Std. - //I MonthLower | II - Month of Year - //W Week of Month | WW Week of Year - //D Day of Week | DD Day Of Month | DDD Day Of Year - - DEBUG_PRINT("cset "); - DEBUG_PRINTLN(cronixieDisplay); - - overlayRefreshMs = 1997; //Only refresh every 2secs if no seconds are displayed - - for (int i = 0; i < 6; i++) - { - dP[i] = 10; - switch (cronixieDisplay[i]) - { - case '_': dP[i] = 10; break; - case '-': dP[i] = 11; break; - case 'r': dP[i] = random(1,7); break; //random btw. 1-6 - case 'R': dP[i] = random(0,10); break; //random btw. 0-9 - //case 't': break; //Test upw. - //case 'T': break; //Test dnw. - case 'b': dP[i] = 14 + getSameCodeLength('b',i,cronixieDisplay); i = i+dP[i]-14; break; - case 'B': dP[i] = 14 + getSameCodeLength('B',i,cronixieDisplay); i = i+dP[i]-14; break; - case 'h': dP[i] = 70 + getSameCodeLength('h',i,cronixieDisplay); i = i+dP[i]-70; break; - case 'H': dP[i] = 20 + getSameCodeLength('H',i,cronixieDisplay); i = i+dP[i]-20; break; - case 'A': dP[i] = 108; i++; break; - case 'a': dP[i] = 58; i++; break; - case 'm': dP[i] = 74 + getSameCodeLength('m',i,cronixieDisplay); i = i+dP[i]-74; break; - case 'M': dP[i] = 24 + getSameCodeLength('M',i,cronixieDisplay); i = i+dP[i]-24; break; - case 's': dP[i] = 80 + getSameCodeLength('s',i,cronixieDisplay); i = i+dP[i]-80; overlayRefreshMs = 497; break; //refresh more often bc. of secs - case 'S': dP[i] = 30 + getSameCodeLength('S',i,cronixieDisplay); i = i+dP[i]-30; overlayRefreshMs = 497; break; - case 'Y': dP[i] = 36 + getSameCodeLength('Y',i,cronixieDisplay); i = i+dP[i]-36; break; - case 'y': dP[i] = 86 + getSameCodeLength('y',i,cronixieDisplay); i = i+dP[i]-86; break; - case 'I': dP[i] = 39 + getSameCodeLength('I',i,cronixieDisplay); i = i+dP[i]-39; break; //Month. Don't ask me why month and minute both start with M. - case 'i': dP[i] = 89 + getSameCodeLength('i',i,cronixieDisplay); i = i+dP[i]-89; break; - //case 'W': break; - //case 'w': break; - case 'D': dP[i] = 43 + getSameCodeLength('D',i,cronixieDisplay); i = i+dP[i]-43; break; - case 'd': dP[i] = 93 + getSameCodeLength('d',i,cronixieDisplay); i = i+dP[i]-93; break; - case '0': dP[i] = 0; break; - case '1': dP[i] = 1; break; - case '2': dP[i] = 2; break; - case '3': dP[i] = 3; break; - case '4': dP[i] = 4; break; - case '5': dP[i] = 5; break; - case '6': dP[i] = 6; break; - case '7': dP[i] = 7; break; - case '8': dP[i] = 8; break; - case '9': dP[i] = 9; break; - //case 'V': break; //user var0 - //case 'v': break; //user var1 - } - } - DEBUG_PRINT("result "); - for (int i = 0; i < 5; i++) - { - DEBUG_PRINT((int)dP[i]); - DEBUG_PRINT(" "); - } - DEBUG_PRINTLN((int)dP[5]); - - _overlayCronixie(); //refresh -} - -void _overlayCronixie() -{ - byte h = hour(local); - byte h0 = h; - byte m = minute(local); - byte s = second(local); - byte d = day(local); - byte mi = month(local); - int y = year(local); - //this has to be changed in time for 22nd century - y -= 2000; if (y<0) y += 30; //makes countdown work - - if (useAMPM && !countdownMode) - { - if (h>12) h-=12; - else if (h==0) h+=12; - } - for (int i = 0; i < 6; i++) - { - if (dP[i] < 12) _digitOut[i] = dP[i]; - else { - if (dP[i] < 65) - { - switch(dP[i]) - { - case 21: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; i++; break; //HH - case 25: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; i++; break; //MM - case 31: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; i++; break; //SS - - case 20: _digitOut[i] = h- (h/10)*10; break; //H - case 24: _digitOut[i] = m/10; break; //M - case 30: _digitOut[i] = s/10; break; //S - - case 43: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //D - case 44: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; i++; break; //DD - case 40: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; i++; break; //II - case 37: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //YY - case 39: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //YYYY - - //case 16: _digitOut[i+2] = ((h0/3)&1)?1:0; i++; //BBB (BBBB NI) - //case 15: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:0; i++; //BB - case 14: _digitOut[i] = (h0>11)?1:0; break; //B - } - } else - { - switch(dP[i]) - { - case 71: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //hh - case 75: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //mm - case 81: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ss - //case 66: _digitOut[i+2] = ((h0/3)&1)?1:10; i++; //bbb (bbbb NI) - //case 65: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:10; i++; //bb - case 64: _digitOut[i] = (h0>11)?1:10; break; //b - - case 93: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //d - case 94: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //dd - case 90: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ii - case 87: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //yy - case 89: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //yyyy - } - } - } - } -} - -void _drawOverlayCronixie() -{ - byte offsets[] = {5, 0, 6, 1, 7, 2, 8, 3, 9, 4}; - - for (uint16_t i = 0; i < 6; i++) - { - byte o = 10*i; - byte excl = 10; - if(_digitOut[i] < 10) excl = offsets[_digitOut[i]]; - excl += o; - - if (cronixieBacklight && _digitOut[i] <11) - { - uint32_t col = strip.gamma32(strip.getSegment(0).colors[1]); - for (uint16_t j=o; j< o+10; j++) { - if (j != excl) strip.setPixelColor(j, col); - } - } else - { - for (uint16_t j=o; j< o+10; j++) { - if (j != excl) strip.setPixelColor(j, 0); - } - } - } -} - -#else // WLED_DISABLE_CRONIXIE -byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) {} -void setCronixie() {} -void _overlayCronixie() {} -void _drawOverlayCronixie() {} -#endif diff --git a/wled00/cronixie.h b/wled00/cronixie.h deleted file mode 100644 index f6eea6b43..000000000 --- a/wled00/cronixie.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef WLED_CRONIXIE_H -#define WLED_CRONIXIE_H -#include -/* - * Support for the Cronixie clock - */ - -byte getSameCodeLength(char code, int index, char const cronixieDisplay[]); -void setCronixie(); -void _overlayCronixie(); -void _drawOverlayCronixie(); - -#endif // WLED_CRONIXIE_H \ No newline at end of file diff --git a/wled00/dmx.h b/wled00/dmx.cpp similarity index 96% rename from wled00/dmx.h rename to wled00/dmx.cpp index 0ab2a4a20..596624a6e 100644 --- a/wled00/dmx.h +++ b/wled00/dmx.cpp @@ -1,6 +1,5 @@ -#ifndef WLED_DMX_H -#define WLED_DMX_H #include "wled.h" + /* * Support for DMX via MAX485. * Change the output pin in src/dependencies/ESPDMX.cpp if needed. @@ -61,5 +60,3 @@ void handleDMX() #else void handleDMX() {} #endif - -#endif //WLED_DMX_H \ No newline at end of file diff --git a/wled00/e131.cpp b/wled00/e131.cpp new file mode 100644 index 000000000..2034f84d9 --- /dev/null +++ b/wled00/e131.cpp @@ -0,0 +1,144 @@ +#include "wled.h" + +/* + * E1.31 handler + */ + +void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ + //E1.31 protocol support + + uint16_t uni = htons(p->universe); + uint8_t previousUniverses = uni - e131Universe; + uint16_t possibleLEDsInCurrentUniverse; + uint16_t dmxChannels = htons(p->property_value_count) -1; + + // only listen for universes we're handling & allocated memory + if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return; + + if (e131SkipOutOfSequence) + if (p->sequence_number < e131LastSequenceNumber[uni-e131Universe] && p->sequence_number > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){ + DEBUG_PRINT("skipping E1.31 frame (last seq="); + DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]); + DEBUG_PRINT(", current seq="); + DEBUG_PRINT(p->sequence_number); + DEBUG_PRINT(", universe="); + DEBUG_PRINT(uni); + DEBUG_PRINTLN(")"); + return; + } + e131LastSequenceNumber[uni-e131Universe] = p->sequence_number; + + // update status info + realtimeIP = clientIP; + + switch (DMXMode) { + case DMX_MODE_DISABLED: + return; // nothing to do + break; + + case DMX_MODE_SINGLE_RGB: + if (uni != e131Universe) return; + if (dmxChannels-DMXAddress+1 < 3) return; + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); + for (uint16_t i = 0; i < ledCount; i++) + setRealtimePixel(i, p->property_values[DMXAddress+0], p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], 0); + break; + + case DMX_MODE_SINGLE_DRGB: + if (uni != e131Universe) return; + if (dmxChannels-DMXAddress+1 < 4) return; + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); + if (DMXOldDimmer != p->property_values[DMXAddress+0]) { + DMXOldDimmer = p->property_values[DMXAddress+0]; + bri = p->property_values[DMXAddress+0]; + strip.setBrightness(bri); + } + for (uint16_t i = 0; i < ledCount; i++) + setRealtimePixel(i, p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], p->property_values[DMXAddress+3], 0); + break; + + case DMX_MODE_EFFECT: + if (uni != e131Universe) return; + if (dmxChannels-DMXAddress+1 < 11) return; + if (DMXOldDimmer != p->property_values[DMXAddress+0]) { + DMXOldDimmer = p->property_values[DMXAddress+0]; + bri = p->property_values[DMXAddress+0]; + } + if (p->property_values[DMXAddress+1] < MODE_COUNT) + effectCurrent = p->property_values[DMXAddress+ 1]; + effectSpeed = p->property_values[DMXAddress+ 2]; // flickers + effectIntensity = p->property_values[DMXAddress+ 3]; + effectPalette = p->property_values[DMXAddress+ 4]; + col[0] = p->property_values[DMXAddress+ 5]; + col[1] = p->property_values[DMXAddress+ 6]; + col[2] = p->property_values[DMXAddress+ 7]; + colSec[0] = p->property_values[DMXAddress+ 8]; + colSec[1] = p->property_values[DMXAddress+ 9]; + colSec[2] = p->property_values[DMXAddress+10]; + if (dmxChannels-DMXAddress+1 > 11) + { + col[3] = p->property_values[DMXAddress+11]; //white + colSec[3] = p->property_values[DMXAddress+12]; + } + transitionDelayTemp = 0; // act fast + colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); // don't send UDP + return; // don't activate realtime live mode + break; + + case DMX_MODE_MULTIPLE_RGB: + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); + if (previousUniverses == 0) { + // first universe of this fixture + possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3; + for (uint16_t i = 0; i < ledCount; i++) { + if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) + setRealtimePixel(i, p->property_values[DMXAddress+i*3+0], p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], 0); + } + } else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) { + // additional universe(s) of this fixture + uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe + if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current + possibleLEDsInCurrentUniverse = dmxChannels / 3; + for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) { + uint8_t j = i - numberOfLEDsInPreviousUniverses; + if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) + setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0); + } + } + break; + + case DMX_MODE_MULTIPLE_DRGB: + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); + if (previousUniverses == 0) { + // first universe of this fixture + if (DMXOldDimmer != p->property_values[DMXAddress+0]) { + DMXOldDimmer = p->property_values[DMXAddress+0]; + bri = p->property_values[DMXAddress+0]; + strip.setBrightness(bri); + } + possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress) / 3; + for (uint16_t i = 0; i < ledCount; i++) { + if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) + setRealtimePixel(i, p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], p->property_values[DMXAddress+i*3+3], 0); + } + } else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) { + // additional universe(s) of this fixture + uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe + if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current + possibleLEDsInCurrentUniverse = dmxChannels / 3; + for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) { + uint8_t j = i - numberOfLEDsInPreviousUniverses; + if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) + setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0); + } + } + break; + + default: + DEBUG_PRINTLN("unknown E1.31 DMX mode"); + return; // nothing to do + break; + } + + e131NewData = true; +} diff --git a/wled00/file.cpp b/wled00/file.cpp index dba27d4fe..eb0dcb931 100644 --- a/wled00/file.cpp +++ b/wled00/file.cpp @@ -1,7 +1,8 @@ -#include "file.h" #include "wled.h" -#include "led.h" -#include "notify.h" + +/* + * Utility for SPIFFS filesystem + */ //filesystem #ifndef WLED_DISABLE_FILESYSTEM @@ -12,85 +13,6 @@ #include "SPIFFSEditor.h" #endif -enum class AdaState { - Header_A, - Header_d, - Header_a, - Header_CountHi, - Header_CountLo, - Header_CountCheck, - Data_Red, - Data_Green, - Data_Blue -}; - -// Maybe Adalight should not be in filehandling? TODO -void handleSerial() -{ - #ifdef WLED_ENABLE_ADALIGHT - static auto state = AdaState::Header_A; - static uint16_t count = 0; - static uint16_t pixel = 0; - static byte check = 0x00; - static byte red = 0x00; - static byte green = 0x00; - - while (Serial.available() > 0) - { - yield(); - byte next = Serial.read(); - switch (state) { - case AdaState::Header_A: - if (next == 'A') state = AdaState::Header_d; - break; - case AdaState::Header_d: - if (next == 'd') state = AdaState::Header_a; - else state = AdaState::Header_A; - break; - case AdaState::Header_a: - if (next == 'a') state = AdaState::Header_CountHi; - else state = AdaState::Header_A; - break; - case AdaState::Header_CountHi: - pixel = 0; - count = next * 0x100; - check = next; - state = AdaState::Header_CountLo; - break; - case AdaState::Header_CountLo: - count += next + 1; - check = check ^ next ^ 0x55; - state = AdaState::Header_CountCheck; - break; - case AdaState::Header_CountCheck: - if (check == next) state = AdaState::Data_Red; - else state = AdaState::Header_A; - break; - case AdaState::Data_Red: - red = next; - state = AdaState::Data_Green; - break; - case AdaState::Data_Green: - green = next; - state = AdaState::Data_Blue; - break; - case AdaState::Data_Blue: - byte blue = next; - setRealtimePixel(pixel++, red, green, blue, 0); - if (--count > 0) state = AdaState::Data_Red; - else { - if (!realtimeMode && bri == 0) strip.setBrightness(briLast); - arlsLock(realtimeTimeoutMs, REALTIME_MODE_ADALIGHT); - - strip.show(); - state = AdaState::Header_A; - } - break; - } - } - #endif -} - #if !defined WLED_DISABLE_FILESYSTEM && defined WLED_ENABLE_FS_SERVING //Un-comment any file types you need diff --git a/wled00/file.h b/wled00/file.h deleted file mode 100644 index 90731db67..000000000 --- a/wled00/file.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef WLED_FILE_H -#define WLED_FILE_H -#include -#include -/* - * Utility for SPIFFS filesystem & Serial console - */ - -void handleSerial(); -bool handleFileRead(AsyncWebServerRequest*, String path); - -#endif // WLED_FILE_H \ No newline at end of file diff --git a/wled00/func_declare.h b/wled00/func_declare.h new file mode 100644 index 000000000..db3cb4bc4 --- /dev/null +++ b/wled00/func_declare.h @@ -0,0 +1,183 @@ +#ifndef WLED_FUNC_DECLARE_H +#define WLED_FUNC_DECLARE_H +#include +#include "src/dependencies/espalexa/EspalexaDevice.h" +#include "src/dependencies/e131/ESPAsyncE131.h" + +/* + * All globally accessible functions are declared here + */ + +//alexa.cpp +void onAlexaChange(EspalexaDevice* dev); +void alexaInit(); +void handleAlexa(); +void onAlexaChange(EspalexaDevice* dev); + +//blynk.cpp +void initBlynk(const char* auth); +void handleBlynk(); +void updateBlynk(); + +//button.cpp +void shortPressAction(); +void handleButton(); +void handleIO(); + +//colors.cpp +void colorFromUint32(uint32_t in, bool secondary = false); +void colorFromUint24(uint32_t in, bool secondary = false); +void relativeChangeWhite(int8_t amount, byte lowerBoundary = 0); +void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb +void colorCTtoRGB(uint16_t mired, byte* rgb); //white spectrum to rgb + +void colorXYtoRGB(float x, float y, byte* rgb); // only defined if huesync disabled TODO +void colorRGBtoXY(byte* rgb, float* xy); // only defined if huesync disabled TODO + +void colorFromDecOrHexString(byte* rgb, char* in); +void colorRGBtoRGBW(byte* rgb); //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY) + +//e131.cpp +void handleE131Packet(e131_packet_t* p, IPAddress clientIP); + +//file.cpp +bool handleFileRead(AsyncWebServerRequest*, String path); + +//dmx.cpp +void handleDMX(); + +//hue.cpp +void handleHue(); +void reconnectHue(); +void onHueError(void* arg, AsyncClient* client, int8_t error); +void onHueConnect(void* arg, AsyncClient* client); +void sendHuePoll(); +void onHueData(void* arg, AsyncClient* client, void *data, size_t len); + +//ir.cpp +bool decodeIRCustom(uint32_t code); +void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF); +void changeEffectSpeed(int8_t amount); +void changeEffectIntensity(int8_t amount); +void decodeIR(uint32_t code); +void decodeIR24(uint32_t code); +void decodeIR24OLD(uint32_t code); +void decodeIR24CT(uint32_t code); +void decodeIR40(uint32_t code); +void decodeIR44(uint32_t code); +void decodeIR21(uint32_t code); +void decodeIR6(uint32_t code); + +void initIR(); +void handleIR(); + +//json.cpp +#include "ESPAsyncWebServer.h" +#include "src/dependencies/json/ArduinoJson-v6.h" +#include "src/dependencies/json/AsyncJson-v6.h" +#include "FX.h" +// TODO: AsynicWebServerRequest conflict? + +void deserializeSegment(JsonObject elem, byte it); +bool deserializeState(JsonObject root); +void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id); +void serializeState(JsonObject root); +void serializeInfo(JsonObject root); +void serveJson(AsyncWebServerRequest* request); +void serveLiveLeds(AsyncWebServerRequest* request); + +//led.cpp +void setValuesFromMainSeg(); +void resetTimebase(); +void toggleOnOff(); +void setAllLeds(); +void setLedsStandard(bool justColors = false); +bool colorChanged(); +void colorUpdated(int callMode); +void updateInterfaces(uint8_t callMode); +void handleTransitions(); +void handleNightlight(); + +//mqtt.cpp +bool initMqtt(); +void publishMqtt(); + +//notify.cpp +void notify(byte callMode, bool followUp=false); +void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC); +void handleNotifications(); +void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w); + +//ntp.cpp +void handleNetworkTime(); +void sendNTPPacket(); +bool checkNTPResponse(); +void updateLocalTime(); +void getTimeString(char* out); +bool checkCountdown(); +void setCountdown(); +byte weekdayMondayFirst(); +void checkTimers(); + +//overlay.cpp +void initCronixie(); +void handleOverlays(); +void handleOverlayDraw(); +void _overlayAnalogCountdown(); +void _overlayAnalogClock(); + +byte getSameCodeLength(char code, int index, char const cronixieDisplay[]); +void setCronixie(); +void _overlayCronixie(); +void _drawOverlayCronixie(); + +//set.cpp +void _setRandomColor(bool _sec,bool fromButton=false); +bool isAsterisksOnly(const char* str, byte maxLen); +void handleSettingsSet(AsyncWebServerRequest *request, byte subPage); +bool handleSet(AsyncWebServerRequest *request, const String& req); +int getNumVal(const String* req, uint16_t pos); +bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255); + +//usermod.cpp +void userSetup(); +void userConnected(); +void userLoop(); + +//wled_eeprom.cpp +void commit(); +void clearEEPROM(); +void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len); +void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len); +void saveSettingsToEEPROM(); +void loadSettingsFromEEPROM(bool first); +void savedToPresets(); +bool applyPreset(byte index, bool loadBri = true); +void savePreset(byte index, bool persist = true); +void loadMacro(byte index, char* m); +void applyMacro(byte index); +void saveMacro(byte index, String mc, bool persist = true); //only commit on single save, not in settings + +//wled_serial.cpp +void handleSerial(); + +//wled_server.cpp +bool isIp(String str); +bool captivePortal(AsyncWebServerRequest *request); +void initServer(); +void serveIndexOrWelcome(AsyncWebServerRequest *request); +void serveIndex(AsyncWebServerRequest* request); +String msgProcessor(const String& var); +void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255); +String settingsProcessor(const String& var); +String dmxProcessor(const String& var); +void serveSettings(AsyncWebServerRequest* request); + +//xml.cpp +char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr); +char* URL_response(AsyncWebServerRequest *request); +void sappend(char stype, const char* key, int val); +void sappends(char stype, const char* key, char* val); +void getSettingsJS(byte subPage, char* dest); + +#endif diff --git a/wled00/hue.cpp b/wled00/hue.cpp index a186a3144..77091f63e 100644 --- a/wled00/hue.cpp +++ b/wled00/hue.cpp @@ -1,9 +1,8 @@ -#include "hue.h" #include "wled.h" -#include "colors.h" -#include "wled_eeprom.h" -#include "notify.h" -#include "led.h" + +/* + * Sync to Philips hue lights + */ #ifndef WLED_DISABLE_HUESYNC diff --git a/wled00/hue.h b/wled00/hue.h deleted file mode 100644 index 7ce629fbe..000000000 --- a/wled00/hue.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef WLED_HUE_H -#define WLED_HUE_H -/* - * Sync to Philips hue lights - */ -#include -class AsyncClient; - -void handleHue(); -void reconnectHue(); -void onHueError(void* arg, AsyncClient* client, int8_t error); -void onHueConnect(void* arg, AsyncClient* client); -void sendHuePoll(); -void onHueData(void* arg, AsyncClient* client, void *data, size_t len); - -#endif //WLED_HUE_H \ No newline at end of file diff --git a/wled00/ir.cpp b/wled00/ir.cpp index 32b0ee937..046991db5 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -1,8 +1,8 @@ -#include "ir.h" #include "wled.h" -#include "led.h" -#include "colors.h" -#include "wled_eeprom.h" + +/* + * Infrared sensor support for generic 24/40/44 key RGB remotes + */ #if defined(WLED_DISABLE_INFRARED) void handleIR(){} diff --git a/wled00/ir.h b/wled00/ir.h deleted file mode 100644 index e6ecb9668..000000000 --- a/wled00/ir.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef WLED_IR_H -#define WLED_IR_H -#include -/* - * Infrared sensor support for generic 24/40/44 key RGB remotes - */ - -bool decodeIRCustom(uint32_t code); -void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF); -void changeEffectSpeed(int8_t amount); -void changeEffectIntensity(int8_t amount); -void decodeIR(uint32_t code); -void decodeIR24(uint32_t code); -void decodeIR24OLD(uint32_t code); -void decodeIR24CT(uint32_t code); -void decodeIR40(uint32_t code); -void decodeIR44(uint32_t code); -void decodeIR21(uint32_t code); -void decodeIR6(uint32_t code); - -void initIR(); -void handleIR(); - -#endif //WLED_IR_H \ No newline at end of file diff --git a/wled00/json.cpp b/wled00/json.cpp index e79737c43..31208bf5b 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -1,7 +1,8 @@ -#include "json.h" #include "wled.h" -#include "wled_eeprom.h" -#include "led.h" + +/* + * JSON API (De)serialization + */ void deserializeSegment(JsonObject elem, byte it) { diff --git a/wled00/json.h b/wled00/json.h deleted file mode 100644 index 77d1b616f..000000000 --- a/wled00/json.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef WLED_JSON_H -#define WLED_JSON_H -/* - * JSON API (De)serialization - */ -#include -#include "ESPAsyncWebServer.h" -#include "src/dependencies/json/ArduinoJson-v6.h" -#include "src/dependencies/json/AsyncJson-v6.h" -#include "fx.h" -// TODO: AsynicWebServerRequest conflict? - -void deserializeSegment(JsonObject elem, byte it); -bool deserializeState(JsonObject root); -void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id); -void serializeState(JsonObject root); -void serializeInfo(JsonObject root); -void serveJson(AsyncWebServerRequest* request); -void serveLiveLeds(AsyncWebServerRequest* request); - -#endif //WLED_JSON_H \ No newline at end of file diff --git a/wled00/led.cpp b/wled00/led.cpp index 7f4d63095..c3f50cc22 100644 --- a/wled00/led.cpp +++ b/wled00/led.cpp @@ -1,10 +1,8 @@ -#include "led.h" #include "wled.h" -#include "notify.h" -#include "blynk.h" -#include "wled_eeprom.h" -#include "mqtt.h" -#include "colors.h" + +/* + * LED methods + */ void setValuesFromMainSeg() { diff --git a/wled00/led.h b/wled00/led.h deleted file mode 100644 index d5eb97a8d..000000000 --- a/wled00/led.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef WLED_LED_H -#define WLED_LED_H -#include -/* - * LED methods - */ - -void setValuesFromMainSeg(); -void resetTimebase(); -void toggleOnOff(); -void setAllLeds(); -void setLedsStandard(bool justColors = false); -bool colorChanged(); -void colorUpdated(int callMode); -void updateInterfaces(uint8_t callMode); -void handleTransitions(); -void handleNightlight(); - -#endif \ No newline at end of file diff --git a/wled00/mqtt.cpp b/wled00/mqtt.cpp index b84184af0..9c15f5bb3 100644 --- a/wled00/mqtt.cpp +++ b/wled00/mqtt.cpp @@ -1,10 +1,8 @@ -#include "mqtt.h" #include "wled.h" -#include "notify.h" -#include "led.h" -#include "colors.h" -#include "xml.h" -#include "set.h" + +/* + * MQTT communication protocol for home automation + */ #ifdef WLED_ENABLE_MQTT #define MQTT_KEEP_ALIVE_TIME 60 // contact the MQTT broker every 60 seconds diff --git a/wled00/mqtt.h b/wled00/mqtt.h deleted file mode 100644 index de602b981..000000000 --- a/wled00/mqtt.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef WLED_MQTT_H -#define WLED_MQTT_H -/* - * MQTT communication protocol for home automation - */ -bool initMqtt(); -void publishMqtt(); - -#endif //WLED_MQTT_H \ No newline at end of file diff --git a/wled00/notify.h b/wled00/notify.h deleted file mode 100644 index a0fbfde2c..000000000 --- a/wled00/notify.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef WLED_NOTIFY_H -#define WLED_NOTIFY_H -#include -#include "src/dependencies/e131/ESPAsyncE131.h" -#include "const.h" -/* - * UDP notifier - */ -//union e131_packet_t; // Will this compile? -class IPAddress; - -void notify(byte callMode, bool followUp=false); -void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC); -void handleE131Packet(e131_packet_t* p, IPAddress clientIP); -void handleNotifications(); -void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w); - -#endif // WLED_NOTIFY_H \ No newline at end of file diff --git a/wled00/ntp.cpp b/wled00/ntp.cpp index 206631097..d6332fd2c 100644 --- a/wled00/ntp.cpp +++ b/wled00/ntp.cpp @@ -1,7 +1,9 @@ -#include "ntp.h" #include "src/dependencies/timezone/Timezone.h" #include "wled.h" -#include "wled_eeprom.h" + +/* + * Acquires time from NTP server + */ TimeChangeRule UTCr = {Last, Sun, Mar, 1, 0}; // UTC Timezone tzUTC(UTCr, UTCr); diff --git a/wled00/ntp.h b/wled00/ntp.h deleted file mode 100644 index 9029661dd..000000000 --- a/wled00/ntp.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef WLED_NTP_H -#define WLED_NTP_H -#include -/* - * Acquires time from NTP server - */ - -void handleNetworkTime(); -void sendNTPPacket(); -bool checkNTPResponse(); -void updateLocalTime(); -void getTimeString(char* out); -bool checkCountdown(); -void setCountdown(); -byte weekdayMondayFirst(); -void checkTimers(); - -#endif // WLED_NTP_H \ No newline at end of file diff --git a/wled00/overlay.cpp b/wled00/overlay.cpp index ccdd3d0cd..ceb6fc209 100644 --- a/wled00/overlay.cpp +++ b/wled00/overlay.cpp @@ -1,7 +1,8 @@ -#include "overlay.h" #include "wled.h" -#include "cronixie.h" -#include "ntp.h" + +/* + * Used to draw clock overlays over the strip + */ void initCronixie() { @@ -127,3 +128,249 @@ void handleOverlayDraw() { case 3: _drawOverlayCronixie(); break; } } + + +/* + * Support for the Cronixie clock + */ + +#ifndef WLED_DISABLE_CRONIXIE +byte _digitOut[6] = {10,10,10,10,10,10}; + +byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) +{ + byte counter = 0; + + for (int i = index+1; i < 6; i++) + { + if (cronixieDisplay[i] == code) + { + counter++; + } else { + return counter; + } + } + return counter; +} + +void setCronixie() +{ + /* + * digit purpose index + * 0-9 | 0-9 (incl. random) + * 10 | blank + * 11 | blank, bg off + * 12 | test upw. + * 13 | test dnw. + * 14 | binary AM/PM + * 15 | BB upper +50 for no trailing 0 + * 16 | BBB + * 17 | BBBB + * 18 | BBBBB + * 19 | BBBBBB + * 20 | H + * 21 | HH + * 22 | HHH + * 23 | HHHH + * 24 | M + * 25 | MM + * 26 | MMM + * 27 | MMMM + * 28 | MMMMM + * 29 | MMMMMM + * 30 | S + * 31 | SS + * 32 | SSS + * 33 | SSSS + * 34 | SSSSS + * 35 | SSSSSS + * 36 | Y + * 37 | YY + * 38 | YYYY + * 39 | I + * 40 | II + * 41 | W + * 42 | WW + * 43 | D + * 44 | DD + * 45 | DDD + * 46 | V + * 47 | VV + * 48 | VVV + * 49 | VVVV + * 50 | VVVVV + * 51 | VVVVVV + * 52 | v + * 53 | vv + * 54 | vvv + * 55 | vvvv + * 56 | vvvvv + * 57 | vvvvvv + */ + + //H HourLower | HH - Hour 24. | AH - Hour 12. | HHH Hour of Month | HHHH Hour of Year + //M MinuteUpper | MM Minute of Hour | MMM Minute of 12h | MMMM Minute of Day | MMMMM Minute of Month | MMMMMM Minute of Year + //S SecondUpper | SS Second of Minute | SSS Second of 10 Minute | SSSS Second of Hour | SSSSS Second of Day | SSSSSS Second of Week + //B AM/PM | BB 0-6/6-12/12-18/18-24 | BBB 0-3... | BBBB 0-1.5... | BBBBB 0-1 | BBBBBB 0-0.5 + + //Y YearLower | YY - Year LU | YYYY - Std. + //I MonthLower | II - Month of Year + //W Week of Month | WW Week of Year + //D Day of Week | DD Day Of Month | DDD Day Of Year + + DEBUG_PRINT("cset "); + DEBUG_PRINTLN(cronixieDisplay); + + overlayRefreshMs = 1997; //Only refresh every 2secs if no seconds are displayed + + for (int i = 0; i < 6; i++) + { + dP[i] = 10; + switch (cronixieDisplay[i]) + { + case '_': dP[i] = 10; break; + case '-': dP[i] = 11; break; + case 'r': dP[i] = random(1,7); break; //random btw. 1-6 + case 'R': dP[i] = random(0,10); break; //random btw. 0-9 + //case 't': break; //Test upw. + //case 'T': break; //Test dnw. + case 'b': dP[i] = 14 + getSameCodeLength('b',i,cronixieDisplay); i = i+dP[i]-14; break; + case 'B': dP[i] = 14 + getSameCodeLength('B',i,cronixieDisplay); i = i+dP[i]-14; break; + case 'h': dP[i] = 70 + getSameCodeLength('h',i,cronixieDisplay); i = i+dP[i]-70; break; + case 'H': dP[i] = 20 + getSameCodeLength('H',i,cronixieDisplay); i = i+dP[i]-20; break; + case 'A': dP[i] = 108; i++; break; + case 'a': dP[i] = 58; i++; break; + case 'm': dP[i] = 74 + getSameCodeLength('m',i,cronixieDisplay); i = i+dP[i]-74; break; + case 'M': dP[i] = 24 + getSameCodeLength('M',i,cronixieDisplay); i = i+dP[i]-24; break; + case 's': dP[i] = 80 + getSameCodeLength('s',i,cronixieDisplay); i = i+dP[i]-80; overlayRefreshMs = 497; break; //refresh more often bc. of secs + case 'S': dP[i] = 30 + getSameCodeLength('S',i,cronixieDisplay); i = i+dP[i]-30; overlayRefreshMs = 497; break; + case 'Y': dP[i] = 36 + getSameCodeLength('Y',i,cronixieDisplay); i = i+dP[i]-36; break; + case 'y': dP[i] = 86 + getSameCodeLength('y',i,cronixieDisplay); i = i+dP[i]-86; break; + case 'I': dP[i] = 39 + getSameCodeLength('I',i,cronixieDisplay); i = i+dP[i]-39; break; //Month. Don't ask me why month and minute both start with M. + case 'i': dP[i] = 89 + getSameCodeLength('i',i,cronixieDisplay); i = i+dP[i]-89; break; + //case 'W': break; + //case 'w': break; + case 'D': dP[i] = 43 + getSameCodeLength('D',i,cronixieDisplay); i = i+dP[i]-43; break; + case 'd': dP[i] = 93 + getSameCodeLength('d',i,cronixieDisplay); i = i+dP[i]-93; break; + case '0': dP[i] = 0; break; + case '1': dP[i] = 1; break; + case '2': dP[i] = 2; break; + case '3': dP[i] = 3; break; + case '4': dP[i] = 4; break; + case '5': dP[i] = 5; break; + case '6': dP[i] = 6; break; + case '7': dP[i] = 7; break; + case '8': dP[i] = 8; break; + case '9': dP[i] = 9; break; + //case 'V': break; //user var0 + //case 'v': break; //user var1 + } + } + DEBUG_PRINT("result "); + for (int i = 0; i < 5; i++) + { + DEBUG_PRINT((int)dP[i]); + DEBUG_PRINT(" "); + } + DEBUG_PRINTLN((int)dP[5]); + + _overlayCronixie(); //refresh +} + +void _overlayCronixie() +{ + byte h = hour(local); + byte h0 = h; + byte m = minute(local); + byte s = second(local); + byte d = day(local); + byte mi = month(local); + int y = year(local); + //this has to be changed in time for 22nd century + y -= 2000; if (y<0) y += 30; //makes countdown work + + if (useAMPM && !countdownMode) + { + if (h>12) h-=12; + else if (h==0) h+=12; + } + for (int i = 0; i < 6; i++) + { + if (dP[i] < 12) _digitOut[i] = dP[i]; + else { + if (dP[i] < 65) + { + switch(dP[i]) + { + case 21: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; i++; break; //HH + case 25: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; i++; break; //MM + case 31: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; i++; break; //SS + + case 20: _digitOut[i] = h- (h/10)*10; break; //H + case 24: _digitOut[i] = m/10; break; //M + case 30: _digitOut[i] = s/10; break; //S + + case 43: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //D + case 44: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; i++; break; //DD + case 40: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; i++; break; //II + case 37: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //YY + case 39: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //YYYY + + //case 16: _digitOut[i+2] = ((h0/3)&1)?1:0; i++; //BBB (BBBB NI) + //case 15: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:0; i++; //BB + case 14: _digitOut[i] = (h0>11)?1:0; break; //B + } + } else + { + switch(dP[i]) + { + case 71: _digitOut[i] = h/10; _digitOut[i+1] = h- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //hh + case 75: _digitOut[i] = m/10; _digitOut[i+1] = m- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //mm + case 81: _digitOut[i] = s/10; _digitOut[i+1] = s- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ss + //case 66: _digitOut[i+2] = ((h0/3)&1)?1:10; i++; //bbb (bbbb NI) + //case 65: _digitOut[i+1] = (h0>17 || (h0>5 && h0<12))?1:10; i++; //bb + case 64: _digitOut[i] = (h0>11)?1:10; break; //b + + case 93: _digitOut[i] = weekday(local); _digitOut[i]--; if (_digitOut[i]<1) _digitOut[i]= 7; break; //d + case 94: _digitOut[i] = d/10; _digitOut[i+1] = d- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //dd + case 90: _digitOut[i] = mi/10; _digitOut[i+1] = mi- _digitOut[i]*10; if(_digitOut[i] == 0) _digitOut[i]=10; i++; break; //ii + case 87: _digitOut[i] = y/10; _digitOut[i+1] = y- _digitOut[i]*10; i++; break; //yy + case 89: _digitOut[i] = 2; _digitOut[i+1] = 0; _digitOut[i+2] = y/10; _digitOut[i+3] = y- _digitOut[i+2]*10; i+=3; break; //yyyy + } + } + } + } +} + +void _drawOverlayCronixie() +{ + byte offsets[] = {5, 0, 6, 1, 7, 2, 8, 3, 9, 4}; + + for (uint16_t i = 0; i < 6; i++) + { + byte o = 10*i; + byte excl = 10; + if(_digitOut[i] < 10) excl = offsets[_digitOut[i]]; + excl += o; + + if (cronixieBacklight && _digitOut[i] <11) + { + uint32_t col = strip.gamma32(strip.getSegment(0).colors[1]); + for (uint16_t j=o; j< o+10; j++) { + if (j != excl) strip.setPixelColor(j, col); + } + } else + { + for (uint16_t j=o; j< o+10; j++) { + if (j != excl) strip.setPixelColor(j, 0); + } + } + } +} + +#else // WLED_DISABLE_CRONIXIE +byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) {} +void setCronixie() {} +void _overlayCronixie() {} +void _drawOverlayCronixie() {} +#endif diff --git a/wled00/overlay.h b/wled00/overlay.h deleted file mode 100644 index f7b54d5db..000000000 --- a/wled00/overlay.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef WLED_OVERLAY_H -#define WLED_OVERLAY_H -#include -/* - * Used to draw clock overlays over the strip - */ - -void initCronixie(); -void handleOverlays(); -void handleOverlayDraw(); -void _overlayAnalogCountdown(); -void _overlayAnalogClock(); - -#endif // WLED_OVERLAY_H \ No newline at end of file diff --git a/wled00/set.cpp b/wled00/set.cpp index f26795c8e..7fa2a3276 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -1,14 +1,8 @@ -#include "set.h" #include "wled.h" -#include "colors.h" -#include "hue.h" -#include "led.h" -#include "blynk.h" -#include "wled_eeprom.h" -#include "alexa.h" -#include "cronixie.h" -#include "xml.h" -#include "wled_server.h" + +/* + * Receives client input + */ void _setRandomColor(bool _sec,bool fromButton) { diff --git a/wled00/set.h b/wled00/set.h deleted file mode 100644 index 6bc7dbd6c..000000000 --- a/wled00/set.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef WLED_SET_H -#define WLED_SET_H -#include -#include -/* - * Receives client input - */ - -void _setRandomColor(bool _sec,bool fromButton=false); -bool isAsterisksOnly(const char* str, byte maxLen); -void handleSettingsSet(AsyncWebServerRequest *request, byte subPage); -bool handleSet(AsyncWebServerRequest *request, const String& req); -int getNumVal(const String* req, uint16_t pos); -bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255); - -#endif // WLED_SET_H \ No newline at end of file diff --git a/wled00/notify.cpp b/wled00/udp.cpp similarity index 55% rename from wled00/notify.cpp rename to wled00/udp.cpp index 30adfee01..528798034 100644 --- a/wled00/notify.cpp +++ b/wled00/udp.cpp @@ -1,12 +1,12 @@ -#include "notify.h" #include "wled.h" -#include "src/dependencies/e131/ESPAsyncE131.h" -#include "led.h" + +/* + * UDP sync notifier + */ #define WLEDPACKETSIZE 29 #define UDP_IN_MAXSIZE 1472 - void notify(byte callMode, bool followUp) { if (!udpConnected) return; @@ -87,146 +87,6 @@ void arlsLock(uint32_t timeoutMs, byte md) } -void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ - //E1.31 protocol support - - uint16_t uni = htons(p->universe); - uint8_t previousUniverses = uni - e131Universe; - uint16_t possibleLEDsInCurrentUniverse; - uint16_t dmxChannels = htons(p->property_value_count) -1; - - // only listen for universes we're handling & allocated memory - if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return; - - if (e131SkipOutOfSequence) - if (p->sequence_number < e131LastSequenceNumber[uni-e131Universe] && p->sequence_number > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){ - DEBUG_PRINT("skipping E1.31 frame (last seq="); - DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]); - DEBUG_PRINT(", current seq="); - DEBUG_PRINT(p->sequence_number); - DEBUG_PRINT(", universe="); - DEBUG_PRINT(uni); - DEBUG_PRINTLN(")"); - return; - } - e131LastSequenceNumber[uni-e131Universe] = p->sequence_number; - - // update status info - realtimeIP = clientIP; - - switch (DMXMode) { - case DMX_MODE_DISABLED: - return; // nothing to do - break; - - case DMX_MODE_SINGLE_RGB: - if (uni != e131Universe) return; - if (dmxChannels-DMXAddress+1 < 3) return; - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); - for (uint16_t i = 0; i < ledCount; i++) - setRealtimePixel(i, p->property_values[DMXAddress+0], p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], 0); - break; - - case DMX_MODE_SINGLE_DRGB: - if (uni != e131Universe) return; - if (dmxChannels-DMXAddress+1 < 4) return; - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); - if (DMXOldDimmer != p->property_values[DMXAddress+0]) { - DMXOldDimmer = p->property_values[DMXAddress+0]; - bri = p->property_values[DMXAddress+0]; - strip.setBrightness(bri); - } - for (uint16_t i = 0; i < ledCount; i++) - setRealtimePixel(i, p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], p->property_values[DMXAddress+3], 0); - break; - - case DMX_MODE_EFFECT: - if (uni != e131Universe) return; - if (dmxChannels-DMXAddress+1 < 11) return; - if (DMXOldDimmer != p->property_values[DMXAddress+0]) { - DMXOldDimmer = p->property_values[DMXAddress+0]; - bri = p->property_values[DMXAddress+0]; - } - if (p->property_values[DMXAddress+1] < MODE_COUNT) - effectCurrent = p->property_values[DMXAddress+ 1]; - effectSpeed = p->property_values[DMXAddress+ 2]; // flickers - effectIntensity = p->property_values[DMXAddress+ 3]; - effectPalette = p->property_values[DMXAddress+ 4]; - col[0] = p->property_values[DMXAddress+ 5]; - col[1] = p->property_values[DMXAddress+ 6]; - col[2] = p->property_values[DMXAddress+ 7]; - colSec[0] = p->property_values[DMXAddress+ 8]; - colSec[1] = p->property_values[DMXAddress+ 9]; - colSec[2] = p->property_values[DMXAddress+10]; - if (dmxChannels-DMXAddress+1 > 11) - { - col[3] = p->property_values[DMXAddress+11]; //white - colSec[3] = p->property_values[DMXAddress+12]; - } - transitionDelayTemp = 0; // act fast - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); // don't send UDP - return; // don't activate realtime live mode - break; - - case DMX_MODE_MULTIPLE_RGB: - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); - if (previousUniverses == 0) { - // first universe of this fixture - possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3; - for (uint16_t i = 0; i < ledCount; i++) { - if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[DMXAddress+i*3+0], p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], 0); - } - } else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) { - // additional universe(s) of this fixture - uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe - if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current - possibleLEDsInCurrentUniverse = dmxChannels / 3; - for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) { - uint8_t j = i - numberOfLEDsInPreviousUniverses; - if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0); - } - } - break; - - case DMX_MODE_MULTIPLE_DRGB: - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); - if (previousUniverses == 0) { - // first universe of this fixture - if (DMXOldDimmer != p->property_values[DMXAddress+0]) { - DMXOldDimmer = p->property_values[DMXAddress+0]; - bri = p->property_values[DMXAddress+0]; - strip.setBrightness(bri); - } - possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress) / 3; - for (uint16_t i = 0; i < ledCount; i++) { - if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], p->property_values[DMXAddress+i*3+3], 0); - } - } else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) { - // additional universe(s) of this fixture - uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe - if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current - possibleLEDsInCurrentUniverse = dmxChannels / 3; - for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) { - uint8_t j = i - numberOfLEDsInPreviousUniverses; - if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0); - } - } - break; - - default: - DEBUG_PRINTLN("unknown E1.31 DMX mode"); - return; // nothing to do - break; - } - - e131NewData = true; -} - - void handleNotifications() { //send second notification if enabled diff --git a/wled00/usermod.cpp b/wled00/usermod.cpp index 96c1f8a6c..2c7c881f5 100644 --- a/wled00/usermod.cpp +++ b/wled00/usermod.cpp @@ -2,7 +2,7 @@ /* * This file allows you to add own functionality to WLED more easily * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality - * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled_eeprom.h) + * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in const.h) * bytes 2400+ are currently ununsed, but might be used for future wled features */ diff --git a/wled00/usermod.h b/wled00/usermod.h deleted file mode 100644 index 8269c6e92..000000000 --- a/wled00/usermod.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef WLED_USERMOD_H -#define WLED_USERMOD_H - -void userSetup(); -void userConnected(); -void userLoop(); - -#endif // WLED_USERMOD_H \ No newline at end of file diff --git a/wled00/wled.cpp b/wled00/wled.cpp index fdb607765..7579a9c5e 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -1,23 +1,8 @@ #include "wled.h" -#include "alexa.h" -#include "blynk.h" -#include "button.h" -#include "dmx.h" -#include "file.h" -#include "hue.h" -#include "ir.h" -#include "led.h" -#include "mqtt.h" -#include "notify.h" -#include "ntp.h" -#include "overlay.h" -#include "usermod.h" -#include "wled_eeprom.h" -#include "wled_server.h" #include // Global Variable definitions -char versionString[] = "0.9.1"; +char versionString[] = "0.9.1n"; // AP and OTA default passwords (for maximum change them!) char apPass[65] = DEFAULT_AP_PASS; diff --git a/wled00/wled.h b/wled00/wled.h index 70b197c8e..926fa0c81 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -3,10 +3,13 @@ /* Main sketch, global variable declarations @title WLED project sketch - @version 0.9.1 + @version 0.9.1n @author Christian Schwinne */ +// version code in format yymmddb (b = daily build) +#define VERSION 2003300 + // ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). // ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). @@ -78,6 +81,7 @@ #include "src/dependencies/json/AsyncJson-v6.h" #include "src/dependencies/json/ArduinoJson-v6.h" +#include "func_declare.h" #include "html_ui.h" #include "html_settings.h" #include "html_other.h" @@ -117,9 +121,6 @@ #endif #endif -// version code in format yymmddb (b = daily build) -#define VERSION 2003301 - // Global external variable declaration. See wled.cpp for definitions and comments. extern char versionString[]; extern char apPass[65]; diff --git a/wled00/wled00.ino b/wled00/wled00.ino index e33348379..f806e5b34 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -1,6 +1,6 @@ /* - Arduino Studio support file. -*/ + * Arduino IDE compatibility file. + */ #include "wled.h" void setup() { @@ -9,4 +9,4 @@ void setup() { void loop() { WLED::instance().loop(); -} \ No newline at end of file +} diff --git a/wled00/wled_eeprom.cpp b/wled00/wled_eeprom.cpp index 0087641aa..ccb16ff56 100644 --- a/wled00/wled_eeprom.cpp +++ b/wled00/wled_eeprom.cpp @@ -1,11 +1,10 @@ -#include "wled_eeprom.h" #include #include "wled.h" -#include "cronixie.h" -#include "ntp.h" -#include "set.h" -#include "led.h" +/* + * Methods to handle saving and loading to non-volatile memory + * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map + */ //eeprom Version code, enables default settings instead of 0 init on update #define EEPVER 18 diff --git a/wled00/wled_eeprom.h b/wled00/wled_eeprom.h deleted file mode 100644 index eae52b128..000000000 --- a/wled00/wled_eeprom.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef WLED_EPPROM_H -#define WLED_EPPROM_H -#include -/* - * Methods to handle saving and loading to non-volatile memory - * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map - */ -#define EEPSIZE 2560 //Maximum is 4096 - -void commit(); -void clearEEPROM(); -void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len); -void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len); -void saveSettingsToEEPROM(); -void loadSettingsFromEEPROM(bool first); -void savedToPresets(); -bool applyPreset(byte index, bool loadBri = true); -void savePreset(byte index, bool persist = true); -void loadMacro(byte index, char* m); -void applyMacro(byte index); -void saveMacro(byte index, String mc, bool persist = true); //only commit on single save, not in settings - -#endif //WLED_EPPROM_H diff --git a/wled00/wled_serial.cpp b/wled00/wled_serial.cpp new file mode 100644 index 000000000..a472729d1 --- /dev/null +++ b/wled00/wled_serial.cpp @@ -0,0 +1,83 @@ +#include "wled.h" + +/* + * Adalight handler + */ + +enum class AdaState { + Header_A, + Header_d, + Header_a, + Header_CountHi, + Header_CountLo, + Header_CountCheck, + Data_Red, + Data_Green, + Data_Blue +}; + +void handleSerial() +{ + #ifdef WLED_ENABLE_ADALIGHT + static auto state = AdaState::Header_A; + static uint16_t count = 0; + static uint16_t pixel = 0; + static byte check = 0x00; + static byte red = 0x00; + static byte green = 0x00; + + while (Serial.available() > 0) + { + yield(); + byte next = Serial.read(); + switch (state) { + case AdaState::Header_A: + if (next == 'A') state = AdaState::Header_d; + break; + case AdaState::Header_d: + if (next == 'd') state = AdaState::Header_a; + else state = AdaState::Header_A; + break; + case AdaState::Header_a: + if (next == 'a') state = AdaState::Header_CountHi; + else state = AdaState::Header_A; + break; + case AdaState::Header_CountHi: + pixel = 0; + count = next * 0x100; + check = next; + state = AdaState::Header_CountLo; + break; + case AdaState::Header_CountLo: + count += next + 1; + check = check ^ next ^ 0x55; + state = AdaState::Header_CountCheck; + break; + case AdaState::Header_CountCheck: + if (check == next) state = AdaState::Data_Red; + else state = AdaState::Header_A; + break; + case AdaState::Data_Red: + red = next; + state = AdaState::Data_Green; + break; + case AdaState::Data_Green: + green = next; + state = AdaState::Data_Blue; + break; + case AdaState::Data_Blue: + byte blue = next; + setRealtimePixel(pixel++, red, green, blue, 0); + if (--count > 0) state = AdaState::Data_Red; + else { + if (!realtimeMode && bri == 0) strip.setBrightness(briLast); + arlsLock(realtimeTimeoutMs, REALTIME_MODE_ADALIGHT); + + strip.show(); + state = AdaState::Header_A; + } + break; + } + } + #endif +} diff --git a/wled00/wled_server.cpp b/wled00/wled_server.cpp index d5b4eebce..cd623bc49 100644 --- a/wled00/wled_server.cpp +++ b/wled00/wled_server.cpp @@ -1,10 +1,8 @@ -#include "wled_server.h" #include "wled.h" -#include "file.h" -#include "set.h" -#include "json.h" -#include "xml.h" +/* + * Integrated HTTP web server page declarations + */ //Is this an IP? bool isIp(String str) { diff --git a/wled00/wled_server.h b/wled00/wled_server.h deleted file mode 100644 index ff7133d63..000000000 --- a/wled00/wled_server.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef WLED_SERVER_H -#define WLED_SERVER_H -#include -/* - * Server page declarations - */ -class AsyncWebServerRequest; - - -bool isIp(String str); -bool captivePortal(AsyncWebServerRequest *request); -void initServer(); -void serveIndexOrWelcome(AsyncWebServerRequest *request); -void serveIndex(AsyncWebServerRequest* request); -String msgProcessor(const String& var); -void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255); -String settingsProcessor(const String& var); -String dmxProcessor(const String& var); -void serveSettings(AsyncWebServerRequest* request); - -#endif //WLED_SERVER_H \ No newline at end of file diff --git a/wled00/xml.cpp b/wled00/xml.cpp index 09e42011d..3af1e54ce 100644 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -1,8 +1,8 @@ -#include "xml.h" #include "wled.h" -#include "wled_eeprom.h" -#include "ntp.h" +/* + * Sending XML status files to client + */ //build XML response to HTTP /win API request char* XML_response(AsyncWebServerRequest *request, char* dest) diff --git a/wled00/xml.h b/wled00/xml.h deleted file mode 100644 index 022982959..000000000 --- a/wled00/xml.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef WLED_XML_H -#define WLED_XML_H -#include -#include - -/* - * Sending XML status files to client - */ -char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr); -char* URL_response(AsyncWebServerRequest *request); -void sappend(char stype, const char* key, int val); -void sappends(char stype, const char* key, char* val); -void getSettingsJS(byte subPage, char* dest); - -#endif // WLED_XML_H \ No newline at end of file From 5cb2a39746e922fecc996a80617c79bf16bb766d Mon Sep 17 00:00:00 2001 From: cschwinne Date: Mon, 6 Apr 2020 02:25:17 +0200 Subject: [PATCH 144/509] Consolidated global variables in wled.h --- CHANGELOG.md | 4 + wled00/const.h | 13 ++ wled00/dmx.cpp | 2 +- wled00/wled.cpp | 339 +-------------------------- wled00/wled.h | 610 ++++++++++++++++++++++++++++-------------------- 5 files changed, 375 insertions(+), 593 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9804b1f4..8df63ff8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ### Development versions after 0.9.1 release +#### Build 2004060 + +- Consolidated global variables in wled.h + #### Build 2003300 - Major change of project structure from .ino to .cpp and func_declare.h diff --git a/wled00/const.h b/wled00/const.h index 535a59870..ef19e51be 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -75,4 +75,17 @@ //EEPROM size #define EEPSIZE 2560 //Maximum is 4096 +#define NTP_PACKET_SIZE 48 + +// maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue +#define MAX_LEDS 1500 +#define MAX_LEDS_DMA 500 + +// string temp buffer (now stored in stack locally) +#define OMAX 2048 + +#define E131_MAX_UNIVERSE_COUNT 9 + +#define ABL_MILLIAMPS_DEFAULT 850; // auto lower brightness to stay close to milliampere limit + #endif diff --git a/wled00/dmx.cpp b/wled00/dmx.cpp index 596624a6e..ea0871241 100644 --- a/wled00/dmx.cpp +++ b/wled00/dmx.cpp @@ -19,7 +19,7 @@ void handleDMX() for (int i = 0; i < ledCount; i++) { // uses the amount of LEDs as fixture count - uint32_t in = strip.getPixelColor(i); // time to get the colors for the individual fixtures as suggested by AirCookie at issue #462 + uint32_t in = strip.getPixelColor(i); // get the colors for the individual fixtures as suggested by Aircoookie in issue #462 byte w = in >> 24 & 0xFF; byte r = in >> 16 & 0xFF; byte g = in >> 8 & 0xFF; diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 7579a9c5e..701b98e31 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -1,344 +1,7 @@ +#define WLED_DEFINE_GLOBAL_VARS //only in one source file, wled.cpp! #include "wled.h" #include -// Global Variable definitions -char versionString[] = "0.9.1n"; - -// AP and OTA default passwords (for maximum change them!) -char apPass[65] = DEFAULT_AP_PASS; -char otaPass[33] = DEFAULT_OTA_PASS; - -// Hardware CONFIG (only changeble HERE, not at runtime) -// LED strip pin, button pin and IR pin changeable in NpbWrapper.h! - -byte auxDefaultState = 0; // 0: input 1: high 2: low -byte auxTriggeredState = 0; // 0: input 1: high 2: low -char ntpServerName[33] = "0.wled.pool.ntp.org"; // NTP server to use - -// WiFi CONFIG (all these can be changed via web UI, no need to set them here) -char clientSSID[33] = CLIENT_SSID; -char clientPass[65] = CLIENT_PASS; -char cmDNS[33] = "x"; // mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) -char apSSID[33] = ""; // AP off by default (unless setup) -byte apChannel = 1; // 2.4GHz WiFi AP channel (1-13) -byte apHide = 0; // hidden AP SSID -byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; // access point opens when no connection after boot by default -IPAddress staticIP(0, 0, 0, 0); // static IP of ESP -IPAddress staticGateway(0, 0, 0, 0); // gateway (router) IP -IPAddress staticSubnet(255, 255, 255, 0); // most common subnet in home networks -bool noWifiSleep = false; // disabling modem sleep modes will increase heat output and power usage, but may help with connection issues - -// LED CONFIG -uint16_t ledCount = 30; // overcurrent prevented by ABL -bool useRGBW = false; // SK6812 strips can contain an extra White channel -bool turnOnAtBoot = true; // turn on LEDs at power-up -byte bootPreset = 0; // save preset to load after power-up - -byte col[] { 255, 160, 0, 0 }; // current RGB(W) primary color. col[] should be updated if you want to change the color. -byte colSec[] { 0, 0, 0, 0 }; // current RGB(W) secondary color -byte briS = 128; // default brightness - -byte nightlightTargetBri = 0; // brightness after nightlight is over -byte nightlightDelayMins = 60; -bool nightlightFade = true; // if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over -bool nightlightColorFade = false; // if enabled, light will gradually fade color from primary to secondary color. -bool fadeTransition = true; // enable crossfading color transition -uint16_t transitionDelay = 750; // default crossfade duration in ms - -bool skipFirstLed = false; // ignore first LED in strip (useful if you need the LED as signal repeater) -byte briMultiplier = 100; // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) - -// User Interface CONFIG -char serverDescription[33] = "WLED"; // Name of module -bool syncToggleReceive = false; // UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise - -// Sync CONFIG -bool buttonEnabled = true; -byte irEnabled = 0; // Infrared receiver - -uint16_t udpPort = 21324; // WLED notifier default port -uint16_t udpRgbPort = 19446; // Hyperion port - -bool receiveNotificationBrightness = true; // apply brightness from incoming notifications -bool receiveNotificationColor = true; // apply color -bool receiveNotificationEffects = true; // apply effects setup -bool notifyDirect = false; // send notification if change via UI or HTTP API -bool notifyButton = false; // send if updated by button or infrared remote -bool notifyAlexa = false; // send notification if updated via Alexa -bool notifyMacro = false; // send notification for macro -bool notifyHue = true; // send notification if Hue light changes -bool notifyTwice = false; // notifications use UDP: enable if devices don't sync reliably - -bool alexaEnabled = true; // enable device discovery by Amazon Echo -char alexaInvocationName[33] = "Light"; // speech control name of device. Choose something voice-to-text can understand - -char blynkApiKey[36] = ""; // Auth token for Blynk server. If empty, no connection will be made - -uint16_t realtimeTimeoutMs = 2500; // ms timeout of realtime mode before returning to normal mode -int arlsOffset = 0; // realtime LED offset -bool receiveDirect = true; // receive UDP realtime -bool arlsDisableGammaCorrection = true; // activate if gamma correction is handled by the source -bool arlsForceMaxBri = false; // enable to force max brightness if source has very dark colors that would be black - -uint16_t e131Universe = 1; // settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; // DMX mode (s.a.) -uint16_t DMXAddress = 1; // DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] -uint8_t DMXOldDimmer = 0; // only update brightness on change -uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; // to detect packet loss -bool e131Multicast = false; // multicast or unicast -bool e131SkipOutOfSequence = false; // freeze instead of flickering - -bool mqttEnabled = false; -char mqttDeviceTopic[33] = ""; // main MQTT topic (individual per device, default is wled/mac) -char mqttGroupTopic[33] = "wled/all"; // second MQTT topic (for example to group devices) -char mqttServer[33] = ""; // both domains and IPs should work (no SSL) -char mqttUser[41] = ""; // optional: username for MQTT auth -char mqttPass[41] = ""; // optional: password for MQTT auth -char mqttClientID[41] = ""; // override the client ID -uint16_t mqttPort = 1883; - -bool huePollingEnabled = false; // poll hue bridge for light state -uint16_t huePollIntervalMs = 2500; // low values (< 1sec) may cause lag but offer quicker response -char hueApiKey[47] = "api"; // key token will be obtained from bridge -byte huePollLightId = 1; // ID of hue lamp to sync to. Find the ID in the hue app ("about" section) -IPAddress hueIP = (0, 0, 0, 0); // IP address of the bridge -bool hueApplyOnOff = true; -bool hueApplyBri = true; -bool hueApplyColor = true; - -// Time CONFIG -bool ntpEnabled = false; // get internet time. Only required if you use clock overlays or time-activated macros -bool useAMPM = false; // 12h/24h clock format -byte currentTimezone = 0; // Timezone ID. Refer to timezones array in wled10_ntp.ino -int utcOffsetSecs = 0; // Seconds to offset from UTC before timzone calculation - -byte overlayDefault = 0; // 0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie -byte overlayMin = 0, overlayMax = ledCount - 1; // boundaries of overlay mode - -byte analogClock12pixel = 0; // The pixel in your strip where "midnight" would be -bool analogClockSecondsTrail = false; // Display seconds as trail of LEDs instead of a single pixel -bool analogClock5MinuteMarks = false; // Light pixels at every 5-minute position - -char cronixieDisplay[7] = "HHMMSS"; // Cronixie Display mask. See wled13_cronixie.ino -bool cronixieBacklight = true; // Allow digits to be back-illuminated - -bool countdownMode = false; // Clock will count down towards date -byte countdownYear = 20, countdownMonth = 1; // Countdown target date, year is last two digits -byte countdownDay = 1, countdownHour = 0; -byte countdownMin = 0, countdownSec = 0; - -byte macroBoot = 0; // macro loaded after startup -byte macroNl = 0; // after nightlight delay over -byte macroCountdown = 0; -byte macroAlexaOn = 0, macroAlexaOff = 0; -byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; - -// Security CONFIG -bool otaLock = false; // prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks -bool wifiLock = false; // prevents access to WiFi settings when OTA lock is enabled -bool aOtaEnabled = true; // ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on - -uint16_t userVar0 = 0, userVar1 = 0; - -#ifdef WLED_ENABLE_DMX - // dmx CONFIG - byte DMXChannels = 7; // number of channels per fixture - byte DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - // assigns the different channels to different functions. See wled21_dmx.ino for more information. - uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. - uint16_t DMXStart = 10; // start address of the first fixture -#endif - -// internal global variable declarations -// wifi -bool apActive = false; -bool forceReconnect = false; -uint32_t lastReconnectAttempt = 0; -bool interfacesInited = false; -bool wasConnected = false; - -// color -byte colOld[] { 0, 0, 0, 0 }; // color before transition -byte colT[] { 0, 0, 0, 0 }; // color that is currently displayed on the LEDs -byte colIT[] { 0, 0, 0, 0 }; // color that was last sent to LEDs -byte colSecT[] { 0, 0, 0, 0 }; -byte colSecOld[] { 0, 0, 0, 0 }; -byte colSecIT[] { 0, 0, 0, 0 }; - -byte lastRandomIndex = 0; // used to save last random color so the new one is not the same - -// transitions -bool transitionActive = false; -uint16_t transitionDelayDefault = transitionDelay; -uint16_t transitionDelayTemp = transitionDelay; -unsigned long transitionStartTime; -float tperLast = 0; // crossfade transition progress, 0.0f - 1.0f -bool jsonTransitionOnce = false; - -// nightlight -bool nightlightActive = false; -bool nightlightActiveOld = false; -uint32_t nightlightDelayMs = 10; -uint8_t nightlightDelayMinsDefault = nightlightDelayMins; -unsigned long nightlightStartTime; -byte briNlT = 0; // current nightlight brightness -byte colNlT[] { 0, 0, 0, 0 }; // current nightlight color - -// brightness -unsigned long lastOnTime = 0; -bool offMode = !turnOnAtBoot; -byte bri = briS; -byte briOld = 0; -byte briT = 0; -byte briIT = 0; -byte briLast = 128; // brightness before turned off. Used for toggle function -byte whiteLast = 128; // white channel before turned off. Used for toggle function - -// button -bool buttonPressedBefore = false; -bool buttonLongPressed = false; -unsigned long buttonPressedTime = 0; -unsigned long buttonWaitTime = 0; - -// notifications -bool notifyDirectDefault = notifyDirect; -bool receiveNotifications = true; -unsigned long notificationSentTime = 0; -byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; -bool notificationTwoRequired = false; - -// effects -byte effectCurrent = 0; -byte effectSpeed = 128; -byte effectIntensity = 128; -byte effectPalette = 0; - -// network -bool udpConnected = false, udpRgbConnected = false; - -// ui style -bool showWelcomePage = false; - -// hue -byte hueError = HUE_ERROR_INACTIVE; -// uint16_t hueFailCount = 0; -float hueXLast = 0, hueYLast = 0; -uint16_t hueHueLast = 0, hueCtLast = 0; -byte hueSatLast = 0, hueBriLast = 0; -unsigned long hueLastRequestSent = 0; -bool hueAuthRequired = false; -bool hueReceived = false; -bool hueStoreAllowed = false, hueNewKey = false; - -// overlays -byte overlayCurrent = overlayDefault; -byte overlaySpeed = 200; -unsigned long overlayRefreshMs = 200; -unsigned long overlayRefreshedTime; - -// cronixie -byte dP[] { 0, 0, 0, 0, 0, 0 }; -bool cronixieInit = false; - -// countdown -unsigned long countdownTime = 1514764800L; -bool countdownOverTriggered = true; - -// timer -byte lastTimerMinute = 0; -byte timerHours[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -byte timerMinutes[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -byte timerMacro[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -byte timerWeekday[] = { 255, 255, 255, 255, 255, 255, 255, 255 }; // weekdays to activate on -// bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity - -// blynk -bool blynkEnabled = false; - -// preset cycling -bool presetCyclingEnabled = false; -byte presetCycleMin = 1, presetCycleMax = 5; -uint16_t presetCycleTime = 1250; -unsigned long presetCycledTime = 0; -byte presetCycCurr = presetCycleMin; -bool presetApplyBri = true; -bool saveCurrPresetCycConf = false; - -// realtime -byte realtimeMode = REALTIME_MODE_INACTIVE; -IPAddress realtimeIP = (0, 0, 0, 0); -unsigned long realtimeTimeout = 0; - -// mqtt -long lastMqttReconnectAttempt = 0; -long lastInterfaceUpdate = 0; -byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; -char mqttStatusTopic[40] = ""; // this must be global because of async handlers - -#if AUXPIN >= 0 - // auxiliary debug pin - byte auxTime = 0; - unsigned long auxStartTime = 0; - bool auxActive = false, auxActiveBefore = false; -#endif - -// alexa udp -String escapedMac; -#ifndef WLED_DISABLE_ALEXA - Espalexa espalexa; - EspalexaDevice* espalexaDevice; -#endif - -// dns server -DNSServer dnsServer; - -// network time -bool ntpConnected = false; -time_t local = 0; -unsigned long ntpLastSyncTime = 999000000L; -unsigned long ntpPacketSentTime = 999000000L; -IPAddress ntpServerIP; -uint16_t ntpLocalPort = 2390; - -// Temp buffer -char* obuf; -uint16_t olen = 0; - -// presets -uint16_t savedPresets = 0; -int8_t currentPreset = -1; -bool isPreset = false; - -byte errorFlag = 0; - -String messageHead, messageSub; -byte optionType; - -bool doReboot = false; // flag to initiate reboot from async handlers -bool doPublishMqtt = false; - -// server library objects -AsyncWebServer server(80); -AsyncClient* hueClient = NULL; -AsyncMqttClient* mqtt = NULL; - -// udp interface objects -WiFiUDP notifierUdp, rgbUdp; -WiFiUDP ntpUdp; -ESPAsyncE131 e131(handleE131Packet); -bool e131NewData = false; - -// led fx library object -WS2812FX strip = WS2812FX(); - -// debug macro variable definitions -#ifdef WLED_DEBUG - unsigned long debugTime = 0; - int lastWifiState = 3; - unsigned long wifiStateChangedTime = 0; - int loops = 0; -#endif - WLED::WLED() { } diff --git a/wled00/wled.h b/wled00/wled.h index 926fa0c81..0c6d31147 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2003300 +#define VERSION 2004060 // ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). @@ -119,268 +119,370 @@ #ifndef ESP8266 #include #endif -#endif - -// Global external variable declaration. See wled.cpp for definitions and comments. -extern char versionString[]; -extern char apPass[65]; -extern char otaPass[33]; -extern byte auxDefaultState; -extern byte auxTriggeredState; -extern char ntpServerName[33]; -extern char clientSSID[33]; -extern char clientPass[65]; -extern char cmDNS[33]; -extern char apSSID[33]; -extern byte apChannel; -extern byte apHide; -extern byte apBehavior; -extern IPAddress staticIP; -extern IPAddress staticGateway; -extern IPAddress staticSubnet; -extern bool noWifiSleep; -extern uint16_t ledCount; -extern bool useRGBW; -#define ABL_MILLIAMPS_DEFAULT 850; // auto lower brightness to stay close to milliampere limit -extern bool turnOnAtBoot; -extern byte bootPreset; -extern byte col[]; -extern byte colSec[]; -extern byte briS; -extern byte nightlightTargetBri; -extern byte nightlightDelayMins; -extern bool nightlightFade; -extern bool nightlightColorFade; -extern bool fadeTransition; -extern uint16_t transitionDelay; -extern bool skipFirstLed; -extern byte briMultiplier; -extern char serverDescription[33]; -extern bool syncToggleReceive; -extern bool buttonEnabled; -extern byte irEnabled; -extern uint16_t udpPort; -extern uint16_t udpRgbPort; -extern bool receiveNotificationBrightness; -extern bool receiveNotificationColor; -extern bool receiveNotificationEffects; -extern bool notifyDirect; -extern bool notifyButton; -extern bool notifyAlexa; -extern bool notifyMacro; -extern bool notifyHue; -extern bool notifyTwice; -extern bool alexaEnabled; -extern char alexaInvocationName[33]; -extern char blynkApiKey[36]; -extern uint16_t realtimeTimeoutMs; -extern int arlsOffset; -extern bool receiveDirect; -extern bool arlsDisableGammaCorrection; -extern bool arlsForceMaxBri; -#define E131_MAX_UNIVERSE_COUNT 9 -extern uint16_t e131Universe; -extern uint8_t DMXMode; -extern uint16_t DMXAddress; -extern uint8_t DMXOldDimmer; -extern uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; -extern bool e131Multicast; -extern bool e131SkipOutOfSequence; -extern bool mqttEnabled; -extern char mqttDeviceTopic[33]; -extern char mqttGroupTopic[33]; -extern char mqttServer[33]; -extern char mqttUser[41]; -extern char mqttPass[41]; -extern char mqttClientID[41]; -extern uint16_t mqttPort; -extern bool huePollingEnabled; -extern uint16_t huePollIntervalMs; -extern char hueApiKey[47]; -extern byte huePollLightId; -extern IPAddress hueIP; -extern bool hueApplyOnOff; -extern bool hueApplyBri; -extern bool hueApplyColor; -extern bool ntpEnabled; -extern bool useAMPM; -extern byte currentTimezone; -extern int utcOffsetSecs; -extern byte overlayDefault; -extern byte overlayMin; -extern byte overlayMax; -extern byte analogClock12pixel; -extern bool analogClockSecondsTrail; -extern bool analogClock5MinuteMarks; -extern char cronixieDisplay[7]; -extern bool cronixieBacklight; -extern bool countdownMode; -extern byte countdownYear, countdownMonth; -extern byte countdownDay, countdownHour; -extern byte countdownMin, countdownSec; -extern byte macroBoot; -extern byte macroNl; -extern byte macroCountdown; -extern byte macroAlexaOn, macroAlexaOff; -extern byte macroButton, macroLongPress, macroDoublePress; -extern bool otaLock; -extern bool wifiLock; -extern bool aOtaEnabled; -extern uint16_t userVar0, userVar1; -#ifdef WLED_ENABLE_DMX - extern byte DMXChannels; - extern byte DMXFixtureMap[15]; - extern uint16_t DMXGap; - extern uint16_t DMXStart; -#endif -extern bool apActive; -extern bool forceReconnect; -extern uint32_t lastReconnectAttempt; -extern bool interfacesInited; -extern bool wasConnected; -extern byte colOld[]; -extern byte colT[]; -extern byte colIT[]; -extern byte colSecT[]; -extern byte colSecOld[]; -extern byte colSecIT[]; -extern byte lastRandomIndex; -extern bool transitionActive; -extern uint16_t transitionDelayDefault; -extern uint16_t transitionDelayTemp; -extern unsigned long transitionStartTime; -extern float tperLast; -extern bool jsonTransitionOnce; -extern bool nightlightActive; -extern bool nightlightActiveOld; -extern uint32_t nightlightDelayMs; -extern uint8_t nightlightDelayMinsDefault; -extern unsigned long nightlightStartTime; -extern byte briNlT; -extern byte colNlT[]; -extern unsigned long lastOnTime; -extern bool offMode; -extern byte bri; -extern byte briOld; -extern byte briT; -extern byte briIT; -extern byte briLast; -extern byte whiteLast; -extern bool buttonPressedBefore; -extern bool buttonLongPressed; -extern unsigned long buttonPressedTime; -extern unsigned long buttonWaitTime; -extern bool notifyDirectDefault; -extern bool receiveNotifications; -extern unsigned long notificationSentTime; -extern byte notificationSentCallMode; -extern bool notificationTwoRequired; -extern byte effectCurrent; -extern byte effectSpeed; -extern byte effectIntensity; -extern byte effectPalette; -extern bool udpConnected, udpRgbConnected; -extern bool showWelcomePage; -extern byte hueError; -extern float hueXLast, hueYLast; -extern uint16_t hueHueLast, hueCtLast; -extern byte hueSatLast, hueBriLast; -extern unsigned long hueLastRequestSent; -extern bool hueAuthRequired; -extern bool hueReceived; -extern bool hueStoreAllowed, hueNewKey; -extern byte overlayCurrent; -extern byte overlaySpeed; -extern unsigned long overlayRefreshMs; -extern unsigned long overlayRefreshedTime; -extern byte dP[]; -extern bool cronixieInit; -extern unsigned long countdownTime; -extern bool countdownOverTriggered; -extern byte lastTimerMinute; -extern byte timerHours[]; -extern byte timerMinutes[]; -extern byte timerMacro[]; -extern byte timerWeekday[]; -extern bool blynkEnabled; -extern bool presetCyclingEnabled; -extern byte presetCycleMin, presetCycleMax; -extern uint16_t presetCycleTime; -extern unsigned long presetCycledTime; -extern byte presetCycCurr; -extern bool presetApplyBri; -extern bool saveCurrPresetCycConf; -extern byte realtimeMode; -extern IPAddress realtimeIP; -extern unsigned long realtimeTimeout; -extern long lastMqttReconnectAttempt; -extern long lastInterfaceUpdate; -extern byte interfaceUpdateCallMode; -extern char mqttStatusTopic[40]; -#if AUXPIN >= 0 - extern byte auxTime; - extern unsigned long auxStartTime; - extern bool auxActive; -#endif -extern String escapedMac; -#ifndef WLED_DISABLE_ALEXA - extern Espalexa espalexa; - extern EspalexaDevice *espalexaDevice; -#endif - -#define NTP_PACKET_SIZE 48 -extern DNSServer dnsServer; -extern bool ntpConnected; -extern time_t local; -extern unsigned long ntpLastSyncTime; -extern unsigned long ntpPacketSentTime; -extern IPAddress ntpServerIP; -extern uint16_t ntpLocalPort; - -// maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue -#define MAX_LEDS 1500 -#define MAX_LEDS_DMA 500 - -// string temp buffer (now stored in stack locally) -#define OMAX 2048 -extern char* obuf; -extern uint16_t olen; - -extern uint16_t savedPresets; -extern int8_t currentPreset; -extern bool isPreset; -extern byte errorFlag; -extern String messageHead, messageSub; -extern byte optionType; -extern bool doReboot; -extern bool doPublishMqtt; -extern AsyncWebServer server; -extern AsyncClient* hueClient; -extern AsyncMqttClient* mqtt; -extern WiFiUDP notifierUdp, rgbUdp; -extern WiFiUDP ntpUdp; -extern ESPAsyncE131 e131; -extern bool e131NewData; -extern WS2812FX strip; - -#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) -#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) - -// debug macros -#ifdef WLED_DEBUG #define DEBUG_PRINT(x) Serial.print(x) #define DEBUG_PRINTLN(x) Serial.println(x) #define DEBUG_PRINTF(x) Serial.printf(x) - extern unsigned long debugTime; - extern int lastWifiState; - extern unsigned long wifiStateChangedTime; - extern int loops; #else #define DEBUG_PRINT(x) #define DEBUG_PRINTLN(x) #define DEBUG_PRINTF(x) #endif +#ifndef WLED_DEFINE_GLOBAL_VARS +# define WLED_GLOBAL extern +# define _INIT(x) +# define _INIT_N(x) +#else +# define WLED_GLOBAL +# define _INIT(x) = x + +//needed to ignore commas in array definitions +#define UNPACK( ... ) __VA_ARGS__ +# define _INIT_N(x) UNPACK x +#endif + +// Global Variable definitions +WLED_GLOBAL char versionString[] _INIT("0.9.1n"); + +// AP and OTA default passwords (for maximum security change them!) +WLED_GLOBAL char apPass[65] _INIT(DEFAULT_AP_PASS); +WLED_GLOBAL char otaPass[33] _INIT(DEFAULT_OTA_PASS); + +// Hardware CONFIG (only changeble HERE, not at runtime) +// LED strip pin, button pin and IR pin changeable in NpbWrapper.h! + +WLED_GLOBAL byte auxDefaultState _INIT(0); // 0: input 1: high 2: low +WLED_GLOBAL byte auxTriggeredState _INIT(0); // 0: input 1: high 2: low +WLED_GLOBAL char ntpServerName[33] _INIT("0.wled.pool.ntp.org"); // NTP server to use + +// WiFi CONFIG (all these can be changed via web UI, no need to set them here) +WLED_GLOBAL char clientSSID[33] _INIT(CLIENT_SSID); +WLED_GLOBAL char clientPass[65] _INIT(CLIENT_PASS); +WLED_GLOBAL char cmDNS[33] _INIT("x"); // mDNS address (placeholder, is replaced by wledXXXXXX.local) +WLED_GLOBAL char apSSID[33] _INIT(""); // AP off by default (unless setup) +WLED_GLOBAL byte apChannel _INIT(1); // 2.4GHz WiFi AP channel (1-13) +WLED_GLOBAL byte apHide _INIT(0); // hidden AP SSID +WLED_GLOBAL byte apBehavior _INIT(AP_BEHAVIOR_BOOT_NO_CONN); // access point opens when no connection after boot by default +WLED_GLOBAL IPAddress staticIP _INIT_N((( 0, 0, 0, 0))); // static IP of ESP +WLED_GLOBAL IPAddress staticGateway _INIT_N((( 0, 0, 0, 0))); // gateway (router) IP +WLED_GLOBAL IPAddress staticSubnet _INIT_N(((255, 255, 255, 0))); // most common subnet in home networks +WLED_GLOBAL bool noWifiSleep _INIT(false); // disabling modem sleep modes will increase heat output and power usage, but may help with connection issues + +// LED CONFIG +WLED_GLOBAL uint16_t ledCount _INIT(30); // overcurrent prevented by ABL +WLED_GLOBAL bool useRGBW _INIT(false); // SK6812 strips can contain an extra White channel +WLED_GLOBAL bool turnOnAtBoot _INIT(true); // turn on LEDs at power-up +WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load after power-up + +WLED_GLOBAL byte col[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. col[] should be updated if you want to change the color. +WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color +WLED_GLOBAL byte briS _INIT(128); // default brightness + +WLED_GLOBAL byte nightlightTargetBri _INIT(0); // brightness after nightlight is over +WLED_GLOBAL byte nightlightDelayMins _INIT(60); +WLED_GLOBAL bool nightlightFade _INIT(true); // if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over +WLED_GLOBAL bool nightlightColorFade _INIT(false); // if enabled, light will gradually fade color from primary to secondary color. +WLED_GLOBAL bool fadeTransition _INIT(true); // enable crossfading color transition +WLED_GLOBAL uint16_t transitionDelay _INIT(750); // default crossfade duration in ms + +WLED_GLOBAL bool skipFirstLed _INIT(false); // ignore first LED in strip (useful if you need the LED as signal repeater) +WLED_GLOBAL byte briMultiplier _INIT(100); // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) + +// User Interface CONFIG +WLED_GLOBAL char serverDescription[33] _INIT("WLED"); // Name of module +WLED_GLOBAL bool syncToggleReceive _INIT(false); // UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise + +// Sync CONFIG +WLED_GLOBAL bool buttonEnabled _INIT(true); +WLED_GLOBAL byte irEnabled _INIT(0); // Infrared receiver + +WLED_GLOBAL uint16_t udpPort _INIT(21324); // WLED notifier default port +WLED_GLOBAL uint16_t udpRgbPort _INIT(19446); // Hyperion port + +WLED_GLOBAL bool receiveNotificationBrightness _INIT(true); // apply brightness from incoming notifications +WLED_GLOBAL bool receiveNotificationColor _INIT(true); // apply color +WLED_GLOBAL bool receiveNotificationEffects _INIT(true); // apply effects setup +WLED_GLOBAL bool notifyDirect _INIT(false); // send notification if change via UI or HTTP API +WLED_GLOBAL bool notifyButton _INIT(false); // send if updated by button or infrared remote +WLED_GLOBAL bool notifyAlexa _INIT(false); // send notification if updated via Alexa +WLED_GLOBAL bool notifyMacro _INIT(false); // send notification for macro +WLED_GLOBAL bool notifyHue _INIT(true); // send notification if Hue light changes +WLED_GLOBAL bool notifyTwice _INIT(false); // notifications use UDP: enable if devices don't sync reliably + +WLED_GLOBAL bool alexaEnabled _INIT(true); // enable device discovery by Amazon Echo +WLED_GLOBAL char alexaInvocationName[33] _INIT("Light"); // speech control name of device. Choose something voice-to-text can understand + +WLED_GLOBAL char blynkApiKey[36] _INIT(""); // Auth token for Blynk server. If empty, no connection will be made + +WLED_GLOBAL uint16_t realtimeTimeoutMs _INIT(2500); // ms timeout of realtime mode before returning to normal mode +WLED_GLOBAL int arlsOffset _INIT(0); // realtime LED offset +WLED_GLOBAL bool receiveDirect _INIT(true); // receive UDP realtime +WLED_GLOBAL bool arlsDisableGammaCorrection _INIT(true); // activate if gamma correction is handled by the source +WLED_GLOBAL bool arlsForceMaxBri _INIT(false); // enable to force max brightness if source has very dark colors that would be black + +WLED_GLOBAL uint16_t e131Universe _INIT(1); // settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) +WLED_GLOBAL byte DMXMode _INIT(DMX_MODE_MULTIPLE_RGB); // DMX mode (s.a.) +WLED_GLOBAL uint16_t DMXAddress _INIT(1); // DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +WLED_GLOBAL byte DMXOldDimmer _INIT(0); // only update brightness on change +WLED_GLOBAL byte e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; // to detect packet loss +WLED_GLOBAL bool e131Multicast _INIT(false); // multicast or unicast +WLED_GLOBAL bool e131SkipOutOfSequence _INIT(false); // freeze instead of flickering + +WLED_GLOBAL bool mqttEnabled _INIT(false); +WLED_GLOBAL char mqttDeviceTopic[33] _INIT(""); // main MQTT topic (individual per device, default is wled/mac) +WLED_GLOBAL char mqttGroupTopic[33] _INIT("wled/all"); // second MQTT topic (for example to group devices) +WLED_GLOBAL char mqttServer[33] _INIT(""); // both domains and IPs should work (no SSL) +WLED_GLOBAL char mqttUser[41] _INIT(""); // optional: username for MQTT auth +WLED_GLOBAL char mqttPass[41] _INIT(""); // optional: password for MQTT auth +WLED_GLOBAL char mqttClientID[41] _INIT(""); // override the client ID +WLED_GLOBAL uint16_t mqttPort _INIT(1883); + +WLED_GLOBAL bool huePollingEnabled _INIT(false); // poll hue bridge for light state +WLED_GLOBAL uint16_t huePollIntervalMs _INIT(2500); // low values (< 1sec) may cause lag but offer quicker response +WLED_GLOBAL char hueApiKey[47] _INIT("api"); // key token will be obtained from bridge +WLED_GLOBAL byte huePollLightId _INIT(1); // ID of hue lamp to sync to. Find the ID in the hue app ("about" section) +WLED_GLOBAL IPAddress hueIP _INIT((0, 0, 0, 0)); // IP address of the bridge +WLED_GLOBAL bool hueApplyOnOff _INIT(true); +WLED_GLOBAL bool hueApplyBri _INIT(true); +WLED_GLOBAL bool hueApplyColor _INIT(true); + +// Time CONFIG +WLED_GLOBAL bool ntpEnabled _INIT(false); // get internet time. Only required if you use clock overlays or time-activated macros +WLED_GLOBAL bool useAMPM _INIT(false); // 12h/24h clock format +WLED_GLOBAL byte currentTimezone _INIT(0); // Timezone ID. Refer to timezones array in wled10_ntp.ino +WLED_GLOBAL int utcOffsetSecs _INIT(0); // Seconds to offset from UTC before timzone calculation + +WLED_GLOBAL byte overlayDefault _INIT(0); // 0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie +WLED_GLOBAL byte overlayMin _INIT(0), overlayMax _INIT(ledCount - 1); // boundaries of overlay mode + +WLED_GLOBAL byte analogClock12pixel _INIT(0); // The pixel in your strip where "midnight" would be +WLED_GLOBAL bool analogClockSecondsTrail _INIT(false); // Display seconds as trail of LEDs instead of a single pixel +WLED_GLOBAL bool analogClock5MinuteMarks _INIT(false); // Light pixels at every 5-minute position + +WLED_GLOBAL char cronixieDisplay[7] _INIT("HHMMSS"); // Cronixie Display mask. See wled13_cronixie.ino +WLED_GLOBAL bool cronixieBacklight _INIT(true); // Allow digits to be back-illuminated + +WLED_GLOBAL bool countdownMode _INIT(false); // Clock will count down towards date +WLED_GLOBAL byte countdownYear _INIT(20), countdownMonth _INIT(1); // Countdown target date, year is last two digits +WLED_GLOBAL byte countdownDay _INIT(1), countdownHour _INIT(0); +WLED_GLOBAL byte countdownMin _INIT(0), countdownSec _INIT(0); + +WLED_GLOBAL byte macroBoot _INIT(0); // macro loaded after startup +WLED_GLOBAL byte macroNl _INIT(0); // after nightlight delay over +WLED_GLOBAL byte macroCountdown _INIT(0); +WLED_GLOBAL byte macroAlexaOn _INIT(0), macroAlexaOff _INIT(0); +WLED_GLOBAL byte macroButton _INIT(0), macroLongPress _INIT(0), macroDoublePress _INIT(0); + +// Security CONFIG +WLED_GLOBAL bool otaLock _INIT(false); // prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks +WLED_GLOBAL bool wifiLock _INIT(false); // prevents access to WiFi settings when OTA lock is enabled +WLED_GLOBAL bool aOtaEnabled _INIT(true); // ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on + +WLED_GLOBAL uint16_t userVar0 _INIT(0), userVar1 _INIT(0); + +#ifdef WLED_ENABLE_DMX + // dmx CONFIG + WLED_GLOBAL byte DMXChannels _INIT(7); // number of channels per fixture + WLED_GLOBAL byte DMXFixtureMap[15] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 })); + // assigns the different channels to different functions. See wled21_dmx.ino for more information. + WLED_GLOBAL uint16_t DMXGap _INIT(10); // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. + WLED_GLOBAL uint16_t DMXStart _INIT(10); // start address of the first fixture +#endif + +// internal global variable declarations +// wifi +WLED_GLOBAL bool apActive _INIT(false); +WLED_GLOBAL bool forceReconnect _INIT(false); +WLED_GLOBAL uint32_t lastReconnectAttempt _INIT(0); +WLED_GLOBAL bool interfacesInited _INIT(false); +WLED_GLOBAL bool wasConnected _INIT(false); + +// color +WLED_GLOBAL byte colOld[] _INIT_N(({ 0, 0, 0, 0 })); // color before transition +WLED_GLOBAL byte colT[] _INIT_N(({ 0, 0, 0, 0 })); // color that is currently displayed on the LEDs +WLED_GLOBAL byte colIT[] _INIT_N(({ 0, 0, 0, 0 })); // color that was last sent to LEDs +WLED_GLOBAL byte colSecT[] _INIT_N(({ 0, 0, 0, 0 })); +WLED_GLOBAL byte colSecOld[] _INIT_N(({ 0, 0, 0, 0 })); +WLED_GLOBAL byte colSecIT[] _INIT_N(({ 0, 0, 0, 0 })); + +WLED_GLOBAL byte lastRandomIndex _INIT(0); // used to save last random color so the new one is not the same + +// transitions +WLED_GLOBAL bool transitionActive _INIT(false); +WLED_GLOBAL uint16_t transitionDelayDefault _INIT(transitionDelay); +WLED_GLOBAL uint16_t transitionDelayTemp _INIT(transitionDelay); +WLED_GLOBAL unsigned long transitionStartTime; +WLED_GLOBAL float tperLast _INIT(0); // crossfade transition progress, 0.0f - 1.0f +WLED_GLOBAL bool jsonTransitionOnce _INIT(false); + +// nightlight +WLED_GLOBAL bool nightlightActive _INIT(false); +WLED_GLOBAL bool nightlightActiveOld _INIT(false); +WLED_GLOBAL uint32_t nightlightDelayMs _INIT(10); +WLED_GLOBAL byte nightlightDelayMinsDefault _INIT(nightlightDelayMins); +WLED_GLOBAL unsigned long nightlightStartTime; +WLED_GLOBAL byte briNlT _INIT(0); // current nightlight brightness +WLED_GLOBAL byte colNlT[] _INIT_N(({ 0, 0, 0, 0 })); // current nightlight color + +// brightness +WLED_GLOBAL unsigned long lastOnTime _INIT(0); +WLED_GLOBAL bool offMode _INIT(!turnOnAtBoot); +WLED_GLOBAL byte bri _INIT(briS); +WLED_GLOBAL byte briOld _INIT(0); +WLED_GLOBAL byte briT _INIT(0); +WLED_GLOBAL byte briIT _INIT(0); +WLED_GLOBAL byte briLast _INIT(128); // brightness before turned off. Used for toggle function +WLED_GLOBAL byte whiteLast _INIT(128); // white channel before turned off. Used for toggle function + +// button +WLED_GLOBAL bool buttonPressedBefore _INIT(false); +WLED_GLOBAL bool buttonLongPressed _INIT(false); +WLED_GLOBAL unsigned long buttonPressedTime _INIT(0); +WLED_GLOBAL unsigned long buttonWaitTime _INIT(0); + +// notifications +WLED_GLOBAL bool notifyDirectDefault _INIT(notifyDirect); +WLED_GLOBAL bool receiveNotifications _INIT(true); +WLED_GLOBAL unsigned long notificationSentTime _INIT(0); +WLED_GLOBAL byte notificationSentCallMode _INIT(NOTIFIER_CALL_MODE_INIT); +WLED_GLOBAL bool notificationTwoRequired _INIT(false); + +// effects +WLED_GLOBAL byte effectCurrent _INIT(0); +WLED_GLOBAL byte effectSpeed _INIT(128); +WLED_GLOBAL byte effectIntensity _INIT(128); +WLED_GLOBAL byte effectPalette _INIT(0); + +// network +WLED_GLOBAL bool udpConnected _INIT(false), udpRgbConnected _INIT(false); + +// ui style +WLED_GLOBAL bool showWelcomePage _INIT(false); + +// hue +WLED_GLOBAL byte hueError _INIT(HUE_ERROR_INACTIVE); +// WLED_GLOBAL uint16_t hueFailCount _INIT(0); +WLED_GLOBAL float hueXLast _INIT(0), hueYLast _INIT(0); +WLED_GLOBAL uint16_t hueHueLast _INIT(0), hueCtLast _INIT(0); +WLED_GLOBAL byte hueSatLast _INIT(0), hueBriLast _INIT(0); +WLED_GLOBAL unsigned long hueLastRequestSent _INIT(0); +WLED_GLOBAL bool hueAuthRequired _INIT(false); +WLED_GLOBAL bool hueReceived _INIT(false); +WLED_GLOBAL bool hueStoreAllowed _INIT(false), hueNewKey _INIT(false); + +// overlays +WLED_GLOBAL byte overlayCurrent _INIT(overlayDefault); +WLED_GLOBAL byte overlaySpeed _INIT(200); +WLED_GLOBAL unsigned long overlayRefreshMs _INIT(200); +WLED_GLOBAL unsigned long overlayRefreshedTime; + +// cronixie +WLED_GLOBAL byte dP[] _INIT_N(({ 0, 0, 0, 0, 0, 0 })); +WLED_GLOBAL bool cronixieInit _INIT(false); + +// countdown +WLED_GLOBAL unsigned long countdownTime _INIT(1514764800L); +WLED_GLOBAL bool countdownOverTriggered _INIT(true); + +// timer +WLED_GLOBAL byte lastTimerMinute _INIT(0); +WLED_GLOBAL byte timerHours[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0 })); +WLED_GLOBAL byte timerMinutes[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0 })); +WLED_GLOBAL byte timerMacro[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0 })); +WLED_GLOBAL byte timerWeekday[] _INIT_N(({ 255, 255, 255, 255, 255, 255, 255, 255 })); // weekdays to activate on +// bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity + +// blynk +WLED_GLOBAL bool blynkEnabled _INIT(false); + +// preset cycling +WLED_GLOBAL bool presetCyclingEnabled _INIT(false); +WLED_GLOBAL byte presetCycleMin _INIT(1), presetCycleMax _INIT(5); +WLED_GLOBAL uint16_t presetCycleTime _INIT(1250); +WLED_GLOBAL unsigned long presetCycledTime _INIT(0); +WLED_GLOBAL byte presetCycCurr _INIT(presetCycleMin); +WLED_GLOBAL bool presetApplyBri _INIT(true); +WLED_GLOBAL bool saveCurrPresetCycConf _INIT(false); + +// realtime +WLED_GLOBAL byte realtimeMode _INIT(REALTIME_MODE_INACTIVE); +WLED_GLOBAL IPAddress realtimeIP _INIT((0, 0, 0, 0)); +WLED_GLOBAL unsigned long realtimeTimeout _INIT(0); + +// mqtt +WLED_GLOBAL long lastMqttReconnectAttempt _INIT(0); +WLED_GLOBAL long lastInterfaceUpdate _INIT(0); +WLED_GLOBAL byte interfaceUpdateCallMode _INIT(NOTIFIER_CALL_MODE_INIT); +WLED_GLOBAL char mqttStatusTopic[40] _INIT(""); // this must be global because of async handlers + +#if AUXPIN >= 0 + // auxiliary debug pin + WLED_GLOBAL byte auxTime _INIT(0); + WLED_GLOBAL unsigned long auxStartTime _INIT(0); + WLED_GLOBAL bool auxActive _INIT(false, auxActiveBefore _INIT(false); +#endif + +// alexa udp +WLED_GLOBAL String escapedMac; +#ifndef WLED_DISABLE_ALEXA + WLED_GLOBAL Espalexa espalexa; + WLED_GLOBAL EspalexaDevice* espalexaDevice; +#endif + +// dns server +WLED_GLOBAL DNSServer dnsServer; + +// network time +WLED_GLOBAL bool ntpConnected _INIT(false); +WLED_GLOBAL time_t local _INIT(0); +WLED_GLOBAL unsigned long ntpLastSyncTime _INIT(999000000L); +WLED_GLOBAL unsigned long ntpPacketSentTime _INIT(999000000L); +WLED_GLOBAL IPAddress ntpServerIP; +WLED_GLOBAL uint16_t ntpLocalPort _INIT(2390); + +// Temp buffer +WLED_GLOBAL char* obuf; +WLED_GLOBAL uint16_t olen _INIT(0); + +// presets +WLED_GLOBAL uint16_t savedPresets _INIT(0); +WLED_GLOBAL int8_t currentPreset _INIT(-1); +WLED_GLOBAL bool isPreset _INIT(false); + +WLED_GLOBAL byte errorFlag _INIT(0); + +WLED_GLOBAL String messageHead, messageSub; +WLED_GLOBAL byte optionType; + +WLED_GLOBAL bool doReboot _INIT(false); // flag to initiate reboot from async handlers +WLED_GLOBAL bool doPublishMqtt _INIT(false); + +// server library objects +WLED_GLOBAL AsyncWebServer server _INIT_N(((80))); +WLED_GLOBAL AsyncClient* hueClient _INIT(NULL); +WLED_GLOBAL AsyncMqttClient* mqtt _INIT(NULL); + +// udp interface objects +WLED_GLOBAL WiFiUDP notifierUdp, rgbUdp; +WLED_GLOBAL WiFiUDP ntpUdp; +WLED_GLOBAL ESPAsyncE131 e131 _INIT_N(((handleE131Packet))); +WLED_GLOBAL bool e131NewData _INIT(false); + +// led fx library object +WLED_GLOBAL WS2812FX strip _INIT(WS2812FX()); + +// debug macro variable definitions +#ifdef WLED_DEBUG + WLED_GLOBAL unsigned long debugTime _INIT(0); + WLED_GLOBAL int lastWifiState _INIT(3); + WLED_GLOBAL unsigned long wifiStateChangedTime _INIT(0); + WLED_GLOBAL int loops _INIT(0); +#endif + + +#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) +#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) + // append new c string to temp buffer efficiently bool oappend(const char* txt); // append new number to temp buffer efficiently From 8da985b6d03a7a77b2bc6932dbe95fcb9fb36bd2 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Tue, 7 Apr 2020 00:04:09 +0200 Subject: [PATCH 145/509] Fixed RBG and BGR getPixelColor (#825) Improved formatting --- CHANGELOG.md | 5 + wled00/FX_fcn.cpp | 4 +- wled00/const.h | 4 + wled00/{func_declare.h => fcn_declare.h} | 4 +- wled00/html_other.h | 2 +- wled00/html_settings.h | 4 +- wled00/wled.cpp | 4 + wled00/wled.h | 114 ++++++++++++----------- wled00/wled00.ino | 11 ++- 9 files changed, 90 insertions(+), 62 deletions(-) rename wled00/{func_declare.h => fcn_declare.h} (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8df63ff8e..d92a1966a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ### Development versions after 0.9.1 release +#### Build 2004061 + +- Fixed RBG and BGR getPixelColor (#825) +- Improved formatting + #### Build 2004060 - Consolidated global variables in wled.h diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index de89a430e..69b8c88a1 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -412,8 +412,8 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811 case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG - case 3: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //3 = RBG - case 4: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //4 = BGR + case 3: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //3 = RBG + case 4: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //4 = BGR case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR } return 0; diff --git a/wled00/const.h b/wled00/const.h index ef19e51be..173d7e7d5 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -1,6 +1,10 @@ #ifndef WLED_CONST_H #define WLED_CONST_H +/* + * Readability defines and their associated numerical values + compile-time constants + */ + //Defaults #define DEFAULT_CLIENT_SSID "Your_Network" #define DEFAULT_AP_PASS "wled1234" diff --git a/wled00/func_declare.h b/wled00/fcn_declare.h similarity index 99% rename from wled00/func_declare.h rename to wled00/fcn_declare.h index db3cb4bc4..c0826d6aa 100644 --- a/wled00/func_declare.h +++ b/wled00/fcn_declare.h @@ -1,5 +1,5 @@ -#ifndef WLED_FUNC_DECLARE_H -#define WLED_FUNC_DECLARE_H +#ifndef WLED_FCN_DECLARE_H +#define WLED_FCN_DECLARE_H #include #include "src/dependencies/espalexa/EspalexaDevice.h" #include "src/dependencies/e131/ESPAsyncE131.h" diff --git a/wled00/html_other.h b/wled00/html_other.h index e27c64dde..ce36cff48 100644 --- a/wled00/html_other.h +++ b/wled00/html_other.h @@ -1,5 +1,5 @@ /* - * Various pages + * Various web pages */ //USER HTML HERE (/u subpage) diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 284d9b30f..e2d94f973 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -1,6 +1,6 @@ /* - Settings html -*/ + * Settings html + */ //common CSS of settings pages const char PAGE_settingsCss[] PROGMEM = R"=====()====="; diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 701b98e31..b68723bb0 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -2,6 +2,10 @@ #include "wled.h" #include +/* + * Main WLED class implementation. Mostly initialization and connection logic + */ + WLED::WLED() { } diff --git a/wled00/wled.h b/wled00/wled.h index 0c6d31147..6f4b2cb00 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2004060 +#define VERSION 2004061 // ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). @@ -81,7 +81,7 @@ #include "src/dependencies/json/AsyncJson-v6.h" #include "src/dependencies/json/ArduinoJson-v6.h" -#include "func_declare.h" +#include "fcn_declare.h" #include "html_ui.h" #include "html_settings.h" #include "html_other.h" @@ -128,6 +128,12 @@ #define DEBUG_PRINTF(x) #endif +// GLOBAL VARIABLES +// both declared and defined in header (solution from http://www.keil.com/support/docs/1868.htm) +// +//e.g. byte test = 2 becomes WLED_GLOBAL byte test _INIT(2); +// int arr[]{0,1,2} becomes WLED_GLOBAL int arr[] _INIT_N(({0,1,2})); + #ifndef WLED_DEFINE_GLOBAL_VARS # define WLED_GLOBAL extern # define _INIT(x) @@ -170,13 +176,13 @@ WLED_GLOBAL bool noWifiSleep _INIT(false); // disabling // LED CONFIG WLED_GLOBAL uint16_t ledCount _INIT(30); // overcurrent prevented by ABL -WLED_GLOBAL bool useRGBW _INIT(false); // SK6812 strips can contain an extra White channel +WLED_GLOBAL bool useRGBW _INIT(false); // SK6812 strips can contain an extra White channel WLED_GLOBAL bool turnOnAtBoot _INIT(true); // turn on LEDs at power-up -WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load after power-up +WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load after power-up -WLED_GLOBAL byte col[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. col[] should be updated if you want to change the color. -WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color -WLED_GLOBAL byte briS _INIT(128); // default brightness +WLED_GLOBAL byte col[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. col[] should be updated if you want to change the color. +WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color +WLED_GLOBAL byte briS _INIT(128); // default brightness WLED_GLOBAL byte nightlightTargetBri _INIT(0); // brightness after nightlight is over WLED_GLOBAL byte nightlightDelayMins _INIT(60); @@ -189,52 +195,52 @@ WLED_GLOBAL bool skipFirstLed _INIT(false); // ignore first LED in strip WLED_GLOBAL byte briMultiplier _INIT(100); // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) // User Interface CONFIG -WLED_GLOBAL char serverDescription[33] _INIT("WLED"); // Name of module -WLED_GLOBAL bool syncToggleReceive _INIT(false); // UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise +WLED_GLOBAL char serverDescription[33] _INIT("WLED"); // Name of module +WLED_GLOBAL bool syncToggleReceive _INIT(false); // UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise // Sync CONFIG -WLED_GLOBAL bool buttonEnabled _INIT(true); -WLED_GLOBAL byte irEnabled _INIT(0); // Infrared receiver +WLED_GLOBAL bool buttonEnabled _INIT(true); +WLED_GLOBAL byte irEnabled _INIT(0); // Infrared receiver -WLED_GLOBAL uint16_t udpPort _INIT(21324); // WLED notifier default port -WLED_GLOBAL uint16_t udpRgbPort _INIT(19446); // Hyperion port +WLED_GLOBAL uint16_t udpPort _INIT(21324); // WLED notifier default port +WLED_GLOBAL uint16_t udpRgbPort _INIT(19446); // Hyperion port -WLED_GLOBAL bool receiveNotificationBrightness _INIT(true); // apply brightness from incoming notifications -WLED_GLOBAL bool receiveNotificationColor _INIT(true); // apply color -WLED_GLOBAL bool receiveNotificationEffects _INIT(true); // apply effects setup -WLED_GLOBAL bool notifyDirect _INIT(false); // send notification if change via UI or HTTP API -WLED_GLOBAL bool notifyButton _INIT(false); // send if updated by button or infrared remote -WLED_GLOBAL bool notifyAlexa _INIT(false); // send notification if updated via Alexa -WLED_GLOBAL bool notifyMacro _INIT(false); // send notification for macro -WLED_GLOBAL bool notifyHue _INIT(true); // send notification if Hue light changes -WLED_GLOBAL bool notifyTwice _INIT(false); // notifications use UDP: enable if devices don't sync reliably +WLED_GLOBAL bool receiveNotificationBrightness _INIT(true); // apply brightness from incoming notifications +WLED_GLOBAL bool receiveNotificationColor _INIT(true); // apply color +WLED_GLOBAL bool receiveNotificationEffects _INIT(true); // apply effects setup +WLED_GLOBAL bool notifyDirect _INIT(false); // send notification if change via UI or HTTP API +WLED_GLOBAL bool notifyButton _INIT(false); // send if updated by button or infrared remote +WLED_GLOBAL bool notifyAlexa _INIT(false); // send notification if updated via Alexa +WLED_GLOBAL bool notifyMacro _INIT(false); // send notification for macro +WLED_GLOBAL bool notifyHue _INIT(true); // send notification if Hue light changes +WLED_GLOBAL bool notifyTwice _INIT(false); // notifications use UDP: enable if devices don't sync reliably -WLED_GLOBAL bool alexaEnabled _INIT(true); // enable device discovery by Amazon Echo -WLED_GLOBAL char alexaInvocationName[33] _INIT("Light"); // speech control name of device. Choose something voice-to-text can understand +WLED_GLOBAL bool alexaEnabled _INIT(true); // enable device discovery by Amazon Echo +WLED_GLOBAL char alexaInvocationName[33] _INIT("Light"); // speech control name of device. Choose something voice-to-text can understand -WLED_GLOBAL char blynkApiKey[36] _INIT(""); // Auth token for Blynk server. If empty, no connection will be made +WLED_GLOBAL char blynkApiKey[36] _INIT(""); // Auth token for Blynk server. If empty, no connection will be made -WLED_GLOBAL uint16_t realtimeTimeoutMs _INIT(2500); // ms timeout of realtime mode before returning to normal mode -WLED_GLOBAL int arlsOffset _INIT(0); // realtime LED offset -WLED_GLOBAL bool receiveDirect _INIT(true); // receive UDP realtime -WLED_GLOBAL bool arlsDisableGammaCorrection _INIT(true); // activate if gamma correction is handled by the source -WLED_GLOBAL bool arlsForceMaxBri _INIT(false); // enable to force max brightness if source has very dark colors that would be black +WLED_GLOBAL uint16_t realtimeTimeoutMs _INIT(2500); // ms timeout of realtime mode before returning to normal mode +WLED_GLOBAL int arlsOffset _INIT(0); // realtime LED offset +WLED_GLOBAL bool receiveDirect _INIT(true); // receive UDP realtime +WLED_GLOBAL bool arlsDisableGammaCorrection _INIT(true); // activate if gamma correction is handled by the source +WLED_GLOBAL bool arlsForceMaxBri _INIT(false); // enable to force max brightness if source has very dark colors that would be black -WLED_GLOBAL uint16_t e131Universe _INIT(1); // settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -WLED_GLOBAL byte DMXMode _INIT(DMX_MODE_MULTIPLE_RGB); // DMX mode (s.a.) -WLED_GLOBAL uint16_t DMXAddress _INIT(1); // DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] -WLED_GLOBAL byte DMXOldDimmer _INIT(0); // only update brightness on change -WLED_GLOBAL byte e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; // to detect packet loss -WLED_GLOBAL bool e131Multicast _INIT(false); // multicast or unicast -WLED_GLOBAL bool e131SkipOutOfSequence _INIT(false); // freeze instead of flickering +WLED_GLOBAL uint16_t e131Universe _INIT(1); // settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) +WLED_GLOBAL byte DMXMode _INIT(DMX_MODE_MULTIPLE_RGB); // DMX mode (s.a.) +WLED_GLOBAL uint16_t DMXAddress _INIT(1); // DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +WLED_GLOBAL byte DMXOldDimmer _INIT(0); // only update brightness on change +WLED_GLOBAL byte e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; // to detect packet loss +WLED_GLOBAL bool e131Multicast _INIT(false); // multicast or unicast +WLED_GLOBAL bool e131SkipOutOfSequence _INIT(false); // freeze instead of flickering WLED_GLOBAL bool mqttEnabled _INIT(false); -WLED_GLOBAL char mqttDeviceTopic[33] _INIT(""); // main MQTT topic (individual per device, default is wled/mac) -WLED_GLOBAL char mqttGroupTopic[33] _INIT("wled/all"); // second MQTT topic (for example to group devices) -WLED_GLOBAL char mqttServer[33] _INIT(""); // both domains and IPs should work (no SSL) -WLED_GLOBAL char mqttUser[41] _INIT(""); // optional: username for MQTT auth -WLED_GLOBAL char mqttPass[41] _INIT(""); // optional: password for MQTT auth -WLED_GLOBAL char mqttClientID[41] _INIT(""); // override the client ID +WLED_GLOBAL char mqttDeviceTopic[33] _INIT(""); // main MQTT topic (individual per device, default is wled/mac) +WLED_GLOBAL char mqttGroupTopic[33] _INIT("wled/all"); // second MQTT topic (for example to group devices) +WLED_GLOBAL char mqttServer[33] _INIT(""); // both domains and IPs should work (no SSL) +WLED_GLOBAL char mqttUser[41] _INIT(""); // optional: username for MQTT auth +WLED_GLOBAL char mqttPass[41] _INIT(""); // optional: password for MQTT auth +WLED_GLOBAL char mqttClientID[41] _INIT(""); // override the client ID WLED_GLOBAL uint16_t mqttPort _INIT(1883); WLED_GLOBAL bool huePollingEnabled _INIT(false); // poll hue bridge for light state @@ -255,30 +261,30 @@ WLED_GLOBAL int utcOffsetSecs _INIT(0); // Seconds to offset from UTC WLED_GLOBAL byte overlayDefault _INIT(0); // 0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie WLED_GLOBAL byte overlayMin _INIT(0), overlayMax _INIT(ledCount - 1); // boundaries of overlay mode -WLED_GLOBAL byte analogClock12pixel _INIT(0); // The pixel in your strip where "midnight" would be -WLED_GLOBAL bool analogClockSecondsTrail _INIT(false); // Display seconds as trail of LEDs instead of a single pixel -WLED_GLOBAL bool analogClock5MinuteMarks _INIT(false); // Light pixels at every 5-minute position +WLED_GLOBAL byte analogClock12pixel _INIT(0); // The pixel in your strip where "midnight" would be +WLED_GLOBAL bool analogClockSecondsTrail _INIT(false); // Display seconds as trail of LEDs instead of a single pixel +WLED_GLOBAL bool analogClock5MinuteMarks _INIT(false); // Light pixels at every 5-minute position WLED_GLOBAL char cronixieDisplay[7] _INIT("HHMMSS"); // Cronixie Display mask. See wled13_cronixie.ino WLED_GLOBAL bool cronixieBacklight _INIT(true); // Allow digits to be back-illuminated WLED_GLOBAL bool countdownMode _INIT(false); // Clock will count down towards date -WLED_GLOBAL byte countdownYear _INIT(20), countdownMonth _INIT(1); // Countdown target date, year is last two digits -WLED_GLOBAL byte countdownDay _INIT(1), countdownHour _INIT(0); -WLED_GLOBAL byte countdownMin _INIT(0), countdownSec _INIT(0); +WLED_GLOBAL byte countdownYear _INIT(20), countdownMonth _INIT(1); // Countdown target date, year is last two digits +WLED_GLOBAL byte countdownDay _INIT(1) , countdownHour _INIT(0); +WLED_GLOBAL byte countdownMin _INIT(0) , countdownSec _INIT(0); WLED_GLOBAL byte macroBoot _INIT(0); // macro loaded after startup -WLED_GLOBAL byte macroNl _INIT(0); // after nightlight delay over +WLED_GLOBAL byte macroNl _INIT(0); // after nightlight delay over WLED_GLOBAL byte macroCountdown _INIT(0); WLED_GLOBAL byte macroAlexaOn _INIT(0), macroAlexaOff _INIT(0); WLED_GLOBAL byte macroButton _INIT(0), macroLongPress _INIT(0), macroDoublePress _INIT(0); // Security CONFIG -WLED_GLOBAL bool otaLock _INIT(false); // prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks -WLED_GLOBAL bool wifiLock _INIT(false); // prevents access to WiFi settings when OTA lock is enabled -WLED_GLOBAL bool aOtaEnabled _INIT(true); // ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on +WLED_GLOBAL bool otaLock _INIT(false); // prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks +WLED_GLOBAL bool wifiLock _INIT(false); // prevents access to WiFi settings when OTA lock is enabled +WLED_GLOBAL bool aOtaEnabled _INIT(true); // ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on -WLED_GLOBAL uint16_t userVar0 _INIT(0), userVar1 _INIT(0); +WLED_GLOBAL uint16_t userVar0 _INIT(0), userVar1 _INIT(0); //available for use in usermod #ifdef WLED_ENABLE_DMX // dmx CONFIG diff --git a/wled00/wled00.ino b/wled00/wled00.ino index f806e5b34..866543ab9 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -1,5 +1,14 @@ /* - * Arduino IDE compatibility file. + * WLED Arduino IDE compatibility file. + * + * Where has everything gone? + * + * In April 2020, the project's structure underwent a major change. + * Global variables are now found in file "wled.h" + * Global function declarations are found in "fcn_declare.h" + * + * Usermod compatibility: Existing wled06_usermod.ino mods should continue to work. Delete usermod.cpp. + * New usermods should use usermod.cpp instead. */ #include "wled.h" From a31da3186f4327c37a0baf23d38774cb40cb89c4 Mon Sep 17 00:00:00 2001 From: Bukovina Date: Wed, 8 Apr 2020 08:35:32 -0400 Subject: [PATCH 146/509] UserMod files update --- usermods/Enclosure_with_OLED_temp_ESP07/readme.md | 2 ++ .../{wled06_usermod.ino => usermod.cpp} | 2 ++ usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md | 1 + .../{wled06_usermod.ino => usermod.cpp} | 2 ++ 4 files changed, 7 insertions(+) rename usermods/Enclosure_with_OLED_temp_ESP07/{wled06_usermod.ino => usermod.cpp} (99%) rename usermods/Wemos_D1_mini+Wemos32_mini_shield/{wled06_usermod.ino => usermod.cpp} (99%) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index 817fb7e4a..f39cece6d 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -1,5 +1,7 @@ # Almost universal controller board for outdoor applications This usermod is using ideas from @mrVanboy and @400killer + +Installation of file: Copy and replace file in wled00 directory ## Project repository - [Original repository](https://github.com/srg74/Controller-for-WLED-firmware) - Main controller repository ## Features diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino b/usermods/Enclosure_with_OLED_temp_ESP07/usermod.cpp similarity index 99% rename from usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino rename to usermods/Enclosure_with_OLED_temp_ESP07/usermod.cpp index 99d155ca6..9724a1b7b 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino +++ b/usermods/Enclosure_with_OLED_temp_ESP07/usermod.cpp @@ -1,3 +1,5 @@ +#include "wled.h" +#include #include // from https://github.com/olikraus/u8g2/ #include //Dallastemperature sensor //The SCL and SDA pins are defined here. diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md index 765e56831..39bc8148b 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -1,4 +1,5 @@ # Wemos D1 mini and Wemos32 mini shield +- Installation of file: Copy and replace file in wled00 directory - Added third choice of controller Heltec WiFi-Kit-8. Totally DIY but with OLED display. ## Project repository - [Original repository](https://github.com/srg74/WLED-wemos-shield) - WLED Wemos shield repository diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino b/usermods/Wemos_D1_mini+Wemos32_mini_shield/usermod.cpp similarity index 99% rename from usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino rename to usermods/Wemos_D1_mini+Wemos32_mini_shield/usermod.cpp index d75cf0a74..579fbfe49 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/wled06_usermod.ino +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/usermod.cpp @@ -1,3 +1,5 @@ +#include "wled.h" +#include #include // from https://github.com/olikraus/u8g2/ #include //Dallastemperature sensor #ifdef ARDUINO_ARCH_ESP32 //ESP32 boards From 88b67b9541d9b67f886f005cb406080f3a695893 Mon Sep 17 00:00:00 2001 From: Bukovina Date: Wed, 8 Apr 2020 08:40:44 -0400 Subject: [PATCH 147/509] Usermod changes --- .../Enclosure_with_OLED_temp_ESP07/readme.md | 5 +++++ .../readme.md | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index f39cece6d..b90beefec 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -27,6 +27,11 @@ Uncomment `U8g2@~2.27.3`,`DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[com ```ini # platformio.ini ... +[platformio] +... +; default_envs = esp01_1m_full +default_envs = esp07 +... [common] ... lib_deps_external = diff --git a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md index 39bc8148b..53405a5e7 100644 --- a/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md +++ b/usermods/Wemos_D1_mini+Wemos32_mini_shield/readme.md @@ -23,3 +23,25 @@ - SSD1306 128x32 I2C OLED display - DS18B20 (temperature sensor) - Push button (N.O. momentary switch) + +### Platformio requirements +Uncomment `U8g2@~2.27.3`,`DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`: +```ini +# platformio.ini +... +[platformio] +... +; default_envs = esp07 +default_envs = d1_mini +... +[common] +... +lib_deps_external = + ... + #For use SSD1306 OLED display uncomment following + U8g2@~2.27.3 + #For Dallas sensor uncomment following 2 lines + DallasTemperature@~3.8.0 + OneWire@~2.3.5 +... +``` From 5be88dd1880df13c3e4a990724963fc18266b325 Mon Sep 17 00:00:00 2001 From: Bukovina Date: Wed, 8 Apr 2020 09:18:26 -0400 Subject: [PATCH 148/509] QuinLED mod update --- platformio.ini | 2 +- .../{readme.txt => readme.md} | 33 +++++++++++++++++-- .../{wled06_usermod.ino => usermod.cpp} | 2 ++ 3 files changed, 33 insertions(+), 4 deletions(-) rename usermods/QuinLED_Dig_Uno_Temp_MQTT/{readme.txt => readme.md} (55%) rename usermods/QuinLED_Dig_Uno_Temp_MQTT/{wled06_usermod.ino => usermod.cpp} (97%) diff --git a/platformio.ini b/platformio.ini index 91bdd8675..5530f9a28 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,7 +30,7 @@ default_envs = d1_mini, esp01, esp01_1m_ota, esp32dev ; default_envs = d1_mini ; default_envs = heltec_wifi_kit_8 ; default_envs = d1_mini_debug -; default_envs = esp32dev +default_envs = esp32dev ; default_envs = esp8285_4CH_MagicHome ; default_envs = esp8285_4CH_H801 ; default_envs = esp8285_5CH_H801 diff --git a/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt b/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.md similarity index 55% rename from usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt rename to usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.md index eb8da7ee1..60fc31f73 100644 --- a/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.txt +++ b/usermods/QuinLED_Dig_Uno_Temp_MQTT/readme.md @@ -1,7 +1,34 @@ -These files allow WLED 0.9.1 to report the temp sensor on the Quinled board to MQTT. I use it to report the board temp to Home Assistant via MQTT, so it will send notifications if something happens and the board start to heat up. +# QuinLED Dig Uno board +These files allow WLED 0.9.1 to report the temp sensor on the Quinled board to MQTT. I use it to report the board temp to Home Assistant via MQTT, so it will send notifications if something happens and the board start to heat up. This code uses Aircookie's WLED software. It has a premade file for user modifications. I use it to publish the temperature from the dallas temperature sensor on the Quinled board. The entries for the top of the WLED00 file, initializes the required libraries, and variables for the sensor. The .ino file waits for 60 seconds, and checks to see if the MQTT server is connected (thanks Aircoookie). It then poles the sensor, and published it using the MQTT service already running, using the main topic programmed in the WLED UI. -To install: +Installation of file: Copy and replace file in wled00 directory -Replace the WLED06_usermod.ino file in Aircoookies WLED folder. +## Project link + +* [QuinLED-Dig-Uno](https://quinled.info/2018/09/15/quinled-dig-uno/) - Project link + +### Platformio requirements + +Uncomment `DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`: + +```ini +# platformio.ini +... +[platformio] +... +; default_envs = esp07 +default_envs = d1_mini +... +[common] +... +lib_deps_external = + ... + #For use SSD1306 OLED display uncomment following + U8g2@~2.27.3 + #For Dallas sensor uncomment following 2 lines + DallasTemperature@~3.8.0 + OneWire@~2.3.5 +... +``` diff --git a/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino b/usermods/QuinLED_Dig_Uno_Temp_MQTT/usermod.cpp similarity index 97% rename from usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino rename to usermods/QuinLED_Dig_Uno_Temp_MQTT/usermod.cpp index d4b77ccc1..5b4e2e5c7 100644 --- a/usermods/QuinLED_Dig_Uno_Temp_MQTT/wled06_usermod.ino +++ b/usermods/QuinLED_Dig_Uno_Temp_MQTT/usermod.cpp @@ -1,3 +1,5 @@ +#include +#include "wled.h" //Intiating code for QuinLED Dig-Uno temp sensor //Uncomment Celsius if that is your prefered temperature scale #include //Dallastemperature sensor From b5b1dbfe85bcc9b95fa379b56ec4dfc3ccb6d1a9 Mon Sep 17 00:00:00 2001 From: Bukovina Date: Wed, 8 Apr 2020 09:30:49 -0400 Subject: [PATCH 149/509] Fix platformio.ini --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 5530f9a28..91bdd8675 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,7 +30,7 @@ default_envs = d1_mini, esp01, esp01_1m_ota, esp32dev ; default_envs = d1_mini ; default_envs = heltec_wifi_kit_8 ; default_envs = d1_mini_debug -default_envs = esp32dev +; default_envs = esp32dev ; default_envs = esp8285_4CH_MagicHome ; default_envs = esp8285_4CH_H801 ; default_envs = esp8285_5CH_H801 From 3a84292f82acaa66bb0e1b1565d192fe581cdffc Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Thu, 9 Apr 2020 09:06:44 -0400 Subject: [PATCH 150/509] Update readme.md --- usermods/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usermods/readme.md b/usermods/readme.md index 350212fb8..34ddef0ff 100644 --- a/usermods/readme.md +++ b/usermods/readme.md @@ -1,13 +1,13 @@ ### Usermods -This folder serves as a repository for usermods (custom `wled06_usermod.ino` files)! +This folder serves as a repository for usermods (custom `usermod.cpp` files)! If you have created an usermod that you believe is useful (for example to support a particular sensor, display, feature...), feel free to contribute by opening a pull request! In order for other people to be able to have fun with your usermod, please keep these points in mind: - Create a folder in this folder with a descriptive name (for example `usermod_ds18b20_temp_sensor_mqtt`) -- Include your custom `wled06_usermod.ino` file +- Include your custom `usermod.cpp` file - If your usermod requires changes to other WLED files, please write a `readme.md` outlining the steps one has to take to use the usermod - Create a pull request! - If your feature is useful for the majority of WLED users, I will consider adding it to the base code! From 19945e4ccb77f9ce84a48bec734b5aa626b07b7c Mon Sep 17 00:00:00 2001 From: cschwinne Date: Fri, 10 Apr 2020 12:30:08 +0200 Subject: [PATCH 151/509] Fix DMX compilation --- CHANGELOG.md | 51 +- wled00/FX.cpp | 16 +- wled00/FX.h | 4 +- wled00/FX_fcn.cpp | 12 +- wled00/NpbWrapper.h | 16 +- wled00/{wled12_alexa.ino => alexa.cpp} | 5 +- wled00/{wled16_blynk.ino => blynk.cpp} | 3 + wled00/{wled09_button.ino => button.cpp} | 4 +- wled00/{wled14_colors.ino => colors.cpp} | 9 +- wled00/const.h | 24 +- wled00/dmx.cpp | 67 ++ wled00/e131.cpp | 144 ++++ wled00/fcn_declare.h | 184 ++++++ wled00/file.cpp | 55 ++ wled00/html_other.h | 2 +- wled00/html_settings.h | 17 +- wled00/{wled15_hue.ino => hue.cpp} | 4 + wled00/{wled20_ir.ino => ir.cpp} | 4 +- wled00/{wled19_json.ino => json.cpp} | 22 + wled00/{wled08_led.ino => led.cpp} | 5 +- wled00/{wled17_mqtt.ino => mqtt.cpp} | 2 + wled00/{wled10_ntp.ino => ntp.cpp} | 4 + wled00/{wled13_cronixie.ino => overlay.cpp} | 147 ++++- wled00/{wled03_set.ino => set.cpp} | 18 +- .../src/dependencies/blynk/BlynkSimpleEsp.cpp | 5 + .../src/dependencies/blynk/BlynkSimpleEsp.h | 4 +- wled00/src/dependencies/dmx/ESPDMX.cpp | 106 +++ wled00/src/dependencies/dmx/ESPDMX.h | 31 + .../dependencies/espalexa/EspalexaDevice.h | 2 +- wled00/{wled07_notify.ino => udp.cpp} | 149 +---- wled00/{wled06_usermod.ino => usermod.cpp} | 3 +- wled00/wled.cpp | 458 +++++++++++++ wled00/wled.h | 519 +++++++++++++++ wled00/wled00.ino | 624 +----------------- wled00/wled00.vcxproj | 317 +++------ wled00/wled00.vcxproj.filters | 547 +++++++++------ wled00/wled05_init.ino | 339 ---------- wled00/wled11_ol.ino | 128 ---- wled00/wled21_dmx.ino | 62 -- wled00/{wled01_eeprom.ino => wled_eeprom.cpp} | 19 +- wled00/{wled04_file.ino => wled_serial.cpp} | 46 +- wled00/{wled18_server.ino => wled_server.cpp} | 6 +- wled00/{wled02_xml.ino => xml.cpp} | 5 +- 43 files changed, 2333 insertions(+), 1856 deletions(-) rename wled00/{wled12_alexa.ino => alexa.cpp} (93%) rename wled00/{wled16_blynk.ino => blynk.cpp} (95%) rename wled00/{wled09_button.ino => button.cpp} (97%) rename wled00/{wled14_colors.ino => colors.cpp} (97%) create mode 100644 wled00/dmx.cpp create mode 100644 wled00/e131.cpp create mode 100644 wled00/fcn_declare.h create mode 100644 wled00/file.cpp rename wled00/{wled15_hue.ino => hue.cpp} (99%) rename wled00/{wled20_ir.ino => ir.cpp} (99%) rename wled00/{wled19_json.ino => json.cpp} (97%) rename wled00/{wled08_led.ino => led.cpp} (99%) rename wled00/{wled17_mqtt.ino => mqtt.cpp} (99%) rename wled00/{wled10_ntp.ino => ntp.cpp} (98%) rename wled00/{wled13_cronixie.ino => overlay.cpp} (66%) rename wled00/{wled03_set.ino => set.cpp} (98%) create mode 100644 wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp create mode 100644 wled00/src/dependencies/dmx/ESPDMX.cpp create mode 100644 wled00/src/dependencies/dmx/ESPDMX.h rename wled00/{wled07_notify.ino => udp.cpp} (55%) rename wled00/{wled06_usermod.ino => usermod.cpp} (92%) create mode 100644 wled00/wled.cpp create mode 100644 wled00/wled.h delete mode 100644 wled00/wled05_init.ino delete mode 100644 wled00/wled11_ol.ino delete mode 100644 wled00/wled21_dmx.ino rename wled00/{wled01_eeprom.ino => wled_eeprom.cpp} (97%) rename wled00/{wled04_file.ino => wled_serial.cpp} (55%) rename wled00/{wled18_server.ino => wled_server.cpp} (99%) rename wled00/{wled02_xml.ino => xml.cpp} (99%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d3a466c4..31c22f526 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,43 +2,62 @@ ### Development versions after 0.9.1 release + +#### Build 2004100 + +- Fixed DMX output compilation +- Added DMX start LED setting + +#### Build 2004061 + +- Fixed RBG and BGR getPixelColor (#825) +- Improved formatting + +#### Build 2004060 + +- Consolidated global variables in wled.h + +#### Build 2003300 + +- Major change of project structure from .ino to .cpp and func_declare.h + #### Build 2003262 - - Fixed compilation for Analog LEDs - - Fixed sync settings network port fields too small +- Fixed compilation for Analog LEDs +- Fixed sync settings network port fields too small #### Build 2003261 - - Fixed live preview not displaying whole light if over 255 LEDs +- Fixed live preview not displaying whole light if over 255 LEDs #### Build 2003251 - - Added Pacifica effect (tentative, doesn't yet support other colors) - - Added Atlantica palette - - Fixed ESP32 build of Espalexa +- Added Pacifica effect (tentative, doesn't yet support other colors) +- Added Atlantica palette +- Fixed ESP32 build of Espalexa #### Build 2003222 - - Fixed Alexa Whites on non-RGBW lights (bump Espalexa to 2.4.5) +- Fixed Alexa Whites on non-RGBW lights (bump Espalexa to 2.4.5) #### Build 2003221 - - Moved Cronixie driver from FX library to drawOverlay handler +- Moved Cronixie driver from FX library to drawOverlay handler #### Build 2003211 - - Added custom mapping compile define to FX_fcn.h - - Merged pull request #784 by @TravisDean: Fixed initialization bug when toggling skip first - - Added link to youtube videos by Room31 to readme +- Added custom mapping compile define to FX_fcn.h +- Merged pull request #784 by @TravisDean: Fixed initialization bug when toggling skip first +- Added link to youtube videos by Room31 to readme #### Build 2003141 - - Fixed color of main segment returned in JSON API during transition not being target color (closes #765) - - Fixed arlsLock() being called after pixels set in E1.31 (closes #772) - - Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment) +- Fixed color of main segment returned in JSON API during transition not being target color (closes #765) +- Fixed arlsLock() being called after pixels set in E1.31 (closes #772) +- Fixed HTTP API calls not having an effect if no segment selected (now applies to main segment) #### Build 2003121 - - Created changelog.md - make tracking changes to code easier - - Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection +- Created changelog.md - make tracking changes to code easier +- Merged pull request #766 by @pille: Fix E1.31 out-of sequence detection diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 1e3ec2d98..7230a9b3e 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -601,7 +601,7 @@ uint16_t WS2812FX::mode_hyper_sparkle(void) { } if(random8(5) < 2) { - for(uint16_t i = 0; i < max(1, SEGLEN/3); i++) { + for(uint16_t i = 0; i < MAX(1, SEGLEN/3); i++) { setPixelColor(random16(SEGLEN), SEGCOLOR(1)); } return 20; @@ -1115,7 +1115,7 @@ uint16_t WS2812FX::mode_fireworks() { if (valid1) setPixelColor(SEGENV.aux0 , sv1); if (valid2) setPixelColor(SEGENV.aux1, sv2); - for(uint16_t i=0; i> 1)) == 0) { uint16_t index = random(SEGLEN); setPixelColor(index, color_from_palette(random8(), false, false, 0)); @@ -1162,12 +1162,12 @@ uint16_t WS2812FX::mode_fire_flicker(void) { byte r = (SEGCOLOR(0) >> 16) & 0xFF; byte g = (SEGCOLOR(0) >> 8) & 0xFF; byte b = (SEGCOLOR(0) & 0xFF); - byte lum = (SEGMENT.palette == 0) ? max(w, max(r, max(g, b))) : 255; + byte lum = (SEGMENT.palette == 0) ? MAX(w, MAX(r, MAX(g, b))) : 255; lum /= (((256-SEGMENT.intensity)/16)+1); for(uint16_t i = 0; i < SEGLEN; i++) { byte flicker = random8(lum); if (SEGMENT.palette == 0) { - setPixelColor(i, max(r - flicker, 0), max(g - flicker, 0), max(b - flicker, 0), max(w - flicker, 0)); + setPixelColor(i, MAX(r - flicker, 0), MAX(g - flicker, 0), MAX(b - flicker, 0), MAX(w - flicker, 0)); } else { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, 255 - flicker)); } @@ -1197,7 +1197,7 @@ uint16_t WS2812FX::gradient_base(bool loading) { { val = abs(((i>pp) ? p2:pp) -i); } else { - val = min(abs(pp-i),min(abs(p1-i),abs(p2-i))); + val = MIN(abs(pp-i),MIN(abs(p1-i),abs(p2-i))); } val = (brd > val) ? val/brd * 255 : 255; setPixelColor(i, color_blend(SEGCOLOR(0), color_from_palette(i, true, PALETTE_SOLID_WRAP, 1), val)); @@ -1778,7 +1778,7 @@ uint16_t WS2812FX::mode_fire_2012() // Step 4. Map from heat cells to LED colors for (uint16_t j = 0; j < SEGLEN; j++) { - CRGB color = ColorFromPalette(currentPalette, min(heat[j],240), 255, LINEARBLEND); + CRGB color = ColorFromPalette(currentPalette, MIN(heat[j],240), 255, LINEARBLEND); setPixelColor(j, color.red, color.green, color.blue); } return FRAMETIME; @@ -2573,7 +2573,7 @@ uint16_t WS2812FX::mode_bouncing_balls(void) { uint32_t color = SEGCOLOR(0); if (SEGMENT.palette) { - color = color_wheel(i*(256/max(numBalls, 8))); + color = color_wheel(i*(256/MAX(numBalls, 8))); } else if (hasCol2) { color = SEGCOLOR(i % NUM_COLORS); } @@ -3101,7 +3101,7 @@ uint16_t WS2812FX::mode_plasma(void) { */ uint16_t WS2812FX::mode_percent(void) { - uint8_t percent = max(0, min(200, SEGMENT.intensity)); + uint8_t percent = MAX(0, MIN(200, SEGMENT.intensity)); uint16_t active_leds = (percent < 100) ? SEGLEN * percent / 100.0 : SEGLEN * (200 - percent) / 100.0; diff --git a/wled00/FX.h b/wled00/FX.h index a87da8e25..a38a1f542 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -38,8 +38,8 @@ #define DEFAULT_SPEED (uint8_t)128 #define DEFAULT_COLOR (uint32_t)0xFFAA00 -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)>(b)?(a):(b)) +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX(a,b) ((a)>(b)?(a):(b)) /* Not used in all effects yet */ #define WLED_FPS 42 diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 055686237..69b8c88a1 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -224,7 +224,7 @@ void WS2812FX::show(void) { if(useWackyWS2815PowerModel) { // ignore white component on WS2815 power calculation - powerSum += (max(max(c.R,c.G),c.B)) * 3; + powerSum += (MAX(MAX(c.R,c.G),c.B)) * 3; } else { @@ -412,8 +412,8 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811 case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG - case 3: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //3 = RBG - case 4: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //4 = BGR + case 3: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //3 = RBG + case 4: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //4 = BGR case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR } return 0; @@ -647,7 +647,7 @@ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) { r = random8(); x = abs(pos - r); y = 255 - x; - d = min(x, y); + d = MIN(x, y); } return r; } @@ -730,8 +730,8 @@ void WS2812FX::handle_palette(void) CHSV prim_hsv = rgb2hsv_approximate(prim); targetPalette = CRGBPalette16( CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v), //color itself - CHSV(prim_hsv.h, max(prim_hsv.s - 50,0), prim_hsv.v), //less saturated - CHSV(prim_hsv.h, prim_hsv.s, max(prim_hsv.v - 50,0)), //darker + CHSV(prim_hsv.h, MAX(prim_hsv.s - 50,0), prim_hsv.v), //less saturated + CHSV(prim_hsv.h, prim_hsv.s, MAX(prim_hsv.v - 50,0)), //darker CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v)); //color itself break;} case 4: {//primary + secondary diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 673d82492..6e58b7197 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -9,6 +9,7 @@ //#define USE_APA102 // Uncomment for using APA102 LEDs. //#define USE_WS2801 // Uncomment for using WS2801 LEDs (make sure you have NeoPixelBus v2.5.6 or newer) //#define USE_LPD8806 // Uncomment for using LPD8806 +//#define USE_P9813 // Uncomment for using P9813 LEDs (make sure you have NeoPixelBus v2.5.8 or newer) //#define WLED_USE_ANALOG_LEDS //Uncomment for using "dumb" PWM controlled LEDs (see pins below, default R: gpio5, G: 12, B: 15, W: 13) //#define WLED_USE_H801 //H801 controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well //#define WLED_USE_5CH_LEDS //5 Channel H801 for cold and warm white @@ -35,7 +36,7 @@ //END CONFIGURATION -#if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) +#if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) #define CLKPIN 0 #define DATAPIN 2 #if BTNPIN == CLKPIN || BTNPIN == DATAPIN @@ -73,6 +74,8 @@ #define PIXELMETHOD NeoWs2801Method #elif defined(USE_LPD8806) #define PIXELMETHOD Lpd8806Method + #elif defined(USE_P9813) + #define PIXELMETHOD P9813Method #else #define PIXELMETHOD NeoEsp32Rmt0Ws2812xMethod #endif @@ -84,6 +87,8 @@ #define PIXELMETHOD NeoWs2801Method #elif defined(USE_LPD8806) #define PIXELMETHOD Lpd8806Method + #elif defined(USE_P9813) + #define PIXELMETHOD P9813Method #elif LEDPIN == 2 #define PIXELMETHOD NeoEsp8266Uart1Ws2813Method //if you get an error here, try to change to NeoEsp8266UartWs2813Method or update Neopixelbus #elif LEDPIN == 3 @@ -101,7 +106,10 @@ #define PIXELFEATURE4 DotStarLbgrFeature #elif defined(USE_LPD8806) #define PIXELFEATURE3 Lpd8806GrbFeature - #define PIXELFEATURE4 Lpd8806GrbFeature + #define PIXELFEATURE4 Lpd8806GrbFeature +#elif defined(USE_P9813) + #define PIXELFEATURE3 P9813BgrFeature + #define PIXELFEATURE4 NeoGrbwFeature #else #define PIXELFEATURE3 NeoGrbFeature #define PIXELFEATURE4 NeoGrbwFeature @@ -143,7 +151,7 @@ public: switch (_type) { case NeoPixelType_Grb: - #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) + #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) _pGrb = new NeoPixelBrightnessBus(countPixels, CLKPIN, DATAPIN); #else _pGrb = new NeoPixelBrightnessBus(countPixels, LEDPIN); @@ -152,7 +160,7 @@ public: break; case NeoPixelType_Grbw: - #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) + #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) _pGrbw = new NeoPixelBrightnessBus(countPixels, CLKPIN, DATAPIN); #else _pGrbw = new NeoPixelBrightnessBus(countPixels, LEDPIN); diff --git a/wled00/wled12_alexa.ino b/wled00/alexa.cpp similarity index 93% rename from wled00/wled12_alexa.ino rename to wled00/alexa.cpp index 5163640e2..c9f61ff23 100644 --- a/wled00/wled12_alexa.ino +++ b/wled00/alexa.cpp @@ -1,10 +1,13 @@ +#include "wled.h" + /* - * Alexa Voice On/Off/Brightness Control. Emulates a Philips Hue bridge to Alexa. + * Alexa Voice On/Off/Brightness/Color Control. Emulates a Philips Hue bridge to Alexa. * * This was put together from these two excellent projects: * https://github.com/kakopappa/arduino-esp8266-alexa-wemo-switch * https://github.com/probonopd/ESP8266HueEmulator */ +#include "src/dependencies/espalexa/EspalexaDevice.h" #ifndef WLED_DISABLE_ALEXA void onAlexaChange(EspalexaDevice* dev); diff --git a/wled00/wled16_blynk.ino b/wled00/blynk.cpp similarity index 95% rename from wled00/wled16_blynk.ino rename to wled00/blynk.cpp index ea4d68771..39b43ba80 100644 --- a/wled00/wled16_blynk.ino +++ b/wled00/blynk.cpp @@ -1,3 +1,6 @@ +#include "wled.h" +#include "src/dependencies/blynk/Blynk/BlynkHandlers.h" + /* * Remote light control with the free Blynk app */ diff --git a/wled00/wled09_button.ino b/wled00/button.cpp similarity index 97% rename from wled00/wled09_button.ino rename to wled00/button.cpp index 1cd868bec..e71cce965 100644 --- a/wled00/wled09_button.ino +++ b/wled00/button.cpp @@ -1,3 +1,5 @@ +#include "wled.h" + /* * Physical IO */ @@ -44,7 +46,7 @@ void handleButton() if (dur > 6000) //long press { - initAP(true); + WLED::instance().initAP(true); } else if (!buttonLongPressed) { //short press if (macroDoublePress) diff --git a/wled00/wled14_colors.ino b/wled00/colors.cpp similarity index 97% rename from wled00/wled14_colors.ino rename to wled00/colors.cpp index a1db307ae..f76499a01 100644 --- a/wled00/wled14_colors.ino +++ b/wled00/colors.cpp @@ -1,3 +1,5 @@ +#include "wled.h" + /* * Color conversion methods */ @@ -18,7 +20,7 @@ void colorFromUint32(uint32_t in, bool secondary) } //load a color without affecting the white channel -void colorFromUint24(uint32_t in, bool secondary = false) +void colorFromUint24(uint32_t in, bool secondary) { if (secondary) { colSec[0] = in >> 16 & 0xFF; @@ -32,7 +34,7 @@ void colorFromUint24(uint32_t in, bool secondary = false) } //relatively change white brightness, minumum A=5 -void relativeChangeWhite(int8_t amount, byte lowerBoundary =0) +void relativeChangeWhite(int8_t amount, byte lowerBoundary) { int16_t new_val = (int16_t) col[3] + amount; if (new_val > 0xFF) new_val = 0xFF; @@ -149,7 +151,8 @@ void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.develo xy[0] = X / (X + Y + Z); xy[1] = Y / (X + Y + Z); } -#endif +#endif // WLED_DISABLE_HUESYNC + void colorFromDecOrHexString(byte* rgb, char* in) { diff --git a/wled00/const.h b/wled00/const.h index 21be19536..173d7e7d5 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -1,5 +1,9 @@ -#ifndef wled_const_h -#define wled_const_h +#ifndef WLED_CONST_H +#define WLED_CONST_H + +/* + * Readability defines and their associated numerical values + compile-time constants + */ //Defaults #define DEFAULT_CLIENT_SSID "Your_Network" @@ -72,4 +76,20 @@ #define HUE_ERROR_TIMEOUT 251 #define HUE_ERROR_ACTIVE 255 +//EEPROM size +#define EEPSIZE 2560 //Maximum is 4096 + +#define NTP_PACKET_SIZE 48 + +// maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue +#define MAX_LEDS 1500 +#define MAX_LEDS_DMA 500 + +// string temp buffer (now stored in stack locally) +#define OMAX 2048 + +#define E131_MAX_UNIVERSE_COUNT 9 + +#define ABL_MILLIAMPS_DEFAULT 850; // auto lower brightness to stay close to milliampere limit + #endif diff --git a/wled00/dmx.cpp b/wled00/dmx.cpp new file mode 100644 index 000000000..ccd3b0643 --- /dev/null +++ b/wled00/dmx.cpp @@ -0,0 +1,67 @@ +#include "wled.h" + +/* + * Support for DMX via MAX485. + * Change the output pin in src/dependencies/ESPDMX.cpp if needed. + * Library from: + * https://github.com/Rickgg/ESP-Dmx + */ + +#ifdef WLED_ENABLE_DMX +#include "src/dependencies/dmx/ESPDMX.h" +DMXESPSerial dmx; + +void handleDMX() +{ + // TODO: calculate brightness manually if no shutter channel is set + + uint8_t brightness = strip.getBrightness(); + + for (int i = DMXStartLED; i < ledCount; i++) { // uses the amount of LEDs as fixture count + + uint32_t in = strip.getPixelColor(i); // get the colors for the individual fixtures as suggested by Aircoookie in issue #462 + byte w = in >> 24 & 0xFF; + byte r = in >> 16 & 0xFF; + byte g = in >> 8 & 0xFF; + byte b = in & 0xFF; + + int DMXFixtureStart = DMXStart + (DMXGap * (i - DMXStartLED)); + for (int j = 0; j < DMXChannels; j++) { + int DMXAddr = DMXFixtureStart + j; + switch (DMXFixtureMap[j]) { + case 0: // Set this channel to 0. Good way to tell strobe- and fade-functions to fuck right off. + dmx.write(DMXAddr, 0); + break; + case 1: // Red + dmx.write(DMXAddr, r); + break; + case 2: // Green + dmx.write(DMXAddr, g); + break; + case 3: // Blue + dmx.write(DMXAddr, b); + break; + case 4: // White + dmx.write(DMXAddr, w); + break; + case 5: // Shutter channel. Controls the brightness. + dmx.write(DMXAddr, brightness); + break; + case 6: // Sets this channel to 255. Like 0, but more wholesome. + dmx.write(DMXAddr, 255); + break; + } + } + } + + dmx.update(); // update the DMX bus +} + +void initDMX() { + dmx.init(512); // initialize with bus length +} + +#else +void handleDMX() {} +void initDMX() {} +#endif diff --git a/wled00/e131.cpp b/wled00/e131.cpp new file mode 100644 index 000000000..2034f84d9 --- /dev/null +++ b/wled00/e131.cpp @@ -0,0 +1,144 @@ +#include "wled.h" + +/* + * E1.31 handler + */ + +void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ + //E1.31 protocol support + + uint16_t uni = htons(p->universe); + uint8_t previousUniverses = uni - e131Universe; + uint16_t possibleLEDsInCurrentUniverse; + uint16_t dmxChannels = htons(p->property_value_count) -1; + + // only listen for universes we're handling & allocated memory + if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return; + + if (e131SkipOutOfSequence) + if (p->sequence_number < e131LastSequenceNumber[uni-e131Universe] && p->sequence_number > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){ + DEBUG_PRINT("skipping E1.31 frame (last seq="); + DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]); + DEBUG_PRINT(", current seq="); + DEBUG_PRINT(p->sequence_number); + DEBUG_PRINT(", universe="); + DEBUG_PRINT(uni); + DEBUG_PRINTLN(")"); + return; + } + e131LastSequenceNumber[uni-e131Universe] = p->sequence_number; + + // update status info + realtimeIP = clientIP; + + switch (DMXMode) { + case DMX_MODE_DISABLED: + return; // nothing to do + break; + + case DMX_MODE_SINGLE_RGB: + if (uni != e131Universe) return; + if (dmxChannels-DMXAddress+1 < 3) return; + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); + for (uint16_t i = 0; i < ledCount; i++) + setRealtimePixel(i, p->property_values[DMXAddress+0], p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], 0); + break; + + case DMX_MODE_SINGLE_DRGB: + if (uni != e131Universe) return; + if (dmxChannels-DMXAddress+1 < 4) return; + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); + if (DMXOldDimmer != p->property_values[DMXAddress+0]) { + DMXOldDimmer = p->property_values[DMXAddress+0]; + bri = p->property_values[DMXAddress+0]; + strip.setBrightness(bri); + } + for (uint16_t i = 0; i < ledCount; i++) + setRealtimePixel(i, p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], p->property_values[DMXAddress+3], 0); + break; + + case DMX_MODE_EFFECT: + if (uni != e131Universe) return; + if (dmxChannels-DMXAddress+1 < 11) return; + if (DMXOldDimmer != p->property_values[DMXAddress+0]) { + DMXOldDimmer = p->property_values[DMXAddress+0]; + bri = p->property_values[DMXAddress+0]; + } + if (p->property_values[DMXAddress+1] < MODE_COUNT) + effectCurrent = p->property_values[DMXAddress+ 1]; + effectSpeed = p->property_values[DMXAddress+ 2]; // flickers + effectIntensity = p->property_values[DMXAddress+ 3]; + effectPalette = p->property_values[DMXAddress+ 4]; + col[0] = p->property_values[DMXAddress+ 5]; + col[1] = p->property_values[DMXAddress+ 6]; + col[2] = p->property_values[DMXAddress+ 7]; + colSec[0] = p->property_values[DMXAddress+ 8]; + colSec[1] = p->property_values[DMXAddress+ 9]; + colSec[2] = p->property_values[DMXAddress+10]; + if (dmxChannels-DMXAddress+1 > 11) + { + col[3] = p->property_values[DMXAddress+11]; //white + colSec[3] = p->property_values[DMXAddress+12]; + } + transitionDelayTemp = 0; // act fast + colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); // don't send UDP + return; // don't activate realtime live mode + break; + + case DMX_MODE_MULTIPLE_RGB: + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); + if (previousUniverses == 0) { + // first universe of this fixture + possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3; + for (uint16_t i = 0; i < ledCount; i++) { + if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) + setRealtimePixel(i, p->property_values[DMXAddress+i*3+0], p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], 0); + } + } else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) { + // additional universe(s) of this fixture + uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe + if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current + possibleLEDsInCurrentUniverse = dmxChannels / 3; + for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) { + uint8_t j = i - numberOfLEDsInPreviousUniverses; + if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) + setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0); + } + } + break; + + case DMX_MODE_MULTIPLE_DRGB: + arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); + if (previousUniverses == 0) { + // first universe of this fixture + if (DMXOldDimmer != p->property_values[DMXAddress+0]) { + DMXOldDimmer = p->property_values[DMXAddress+0]; + bri = p->property_values[DMXAddress+0]; + strip.setBrightness(bri); + } + possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress) / 3; + for (uint16_t i = 0; i < ledCount; i++) { + if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) + setRealtimePixel(i, p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], p->property_values[DMXAddress+i*3+3], 0); + } + } else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) { + // additional universe(s) of this fixture + uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe + if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current + possibleLEDsInCurrentUniverse = dmxChannels / 3; + for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) { + uint8_t j = i - numberOfLEDsInPreviousUniverses; + if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) + setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0); + } + } + break; + + default: + DEBUG_PRINTLN("unknown E1.31 DMX mode"); + return; // nothing to do + break; + } + + e131NewData = true; +} diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h new file mode 100644 index 000000000..7261efcb1 --- /dev/null +++ b/wled00/fcn_declare.h @@ -0,0 +1,184 @@ +#ifndef WLED_FCN_DECLARE_H +#define WLED_FCN_DECLARE_H +#include +#include "src/dependencies/espalexa/EspalexaDevice.h" +#include "src/dependencies/e131/ESPAsyncE131.h" + +/* + * All globally accessible functions are declared here + */ + +//alexa.cpp +void onAlexaChange(EspalexaDevice* dev); +void alexaInit(); +void handleAlexa(); +void onAlexaChange(EspalexaDevice* dev); + +//blynk.cpp +void initBlynk(const char* auth); +void handleBlynk(); +void updateBlynk(); + +//button.cpp +void shortPressAction(); +void handleButton(); +void handleIO(); + +//colors.cpp +void colorFromUint32(uint32_t in, bool secondary = false); +void colorFromUint24(uint32_t in, bool secondary = false); +void relativeChangeWhite(int8_t amount, byte lowerBoundary = 0); +void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb +void colorCTtoRGB(uint16_t mired, byte* rgb); //white spectrum to rgb + +void colorXYtoRGB(float x, float y, byte* rgb); // only defined if huesync disabled TODO +void colorRGBtoXY(byte* rgb, float* xy); // only defined if huesync disabled TODO + +void colorFromDecOrHexString(byte* rgb, char* in); +void colorRGBtoRGBW(byte* rgb); //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY) + +//dmx.cpp +void initDMX(); +void handleDMX(); + +//e131.cpp +void handleE131Packet(e131_packet_t* p, IPAddress clientIP); + +//file.cpp +bool handleFileRead(AsyncWebServerRequest*, String path); + +//hue.cpp +void handleHue(); +void reconnectHue(); +void onHueError(void* arg, AsyncClient* client, int8_t error); +void onHueConnect(void* arg, AsyncClient* client); +void sendHuePoll(); +void onHueData(void* arg, AsyncClient* client, void *data, size_t len); + +//ir.cpp +bool decodeIRCustom(uint32_t code); +void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF); +void changeEffectSpeed(int8_t amount); +void changeEffectIntensity(int8_t amount); +void decodeIR(uint32_t code); +void decodeIR24(uint32_t code); +void decodeIR24OLD(uint32_t code); +void decodeIR24CT(uint32_t code); +void decodeIR40(uint32_t code); +void decodeIR44(uint32_t code); +void decodeIR21(uint32_t code); +void decodeIR6(uint32_t code); + +void initIR(); +void handleIR(); + +//json.cpp +#include "ESPAsyncWebServer.h" +#include "src/dependencies/json/ArduinoJson-v6.h" +#include "src/dependencies/json/AsyncJson-v6.h" +#include "FX.h" +// TODO: AsynicWebServerRequest conflict? + +void deserializeSegment(JsonObject elem, byte it); +bool deserializeState(JsonObject root); +void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id); +void serializeState(JsonObject root); +void serializeInfo(JsonObject root); +void serveJson(AsyncWebServerRequest* request); +void serveLiveLeds(AsyncWebServerRequest* request); + +//led.cpp +void setValuesFromMainSeg(); +void resetTimebase(); +void toggleOnOff(); +void setAllLeds(); +void setLedsStandard(bool justColors = false); +bool colorChanged(); +void colorUpdated(int callMode); +void updateInterfaces(uint8_t callMode); +void handleTransitions(); +void handleNightlight(); + +//mqtt.cpp +bool initMqtt(); +void publishMqtt(); + +//notify.cpp +void notify(byte callMode, bool followUp=false); +void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC); +void handleNotifications(); +void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w); + +//ntp.cpp +void handleNetworkTime(); +void sendNTPPacket(); +bool checkNTPResponse(); +void updateLocalTime(); +void getTimeString(char* out); +bool checkCountdown(); +void setCountdown(); +byte weekdayMondayFirst(); +void checkTimers(); + +//overlay.cpp +void initCronixie(); +void handleOverlays(); +void handleOverlayDraw(); +void _overlayAnalogCountdown(); +void _overlayAnalogClock(); + +byte getSameCodeLength(char code, int index, char const cronixieDisplay[]); +void setCronixie(); +void _overlayCronixie(); +void _drawOverlayCronixie(); + +//set.cpp +void _setRandomColor(bool _sec,bool fromButton=false); +bool isAsterisksOnly(const char* str, byte maxLen); +void handleSettingsSet(AsyncWebServerRequest *request, byte subPage); +bool handleSet(AsyncWebServerRequest *request, const String& req); +int getNumVal(const String* req, uint16_t pos); +bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255); + +//usermod.cpp +void userSetup(); +void userConnected(); +void userLoop(); + +//wled_eeprom.cpp +void commit(); +void clearEEPROM(); +void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len); +void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len); +void saveSettingsToEEPROM(); +void loadSettingsFromEEPROM(bool first); +void savedToPresets(); +bool applyPreset(byte index, bool loadBri = true); +void savePreset(byte index, bool persist = true); +void loadMacro(byte index, char* m); +void applyMacro(byte index); +void saveMacro(byte index, String mc, bool persist = true); //only commit on single save, not in settings + +//wled_serial.cpp +void handleSerial(); + +//wled_server.cpp +bool isIp(String str); +bool captivePortal(AsyncWebServerRequest *request); +void initServer(); +void serveIndexOrWelcome(AsyncWebServerRequest *request); +void serveIndex(AsyncWebServerRequest* request); +String msgProcessor(const String& var); +void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255); +String settingsProcessor(const String& var); +String dmxProcessor(const String& var); +void serveSettings(AsyncWebServerRequest* request); + +//xml.cpp +char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr); +char* URL_response(AsyncWebServerRequest *request); +void sappend(char stype, const char* key, int val); +void sappends(char stype, const char* key, char* val); +void getSettingsJS(byte subPage, char* dest); + +#endif diff --git a/wled00/file.cpp b/wled00/file.cpp new file mode 100644 index 000000000..eb0dcb931 --- /dev/null +++ b/wled00/file.cpp @@ -0,0 +1,55 @@ +#include "wled.h" + +/* + * Utility for SPIFFS filesystem + */ + +//filesystem +#ifndef WLED_DISABLE_FILESYSTEM +#include +#ifdef ARDUINO_ARCH_ESP32 +#include "SPIFFS.h" +#endif +#include "SPIFFSEditor.h" +#endif + + +#if !defined WLED_DISABLE_FILESYSTEM && defined WLED_ENABLE_FS_SERVING +//Un-comment any file types you need +String getContentType(AsyncWebServerRequest* request, String filename){ + if(request->hasArg("download")) return "application/octet-stream"; + else if(filename.endsWith(".htm")) return "text/html"; + else if(filename.endsWith(".html")) return "text/html"; +// else if(filename.endsWith(".css")) return "text/css"; +// else if(filename.endsWith(".js")) return "application/javascript"; + else if(filename.endsWith(".json")) return "application/json"; + else if(filename.endsWith(".png")) return "image/png"; +// else if(filename.endsWith(".gif")) return "image/gif"; + else if(filename.endsWith(".jpg")) return "image/jpeg"; + else if(filename.endsWith(".ico")) return "image/x-icon"; +// else if(filename.endsWith(".xml")) return "text/xml"; +// else if(filename.endsWith(".pdf")) return "application/x-pdf"; +// else if(filename.endsWith(".zip")) return "application/x-zip"; +// else if(filename.endsWith(".gz")) return "application/x-gzip"; + return "text/plain"; +} + +bool handleFileRead(AsyncWebServerRequest* request, String path){ + DEBUG_PRINTLN("FileRead: " + path); + if(path.endsWith("/")) path += "index.htm"; + String contentType = getContentType(request, path); + String pathWithGz = path + ".gz"; + if(SPIFFS.exists(pathWithGz)){ + request->send(SPIFFS, pathWithGz, contentType); + return true; + } + if(SPIFFS.exists(path)) { + request->send(SPIFFS, path, contentType); + return true; + } + return false; +} + +#else +bool handleFileRead(AsyncWebServerRequest*, String path){return false;} +#endif diff --git a/wled00/html_other.h b/wled00/html_other.h index e27c64dde..ce36cff48 100644 --- a/wled00/html_other.h +++ b/wled00/html_other.h @@ -1,5 +1,5 @@ /* - * Various pages + * Various web pages */ //USER HTML HERE (/u subpage) diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 7def2314d..fa0195334 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -1,6 +1,6 @@ /* - Settings html -*/ + * Settings html + */ //common CSS of settings pages const char PAGE_settingsCss[] PROGMEM = R"=====()====="; @@ -214,17 +214,12 @@ function S(){GCH(15);GetV();mMap();}function H(){window.open("https://github.com Number of fixtures is taken from LED config page
-channels per fixture (15 max):
-start channel:
-spacing between start channels: [ info ]
+Channels per fixture (15 max):
+Start channel:
+Spacing between start channels: [ info ]

- -If wanting to use DMX together with LEDs. Number of fixtures will also depend on the segment and start LED settings below
-Using these settings, you can position your fixtures anywhere you want on the LED strip
-which segment should DMX use:
-start LED from the above channel from which DMX fixtures should start:
- +DMX fixtures start LED:

channel functions


diff --git a/wled00/wled15_hue.ino b/wled00/hue.cpp similarity index 99% rename from wled00/wled15_hue.ino rename to wled00/hue.cpp index 5f6b8f5bf..77091f63e 100644 --- a/wled00/wled15_hue.ino +++ b/wled00/hue.cpp @@ -1,7 +1,11 @@ +#include "wled.h" + /* * Sync to Philips hue lights */ + #ifndef WLED_DISABLE_HUESYNC + void handleHue() { if (hueReceived) diff --git a/wled00/wled20_ir.ino b/wled00/ir.cpp similarity index 99% rename from wled00/wled20_ir.ino rename to wled00/ir.cpp index 64c131c21..046991db5 100644 --- a/wled00/wled20_ir.ino +++ b/wled00/ir.cpp @@ -1,3 +1,5 @@ +#include "wled.h" + /* * Infrared sensor support for generic 24/40/44 key RGB remotes */ @@ -35,7 +37,7 @@ bool decodeIRCustom(uint32_t code) //relatively change brightness, minumum A=5 -void relativeChange(byte* property, int8_t amount, byte lowerBoundary = 0, byte higherBoundary = 0xFF) +void relativeChange(byte* property, int8_t amount, byte lowerBoundary, byte higherBoundary) { int16_t new_val = (int16_t) *property + amount; if (new_val > higherBoundary) new_val = higherBoundary; diff --git a/wled00/wled19_json.ino b/wled00/json.cpp similarity index 97% rename from wled00/wled19_json.ino rename to wled00/json.cpp index c0e23b4b5..31208bf5b 100644 --- a/wled00/wled19_json.ino +++ b/wled00/json.cpp @@ -1,3 +1,5 @@ +#include "wled.h" + /* * JSON API (De)serialization */ @@ -248,6 +250,26 @@ void serializeState(JsonObject root) } } +//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp +int getSignalQuality(int rssi) +{ + int quality = 0; + + if (rssi <= -100) + { + quality = 0; + } + else if (rssi >= -50) + { + quality = 100; + } + else + { + quality = 2 * (rssi + 100); + } + return quality; +} + void serializeInfo(JsonObject root) { root["ver"] = versionString; diff --git a/wled00/wled08_led.ino b/wled00/led.cpp similarity index 99% rename from wled00/wled08_led.ino rename to wled00/led.cpp index 63009f983..c3f50cc22 100644 --- a/wled00/wled08_led.ino +++ b/wled00/led.cpp @@ -1,6 +1,9 @@ +#include "wled.h" + /* * LED methods */ + void setValuesFromMainSeg() { WS2812FX::Segment& seg = strip.getSegment(strip.getMainSegmentId()); @@ -50,7 +53,7 @@ void setAllLeds() { } -void setLedsStandard(bool justColors = false) +void setLedsStandard(bool justColors) { for (byte i=0; i<4; i++) { diff --git a/wled00/wled17_mqtt.ino b/wled00/mqtt.cpp similarity index 99% rename from wled00/wled17_mqtt.ino rename to wled00/mqtt.cpp index 741c807f8..9c15f5bb3 100644 --- a/wled00/wled17_mqtt.ino +++ b/wled00/mqtt.cpp @@ -1,3 +1,5 @@ +#include "wled.h" + /* * MQTT communication protocol for home automation */ diff --git a/wled00/wled10_ntp.ino b/wled00/ntp.cpp similarity index 98% rename from wled00/wled10_ntp.ino rename to wled00/ntp.cpp index 2c5a64c45..d6332fd2c 100644 --- a/wled00/wled10_ntp.ino +++ b/wled00/ntp.cpp @@ -1,3 +1,6 @@ +#include "src/dependencies/timezone/Timezone.h" +#include "wled.h" + /* * Acquires time from NTP server */ @@ -57,6 +60,7 @@ Timezone tzNK(NKST, NKST); TimeChangeRule IST = {Last, Sun, Mar, 1, 330}; // India Standard Time = UTC + 5.5 hours Timezone tzIndia(IST, IST); +// Pick your timezone from here. Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia, &tzCASaskatchewan}; void handleNetworkTime() diff --git a/wled00/wled13_cronixie.ino b/wled00/overlay.cpp similarity index 66% rename from wled00/wled13_cronixie.ino rename to wled00/overlay.cpp index dd687ca14..ceb6fc209 100644 --- a/wled00/wled13_cronixie.ino +++ b/wled00/overlay.cpp @@ -1,9 +1,141 @@ +#include "wled.h" + +/* + * Used to draw clock overlays over the strip + */ + +void initCronixie() +{ + if (overlayCurrent == 3 && !cronixieInit) + { + setCronixie(); + strip.getSegment(0).grouping = 10; //10 LEDs per digit + cronixieInit = true; + } else if (cronixieInit && overlayCurrent != 3) + { + strip.getSegment(0).grouping = 1; + cronixieInit = false; + } +} + + +void handleOverlays() +{ + if (millis() - overlayRefreshedTime > overlayRefreshMs) + { + initCronixie(); + updateLocalTime(); + checkTimers(); + checkCountdown(); + if (overlayCurrent == 3) _overlayCronixie();//Diamex cronixie clock kit + overlayRefreshedTime = millis(); + } +} + + +void _overlayAnalogClock() +{ + int overlaySize = overlayMax - overlayMin +1; + if (countdownMode) + { + _overlayAnalogCountdown(); return; + } + double hourP = ((double)(hour(local)%12))/12; + double minuteP = ((double)minute(local))/60; + hourP = hourP + minuteP/12; + double secondP = ((double)second(local))/60; + int hourPixel = floor(analogClock12pixel + overlaySize*hourP); + if (hourPixel > overlayMax) hourPixel = overlayMin -1 + hourPixel - overlayMax; + int minutePixel = floor(analogClock12pixel + overlaySize*minuteP); + if (minutePixel > overlayMax) minutePixel = overlayMin -1 + minutePixel - overlayMax; + int secondPixel = floor(analogClock12pixel + overlaySize*secondP); + if (secondPixel > overlayMax) secondPixel = overlayMin -1 + secondPixel - overlayMax; + if (analogClockSecondsTrail) + { + if (secondPixel < analogClock12pixel) + { + strip.setRange(analogClock12pixel, overlayMax, 0xFF0000); + strip.setRange(overlayMin, secondPixel, 0xFF0000); + } else + { + strip.setRange(analogClock12pixel, secondPixel, 0xFF0000); + } + } + if (analogClock5MinuteMarks) + { + int pix; + for (int i = 0; i <= 12; i++) + { + pix = analogClock12pixel + round((overlaySize / 12.0) *i); + if (pix > overlayMax) pix -= overlaySize; + strip.setPixelColor(pix, 0x00FFAA); + } + } + if (!analogClockSecondsTrail) strip.setPixelColor(secondPixel, 0xFF0000); + strip.setPixelColor(minutePixel, 0x00FF00); + strip.setPixelColor(hourPixel, 0x0000FF); + overlayRefreshMs = 998; +} + + +void _overlayAnalogCountdown() +{ + if (now() < countdownTime) + { + long diff = countdownTime - now(); + double pval = 60; + if (diff > 31557600L) //display in years if more than 365 days + { + pval = 315576000L; //10 years + } else if (diff > 2592000L) //display in months if more than a month + { + pval = 31557600L; //1 year + } else if (diff > 604800) //display in weeks if more than a week + { + pval = 2592000L; //1 month + } else if (diff > 86400) //display in days if more than 24 hours + { + pval = 604800; //1 week + } else if (diff > 3600) //display in hours if more than 60 minutes + { + pval = 86400; //1 day + } else if (diff > 60) //display in minutes if more than 60 seconds + { + pval = 3600; //1 hour + } + int overlaySize = overlayMax - overlayMin +1; + double perc = (pval-(double)diff)/pval; + if (perc > 1.0) perc = 1.0; + byte pixelCnt = perc*overlaySize; + if (analogClock12pixel + pixelCnt > overlayMax) + { + strip.setRange(analogClock12pixel, overlayMax, ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]); + strip.setRange(overlayMin, overlayMin +pixelCnt -(1+ overlayMax -analogClock12pixel), ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]); + } else + { + strip.setRange(analogClock12pixel, analogClock12pixel + pixelCnt, ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]); + } + } + overlayRefreshMs = 998; +} + + +void handleOverlayDraw() { + if (!overlayCurrent) return; + switch (overlayCurrent) + { + case 1: _overlayAnalogClock(); break; + case 3: _drawOverlayCronixie(); break; + } +} + + /* * Support for the Cronixie clock */ + #ifndef WLED_DISABLE_CRONIXIE byte _digitOut[6] = {10,10,10,10,10,10}; -#endif byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) { @@ -23,7 +155,6 @@ byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) void setCronixie() { - #ifndef WLED_DISABLE_CRONIXIE /* * digit purpose index * 0-9 | 0-9 (incl. random) @@ -144,12 +275,10 @@ void setCronixie() DEBUG_PRINTLN((int)dP[5]); _overlayCronixie(); //refresh - #endif } void _overlayCronixie() { - #ifndef WLED_DISABLE_CRONIXIE byte h = hour(local); byte h0 = h; byte m = minute(local); @@ -211,12 +340,10 @@ void _overlayCronixie() } } } - #endif } void _drawOverlayCronixie() { - #ifndef WLED_DISABLE_CRONIXIE byte offsets[] = {5, 0, 6, 1, 7, 2, 8, 3, 9, 4}; for (uint16_t i = 0; i < 6; i++) @@ -239,5 +366,11 @@ void _drawOverlayCronixie() } } } - #endif } + +#else // WLED_DISABLE_CRONIXIE +byte getSameCodeLength(char code, int index, char const cronixieDisplay[]) {} +void setCronixie() {} +void _overlayCronixie() {} +void _drawOverlayCronixie() {} +#endif diff --git a/wled00/wled03_set.ino b/wled00/set.cpp similarity index 98% rename from wled00/wled03_set.ino rename to wled00/set.cpp index 088f31ad3..fb7b85967 100644 --- a/wled00/wled03_set.ino +++ b/wled00/set.cpp @@ -1,8 +1,10 @@ +#include "wled.h" + /* * Receives client input */ -void _setRandomColor(bool _sec,bool fromButton=false) +void _setRandomColor(bool _sec,bool fromButton) { lastRandomIndex = strip.get_random_wheel_index(lastRandomIndex); if (_sec){ @@ -305,19 +307,15 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) if (t>0 && t<513) { DMXGap = t; } + t = request->arg("SL").toInt(); + if (t>=0 && t < MAX_LEDS) { + DMXStartLED = t; + } for (int i=0; i<15; i++) { String argname = "CH" + String((i+1)); t = request->arg(argname).toInt(); DMXFixtureMap[i] = t; } - t = request->arg("SEG").toInt(); - if (t>=0 && t<10) { - DMXSegment = t; - } - t = request->arg("SL").toInt(); - if (t>=0 && t<1500) { - DMXStartLED = t; - } } #endif @@ -338,7 +336,7 @@ int getNumVal(const String* req, uint16_t pos) //helper to get int value at a position in string -bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255) +bool updateVal(const String* req, const char* key, byte* val, byte minv, byte maxv) { int pos = req->indexOf(key); if (pos < 1) return false; diff --git a/wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp b/wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp new file mode 100644 index 000000000..60ba109ed --- /dev/null +++ b/wled00/src/dependencies/blynk/BlynkSimpleEsp.cpp @@ -0,0 +1,5 @@ +#include "BlynkSimpleEsp.h" + +WiFiClient _blynkWifiClient; +BlynkArduinoClient _blynkTransport(_blynkWifiClient); +BlynkWifi Blynk(_blynkTransport); \ No newline at end of file diff --git a/wled00/src/dependencies/blynk/BlynkSimpleEsp.h b/wled00/src/dependencies/blynk/BlynkSimpleEsp.h index f6b2a0f1c..6697686fa 100644 --- a/wled00/src/dependencies/blynk/BlynkSimpleEsp.h +++ b/wled00/src/dependencies/blynk/BlynkSimpleEsp.h @@ -89,8 +89,6 @@ public: }; -static WiFiClient _blynkWifiClient; -static BlynkArduinoClient _blynkTransport(_blynkWifiClient); -BlynkWifi Blynk(_blynkTransport); +extern BlynkWifi Blynk; #endif diff --git a/wled00/src/dependencies/dmx/ESPDMX.cpp b/wled00/src/dependencies/dmx/ESPDMX.cpp new file mode 100644 index 000000000..f3ece1c8e --- /dev/null +++ b/wled00/src/dependencies/dmx/ESPDMX.cpp @@ -0,0 +1,106 @@ +// - - - - - +// ESPDMX - A Arduino library for sending and receiving DMX using the builtin serial hardware port. +// ESPDMX.cpp: Library implementation file +// +// Copyright (C) 2015 Rick +// This work is licensed under a GNU style license. +// +// Last change: Marcel Seerig +// +// Documentation and samples are available at https://github.com/Rickgg/ESP-Dmx +// - - - - - + +/* ----- LIBRARIES ----- */ +#include + +#include "ESPDMX.h" + + + +#define dmxMaxChannel 512 +#define defaultMax 32 + +#define DMXSPEED 250000 +#define DMXFORMAT SERIAL_8N2 +#define BREAKSPEED 83333 +#define BREAKFORMAT SERIAL_8N1 + +bool dmxStarted = false; +int sendPin = 2; //dafault on ESP8266 + +//DMX value array and size. Entry 0 will hold startbyte +uint8_t dmxData[dmxMaxChannel] = {}; +int chanSize; + + +void DMXESPSerial::init() { + chanSize = defaultMax; + + Serial1.begin(DMXSPEED); + pinMode(sendPin, OUTPUT); + dmxStarted = true; +} + +// Set up the DMX-Protocol +void DMXESPSerial::init(int chanQuant) { + + if (chanQuant > dmxMaxChannel || chanQuant <= 0) { + chanQuant = defaultMax; + } + + chanSize = chanQuant; + + Serial1.begin(DMXSPEED); + pinMode(sendPin, OUTPUT); + dmxStarted = true; +} + +// Function to read DMX data +uint8_t DMXESPSerial::read(int Channel) { + if (dmxStarted == false) init(); + + if (Channel < 1) Channel = 1; + if (Channel > dmxMaxChannel) Channel = dmxMaxChannel; + return(dmxData[Channel]); +} + +// Function to send DMX data +void DMXESPSerial::write(int Channel, uint8_t value) { + if (dmxStarted == false) init(); + + if (Channel < 1) Channel = 1; + if (Channel > chanSize) Channel = chanSize; + if (value < 0) value = 0; + if (value > 255) value = 255; + + dmxData[Channel] = value; +} + +void DMXESPSerial::end() { + delete dmxData; + chanSize = 0; + Serial1.end(); + dmxStarted == false; +} + +void DMXESPSerial::update() { + if (dmxStarted == false) init(); + + //Send break + digitalWrite(sendPin, HIGH); + Serial1.begin(BREAKSPEED, BREAKFORMAT); + Serial1.write(0); + Serial1.flush(); + delay(1); + Serial1.end(); + + //send data + Serial1.begin(DMXSPEED, DMXFORMAT); + digitalWrite(sendPin, LOW); + Serial1.write(dmxData, chanSize); + Serial1.flush(); + delay(1); + Serial1.end(); +} + +// Function to update the DMX bus diff --git a/wled00/src/dependencies/dmx/ESPDMX.h b/wled00/src/dependencies/dmx/ESPDMX.h new file mode 100644 index 000000000..4585bdd26 --- /dev/null +++ b/wled00/src/dependencies/dmx/ESPDMX.h @@ -0,0 +1,31 @@ +// - - - - - +// ESPDMX - A Arduino library for sending and receiving DMX using the builtin serial hardware port. +// ESPDMX.cpp: Library implementation file +// +// Copyright (C) 2015 Rick +// This work is licensed under a GNU style license. +// +// Last change: Marcel Seerig +// +// Documentation and samples are available at https://github.com/Rickgg/ESP-Dmx +// - - - - - + +#include + + +#ifndef ESPDMX_h +#define ESPDMX_h + +// ---- Methods ---- + +class DMXESPSerial { +public: + void init(); + void init(int MaxChan); + uint8_t read(int Channel); + void write(int channel, uint8_t value); + void update(); + void end(); +}; + +#endif diff --git a/wled00/src/dependencies/espalexa/EspalexaDevice.h b/wled00/src/dependencies/espalexa/EspalexaDevice.h index 0653a4188..4ebdd2b8c 100644 --- a/wled00/src/dependencies/espalexa/EspalexaDevice.h +++ b/wled00/src/dependencies/espalexa/EspalexaDevice.h @@ -1,6 +1,6 @@ #ifndef EspalexaDevice_h #define EspalexaDevice_h - +#include #include "Arduino.h" #include diff --git a/wled00/wled07_notify.ino b/wled00/udp.cpp similarity index 55% rename from wled00/wled07_notify.ino rename to wled00/udp.cpp index 8fcbdbe82..528798034 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/udp.cpp @@ -1,12 +1,13 @@ +#include "wled.h" + /* - * UDP notifier + * UDP sync notifier */ #define WLEDPACKETSIZE 29 #define UDP_IN_MAXSIZE 1472 - -void notify(byte callMode, bool followUp=false) +void notify(byte callMode, bool followUp) { if (!udpConnected) return; switch (callMode) @@ -71,7 +72,7 @@ void notify(byte callMode, bool followUp=false) } -void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC) +void arlsLock(uint32_t timeoutMs, byte md) { if (!realtimeMode){ for (uint16_t i = 0; i < ledCount; i++) @@ -86,146 +87,6 @@ void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC) } -void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ - //E1.31 protocol support - - uint16_t uni = htons(p->universe); - uint8_t previousUniverses = uni - e131Universe; - uint16_t possibleLEDsInCurrentUniverse; - uint16_t dmxChannels = htons(p->property_value_count) -1; - - // only listen for universes we're handling & allocated memory - if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return; - - if (e131SkipOutOfSequence) - if (p->sequence_number < e131LastSequenceNumber[uni-e131Universe] && p->sequence_number > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){ - DEBUG_PRINT("skipping E1.31 frame (last seq="); - DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]); - DEBUG_PRINT(", current seq="); - DEBUG_PRINT(p->sequence_number); - DEBUG_PRINT(", universe="); - DEBUG_PRINT(uni); - DEBUG_PRINTLN(")"); - return; - } - e131LastSequenceNumber[uni-e131Universe] = p->sequence_number; - - // update status info - realtimeIP = clientIP; - - switch (DMXMode) { - case DMX_MODE_DISABLED: - return; // nothing to do - break; - - case DMX_MODE_SINGLE_RGB: - if (uni != e131Universe) return; - if (dmxChannels-DMXAddress+1 < 3) return; - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); - for (uint16_t i = 0; i < ledCount; i++) - setRealtimePixel(i, p->property_values[DMXAddress+0], p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], 0); - break; - - case DMX_MODE_SINGLE_DRGB: - if (uni != e131Universe) return; - if (dmxChannels-DMXAddress+1 < 4) return; - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); - if (DMXOldDimmer != p->property_values[DMXAddress+0]) { - DMXOldDimmer = p->property_values[DMXAddress+0]; - bri = p->property_values[DMXAddress+0]; - strip.setBrightness(bri); - } - for (uint16_t i = 0; i < ledCount; i++) - setRealtimePixel(i, p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], p->property_values[DMXAddress+3], 0); - break; - - case DMX_MODE_EFFECT: - if (uni != e131Universe) return; - if (dmxChannels-DMXAddress+1 < 11) return; - if (DMXOldDimmer != p->property_values[DMXAddress+0]) { - DMXOldDimmer = p->property_values[DMXAddress+0]; - bri = p->property_values[DMXAddress+0]; - } - if (p->property_values[DMXAddress+1] < MODE_COUNT) - effectCurrent = p->property_values[DMXAddress+ 1]; - effectSpeed = p->property_values[DMXAddress+ 2]; // flickers - effectIntensity = p->property_values[DMXAddress+ 3]; - effectPalette = p->property_values[DMXAddress+ 4]; - col[0] = p->property_values[DMXAddress+ 5]; - col[1] = p->property_values[DMXAddress+ 6]; - col[2] = p->property_values[DMXAddress+ 7]; - colSec[0] = p->property_values[DMXAddress+ 8]; - colSec[1] = p->property_values[DMXAddress+ 9]; - colSec[2] = p->property_values[DMXAddress+10]; - if (dmxChannels-DMXAddress+1 > 11) - { - col[3] = p->property_values[DMXAddress+11]; //white - colSec[3] = p->property_values[DMXAddress+12]; - } - transitionDelayTemp = 0; // act fast - colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); // don't send UDP - return; // don't activate realtime live mode - break; - - case DMX_MODE_MULTIPLE_RGB: - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); - if (previousUniverses == 0) { - // first universe of this fixture - possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3; - for (uint16_t i = 0; i < ledCount; i++) { - if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[DMXAddress+i*3+0], p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], 0); - } - } else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) { - // additional universe(s) of this fixture - uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe - if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current - possibleLEDsInCurrentUniverse = dmxChannels / 3; - for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) { - uint8_t j = i - numberOfLEDsInPreviousUniverses; - if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0); - } - } - break; - - case DMX_MODE_MULTIPLE_DRGB: - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); - if (previousUniverses == 0) { - // first universe of this fixture - if (DMXOldDimmer != p->property_values[DMXAddress+0]) { - DMXOldDimmer = p->property_values[DMXAddress+0]; - bri = p->property_values[DMXAddress+0]; - strip.setBrightness(bri); - } - possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress) / 3; - for (uint16_t i = 0; i < ledCount; i++) { - if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], p->property_values[DMXAddress+i*3+3], 0); - } - } else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) { - // additional universe(s) of this fixture - uint16_t numberOfLEDsInPreviousUniverses = ((512 - DMXAddress + 1) / 3); // first universe - if (previousUniverses > 1) numberOfLEDsInPreviousUniverses += (512 / 3) * (previousUniverses - 1); // extended universe(s) before current - possibleLEDsInCurrentUniverse = dmxChannels / 3; - for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) { - uint8_t j = i - numberOfLEDsInPreviousUniverses; - if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0); - } - } - break; - - default: - DEBUG_PRINTLN("unknown E1.31 DMX mode"); - return; // nothing to do - break; - } - - e131NewData = true; -} - - void handleNotifications() { //send second notification if enabled diff --git a/wled00/wled06_usermod.ino b/wled00/usermod.cpp similarity index 92% rename from wled00/wled06_usermod.ino rename to wled00/usermod.cpp index 010d0f386..2c7c881f5 100644 --- a/wled00/wled06_usermod.ino +++ b/wled00/usermod.cpp @@ -1,7 +1,8 @@ +#include "wled.h" /* * This file allows you to add own functionality to WLED more easily * See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality - * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in wled01_eeprom.h) + * EEPROM bytes 2750+ are reserved for your custom use case. (if you extend #define EEPSIZE in const.h) * bytes 2400+ are currently ununsed, but might be used for future wled features */ diff --git a/wled00/wled.cpp b/wled00/wled.cpp new file mode 100644 index 000000000..7f8ef5973 --- /dev/null +++ b/wled00/wled.cpp @@ -0,0 +1,458 @@ +#define WLED_DEFINE_GLOBAL_VARS //only in one source file, wled.cpp! +#include "wled.h" +#include + +/* + * Main WLED class implementation. Mostly initialization and connection logic + */ + +WLED::WLED() +{ +} + +// turns all LEDs off and restarts ESP +void WLED::reset() +{ + briT = 0; + long dly = millis(); + while (millis() - dly < 250) { + yield(); // enough time to send response to client + } + setAllLeds(); + DEBUG_PRINTLN("MODULE RESET"); + ESP.restart(); +} + +bool oappendi(int i) +{ + char s[11]; + sprintf(s, "%ld", i); + return oappend(s); +} + +bool oappend(const char* txt) +{ + uint16_t len = strlen(txt); + if (olen + len >= OMAX) + return false; // buffer full + strcpy(obuf + olen, txt); + olen += len; + return true; +} + +void WLED::loop() +{ + handleIR(); // 2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too + handleConnection(); + handleSerial(); + handleNotifications(); + handleTransitions(); +#ifdef WLED_ENABLE_DMX + handleDMX(); +#endif + userLoop(); + + yield(); + handleIO(); + handleIR(); + handleNetworkTime(); + handleAlexa(); + + handleOverlays(); + yield(); +#ifdef WLED_USE_ANALOG_LEDS + strip.setRgbwPwm(); +#endif + + if (doReboot) + reset(); + + if (!realtimeMode) // block stuff if WARLS/Adalight is enabled + { + if (apActive) + dnsServer.processNextRequest(); +#ifndef WLED_DISABLE_OTA + if (WLED_CONNECTED && aOtaEnabled) + ArduinoOTA.handle(); +#endif + handleNightlight(); + yield(); + + handleHue(); + handleBlynk(); + + yield(); + if (!offMode) + strip.service(); + } + yield(); +#ifdef ESP8266 + MDNS.update(); +#endif + if (millis() - lastMqttReconnectAttempt > 30000) + initMqtt(); + +// DEBUG serial logging +#ifdef WLED_DEBUG + if (millis() - debugTime > 9999) { + DEBUG_PRINTLN("---DEBUG INFO---"); + DEBUG_PRINT("Runtime: "); + DEBUG_PRINTLN(millis()); + DEBUG_PRINT("Unix time: "); + DEBUG_PRINTLN(now()); + DEBUG_PRINT("Free heap: "); + DEBUG_PRINTLN(ESP.getFreeHeap()); + DEBUG_PRINT("Wifi state: "); + DEBUG_PRINTLN(WiFi.status()); + if (WiFi.status() != lastWifiState) { + wifiStateChangedTime = millis(); + } + lastWifiState = WiFi.status(); + DEBUG_PRINT("State time: "); + DEBUG_PRINTLN(wifiStateChangedTime); + DEBUG_PRINT("NTP last sync: "); + DEBUG_PRINTLN(ntpLastSyncTime); + DEBUG_PRINT("Client IP: "); + DEBUG_PRINTLN(WiFi.localIP()); + DEBUG_PRINT("Loops/sec: "); + DEBUG_PRINTLN(loops / 10); + loops = 0; + debugTime = millis(); + } + loops++; +#endif // WLED_DEBU +} + +void WLED::setup() +{ + EEPROM.begin(EEPSIZE); + ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); + if (ledCount > MAX_LEDS || ledCount == 0) + ledCount = 30; + +#ifdef ESP8266 + #if LEDPIN == 3 + if (ledCount > MAX_LEDS_DMA) + ledCount = MAX_LEDS_DMA; // DMA method uses too much ram + #endif +#endif + Serial.begin(115200); + Serial.setTimeout(50); + DEBUG_PRINTLN(); + DEBUG_PRINT("---WLED "); + DEBUG_PRINT(versionString); + DEBUG_PRINT(" "); + DEBUG_PRINT(VERSION); + DEBUG_PRINTLN(" INIT---"); +#ifdef ARDUINO_ARCH_ESP32 + DEBUG_PRINT("esp32 "); + DEBUG_PRINTLN(ESP.getSdkVersion()); +#else + DEBUG_PRINT("esp8266 "); + DEBUG_PRINTLN(ESP.getCoreVersion()); +#endif + int heapPreAlloc = ESP.getFreeHeap(); + DEBUG_PRINT("heap "); + DEBUG_PRINTLN(ESP.getFreeHeap()); + + strip.init(EEPROM.read(372), ledCount, EEPROM.read(2204)); // init LEDs quickly + strip.setBrightness(0); + + DEBUG_PRINT("LEDs inited. heap usage ~"); + DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap()); + +#ifndef WLED_DISABLE_FILESYSTEM + #ifdef ARDUINO_ARCH_ESP32 + SPIFFS.begin(true); + #endif + SPIFFS.begin(); +#endif + + DEBUG_PRINTLN("Load EEPROM"); + loadSettingsFromEEPROM(true); + beginStrip(); + userSetup(); + if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0) + showWelcomePage = true; + WiFi.persistent(false); + + if (macroBoot > 0) + applyMacro(macroBoot); + Serial.println("Ada"); + + // generate module IDs + escapedMac = WiFi.macAddress(); + escapedMac.replace(":", ""); + escapedMac.toLowerCase(); + if (strcmp(cmDNS, "x") == 0) // fill in unique mdns default + { + strcpy(cmDNS, "wled-"); + sprintf(cmDNS + 5, "%*s", 6, escapedMac.c_str() + 6); + } + if (mqttDeviceTopic[0] == 0) { + strcpy(mqttDeviceTopic, "wled/"); + sprintf(mqttDeviceTopic + 5, "%*s", 6, escapedMac.c_str() + 6); + } + if (mqttClientID[0] == 0) { + strcpy(mqttClientID, "WLED-"); + sprintf(mqttClientID + 5, "%*s", 6, escapedMac.c_str() + 6); + } + + strip.service(); + +#ifndef WLED_DISABLE_OTA + if (aOtaEnabled) { + ArduinoOTA.onStart([]() { +#ifdef ESP8266 + wifi_set_sleep_type(NONE_SLEEP_T); +#endif + DEBUG_PRINTLN("Start ArduinoOTA"); + }); + if (strlen(cmDNS) > 0) + ArduinoOTA.setHostname(cmDNS); + } +#endif +#ifdef WLED_ENABLE_DMX + initDMX(); +#endif + // HTTP server page init + initServer(); +} + +void WLED::beginStrip() +{ + // Initialize NeoPixel Strip and button + strip.setShowCallback(handleOverlayDraw); + +#ifdef BTNPIN + pinMode(BTNPIN, INPUT_PULLUP); +#endif + + if (bootPreset > 0) + applyPreset(bootPreset, turnOnAtBoot); + colorUpdated(NOTIFIER_CALL_MODE_INIT); + +// init relay pin +#if RLYPIN >= 0 + pinMode(RLYPIN, OUTPUT); +#if RLYMDE + digitalWrite(RLYPIN, bri); +#else + digitalWrite(RLYPIN, !bri); +#endif +#endif + + // disable button if it is "pressed" unintentionally +#ifdef BTNPIN + if (digitalRead(BTNPIN) == LOW) + buttonEnabled = false; +#else + buttonEnabled = false; +#endif +} + +void WLED::initAP(bool resetAP) +{ + if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) + return; + + if (!apSSID[0] || resetAP) + strcpy(apSSID, "WLED-AP"); + if (resetAP) + strcpy(apPass, DEFAULT_AP_PASS); + DEBUG_PRINT("Opening access point "); + DEBUG_PRINTLN(apSSID); + WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0)); + WiFi.softAP(apSSID, apPass, apChannel, apHide); + + if (!apActive) // start captive portal if AP active + { + DEBUG_PRINTLN("Init AP interfaces"); + server.begin(); + if (udpPort > 0 && udpPort != ntpLocalPort) { + udpConnected = notifierUdp.begin(udpPort); + } + if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) { + udpRgbConnected = rgbUdp.begin(udpRgbPort); + } + + dnsServer.setErrorReplyCode(DNSReplyCode::NoError); + dnsServer.start(53, "*", WiFi.softAPIP()); + } + apActive = true; +} + +void WLED::initConnection() +{ + WiFi.disconnect(); // close old connections +#ifdef ESP8266 + WiFi.setPhyMode(WIFI_PHY_MODE_11N); +#endif + + if (staticIP[0] != 0 && staticGateway[0] != 0) { + WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8, 8, 8, 8)); + } else { + WiFi.config(0U, 0U, 0U); + } + + lastReconnectAttempt = millis(); + + if (!WLED_WIFI_CONFIGURED) { + DEBUG_PRINT("No connection configured. "); + if (!apActive) + initAP(); // instantly go to ap mode + return; + } else if (!apActive) { + if (apBehavior == AP_BEHAVIOR_ALWAYS) { + initAP(); + } else { + DEBUG_PRINTLN("Access point disabled."); + WiFi.softAPdisconnect(true); + } + } + showWelcomePage = false; + + DEBUG_PRINT("Connecting to "); + DEBUG_PRINT(clientSSID); + DEBUG_PRINTLN("..."); + +#ifdef ESP8266 + WiFi.hostname(serverDescription); +#endif + + WiFi.begin(clientSSID, clientPass); + +#ifdef ARDUINO_ARCH_ESP32 + WiFi.setSleep(!noWifiSleep); + WiFi.setHostname(serverDescription); +#else + wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); +#endif +} + +void WLED::initInterfaces() +{ + DEBUG_PRINTLN("Init STA interfaces"); + + if (hueIP[0] == 0) { + hueIP[0] = WiFi.localIP()[0]; + hueIP[1] = WiFi.localIP()[1]; + hueIP[2] = WiFi.localIP()[2]; + } + + // init Alexa hue emulation + if (alexaEnabled) + alexaInit(); + +#ifndef WLED_DISABLE_OTA + if (aOtaEnabled) + ArduinoOTA.begin(); +#endif + + strip.service(); + // Set up mDNS responder: + if (strlen(cmDNS) > 0) { + if (!aOtaEnabled) + MDNS.begin(cmDNS); + + DEBUG_PRINTLN("mDNS started"); + MDNS.addService("http", "tcp", 80); + MDNS.addService("wled", "tcp", 80); + MDNS.addServiceTxt("wled", "tcp", "mac", escapedMac.c_str()); + } + server.begin(); + + if (udpPort > 0 && udpPort != ntpLocalPort) { + udpConnected = notifierUdp.begin(udpPort); + if (udpConnected && udpRgbPort != udpPort) + udpRgbConnected = rgbUdp.begin(udpRgbPort); + } + if (ntpEnabled) + ntpConnected = ntpUdp.begin(ntpLocalPort); + + initBlynk(blynkApiKey); + e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST, e131Universe, E131_MAX_UNIVERSE_COUNT); + reconnectHue(); + initMqtt(); + interfacesInited = true; + wasConnected = true; +} + +byte stacO = 0; +uint32_t lastHeap; +unsigned long heapTime = 0; + +void WLED::handleConnection() +{ + if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) + return; + if (lastReconnectAttempt == 0) + initConnection(); + + // reconnect WiFi to clear stale allocations if heap gets too low + if (millis() - heapTime > 5000) { + uint32_t heap = ESP.getFreeHeap(); + if (heap < 9000 && lastHeap < 9000) { + DEBUG_PRINT("Heap too low! "); + DEBUG_PRINTLN(heap); + forceReconnect = true; + } + lastHeap = heap; + heapTime = millis(); + } + + byte stac = 0; + if (apActive) { +#ifdef ESP8266 + stac = wifi_softap_get_station_num(); +#else + wifi_sta_list_t stationList; + esp_wifi_ap_get_sta_list(&stationList); + stac = stationList.num; +#endif + if (stac != stacO) { + stacO = stac; + DEBUG_PRINT("Connected AP clients: "); + DEBUG_PRINTLN(stac); + if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { // trying to connect, but not connected + if (stac) + WiFi.disconnect(); // disable search so that AP can work + else + initConnection(); // restart search + } + } + } + if (forceReconnect) { + DEBUG_PRINTLN("Forcing reconnect."); + initConnection(); + interfacesInited = false; + forceReconnect = false; + wasConnected = false; + return; + } + if (!WLED_CONNECTED) { + if (interfacesInited) { + DEBUG_PRINTLN("Disconnected!"); + interfacesInited = false; + initConnection(); + } + if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) + initConnection(); + if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) + initAP(); + } else if (!interfacesInited) { // newly connected + DEBUG_PRINTLN(""); + DEBUG_PRINT("Connected! IP address: "); + DEBUG_PRINTLN(WiFi.localIP()); + initInterfaces(); + userConnected(); + + // shut down AP + if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) { + dnsServer.stop(); + WiFi.softAPdisconnect(true); + apActive = false; + DEBUG_PRINTLN("Access point disabled."); + } + } +} diff --git a/wled00/wled.h b/wled00/wled.h new file mode 100644 index 000000000..3c82efbd6 --- /dev/null +++ b/wled00/wled.h @@ -0,0 +1,519 @@ +#ifndef WLED_H +#define WLED_H +/* + Main sketch, global variable declarations + @title WLED project sketch + @version 0.9.1n + @author Christian Schwinne + */ + +// version code in format yymmddb (b = daily build) +#define VERSION 2004100 + +// ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). + +// ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). +// Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): +// Alternatively, with platformio pass your chosen flags to your custom build target in platformio.ini.override + +// You are required to disable over-the-air updates: +//#define WLED_DISABLE_OTA // saves 14kb + +// You need to choose some of these features to disable: +//#define WLED_DISABLE_ALEXA // saves 11kb +//#define WLED_DISABLE_BLYNK // saves 6kb +//#define WLED_DISABLE_CRONIXIE // saves 3kb +//#define WLED_DISABLE_HUESYNC // saves 4kb +//#define WLED_DISABLE_INFRARED // there is no pin left for this on ESP8266-01, saves 12kb +#define WLED_ENABLE_MQTT // saves 12kb +#define WLED_ENABLE_ADALIGHT // saves 500b only +//#define WLED_ENABLE_DMX // uses 3.5kb (use LEDPIN other than 2) + +#define WLED_DISABLE_FILESYSTEM // SPIFFS is not used by any WLED feature yet +//#define WLED_ENABLE_FS_SERVING // Enable sending html file from SPIFFS before serving progmem version +//#define WLED_ENABLE_FS_EDITOR // enable /edit page for editing SPIFFS content. Will also be disabled with OTA lock + +// to toggle usb serial debug (un)comment the following line +//#define WLED_DEBUG + +// Library inclusions. +#include +#ifdef ESP8266 + #include + #include + #include + extern "C" + { + #include + } +#else // ESP32 + #include + #include "esp_wifi.h" + #include + #include + #include "SPIFFS.h" +#endif + +#include +#include +#include +#include +#ifndef WLED_DISABLE_OTA + #include +#endif +#include +#include "src/dependencies/time/TimeLib.h" +#include "src/dependencies/timezone/Timezone.h" + +#ifndef WLED_DISABLE_ALEXA + #define ESPALEXA_ASYNC + #define ESPALEXA_NO_SUBPAGE + #define ESPALEXA_MAXDEVICES 1 + // #define ESPALEXA_DEBUG + #include "src/dependencies/espalexa/Espalexa.h" +#endif +#ifndef WLED_DISABLE_BLYNK + #include "src/dependencies/blynk/BlynkSimpleEsp.h" +#endif + +#include "src/dependencies/e131/ESPAsyncE131.h" +#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h" +#include "src/dependencies/json/AsyncJson-v6.h" +#include "src/dependencies/json/ArduinoJson-v6.h" + +#include "fcn_declare.h" +#include "html_ui.h" +#include "html_settings.h" +#include "html_other.h" +#include "FX.h" +#include "ir_codes.h" +#include "const.h" + +#ifndef CLIENT_SSID + #define CLIENT_SSID DEFAULT_CLIENT_SSID +#endif + +#ifndef CLIENT_PASS + #define CLIENT_PASS "" +#endif + +#if IR_PIN < 0 + #ifndef WLED_DISABLE_INFRARED + #define WLED_DISABLE_INFRARED + #endif +#endif + +#ifndef WLED_DISABLE_INFRARED + #include + #include + #include +#endif + +// remove flicker because PWM signal of RGB channels can become out of phase +#if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266) + #include "src/dependencies/arduino/core_esp8266_waveform.h" +#endif + +// enable additional debug output +#ifdef WLED_DEBUG + #ifndef ESP8266 + #include + #endif + #define DEBUG_PRINT(x) Serial.print(x) + #define DEBUG_PRINTLN(x) Serial.println(x) + #define DEBUG_PRINTF(x) Serial.printf(x) +#else + #define DEBUG_PRINT(x) + #define DEBUG_PRINTLN(x) + #define DEBUG_PRINTF(x) +#endif + +// GLOBAL VARIABLES +// both declared and defined in header (solution from http://www.keil.com/support/docs/1868.htm) +// +//e.g. byte test = 2 becomes WLED_GLOBAL byte test _INIT(2); +// int arr[]{0,1,2} becomes WLED_GLOBAL int arr[] _INIT_N(({0,1,2})); + +#ifndef WLED_DEFINE_GLOBAL_VARS +# define WLED_GLOBAL extern +# define _INIT(x) +# define _INIT_N(x) +#else +# define WLED_GLOBAL +# define _INIT(x) = x + +//needed to ignore commas in array definitions +#define UNPACK( ... ) __VA_ARGS__ +# define _INIT_N(x) UNPACK x +#endif + +// Global Variable definitions +WLED_GLOBAL char versionString[] _INIT("0.9.1n"); + +// AP and OTA default passwords (for maximum security change them!) +WLED_GLOBAL char apPass[65] _INIT(DEFAULT_AP_PASS); +WLED_GLOBAL char otaPass[33] _INIT(DEFAULT_OTA_PASS); + +// Hardware CONFIG (only changeble HERE, not at runtime) +// LED strip pin, button pin and IR pin changeable in NpbWrapper.h! + +WLED_GLOBAL byte auxDefaultState _INIT(0); // 0: input 1: high 2: low +WLED_GLOBAL byte auxTriggeredState _INIT(0); // 0: input 1: high 2: low +WLED_GLOBAL char ntpServerName[33] _INIT("0.wled.pool.ntp.org"); // NTP server to use + +// WiFi CONFIG (all these can be changed via web UI, no need to set them here) +WLED_GLOBAL char clientSSID[33] _INIT(CLIENT_SSID); +WLED_GLOBAL char clientPass[65] _INIT(CLIENT_PASS); +WLED_GLOBAL char cmDNS[33] _INIT("x"); // mDNS address (placeholder, is replaced by wledXXXXXX.local) +WLED_GLOBAL char apSSID[33] _INIT(""); // AP off by default (unless setup) +WLED_GLOBAL byte apChannel _INIT(1); // 2.4GHz WiFi AP channel (1-13) +WLED_GLOBAL byte apHide _INIT(0); // hidden AP SSID +WLED_GLOBAL byte apBehavior _INIT(AP_BEHAVIOR_BOOT_NO_CONN); // access point opens when no connection after boot by default +WLED_GLOBAL IPAddress staticIP _INIT_N((( 0, 0, 0, 0))); // static IP of ESP +WLED_GLOBAL IPAddress staticGateway _INIT_N((( 0, 0, 0, 0))); // gateway (router) IP +WLED_GLOBAL IPAddress staticSubnet _INIT_N(((255, 255, 255, 0))); // most common subnet in home networks +WLED_GLOBAL bool noWifiSleep _INIT(false); // disabling modem sleep modes will increase heat output and power usage, but may help with connection issues + +// LED CONFIG +WLED_GLOBAL uint16_t ledCount _INIT(30); // overcurrent prevented by ABL +WLED_GLOBAL bool useRGBW _INIT(false); // SK6812 strips can contain an extra White channel +WLED_GLOBAL bool turnOnAtBoot _INIT(true); // turn on LEDs at power-up +WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load after power-up + +WLED_GLOBAL byte col[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. col[] should be updated if you want to change the color. +WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color +WLED_GLOBAL byte briS _INIT(128); // default brightness + +WLED_GLOBAL byte nightlightTargetBri _INIT(0); // brightness after nightlight is over +WLED_GLOBAL byte nightlightDelayMins _INIT(60); +WLED_GLOBAL bool nightlightFade _INIT(true); // if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over +WLED_GLOBAL bool nightlightColorFade _INIT(false); // if enabled, light will gradually fade color from primary to secondary color. +WLED_GLOBAL bool fadeTransition _INIT(true); // enable crossfading color transition +WLED_GLOBAL uint16_t transitionDelay _INIT(750); // default crossfade duration in ms + +WLED_GLOBAL bool skipFirstLed _INIT(false); // ignore first LED in strip (useful if you need the LED as signal repeater) +WLED_GLOBAL byte briMultiplier _INIT(100); // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) + +// User Interface CONFIG +WLED_GLOBAL char serverDescription[33] _INIT("WLED"); // Name of module +WLED_GLOBAL bool syncToggleReceive _INIT(false); // UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise + +// Sync CONFIG +WLED_GLOBAL bool buttonEnabled _INIT(true); +WLED_GLOBAL byte irEnabled _INIT(0); // Infrared receiver + +WLED_GLOBAL uint16_t udpPort _INIT(21324); // WLED notifier default port +WLED_GLOBAL uint16_t udpRgbPort _INIT(19446); // Hyperion port + +WLED_GLOBAL bool receiveNotificationBrightness _INIT(true); // apply brightness from incoming notifications +WLED_GLOBAL bool receiveNotificationColor _INIT(true); // apply color +WLED_GLOBAL bool receiveNotificationEffects _INIT(true); // apply effects setup +WLED_GLOBAL bool notifyDirect _INIT(false); // send notification if change via UI or HTTP API +WLED_GLOBAL bool notifyButton _INIT(false); // send if updated by button or infrared remote +WLED_GLOBAL bool notifyAlexa _INIT(false); // send notification if updated via Alexa +WLED_GLOBAL bool notifyMacro _INIT(false); // send notification for macro +WLED_GLOBAL bool notifyHue _INIT(true); // send notification if Hue light changes +WLED_GLOBAL bool notifyTwice _INIT(false); // notifications use UDP: enable if devices don't sync reliably + +WLED_GLOBAL bool alexaEnabled _INIT(true); // enable device discovery by Amazon Echo +WLED_GLOBAL char alexaInvocationName[33] _INIT("Light"); // speech control name of device. Choose something voice-to-text can understand + +WLED_GLOBAL char blynkApiKey[36] _INIT(""); // Auth token for Blynk server. If empty, no connection will be made + +WLED_GLOBAL uint16_t realtimeTimeoutMs _INIT(2500); // ms timeout of realtime mode before returning to normal mode +WLED_GLOBAL int arlsOffset _INIT(0); // realtime LED offset +WLED_GLOBAL bool receiveDirect _INIT(true); // receive UDP realtime +WLED_GLOBAL bool arlsDisableGammaCorrection _INIT(true); // activate if gamma correction is handled by the source +WLED_GLOBAL bool arlsForceMaxBri _INIT(false); // enable to force max brightness if source has very dark colors that would be black + +WLED_GLOBAL uint16_t e131Universe _INIT(1); // settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) +WLED_GLOBAL byte DMXMode _INIT(DMX_MODE_MULTIPLE_RGB); // DMX mode (s.a.) +WLED_GLOBAL uint16_t DMXAddress _INIT(1); // DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +WLED_GLOBAL byte DMXOldDimmer _INIT(0); // only update brightness on change +WLED_GLOBAL byte e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; // to detect packet loss +WLED_GLOBAL bool e131Multicast _INIT(false); // multicast or unicast +WLED_GLOBAL bool e131SkipOutOfSequence _INIT(false); // freeze instead of flickering + +WLED_GLOBAL bool mqttEnabled _INIT(false); +WLED_GLOBAL char mqttDeviceTopic[33] _INIT(""); // main MQTT topic (individual per device, default is wled/mac) +WLED_GLOBAL char mqttGroupTopic[33] _INIT("wled/all"); // second MQTT topic (for example to group devices) +WLED_GLOBAL char mqttServer[33] _INIT(""); // both domains and IPs should work (no SSL) +WLED_GLOBAL char mqttUser[41] _INIT(""); // optional: username for MQTT auth +WLED_GLOBAL char mqttPass[41] _INIT(""); // optional: password for MQTT auth +WLED_GLOBAL char mqttClientID[41] _INIT(""); // override the client ID +WLED_GLOBAL uint16_t mqttPort _INIT(1883); + +WLED_GLOBAL bool huePollingEnabled _INIT(false); // poll hue bridge for light state +WLED_GLOBAL uint16_t huePollIntervalMs _INIT(2500); // low values (< 1sec) may cause lag but offer quicker response +WLED_GLOBAL char hueApiKey[47] _INIT("api"); // key token will be obtained from bridge +WLED_GLOBAL byte huePollLightId _INIT(1); // ID of hue lamp to sync to. Find the ID in the hue app ("about" section) +WLED_GLOBAL IPAddress hueIP _INIT((0, 0, 0, 0)); // IP address of the bridge +WLED_GLOBAL bool hueApplyOnOff _INIT(true); +WLED_GLOBAL bool hueApplyBri _INIT(true); +WLED_GLOBAL bool hueApplyColor _INIT(true); + +// Time CONFIG +WLED_GLOBAL bool ntpEnabled _INIT(false); // get internet time. Only required if you use clock overlays or time-activated macros +WLED_GLOBAL bool useAMPM _INIT(false); // 12h/24h clock format +WLED_GLOBAL byte currentTimezone _INIT(0); // Timezone ID. Refer to timezones array in wled10_ntp.ino +WLED_GLOBAL int utcOffsetSecs _INIT(0); // Seconds to offset from UTC before timzone calculation + +WLED_GLOBAL byte overlayDefault _INIT(0); // 0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie +WLED_GLOBAL byte overlayMin _INIT(0), overlayMax _INIT(ledCount - 1); // boundaries of overlay mode + +WLED_GLOBAL byte analogClock12pixel _INIT(0); // The pixel in your strip where "midnight" would be +WLED_GLOBAL bool analogClockSecondsTrail _INIT(false); // Display seconds as trail of LEDs instead of a single pixel +WLED_GLOBAL bool analogClock5MinuteMarks _INIT(false); // Light pixels at every 5-minute position + +WLED_GLOBAL char cronixieDisplay[7] _INIT("HHMMSS"); // Cronixie Display mask. See wled13_cronixie.ino +WLED_GLOBAL bool cronixieBacklight _INIT(true); // Allow digits to be back-illuminated + +WLED_GLOBAL bool countdownMode _INIT(false); // Clock will count down towards date +WLED_GLOBAL byte countdownYear _INIT(20), countdownMonth _INIT(1); // Countdown target date, year is last two digits +WLED_GLOBAL byte countdownDay _INIT(1) , countdownHour _INIT(0); +WLED_GLOBAL byte countdownMin _INIT(0) , countdownSec _INIT(0); + +WLED_GLOBAL byte macroBoot _INIT(0); // macro loaded after startup +WLED_GLOBAL byte macroNl _INIT(0); // after nightlight delay over +WLED_GLOBAL byte macroCountdown _INIT(0); +WLED_GLOBAL byte macroAlexaOn _INIT(0), macroAlexaOff _INIT(0); +WLED_GLOBAL byte macroButton _INIT(0), macroLongPress _INIT(0), macroDoublePress _INIT(0); + +// Security CONFIG +WLED_GLOBAL bool otaLock _INIT(false); // prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks +WLED_GLOBAL bool wifiLock _INIT(false); // prevents access to WiFi settings when OTA lock is enabled +WLED_GLOBAL bool aOtaEnabled _INIT(true); // ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on + +WLED_GLOBAL uint16_t userVar0 _INIT(0), userVar1 _INIT(0); //available for use in usermod + +#ifdef WLED_ENABLE_DMX + // dmx CONFIG + WLED_GLOBAL byte DMXChannels _INIT(7); // number of channels per fixture + WLED_GLOBAL byte DMXFixtureMap[15] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 })); + // assigns the different channels to different functions. See wled21_dmx.ino for more information. + WLED_GLOBAL uint16_t DMXGap _INIT(10); // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. + WLED_GLOBAL uint16_t DMXStart _INIT(10); // start address of the first fixture + WLED_GLOBAL uint16_t DMXStartLED _INIT(0); // LED from which DMX fixtures start +#endif + +// internal global variable declarations +// wifi +WLED_GLOBAL bool apActive _INIT(false); +WLED_GLOBAL bool forceReconnect _INIT(false); +WLED_GLOBAL uint32_t lastReconnectAttempt _INIT(0); +WLED_GLOBAL bool interfacesInited _INIT(false); +WLED_GLOBAL bool wasConnected _INIT(false); + +// color +WLED_GLOBAL byte colOld[] _INIT_N(({ 0, 0, 0, 0 })); // color before transition +WLED_GLOBAL byte colT[] _INIT_N(({ 0, 0, 0, 0 })); // color that is currently displayed on the LEDs +WLED_GLOBAL byte colIT[] _INIT_N(({ 0, 0, 0, 0 })); // color that was last sent to LEDs +WLED_GLOBAL byte colSecT[] _INIT_N(({ 0, 0, 0, 0 })); +WLED_GLOBAL byte colSecOld[] _INIT_N(({ 0, 0, 0, 0 })); +WLED_GLOBAL byte colSecIT[] _INIT_N(({ 0, 0, 0, 0 })); + +WLED_GLOBAL byte lastRandomIndex _INIT(0); // used to save last random color so the new one is not the same + +// transitions +WLED_GLOBAL bool transitionActive _INIT(false); +WLED_GLOBAL uint16_t transitionDelayDefault _INIT(transitionDelay); +WLED_GLOBAL uint16_t transitionDelayTemp _INIT(transitionDelay); +WLED_GLOBAL unsigned long transitionStartTime; +WLED_GLOBAL float tperLast _INIT(0); // crossfade transition progress, 0.0f - 1.0f +WLED_GLOBAL bool jsonTransitionOnce _INIT(false); + +// nightlight +WLED_GLOBAL bool nightlightActive _INIT(false); +WLED_GLOBAL bool nightlightActiveOld _INIT(false); +WLED_GLOBAL uint32_t nightlightDelayMs _INIT(10); +WLED_GLOBAL byte nightlightDelayMinsDefault _INIT(nightlightDelayMins); +WLED_GLOBAL unsigned long nightlightStartTime; +WLED_GLOBAL byte briNlT _INIT(0); // current nightlight brightness +WLED_GLOBAL byte colNlT[] _INIT_N(({ 0, 0, 0, 0 })); // current nightlight color + +// brightness +WLED_GLOBAL unsigned long lastOnTime _INIT(0); +WLED_GLOBAL bool offMode _INIT(!turnOnAtBoot); +WLED_GLOBAL byte bri _INIT(briS); +WLED_GLOBAL byte briOld _INIT(0); +WLED_GLOBAL byte briT _INIT(0); +WLED_GLOBAL byte briIT _INIT(0); +WLED_GLOBAL byte briLast _INIT(128); // brightness before turned off. Used for toggle function +WLED_GLOBAL byte whiteLast _INIT(128); // white channel before turned off. Used for toggle function + +// button +WLED_GLOBAL bool buttonPressedBefore _INIT(false); +WLED_GLOBAL bool buttonLongPressed _INIT(false); +WLED_GLOBAL unsigned long buttonPressedTime _INIT(0); +WLED_GLOBAL unsigned long buttonWaitTime _INIT(0); + +// notifications +WLED_GLOBAL bool notifyDirectDefault _INIT(notifyDirect); +WLED_GLOBAL bool receiveNotifications _INIT(true); +WLED_GLOBAL unsigned long notificationSentTime _INIT(0); +WLED_GLOBAL byte notificationSentCallMode _INIT(NOTIFIER_CALL_MODE_INIT); +WLED_GLOBAL bool notificationTwoRequired _INIT(false); + +// effects +WLED_GLOBAL byte effectCurrent _INIT(0); +WLED_GLOBAL byte effectSpeed _INIT(128); +WLED_GLOBAL byte effectIntensity _INIT(128); +WLED_GLOBAL byte effectPalette _INIT(0); + +// network +WLED_GLOBAL bool udpConnected _INIT(false), udpRgbConnected _INIT(false); + +// ui style +WLED_GLOBAL bool showWelcomePage _INIT(false); + +// hue +WLED_GLOBAL byte hueError _INIT(HUE_ERROR_INACTIVE); +// WLED_GLOBAL uint16_t hueFailCount _INIT(0); +WLED_GLOBAL float hueXLast _INIT(0), hueYLast _INIT(0); +WLED_GLOBAL uint16_t hueHueLast _INIT(0), hueCtLast _INIT(0); +WLED_GLOBAL byte hueSatLast _INIT(0), hueBriLast _INIT(0); +WLED_GLOBAL unsigned long hueLastRequestSent _INIT(0); +WLED_GLOBAL bool hueAuthRequired _INIT(false); +WLED_GLOBAL bool hueReceived _INIT(false); +WLED_GLOBAL bool hueStoreAllowed _INIT(false), hueNewKey _INIT(false); + +// overlays +WLED_GLOBAL byte overlayCurrent _INIT(overlayDefault); +WLED_GLOBAL byte overlaySpeed _INIT(200); +WLED_GLOBAL unsigned long overlayRefreshMs _INIT(200); +WLED_GLOBAL unsigned long overlayRefreshedTime; + +// cronixie +WLED_GLOBAL byte dP[] _INIT_N(({ 0, 0, 0, 0, 0, 0 })); +WLED_GLOBAL bool cronixieInit _INIT(false); + +// countdown +WLED_GLOBAL unsigned long countdownTime _INIT(1514764800L); +WLED_GLOBAL bool countdownOverTriggered _INIT(true); + +// timer +WLED_GLOBAL byte lastTimerMinute _INIT(0); +WLED_GLOBAL byte timerHours[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0 })); +WLED_GLOBAL byte timerMinutes[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0 })); +WLED_GLOBAL byte timerMacro[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0 })); +WLED_GLOBAL byte timerWeekday[] _INIT_N(({ 255, 255, 255, 255, 255, 255, 255, 255 })); // weekdays to activate on +// bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity + +// blynk +WLED_GLOBAL bool blynkEnabled _INIT(false); + +// preset cycling +WLED_GLOBAL bool presetCyclingEnabled _INIT(false); +WLED_GLOBAL byte presetCycleMin _INIT(1), presetCycleMax _INIT(5); +WLED_GLOBAL uint16_t presetCycleTime _INIT(1250); +WLED_GLOBAL unsigned long presetCycledTime _INIT(0); +WLED_GLOBAL byte presetCycCurr _INIT(presetCycleMin); +WLED_GLOBAL bool presetApplyBri _INIT(true); +WLED_GLOBAL bool saveCurrPresetCycConf _INIT(false); + +// realtime +WLED_GLOBAL byte realtimeMode _INIT(REALTIME_MODE_INACTIVE); +WLED_GLOBAL IPAddress realtimeIP _INIT((0, 0, 0, 0)); +WLED_GLOBAL unsigned long realtimeTimeout _INIT(0); + +// mqtt +WLED_GLOBAL long lastMqttReconnectAttempt _INIT(0); +WLED_GLOBAL long lastInterfaceUpdate _INIT(0); +WLED_GLOBAL byte interfaceUpdateCallMode _INIT(NOTIFIER_CALL_MODE_INIT); +WLED_GLOBAL char mqttStatusTopic[40] _INIT(""); // this must be global because of async handlers + +#if AUXPIN >= 0 + // auxiliary debug pin + WLED_GLOBAL byte auxTime _INIT(0); + WLED_GLOBAL unsigned long auxStartTime _INIT(0); + WLED_GLOBAL bool auxActive _INIT(false, auxActiveBefore _INIT(false); +#endif + +// alexa udp +WLED_GLOBAL String escapedMac; +#ifndef WLED_DISABLE_ALEXA + WLED_GLOBAL Espalexa espalexa; + WLED_GLOBAL EspalexaDevice* espalexaDevice; +#endif + +// dns server +WLED_GLOBAL DNSServer dnsServer; + +// network time +WLED_GLOBAL bool ntpConnected _INIT(false); +WLED_GLOBAL time_t local _INIT(0); +WLED_GLOBAL unsigned long ntpLastSyncTime _INIT(999000000L); +WLED_GLOBAL unsigned long ntpPacketSentTime _INIT(999000000L); +WLED_GLOBAL IPAddress ntpServerIP; +WLED_GLOBAL uint16_t ntpLocalPort _INIT(2390); + +// Temp buffer +WLED_GLOBAL char* obuf; +WLED_GLOBAL uint16_t olen _INIT(0); + +// presets +WLED_GLOBAL uint16_t savedPresets _INIT(0); +WLED_GLOBAL int8_t currentPreset _INIT(-1); +WLED_GLOBAL bool isPreset _INIT(false); + +WLED_GLOBAL byte errorFlag _INIT(0); + +WLED_GLOBAL String messageHead, messageSub; +WLED_GLOBAL byte optionType; + +WLED_GLOBAL bool doReboot _INIT(false); // flag to initiate reboot from async handlers +WLED_GLOBAL bool doPublishMqtt _INIT(false); + +// server library objects +WLED_GLOBAL AsyncWebServer server _INIT_N(((80))); +WLED_GLOBAL AsyncClient* hueClient _INIT(NULL); +WLED_GLOBAL AsyncMqttClient* mqtt _INIT(NULL); + +// udp interface objects +WLED_GLOBAL WiFiUDP notifierUdp, rgbUdp; +WLED_GLOBAL WiFiUDP ntpUdp; +WLED_GLOBAL ESPAsyncE131 e131 _INIT_N(((handleE131Packet))); +WLED_GLOBAL bool e131NewData _INIT(false); + +// led fx library object +WLED_GLOBAL WS2812FX strip _INIT(WS2812FX()); + +// debug macro variable definitions +#ifdef WLED_DEBUG + WLED_GLOBAL unsigned long debugTime _INIT(0); + WLED_GLOBAL int lastWifiState _INIT(3); + WLED_GLOBAL unsigned long wifiStateChangedTime _INIT(0); + WLED_GLOBAL int loops _INIT(0); +#endif + + +#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) +#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) + +// append new c string to temp buffer efficiently +bool oappend(const char* txt); +// append new number to temp buffer efficiently +bool oappendi(int i); + +class WLED { +public: + WLED(); + static WLED& instance() + { + static WLED instance; + return instance; + } + + // boot starts here + void setup(); + + void loop(); + void reset(); + + void beginStrip(); + void handleConnection(); + void initAP(bool resetAP = false); + void initConnection(); + void initInterfaces(); +}; +#endif // WLED_H diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 851a9c45d..866543ab9 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -1,619 +1,21 @@ /* - Main sketch, global variable declarations -*/ -/* - * @title WLED project sketch - * @version 0.9.1 - * @author Christian Schwinne + * WLED Arduino IDE compatibility file. + * + * Where has everything gone? + * + * In April 2020, the project's structure underwent a major change. + * Global variables are now found in file "wled.h" + * Global function declarations are found in "fcn_declare.h" + * + * Usermod compatibility: Existing wled06_usermod.ino mods should continue to work. Delete usermod.cpp. + * New usermods should use usermod.cpp instead. */ +#include "wled.h" -//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). - -//ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). -//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): - -//You are required to disable over-the-air updates: -//#define WLED_DISABLE_OTA //saves 14kb - -//You need to choose some of these features to disable: -//#define WLED_DISABLE_ALEXA //saves 11kb -//#define WLED_DISABLE_BLYNK //saves 6kb -//#define WLED_DISABLE_CRONIXIE //saves 3kb -//#define WLED_DISABLE_HUESYNC //saves 4kb -//#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01, saves 12kb -#define WLED_ENABLE_MQTT //saves 12kb -#define WLED_ENABLE_ADALIGHT //saves 500b only -//#define WLED_ENABLE_DMX //uses 3.5kb, if wanting to use DMX together with LEDs, you should change the LEDPIN to something other than 2 in NpbWrapper.h - -#define WLED_DISABLE_FILESYSTEM //SPIFFS is not used by any WLED feature yet -//#define WLED_ENABLE_FS_SERVING //Enable sending html file from SPIFFS before serving progmem version -//#define WLED_ENABLE_FS_EDITOR //enable /edit page for editing SPIFFS content. Will also be disabled with OTA lock - -//to toggle usb serial debug (un)comment the following line -//#define WLED_DEBUG - -//library inclusions -#include -#ifdef WLED_ENABLE_DMX - #include - DMXESPSerial dmx; -#endif -#ifdef ESP8266 - #include - #include - #include - extern "C" { - #include - } -#else //ESP32 - #include - #include "esp_wifi.h" - #include - #include - #include "SPIFFS.h" -#endif - -#include -#include -#include -#include -#ifndef WLED_DISABLE_OTA - #include -#endif -#include -#include "src/dependencies/time/TimeLib.h" -#include "src/dependencies/timezone/Timezone.h" -#ifndef WLED_DISABLE_ALEXA - #define ESPALEXA_ASYNC - #define ESPALEXA_NO_SUBPAGE - #define ESPALEXA_MAXDEVICES 1 - // #define ESPALEXA_DEBUG - #include "src/dependencies/espalexa/Espalexa.h" -#endif -#ifndef WLED_DISABLE_BLYNK - #include "src/dependencies/blynk/BlynkSimpleEsp.h" -#endif -#include "src/dependencies/e131/ESPAsyncE131.h" -#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h" -#include "src/dependencies/json/AsyncJson-v6.h" -#include "src/dependencies/json/ArduinoJson-v6.h" -#include "html_ui.h" -#include "html_settings.h" -#include "html_other.h" -#include "FX.h" -#include "ir_codes.h" -#include "const.h" - -#ifndef CLIENT_SSID -#define CLIENT_SSID DEFAULT_CLIENT_SSID -#endif - -#ifndef CLIENT_PASS -#define CLIENT_PASS "" -#endif - - -#if IR_PIN < 0 - #ifndef WLED_DISABLE_INFRARED - #define WLED_DISABLE_INFRARED - #endif -#endif - -#ifndef WLED_DISABLE_INFRARED - #include - #include - #include -#endif - -// remove flicker because PWM signal of RGB channels can become out of phase -#if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266) - #include "src/dependencies/arduino/core_esp8266_waveform.h" -#endif - -// enable additional debug output -#ifdef WLED_DEBUG - #ifndef ESP8266 - #include - #endif -#endif - -//version code in format yymmddb (b = daily build) -#define VERSION 2003262 - -char versionString[] = "0.9.1"; - - -//AP and OTA default passwords (for maximum change them!) -char apPass[65] = DEFAULT_AP_PASS; -char otaPass[33] = DEFAULT_OTA_PASS; - - -//Hardware CONFIG (only changeble HERE, not at runtime) -//LED strip pin, button pin and IR pin changeable in NpbWrapper.h! - -byte auxDefaultState = 0; //0: input 1: high 2: low -byte auxTriggeredState = 0; //0: input 1: high 2: low -char ntpServerName[33] = "0.wled.pool.ntp.org";//NTP server to use - - -//WiFi CONFIG (all these can be changed via web UI, no need to set them here) -char clientSSID[33] = CLIENT_SSID; -char clientPass[65] = CLIENT_PASS; -char cmDNS[33] = "x"; //mDNS address (placeholder, will be replaced by wledXXXXXXXXXXXX.local) -char apSSID[33] = ""; //AP off by default (unless setup) -byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) -byte apHide = 0; //hidden AP SSID -byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no connection after boot by default -IPAddress staticIP(0, 0, 0, 0); //static IP of ESP -IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP -IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks -bool noWifiSleep = false; //disabling modem sleep modes will increase heat output and power usage, but may help with connection issues - - -//LED CONFIG -uint16_t ledCount = 30; //overcurrent prevented by ABL -bool useRGBW = false; //SK6812 strips can contain an extra White channel -#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit -bool turnOnAtBoot = true; //turn on LEDs at power-up -byte bootPreset = 0; //save preset to load after power-up - -byte col[] {255, 160, 0, 0}; //current RGB(W) primary color. col[] should be updated if you want to change the color. -byte colSec[] {0, 0, 0, 0}; //current RGB(W) secondary color -byte briS = 128; //default brightness - -byte nightlightTargetBri = 0; //brightness after nightlight is over -byte nightlightDelayMins = 60; -bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over -bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. -bool fadeTransition = true; //enable crossfading color transition -uint16_t transitionDelay = 750; //default crossfade duration in ms - -bool skipFirstLed = false; //ignore first LED in strip (useful if you need the LED as signal repeater) -byte briMultiplier = 100; //% of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) - - -//User Interface CONFIG -char serverDescription[33] = "WLED"; //Name of module -bool syncToggleReceive = false; //UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise - - -//Sync CONFIG -bool buttonEnabled = true; -byte irEnabled = 0; //Infrared receiver - -uint16_t udpPort = 21324; //WLED notifier default port -uint16_t udpRgbPort = 19446; //Hyperion port - -bool receiveNotificationBrightness = true; //apply brightness from incoming notifications -bool receiveNotificationColor = true; //apply color -bool receiveNotificationEffects = true; //apply effects setup -bool notifyDirect = false; //send notification if change via UI or HTTP API -bool notifyButton = false; //send if updated by button or infrared remote -bool notifyAlexa = false; //send notification if updated via Alexa -bool notifyMacro = false; //send notification for macro -bool notifyHue = true; //send notification if Hue light changes -bool notifyTwice = false; //notifications use UDP: enable if devices don't sync reliably - -bool alexaEnabled = true; //enable device discovery by Amazon Echo -char alexaInvocationName[33] = "Light"; //speech control name of device. Choose something voice-to-text can understand - -char blynkApiKey[36] = ""; //Auth token for Blynk server. If empty, no connection will be made - -uint16_t realtimeTimeoutMs = 2500; //ms timeout of realtime mode before returning to normal mode -int arlsOffset = 0; //realtime LED offset -bool receiveDirect = true; //receive UDP realtime -bool arlsDisableGammaCorrection = true; //activate if gamma correction is handled by the source -bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black - -#define E131_MAX_UNIVERSE_COUNT 9 -uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) -uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] -uint8_t DMXOldDimmer = 0; //only update brightness on change -uint8_t e131LastSequenceNumber[E131_MAX_UNIVERSE_COUNT]; //to detect packet loss -bool e131Multicast = false; //multicast or unicast -bool e131SkipOutOfSequence = false; //freeze instead of flickering - -bool mqttEnabled = false; -char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac) -char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices) -char mqttServer[33] = ""; //both domains and IPs should work (no SSL) -char mqttUser[41] = ""; //optional: username for MQTT auth -char mqttPass[41] = ""; //optional: password for MQTT auth -char mqttClientID[41] = ""; //override the client ID -uint16_t mqttPort = 1883; - -bool huePollingEnabled = false; //poll hue bridge for light state -uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response -char hueApiKey[47] = "api"; //key token will be obtained from bridge -byte huePollLightId = 1; //ID of hue lamp to sync to. Find the ID in the hue app ("about" section) -IPAddress hueIP = (0, 0, 0, 0); //IP address of the bridge -bool hueApplyOnOff = true; -bool hueApplyBri = true; -bool hueApplyColor = true; - - -//Time CONFIG -bool ntpEnabled = false; //get internet time. Only required if you use clock overlays or time-activated macros -bool useAMPM = false; //12h/24h clock format -byte currentTimezone = 0; //Timezone ID. Refer to timezones array in wled10_ntp.ino -int utcOffsetSecs = 0; //Seconds to offset from UTC before timzone calculation - -byte overlayDefault = 0; //0: no overlay 1: analog clock 2: single-digit clocl 3: cronixie -byte overlayMin = 0, overlayMax = ledCount - 1; //boundaries of overlay mode - -byte analogClock12pixel = 0; //The pixel in your strip where "midnight" would be -bool analogClockSecondsTrail = false; //Display seconds as trail of LEDs instead of a single pixel -bool analogClock5MinuteMarks = false; //Light pixels at every 5-minute position - -char cronixieDisplay[7] = "HHMMSS"; //Cronixie Display mask. See wled13_cronixie.ino -bool cronixieBacklight = true; //Allow digits to be back-illuminated - -bool countdownMode = false; //Clock will count down towards date -byte countdownYear = 20, countdownMonth = 1; //Countdown target date, year is last two digits -byte countdownDay = 1, countdownHour = 0; -byte countdownMin = 0, countdownSec = 0; - - -byte macroBoot = 0; //macro loaded after startup -byte macroNl = 0; //after nightlight delay over -byte macroCountdown = 0; -byte macroAlexaOn = 0, macroAlexaOff = 0; -byte macroButton = 0, macroLongPress = 0, macroDoublePress = 0; - - -//Security CONFIG -bool otaLock = false; //prevents OTA firmware updates without password. ALWAYS enable if system exposed to any public networks -bool wifiLock = false; //prevents access to WiFi settings when OTA lock is enabled -bool aOtaEnabled = true; //ArduinoOTA allows easy updates directly from the IDE. Careful, it does not auto-disable when OTA lock is on - - -uint16_t userVar0 = 0, userVar1 = 0; - -#ifdef WLED_ENABLE_DMX - //dmx CONFIG - byte DMXChannels = 7; // number of channels per fixture - byte DMXFixtureMap[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - // assigns the different channels to different functions. See wled21_dmx.ino for more information. - uint16_t DMXGap = 10; // gap between the fixtures. makes addressing easier because you don't have to memorize odd numbers when climbing up onto a rig. - uint16_t DMXStart = 10; // start address of the first fixture - uint16_t DMXSegment = 0; // segment which DMX fixtures use - uint16_t DMXStartLED = 0; // start LED from which DMX fixtures should start -#endif - - -//internal global variable declarations -//wifi -bool apActive = false; -bool forceReconnect = false; -uint32_t lastReconnectAttempt = 0; -bool interfacesInited = false; -bool wasConnected = false; - -//color -byte colOld[] {0, 0, 0, 0}; //color before transition -byte colT[] {0, 0, 0, 0}; //color that is currently displayed on the LEDs -byte colIT[] {0, 0, 0, 0}; //color that was last sent to LEDs -byte colSecT[] {0, 0, 0, 0}; -byte colSecOld[] {0, 0, 0, 0}; -byte colSecIT[] {0, 0, 0, 0}; - -byte lastRandomIndex = 0; //used to save last random color so the new one is not the same - -//transitions -bool transitionActive = false; -uint16_t transitionDelayDefault = transitionDelay; -uint16_t transitionDelayTemp = transitionDelay; -unsigned long transitionStartTime; -float tperLast = 0; //crossfade transition progress, 0.0f - 1.0f -bool jsonTransitionOnce = false; - -//nightlight -bool nightlightActive = false; -bool nightlightActiveOld = false; -uint32_t nightlightDelayMs = 10; -uint8_t nightlightDelayMinsDefault = nightlightDelayMins; -unsigned long nightlightStartTime; -byte briNlT = 0; //current nightlight brightness -byte colNlT[] {0, 0, 0, 0}; //current nightlight color - -//brightness -unsigned long lastOnTime = 0; -bool offMode = !turnOnAtBoot; -byte bri = briS; -byte briOld = 0; -byte briT = 0; -byte briIT = 0; -byte briLast = 128; //brightness before turned off. Used for toggle function -byte whiteLast = 128; //white channel before turned off. Used for toggle function - -//button -bool buttonPressedBefore = false; -bool buttonLongPressed = false; -unsigned long buttonPressedTime = 0; -unsigned long buttonWaitTime = 0; - -//notifications -bool notifyDirectDefault = notifyDirect; -bool receiveNotifications = true; -unsigned long notificationSentTime = 0; -byte notificationSentCallMode = NOTIFIER_CALL_MODE_INIT; -bool notificationTwoRequired = false; - -//effects -byte effectCurrent = 0; -byte effectSpeed = 128; -byte effectIntensity = 128; -byte effectPalette = 0; - -//network -bool udpConnected = false, udpRgbConnected = false; - -//ui style -bool showWelcomePage = false; - -//hue -byte hueError = HUE_ERROR_INACTIVE; -//uint16_t hueFailCount = 0; -float hueXLast = 0, hueYLast = 0; -uint16_t hueHueLast = 0, hueCtLast = 0; -byte hueSatLast = 0, hueBriLast = 0; -unsigned long hueLastRequestSent = 0; -bool hueAuthRequired = false; -bool hueReceived = false; -bool hueStoreAllowed = false, hueNewKey = false; - -//overlays -byte overlayCurrent = overlayDefault; -byte overlaySpeed = 200; -unsigned long overlayRefreshMs = 200; -unsigned long overlayRefreshedTime; - -//cronixie -byte dP[] {0, 0, 0, 0, 0, 0}; -bool cronixieInit = false; - -//countdown -unsigned long countdownTime = 1514764800L; -bool countdownOverTriggered = true; - -//timer -byte lastTimerMinute = 0; -byte timerHours[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMinutes[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerMacro[] = {0, 0, 0, 0, 0, 0, 0, 0}; -byte timerWeekday[] = {255, 255, 255, 255, 255, 255, 255, 255}; //weekdays to activate on -//bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity - -//blynk -bool blynkEnabled = false; - -//preset cycling -bool presetCyclingEnabled = false; -byte presetCycleMin = 1, presetCycleMax = 5; -uint16_t presetCycleTime = 1250; -unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin; -bool presetApplyBri = true; -bool saveCurrPresetCycConf = false; - -//realtime -byte realtimeMode = REALTIME_MODE_INACTIVE; -IPAddress realtimeIP = (0,0,0,0); -unsigned long realtimeTimeout = 0; - -//mqtt -long lastMqttReconnectAttempt = 0; -long lastInterfaceUpdate = 0; -byte interfaceUpdateCallMode = NOTIFIER_CALL_MODE_INIT; -char mqttStatusTopic[40] = ""; //this must be global because of async handlers - -#if AUXPIN >= 0 - //auxiliary debug pin - byte auxTime = 0; - unsigned long auxStartTime = 0; - bool auxActive = false, auxActiveBefore = false; -#endif - -//alexa udp -String escapedMac; -#ifndef WLED_DISABLE_ALEXA - Espalexa espalexa; - EspalexaDevice* espalexaDevice; -#endif - -//dns server -DNSServer dnsServer; - -//network time -bool ntpConnected = false; -time_t local = 0; -unsigned long ntpLastSyncTime = 999000000L; -unsigned long ntpPacketSentTime = 999000000L; -IPAddress ntpServerIP; -uint16_t ntpLocalPort = 2390; -#define NTP_PACKET_SIZE 48 - -//maximum number of LEDs - MAX_LEDS is coming from the JSON response getting too big, MAX_LEDS_DMA will become a timing issue -#define MAX_LEDS 1500 -#define MAX_LEDS_DMA 500 - -//string temp buffer (now stored in stack locally) -#define OMAX 2048 -char* obuf; -uint16_t olen = 0; - -//presets -uint16_t savedPresets = 0; -int8_t currentPreset = -1; -bool isPreset = false; - -byte errorFlag = 0; - -String messageHead, messageSub; -byte optionType; - -bool doReboot = false; //flag to initiate reboot from async handlers -bool doPublishMqtt = false; - -//server library objects -AsyncWebServer server(80); -AsyncClient* hueClient = NULL; -AsyncMqttClient* mqtt = NULL; - -//function prototypes -void colorFromUint32(uint32_t, bool = false); -void serveMessage(AsyncWebServerRequest*, uint16_t, String, String, byte); -void handleE131Packet(e131_packet_t*, IPAddress); -void arlsLock(uint32_t,byte); -void handleOverlayDraw(); - -//udp interface objects -WiFiUDP notifierUdp, rgbUdp; -WiFiUDP ntpUdp; -ESPAsyncE131 e131(handleE131Packet); -bool e131NewData = false; - -//led fx library object -WS2812FX strip = WS2812FX(); - -#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) -#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID,DEFAULT_CLIENT_SSID) != 0) - -//debug macros -#ifdef WLED_DEBUG - #define DEBUG_PRINT(x) Serial.print (x) - #define DEBUG_PRINTLN(x) Serial.println (x) - #define DEBUG_PRINTF(x) Serial.printf (x) - unsigned long debugTime = 0; - int lastWifiState = 3; - unsigned long wifiStateChangedTime = 0; - int loops = 0; -#else - #define DEBUG_PRINT(x) - #define DEBUG_PRINTLN(x) - #define DEBUG_PRINTF(x) -#endif - -//filesystem -#ifndef WLED_DISABLE_FILESYSTEM - #include - #ifdef ARDUINO_ARCH_ESP32 - #include "SPIFFS.h" - #endif - #include "SPIFFSEditor.h" -#endif - - - -//turns all LEDs off and restarts ESP -void reset() -{ - briT = 0; - long dly = millis(); - while (millis() - dly < 250) - { - yield(); //enough time to send response to client - } - setAllLeds(); - DEBUG_PRINTLN("MODULE RESET"); - ESP.restart(); -} - - -//append new c string to temp buffer efficiently -bool oappend(const char* txt) -{ - uint16_t len = strlen(txt); - if (olen + len >= OMAX) return false; //buffer full - strcpy(obuf + olen, txt); - olen += len; - return true; -} - - -//append new number to temp buffer efficiently -bool oappendi(int i) -{ - char s[11]; - sprintf(s, "%ld", i); - return oappend(s); -} - - -//boot starts here void setup() { - wledInit(); + WLED::instance().setup(); } - -//main program loop void loop() { - handleIR(); //2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too - handleConnection(); - handleSerial(); - handleNotifications(); - handleTransitions(); -#ifdef WLED_ENABLE_DMX - handleDMX(); -#endif - userLoop(); - - yield(); - handleIO(); - handleIR(); - handleNetworkTime(); - handleAlexa(); - - handleOverlays(); - yield(); -#ifdef WLED_USE_ANALOG_LEDS - strip.setRgbwPwm(); -#endif - - if (doReboot) reset(); - - if (!realtimeMode) //block stuff if WARLS/Adalight is enabled - { - if (apActive) dnsServer.processNextRequest(); -#ifndef WLED_DISABLE_OTA - if (WLED_CONNECTED && aOtaEnabled) ArduinoOTA.handle(); -#endif - handleNightlight(); - yield(); - - handleHue(); - handleBlynk(); - - yield(); - if (!offMode) strip.service(); - } - yield(); -#ifdef ESP8266 - MDNS.update(); -#endif - if (millis() - lastMqttReconnectAttempt > 30000) initMqtt(); - - //DEBUG serial logging -#ifdef WLED_DEBUG - if (millis() - debugTime > 9999) - { - DEBUG_PRINTLN("---DEBUG INFO---"); - DEBUG_PRINT("Runtime: "); DEBUG_PRINTLN(millis()); - DEBUG_PRINT("Unix time: "); DEBUG_PRINTLN(now()); - DEBUG_PRINT("Free heap: "); DEBUG_PRINTLN(ESP.getFreeHeap()); - DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(WiFi.status()); - if (WiFi.status() != lastWifiState) - { - wifiStateChangedTime = millis(); - } - lastWifiState = WiFi.status(); - DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime); - DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime); - DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP()); - DEBUG_PRINT("Loops/sec: "); DEBUG_PRINTLN(loops / 10); - loops = 0; - debugTime = millis(); - } - loops++; -#endif + WLED::instance().loop(); } diff --git a/wled00/wled00.vcxproj b/wled00/wled00.vcxproj index 2183ad262..e095b8f76 100644 --- a/wled00/wled00.vcxproj +++ b/wled00/wled00.vcxproj @@ -104,231 +104,103 @@ CppCode - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode -
- - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - - - CppCode - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -350,6 +222,11 @@ + + + + + VisualMicroDebugger @@ -362,4 +239,4 @@ -
\ No newline at end of file + diff --git a/wled00/wled00.vcxproj.filters b/wled00/wled00.vcxproj.filters index e2c2b219c..3ed232a98 100644 --- a/wled00/wled00.vcxproj.filters +++ b/wled00/wled00.vcxproj.filters @@ -13,29 +13,15 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + {72fe60da-ba26-45b4-82c1-bdff809975da} + + + {8880888d-efea-4189-a25a-834b7b3bb756} + - - - - - - - - - - - - - - - - - - - - @@ -53,219 +39,348 @@ Header Files - + Header Files + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files\Dependencies + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + Header Files Header Files - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - Source Files Source Files + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files\Dependencies + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + Source Files diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino deleted file mode 100644 index 29ae0e7ab..000000000 --- a/wled00/wled05_init.ino +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Setup code - */ - -void wledInit() -{ - EEPROM.begin(EEPSIZE); - ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); - if (ledCount > MAX_LEDS || ledCount == 0) ledCount = 30; - - #ifdef ESP8266 - #if LEDPIN == 3 - if (ledCount > MAX_LEDS_DMA) ledCount = MAX_LEDS_DMA; //DMA method uses too much ram - #endif - #endif - Serial.begin(115200); - Serial.setTimeout(50); - DEBUG_PRINTLN(); - DEBUG_PRINT("---WLED "); DEBUG_PRINT(versionString); DEBUG_PRINT(" "); DEBUG_PRINT(VERSION); DEBUG_PRINTLN(" INIT---"); - #ifdef ARDUINO_ARCH_ESP32 - DEBUG_PRINT("esp32 "); DEBUG_PRINTLN(ESP.getSdkVersion()); - #else - DEBUG_PRINT("esp8266 "); DEBUG_PRINTLN(ESP.getCoreVersion()); - #endif - int heapPreAlloc = ESP.getFreeHeap(); - DEBUG_PRINT("heap "); - DEBUG_PRINTLN(ESP.getFreeHeap()); - - strip.init(EEPROM.read(372),ledCount,EEPROM.read(2204)); //init LEDs quickly - strip.setBrightness(0); - - DEBUG_PRINT("LEDs inited. heap usage ~"); - DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap()); - - #ifndef WLED_DISABLE_FILESYSTEM - #ifdef ARDUINO_ARCH_ESP32 - SPIFFS.begin(true); - #endif - SPIFFS.begin(); - #endif - - DEBUG_PRINTLN("Load EEPROM"); - loadSettingsFromEEPROM(true); - beginStrip(); - userSetup(); - if (strcmp(clientSSID,DEFAULT_CLIENT_SSID) == 0) showWelcomePage = true; - WiFi.persistent(false); - - if (macroBoot>0) applyMacro(macroBoot); - Serial.println("Ada"); - - //generate module IDs - escapedMac = WiFi.macAddress(); - escapedMac.replace(":", ""); - escapedMac.toLowerCase(); - if (strcmp(cmDNS,"x") == 0) //fill in unique mdns default - { - strcpy(cmDNS, "wled-"); - sprintf(cmDNS+5, "%*s", 6, escapedMac.c_str()+6); - } - if (mqttDeviceTopic[0] == 0) - { - strcpy(mqttDeviceTopic, "wled/"); - sprintf(mqttDeviceTopic+5, "%*s", 6, escapedMac.c_str()+6); - } - if (mqttClientID[0] == 0) - { - strcpy(mqttClientID, "WLED-"); - sprintf(mqttClientID+5, "%*s", 6, escapedMac.c_str()+6); - } - - strip.service(); - - #ifndef WLED_DISABLE_OTA - if (aOtaEnabled) - { - ArduinoOTA.onStart([]() { - #ifdef ESP8266 - wifi_set_sleep_type(NONE_SLEEP_T); - #endif - DEBUG_PRINTLN("Start ArduinoOTA"); - }); - if (strlen(cmDNS) > 0) ArduinoOTA.setHostname(cmDNS); - } - #endif - #ifdef WLED_ENABLE_DMX - dmx.init(512); // initialize with bus length - #endif - //HTTP server page init - initServer(); -} - - -void beginStrip() -{ - // Initialize NeoPixel Strip and button - strip.setShowCallback(handleOverlayDraw); - -#ifdef BTNPIN - pinMode(BTNPIN, INPUT_PULLUP); -#endif - - if (bootPreset > 0) applyPreset(bootPreset, turnOnAtBoot); - colorUpdated(NOTIFIER_CALL_MODE_INIT); - - //init relay pin - #if RLYPIN >= 0 - pinMode(RLYPIN, OUTPUT); - #if RLYMDE - digitalWrite(RLYPIN, bri); - #else - digitalWrite(RLYPIN, !bri); - #endif - #endif - - //disable button if it is "pressed" unintentionally -#ifdef BTNPIN - if(digitalRead(BTNPIN) == LOW) buttonEnabled = false; -#else - buttonEnabled = false; -#endif -} - - -void initAP(bool resetAP=false){ - if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) return; - - if (!apSSID[0] || resetAP) strcpy(apSSID, "WLED-AP"); - if (resetAP) strcpy(apPass,DEFAULT_AP_PASS); - DEBUG_PRINT("Opening access point "); - DEBUG_PRINTLN(apSSID); - WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255,255,255,0)); - WiFi.softAP(apSSID, apPass, apChannel, apHide); - - if (!apActive) //start captive portal if AP active - { - DEBUG_PRINTLN("Init AP interfaces"); - server.begin(); - if (udpPort > 0 && udpPort != ntpLocalPort) - { - udpConnected = notifierUdp.begin(udpPort); - } - if (udpRgbPort > 0 && udpRgbPort != ntpLocalPort && udpRgbPort != udpPort) - { - udpRgbConnected = rgbUdp.begin(udpRgbPort); - } - - dnsServer.setErrorReplyCode(DNSReplyCode::NoError); - dnsServer.start(53, "*", WiFi.softAPIP()); - } - apActive = true; -} - -void initConnection() -{ - WiFi.disconnect(); //close old connections - #ifdef ESP8266 - WiFi.setPhyMode(WIFI_PHY_MODE_11N); - #endif - - if (staticIP[0] != 0 && staticGateway[0] != 0) - { - WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(8,8,8,8)); - } else - { - WiFi.config(0U, 0U, 0U); - } - - lastReconnectAttempt = millis(); - - if (!WLED_WIFI_CONFIGURED) - { - DEBUG_PRINT("No connection configured. "); - if (!apActive) initAP(); //instantly go to ap mode - return; - } else if (!apActive) { - if (apBehavior == AP_BEHAVIOR_ALWAYS) - { - initAP(); - } else - { - DEBUG_PRINTLN("Access point disabled."); - WiFi.softAPdisconnect(true); - } - } - showWelcomePage = false; - - DEBUG_PRINT("Connecting to "); - DEBUG_PRINT(clientSSID); - DEBUG_PRINTLN("..."); - - #ifdef ESP8266 - WiFi.hostname(serverDescription); - #endif - - WiFi.begin(clientSSID, clientPass); - - #ifdef ARDUINO_ARCH_ESP32 - WiFi.setSleep(!noWifiSleep); - WiFi.setHostname(serverDescription); - #else - wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); - #endif -} - -void initInterfaces() { - DEBUG_PRINTLN("Init STA interfaces"); - - if (hueIP[0] == 0) - { - hueIP[0] = WiFi.localIP()[0]; - hueIP[1] = WiFi.localIP()[1]; - hueIP[2] = WiFi.localIP()[2]; - } - - //init Alexa hue emulation - if (alexaEnabled) alexaInit(); - - #ifndef WLED_DISABLE_OTA - if (aOtaEnabled) ArduinoOTA.begin(); - #endif - - strip.service(); - // Set up mDNS responder: - if (strlen(cmDNS) > 0) - { - if (!aOtaEnabled) MDNS.begin(cmDNS); - - DEBUG_PRINTLN("mDNS started"); - MDNS.addService("http", "tcp", 80); - MDNS.addService("wled", "tcp", 80); - MDNS.addServiceTxt("wled", "tcp", "mac", escapedMac.c_str()); - } - server.begin(); - - if (udpPort > 0 && udpPort != ntpLocalPort) - { - udpConnected = notifierUdp.begin(udpPort); - if (udpConnected && udpRgbPort != udpPort) udpRgbConnected = rgbUdp.begin(udpRgbPort); - } - if (ntpEnabled) ntpConnected = ntpUdp.begin(ntpLocalPort); - - initBlynk(blynkApiKey); - e131.begin((e131Multicast) ? E131_MULTICAST : E131_UNICAST , e131Universe, E131_MAX_UNIVERSE_COUNT); - reconnectHue(); - initMqtt(); - interfacesInited = true; - wasConnected = true; -} - -byte stacO = 0; -uint32_t lastHeap; -unsigned long heapTime = 0; - -void handleConnection() { - if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) return; - if (lastReconnectAttempt == 0) initConnection(); - - //reconnect WiFi to clear stale allocations if heap gets too low - if (millis() - heapTime > 5000) - { - uint32_t heap = ESP.getFreeHeap(); - if (heap < 9000 && lastHeap < 9000) { - DEBUG_PRINT("Heap too low! "); - DEBUG_PRINTLN(heap); - forceReconnect = true; - } - lastHeap = heap; - heapTime = millis(); - } - - byte stac = 0; - if (apActive) { - #ifdef ESP8266 - stac = wifi_softap_get_station_num(); - #else - wifi_sta_list_t stationList; - esp_wifi_ap_get_sta_list(&stationList); - stac = stationList.num; - #endif - if (stac != stacO) - { - stacO = stac; - DEBUG_PRINT("Connected AP clients: "); - DEBUG_PRINTLN(stac); - if (!WLED_CONNECTED && WLED_WIFI_CONFIGURED) { //trying to connect, but not connected - if (stac) WiFi.disconnect(); //disable search so that AP can work - else initConnection(); //restart search - } - } - } - if (forceReconnect) { - DEBUG_PRINTLN("Forcing reconnect."); - initConnection(); - interfacesInited = false; - forceReconnect = false; - wasConnected = false; - return; - } - if (!WLED_CONNECTED) { - if (interfacesInited) { - DEBUG_PRINTLN("Disconnected!"); - interfacesInited = false; - initConnection(); - } - if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) initConnection(); - if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) initAP(); - } else if (!interfacesInited) { //newly connected - DEBUG_PRINTLN(""); - DEBUG_PRINT("Connected! IP address: "); - DEBUG_PRINTLN(WiFi.localIP()); - initInterfaces(); - userConnected(); - - //shut down AP - if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) - { - dnsServer.stop(); - WiFi.softAPdisconnect(true); - apActive = false; - DEBUG_PRINTLN("Access point disabled."); - } - } -} - -//by https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp -int getSignalQuality(int rssi) -{ - int quality = 0; - - if (rssi <= -100) { - quality = 0; - } else if (rssi >= -50) { - quality = 100; - } else { - quality = 2 * (rssi + 100); - } - return quality; -} diff --git a/wled00/wled11_ol.ino b/wled00/wled11_ol.ino deleted file mode 100644 index 93f7b96df..000000000 --- a/wled00/wled11_ol.ino +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Used to draw clock overlays over the strip - */ - -void initCronixie() -{ - if (overlayCurrent == 3 && !cronixieInit) - { - setCronixie(); - strip.getSegment(0).grouping = 10; //10 LEDs per digit - cronixieInit = true; - } else if (cronixieInit && overlayCurrent != 3) - { - strip.getSegment(0).grouping = 1; - cronixieInit = false; - } -} - - -void handleOverlays() -{ - if (millis() - overlayRefreshedTime > overlayRefreshMs) - { - initCronixie(); - updateLocalTime(); - checkTimers(); - checkCountdown(); - if (overlayCurrent == 3) _overlayCronixie();//Diamex cronixie clock kit - overlayRefreshedTime = millis(); - } -} - - -void _overlayAnalogClock() -{ - int overlaySize = overlayMax - overlayMin +1; - if (countdownMode) - { - _overlayAnalogCountdown(); return; - } - double hourP = ((double)(hour(local)%12))/12; - double minuteP = ((double)minute(local))/60; - hourP = hourP + minuteP/12; - double secondP = ((double)second(local))/60; - int hourPixel = floor(analogClock12pixel + overlaySize*hourP); - if (hourPixel > overlayMax) hourPixel = overlayMin -1 + hourPixel - overlayMax; - int minutePixel = floor(analogClock12pixel + overlaySize*minuteP); - if (minutePixel > overlayMax) minutePixel = overlayMin -1 + minutePixel - overlayMax; - int secondPixel = floor(analogClock12pixel + overlaySize*secondP); - if (secondPixel > overlayMax) secondPixel = overlayMin -1 + secondPixel - overlayMax; - if (analogClockSecondsTrail) - { - if (secondPixel < analogClock12pixel) - { - strip.setRange(analogClock12pixel, overlayMax, 0xFF0000); - strip.setRange(overlayMin, secondPixel, 0xFF0000); - } else - { - strip.setRange(analogClock12pixel, secondPixel, 0xFF0000); - } - } - if (analogClock5MinuteMarks) - { - int pix; - for (int i = 0; i <= 12; i++) - { - pix = analogClock12pixel + round((overlaySize / 12.0) *i); - if (pix > overlayMax) pix -= overlaySize; - strip.setPixelColor(pix, 0x00FFAA); - } - } - if (!analogClockSecondsTrail) strip.setPixelColor(secondPixel, 0xFF0000); - strip.setPixelColor(minutePixel, 0x00FF00); - strip.setPixelColor(hourPixel, 0x0000FF); - overlayRefreshMs = 998; -} - - -void _overlayAnalogCountdown() -{ - if (now() < countdownTime) - { - long diff = countdownTime - now(); - double pval = 60; - if (diff > 31557600L) //display in years if more than 365 days - { - pval = 315576000L; //10 years - } else if (diff > 2592000L) //display in months if more than a month - { - pval = 31557600L; //1 year - } else if (diff > 604800) //display in weeks if more than a week - { - pval = 2592000L; //1 month - } else if (diff > 86400) //display in days if more than 24 hours - { - pval = 604800; //1 week - } else if (diff > 3600) //display in hours if more than 60 minutes - { - pval = 86400; //1 day - } else if (diff > 60) //display in minutes if more than 60 seconds - { - pval = 3600; //1 hour - } - int overlaySize = overlayMax - overlayMin +1; - double perc = (pval-(double)diff)/pval; - if (perc > 1.0) perc = 1.0; - byte pixelCnt = perc*overlaySize; - if (analogClock12pixel + pixelCnt > overlayMax) - { - strip.setRange(analogClock12pixel, overlayMax, ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]); - strip.setRange(overlayMin, overlayMin +pixelCnt -(1+ overlayMax -analogClock12pixel), ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]); - } else - { - strip.setRange(analogClock12pixel, analogClock12pixel + pixelCnt, ((uint32_t)colSec[3] << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]); - } - } - overlayRefreshMs = 998; -} - - -void handleOverlayDraw() { - if (!overlayCurrent) return; - switch (overlayCurrent) - { - case 1: _overlayAnalogClock(); break; - case 3: _drawOverlayCronixie(); break; - } -} diff --git a/wled00/wled21_dmx.ino b/wled00/wled21_dmx.ino deleted file mode 100644 index e48b051a0..000000000 --- a/wled00/wled21_dmx.ino +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Support for DMX via MAX485. - * Needs the espdmx library. You might have to change the output pin within the library. Sketchy, i know. - * https://github.com/Rickgg/ESP-Dmx - */ -#ifdef WLED_ENABLE_DMX - -void handleDMX() { - WS2812FX::Segment& seg = strip.getSegment(DMXSegment); - - if (!seg.isActive()) { - return; - } - - // TODO: calculate brightness manually if no shutter channel is set - uint8_t brightness = strip.getBrightness(); - - // Calculate the start LED depending on segment and DMXStartLED config - uint8_t startLed = seg.start + DMXStartLED; - - for (int i = startLed; i < seg.stop; i++) { - uint32_t in = strip.getPixelColor(i); // time to get the colors for the individual fixtures as suggested by AirCookie at issue #462 - byte w = in >> 24 & 0xFF; - byte r = in >> 16 & 0xFF; - byte g = in >> 8 & 0xFF; - byte b = in & 0xFF; - - int DMXFixtureStart = DMXStart + (DMXGap * (i - startLed)); - for (int j = 0; j < DMXChannels; j++) { - int DMXAddr = DMXFixtureStart + j; - switch (DMXFixtureMap[j]) { - case 0: // Set this channel to 0. Good way to tell strobe- and fade-functions to fuck right off. - dmx.write(DMXAddr, 0); - break; - case 1: // Red - dmx.write(DMXAddr, r); - break; - case 2: // Green - dmx.write(DMXAddr, g); - break; - case 3: // Blue - dmx.write(DMXAddr, b); - break; - case 4: // White - dmx.write(DMXAddr, w); - break; - case 5: // Shutter channel. Controls the brightness. - dmx.write(DMXAddr, brightness); - break; - case 6:// Sets this channel to 255. Like 0, but more wholesome. - dmx.write(DMXAddr, 255); - break; - } - } - } - - dmx.update(); // update the DMX bus -} - -#else -void handleDMX() {} -#endif diff --git a/wled00/wled01_eeprom.ino b/wled00/wled_eeprom.cpp similarity index 97% rename from wled00/wled01_eeprom.ino rename to wled00/wled_eeprom.cpp index c741d4e3f..b06371ee6 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled_eeprom.cpp @@ -1,10 +1,11 @@ +#include +#include "wled.h" + /* * Methods to handle saving and loading to non-volatile memory * EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map */ -#define EEPSIZE 2560 //Maximum is 4096 - //eeprom Version code, enables default settings instead of 0 init on update #define EEPVER 18 //0 -> old version, default @@ -270,9 +271,6 @@ void saveSettingsToEEPROM() for (int i=0; i<15; i++) { EEPROM.write(2535+i, DMXFixtureMap[i]); } // last used: 2549. maybe leave a few bytes for future expansion and go on with 2600 kthxbye. - - EEPROM.write(2550, DMXSegment); - EEPROM.write(2551, DMXStartLED); #endif commit(); @@ -554,12 +552,11 @@ void loadSettingsFromEEPROM(bool first) DMXChannels = EEPROM.read(2530); DMXGap = EEPROM.read(2531) + ((EEPROM.read(2532) << 8) & 0xFF00); DMXStart = EEPROM.read(2533) + ((EEPROM.read(2534) << 8) & 0xFF00); - DMXSegment = EEPROM.read(2550); - DMXStartLED = EEPROM.read(2551); for (int i=0;i<15;i++) { DMXFixtureMap[i] = EEPROM.read(2535+i); - } //last used: 2549. maybe leave a few bytes for future expansion and go on with 2600 kthxbye. + } //last used: 2549 + EEPROM.write(2550, DMXStartLED); #endif //user MOD memory @@ -596,7 +593,7 @@ void savedToPresets() } } -bool applyPreset(byte index, bool loadBri = true) +bool applyPreset(byte index, bool loadBri) { if (index == 255 || index == 0) { @@ -634,7 +631,7 @@ bool applyPreset(byte index, bool loadBri = true) return true; } -void savePreset(byte index, bool persist = true) +void savePreset(byte index, bool persist) { if (index > 16) return; if (index < 1) {saveSettingsToEEPROM();return;} @@ -702,7 +699,7 @@ void applyMacro(byte index) } -void saveMacro(byte index, String mc, bool persist = true) //only commit on single save, not in settings +void saveMacro(byte index, String mc, bool persist) //only commit on single save, not in settings { index-=1; if (index > 15) return; diff --git a/wled00/wled04_file.ino b/wled00/wled_serial.cpp similarity index 55% rename from wled00/wled04_file.ino rename to wled00/wled_serial.cpp index de7523281..a472729d1 100644 --- a/wled00/wled04_file.ino +++ b/wled00/wled_serial.cpp @@ -1,6 +1,9 @@ +#include "wled.h" + /* - * Utility for SPIFFS filesystem & Serial console + * Adalight handler */ + enum class AdaState { Header_A, Header_d, @@ -78,44 +81,3 @@ void handleSerial() } #endif } - - -#if !defined WLED_DISABLE_FILESYSTEM && defined WLED_ENABLE_FS_SERVING -//Un-comment any file types you need -String getContentType(AsyncWebServerRequest* request, String filename){ - if(request->hasArg("download")) return "application/octet-stream"; - else if(filename.endsWith(".htm")) return "text/html"; - else if(filename.endsWith(".html")) return "text/html"; -// else if(filename.endsWith(".css")) return "text/css"; -// else if(filename.endsWith(".js")) return "application/javascript"; - else if(filename.endsWith(".json")) return "application/json"; - else if(filename.endsWith(".png")) return "image/png"; -// else if(filename.endsWith(".gif")) return "image/gif"; - else if(filename.endsWith(".jpg")) return "image/jpeg"; - else if(filename.endsWith(".ico")) return "image/x-icon"; -// else if(filename.endsWith(".xml")) return "text/xml"; -// else if(filename.endsWith(".pdf")) return "application/x-pdf"; -// else if(filename.endsWith(".zip")) return "application/x-zip"; -// else if(filename.endsWith(".gz")) return "application/x-gzip"; - return "text/plain"; -} - -bool handleFileRead(AsyncWebServerRequest* request, String path){ - DEBUG_PRINTLN("FileRead: " + path); - if(path.endsWith("/")) path += "index.htm"; - String contentType = getContentType(request, path); - String pathWithGz = path + ".gz"; - if(SPIFFS.exists(pathWithGz)){ - request->send(SPIFFS, pathWithGz, contentType); - return true; - } - if(SPIFFS.exists(path)) { - request->send(SPIFFS, path, contentType); - return true; - } - return false; -} - -#else -bool handleFileRead(AsyncWebServerRequest*, String path){return false;} -#endif diff --git a/wled00/wled18_server.ino b/wled00/wled_server.cpp similarity index 99% rename from wled00/wled18_server.ino rename to wled00/wled_server.cpp index f11a64bec..cd623bc49 100644 --- a/wled00/wled18_server.ino +++ b/wled00/wled_server.cpp @@ -1,5 +1,7 @@ +#include "wled.h" + /* - * Server page definitions + * Integrated HTTP web server page declarations */ //Is this an IP? @@ -303,7 +305,7 @@ String msgProcessor(const String& var) } -void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl="", byte optionT=255) +void serveMessage(AsyncWebServerRequest* request, uint16_t code, String headl, String subl, byte optionT) { messageHead = headl; messageSub = subl; diff --git a/wled00/wled02_xml.ino b/wled00/xml.cpp similarity index 99% rename from wled00/wled02_xml.ino rename to wled00/xml.cpp index a05c1e97b..1e14ea7da 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/xml.cpp @@ -1,9 +1,11 @@ +#include "wled.h" + /* * Sending XML status files to client */ //build XML response to HTTP /win API request -char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr) +char* XML_response(AsyncWebServerRequest *request, char* dest) { char sbuf[(dest == nullptr)?1024:1]; //allocate local buffer if none passed obuf = (dest == nullptr)? sbuf:dest; @@ -455,7 +457,6 @@ void getSettingsJS(byte subPage, char* dest) sappend('v',"CN",DMXChannels); sappend('v',"CG",DMXGap); sappend('v',"CS",DMXStart); - sappend('v',"SEG",DMXSegment); sappend('v',"SL",DMXStartLED); sappend('i',"CH1",DMXFixtureMap[0]); From 3e9b44d19384ac98fd914f76c2882217fa495530 Mon Sep 17 00:00:00 2001 From: Ament Martin Date: Fri, 10 Apr 2020 21:33:16 +0200 Subject: [PATCH 152/509] Added support for BW-LT11 --- platformio_override.ini.example | 4 +++- wled00/NpbWrapper.h | 14 ++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/platformio_override.ini.example b/platformio_override.ini.example index 46119f159..ba829aa1d 100644 --- a/platformio_override.ini.example +++ b/platformio_override.ini.example @@ -28,7 +28,9 @@ build_flags = ${common.build_flags_esp8266} ; to drive analog LED strips (aka 5050), uncomment the following ; PWM pins 5,12,13,15 are used with Magic Home LED Controller (default) ; -D WLED_USE_ANALOG_LEDS -; for the H801 controler (PINs 15,13,12,14 (W2 = 04)) uncomment this +; for the H801 controller (PINs 15,13,12,14 (W2 = 04)) uncomment this ; -D WLED_USE_H801 +; for the BW-LT11 controller (PINs 12,4,14,5 ) uncomment this +; -D WLED_USE_BWLT11 ; and to enable channel 5 for RGBW-CT led strips this ; -D WLED_USE_5CH_LEDS diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 6e58b7197..1f360bfc2 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -55,12 +55,18 @@ #undef BTNPIN #undef IR_PIN #define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 + #elif defined(WLED_USE_BWLT11) + //PWM pins - to use with BW-LT11 + #define RPIN 12 //R pin for analog LED strip + #define GPIN 4 //G pin for analog LED strip + #define BPIN 14 //B pin for analog LED strip + #define WPIN 5 //W pin for analog LED strip #else //PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller - #define RPIN 5 //R pin for analog LED strip - #define GPIN 12 //G pin for analog LED strip - #define BPIN 15 //B pin for analog LED strip - #define WPIN 13 //W pin for analog LED strip + #define RPIN 5 //R pin for analog LED strip + #define GPIN 12 //G pin for analog LED strip + #define BPIN 15 //B pin for analog LED strip + #define WPIN 13 //W pin for analog LED strip #endif #undef RLYPIN #define RLYPIN -1 //disable as pin 12 is used by analog LEDs From e12757dbb94d498acc98c6440e28398cc0446f88 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Mon, 13 Apr 2020 00:42:27 +0200 Subject: [PATCH 153/509] Add Art-Net support (#417) --- CHANGELOG.md | 6 +- platformio.ini | 10 + wled00/const.h | 1 + wled00/data/settings_sync.htm | 240 ++++++++---------- wled00/e131.cpp | 96 ++++--- wled00/fcn_declare.h | 14 +- wled00/html_settings.h | 108 ++++---- wled00/set.cpp | 6 +- wled00/src/dependencies/e131/ESPAsyncE131.cpp | 57 +++-- wled00/src/dependencies/e131/ESPAsyncE131.h | 52 ++-- wled00/udp.cpp | 6 +- wled00/wled.cpp | 2 +- wled00/wled.h | 3 +- wled00/wled_eeprom.cpp | 11 +- wled00/wled_serial.cpp | 2 +- wled00/xml.cpp | 6 +- 16 files changed, 325 insertions(+), 295 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31c22f526..1277b32e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ### Development versions after 0.9.1 release +#### Build 2004120 + +- Added Art-Net support +- Added OTA platform to platformio.ini #### Build 2004100 @@ -23,7 +27,7 @@ #### Build 2003262 -- Fixed compilation for Analog LEDs +- Fixed compilation for Analog LEDs - Fixed sync settings network port fields too small #### Build 2003261 diff --git a/platformio.ini b/platformio.ini index 91bdd8675..495176133 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,6 +30,7 @@ default_envs = d1_mini, esp01, esp01_1m_ota, esp32dev ; default_envs = d1_mini ; default_envs = heltec_wifi_kit_8 ; default_envs = d1_mini_debug +; default_envs = d1_mini_ota ; default_envs = esp32dev ; default_envs = esp8285_4CH_MagicHome ; default_envs = esp8285_4CH_H801 @@ -241,6 +242,15 @@ platform = ${common.platform_latest} board_build.ldscript = ${common.ldscript_4m1m} build_flags = ${common.build_flags_esp8266} ${common.debug_flags} +[env:d1_mini_ota] +board = d1_mini +upload_protocol = espota +# exchange for your WLED IP +upload_port = "10.10.1.27" +platform = ${common.platform_latest} +board_build.ldscript = ${common.ldscript_4m1m} +build_flags = ${common.build_flags_esp8266} + # ------------------------------------------------------------------------------ # custom board configurations # ------------------------------------------------------------------------------ diff --git a/wled00/const.h b/wled00/const.h index 173d7e7d5..5cd4b02f4 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -43,6 +43,7 @@ #define REALTIME_MODE_HYPERION 3 #define REALTIME_MODE_E131 4 #define REALTIME_MODE_ADALIGHT 5 +#define REALTIME_MODE_ARTNET 6 //E1.31 DMX modes #define DMX_MODE_DISABLED 0 //not used diff --git a/wled00/data/settings_sync.htm b/wled00/data/settings_sync.htm index 5cf4b6082..91fe89924 100644 --- a/wled00/data/settings_sync.htm +++ b/wled00/data/settings_sync.htm @@ -1,141 +1,105 @@ - - - - Sync Settings - - - - -
-
-
-

Sync setup

-

Button setup

- On/Off button enabled:
- Infrared receiver enabled:
- IR info -

WLED Sync UDP Broadcast

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

Realtime

- Receive UDP realtime:

- E1.31 (sACN)
- Skip out-of-sequence packets (freeze instead of flicker):
- Multicast mode:
- E1.31 start universe:
- Reboot required. Check out LedFx!

- DMX start address:
- DMX mode: disabled
- Single RGB (3 Channels for all LEDs: Red Green Blue)
- Single DRGB (4 Channels for all LEDs: Dimmer Red Green Blue)
- Effect (11 Channels parametrizing Effects: Dimmer Effect Speed Intensity Palette PriRed PriGreen PriBlue SecRed SecGreen SecBlue)
- Multiple RGB (3 Channels for each LED: Red Green Blue)
- Multiple DRGB (1+3 Channels for each LED: Dimmer Red1 Green1 Blue1 Red2 Green2 Blue2...)
- Reboot required. Check out LedFx!

- Timeout: ms
- Force max brightness:
- Disable realtime gamma correction:
- Realtime LED offset: -

Alexa Voice Assistant

- Emulate Alexa device:
- Alexa invocation name: -

Blynk

- Blynk, MQTT and Hue sync all connect to external hosts!
- This may impact the responsiveness of the ESP8266.

- For best results, only use one of these services at a time.
- (alternatively, connect a second ESP to them and use the UDP sync)

- Device Auth token:
- Clear the token field to disable. Setup info -

MQTT

- Enable MQTT:
- Broker:
- Port:
- The MQTT credentials are sent over an unsecured connection.
- Never use the MQTT password for another service!

- Username:
- Password:
- Client ID:
- Device Topic:
- Group Topic:
- MQTT info -

Philips Hue

- You can find the bridge IP and the light number in the 'About' section of the hue app.
- Poll Hue light every ms:
- Then, receive On/Off, Brightness, and Color
- Hue Bridge IP:
- . - . - . -
- Press the pushlink button on the bridge, after that save this page!
- (when first connecting)
- Hue status: Internal ESP Error!
- -
+Sync Settings + + + +
+
+
+

Sync setup

+

Button setup

+On/Off button enabled:
+Infrared remote: +
+IR info +

WLED Broadcast

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

Realtime

+Receive UDP realtime:

+Network DMX input
+Type: +
+
Port:
+Multicast:
+Start universe:
+Reboot required. Check out LedFx!
+Skip out-of-sequence packets:
+DMX start address:
+DMX mode: +
+E1.31 info
+Timeout: ms
+Force max brightness:
+Disable realtime gamma correction:
+Realtime LED offset: +

Alexa Voice Assistant

+Emulate Alexa device:
+Alexa invocation name: +

Blynk

+Blynk, MQTT and Hue sync all connect to external hosts!
+This may impact the responsiveness of the ESP8266.

+For best results, only use one of these services at a time.
+(alternatively, connect a second ESP to them and use the UDP sync)

+Device Auth token:
+Clear the token field to disable. Setup info +

MQTT

+Enable MQTT:
+Broker: +Port:
+The MQTT credentials are sent over an unsecured connection.
+Never use the MQTT password for another service!

+Username:
+Password:
+Client ID:
+Device Topic:
+Group Topic:
+Reboot required to apply changes. MQTT info +

Philips Hue

+You can find the bridge IP and the light number in the 'About' section of the hue app.
+Poll Hue light every ms:
+Then, receive On/Off, Brightness, and Color
+Hue Bridge IP:
+ . + . + . +
+Press the pushlink button on the bridge, after that save this page!
+(when first connecting)
+Hue status: Disabled in this build
+ +
\ No newline at end of file diff --git a/wled00/e131.cpp b/wled00/e131.cpp index 2034f84d9..6e774194a 100644 --- a/wled00/e131.cpp +++ b/wled00/e131.cpp @@ -4,29 +4,45 @@ * E1.31 handler */ -void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ +void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){ //E1.31 protocol support - uint16_t uni = htons(p->universe); - uint8_t previousUniverses = uni - e131Universe; - uint16_t possibleLEDsInCurrentUniverse; - uint16_t dmxChannels = htons(p->property_value_count) -1; + uint16_t uni = 0, dmxChannels = 0; + uint8_t* e131_data = nullptr; + uint8_t seq = 0, mde = REALTIME_MODE_E131; + + if (isArtnet) + { + uni = p->art_universe; + dmxChannels = htons(p->art_length); + e131_data = p->art_data; + seq = p->art_sequence_number; + mde = REALTIME_MODE_ARTNET; + } else { + uni = htons(p->universe); + dmxChannels = htons(p->property_value_count) -1; + e131_data = p->property_values; + seq = p->sequence_number; + } // only listen for universes we're handling & allocated memory if (uni >= (e131Universe + E131_MAX_UNIVERSE_COUNT)) return; + uint8_t previousUniverses = uni - e131Universe; + uint16_t possibleLEDsInCurrentUniverse; + if (e131SkipOutOfSequence) - if (p->sequence_number < e131LastSequenceNumber[uni-e131Universe] && p->sequence_number > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){ + if (seq < e131LastSequenceNumber[uni-e131Universe] && seq > 20 && e131LastSequenceNumber[uni-e131Universe] < 250){ DEBUG_PRINT("skipping E1.31 frame (last seq="); DEBUG_PRINT(e131LastSequenceNumber[uni-e131Universe]); DEBUG_PRINT(", current seq="); - DEBUG_PRINT(p->sequence_number); + DEBUG_PRINT(seq); DEBUG_PRINT(", universe="); DEBUG_PRINT(uni); DEBUG_PRINTLN(")"); return; } - e131LastSequenceNumber[uni-e131Universe] = p->sequence_number; + e131LastSequenceNumber[uni-e131Universe] = seq; // update status info realtimeIP = clientIP; @@ -39,46 +55,46 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ case DMX_MODE_SINGLE_RGB: if (uni != e131Universe) return; if (dmxChannels-DMXAddress+1 < 3) return; - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); + realtimeLock(realtimeTimeoutMs, mde); for (uint16_t i = 0; i < ledCount; i++) - setRealtimePixel(i, p->property_values[DMXAddress+0], p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], 0); + setRealtimePixel(i, e131_data[DMXAddress+0], e131_data[DMXAddress+1], e131_data[DMXAddress+2], 0); break; case DMX_MODE_SINGLE_DRGB: if (uni != e131Universe) return; if (dmxChannels-DMXAddress+1 < 4) return; - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); - if (DMXOldDimmer != p->property_values[DMXAddress+0]) { - DMXOldDimmer = p->property_values[DMXAddress+0]; - bri = p->property_values[DMXAddress+0]; + realtimeLock(realtimeTimeoutMs, mde); + if (DMXOldDimmer != e131_data[DMXAddress+0]) { + DMXOldDimmer = e131_data[DMXAddress+0]; + bri = e131_data[DMXAddress+0]; strip.setBrightness(bri); } for (uint16_t i = 0; i < ledCount; i++) - setRealtimePixel(i, p->property_values[DMXAddress+1], p->property_values[DMXAddress+2], p->property_values[DMXAddress+3], 0); + setRealtimePixel(i, e131_data[DMXAddress+1], e131_data[DMXAddress+2], e131_data[DMXAddress+3], 0); break; case DMX_MODE_EFFECT: if (uni != e131Universe) return; if (dmxChannels-DMXAddress+1 < 11) return; - if (DMXOldDimmer != p->property_values[DMXAddress+0]) { - DMXOldDimmer = p->property_values[DMXAddress+0]; - bri = p->property_values[DMXAddress+0]; + if (DMXOldDimmer != e131_data[DMXAddress+0]) { + DMXOldDimmer = e131_data[DMXAddress+0]; + bri = e131_data[DMXAddress+0]; } - if (p->property_values[DMXAddress+1] < MODE_COUNT) - effectCurrent = p->property_values[DMXAddress+ 1]; - effectSpeed = p->property_values[DMXAddress+ 2]; // flickers - effectIntensity = p->property_values[DMXAddress+ 3]; - effectPalette = p->property_values[DMXAddress+ 4]; - col[0] = p->property_values[DMXAddress+ 5]; - col[1] = p->property_values[DMXAddress+ 6]; - col[2] = p->property_values[DMXAddress+ 7]; - colSec[0] = p->property_values[DMXAddress+ 8]; - colSec[1] = p->property_values[DMXAddress+ 9]; - colSec[2] = p->property_values[DMXAddress+10]; + if (e131_data[DMXAddress+1] < MODE_COUNT) + effectCurrent = e131_data[DMXAddress+ 1]; + effectSpeed = e131_data[DMXAddress+ 2]; // flickers + effectIntensity = e131_data[DMXAddress+ 3]; + effectPalette = e131_data[DMXAddress+ 4]; + col[0] = e131_data[DMXAddress+ 5]; + col[1] = e131_data[DMXAddress+ 6]; + col[2] = e131_data[DMXAddress+ 7]; + colSec[0] = e131_data[DMXAddress+ 8]; + colSec[1] = e131_data[DMXAddress+ 9]; + colSec[2] = e131_data[DMXAddress+10]; if (dmxChannels-DMXAddress+1 > 11) { - col[3] = p->property_values[DMXAddress+11]; //white - colSec[3] = p->property_values[DMXAddress+12]; + col[3] = e131_data[DMXAddress+11]; //white + colSec[3] = e131_data[DMXAddress+12]; } transitionDelayTemp = 0; // act fast colorUpdated(NOTIFIER_CALL_MODE_NOTIFICATION); // don't send UDP @@ -86,13 +102,13 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ break; case DMX_MODE_MULTIPLE_RGB: - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); + realtimeLock(realtimeTimeoutMs, mde); if (previousUniverses == 0) { // first universe of this fixture possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3; for (uint16_t i = 0; i < ledCount; i++) { if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[DMXAddress+i*3+0], p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], 0); + setRealtimePixel(i, e131_data[DMXAddress+i*3+0], e131_data[DMXAddress+i*3+1], e131_data[DMXAddress+i*3+2], 0); } } else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) { // additional universe(s) of this fixture @@ -102,24 +118,24 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) { uint8_t j = i - numberOfLEDsInPreviousUniverses; if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0); + setRealtimePixel(i, e131_data[j*3+1], e131_data[j*3+2], e131_data[j*3+3], 0); } } break; case DMX_MODE_MULTIPLE_DRGB: - arlsLock(realtimeTimeoutMs, REALTIME_MODE_E131); + realtimeLock(realtimeTimeoutMs, mde); if (previousUniverses == 0) { // first universe of this fixture - if (DMXOldDimmer != p->property_values[DMXAddress+0]) { - DMXOldDimmer = p->property_values[DMXAddress+0]; - bri = p->property_values[DMXAddress+0]; + if (DMXOldDimmer != e131_data[DMXAddress+0]) { + DMXOldDimmer = e131_data[DMXAddress+0]; + bri = e131_data[DMXAddress+0]; strip.setBrightness(bri); } possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress) / 3; for (uint16_t i = 0; i < ledCount; i++) { if (i >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[DMXAddress+i*3+1], p->property_values[DMXAddress+i*3+2], p->property_values[DMXAddress+i*3+3], 0); + setRealtimePixel(i, e131_data[DMXAddress+i*3+1], e131_data[DMXAddress+i*3+2], e131_data[DMXAddress+i*3+3], 0); } } else if (previousUniverses > 0 && uni < (e131Universe + E131_MAX_UNIVERSE_COUNT)) { // additional universe(s) of this fixture @@ -129,7 +145,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP){ for (uint16_t i = numberOfLEDsInPreviousUniverses; i < ledCount; i++) { uint8_t j = i - numberOfLEDsInPreviousUniverses; if (j >= possibleLEDsInCurrentUniverse) break; // more LEDs will follow in next universe(s) - setRealtimePixel(i, p->property_values[j*3+1], p->property_values[j*3+2], p->property_values[j*3+3], 0); + setRealtimePixel(i, e131_data[j*3+1], e131_data[j*3+2], e131_data[j*3+3], 0); } } break; diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 7261efcb1..2d8401bc8 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -42,7 +42,7 @@ void initDMX(); void handleDMX(); //e131.cpp -void handleE131Packet(e131_packet_t* p, IPAddress clientIP); +void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet); //file.cpp bool handleFileRead(AsyncWebServerRequest*, String path); @@ -103,12 +103,6 @@ void handleNightlight(); bool initMqtt(); void publishMqtt(); -//notify.cpp -void notify(byte callMode, bool followUp=false); -void arlsLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC); -void handleNotifications(); -void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w); - //ntp.cpp void handleNetworkTime(); void sendNTPPacket(); @@ -140,6 +134,12 @@ bool handleSet(AsyncWebServerRequest *request, const String& req); int getNumVal(const String* req, uint16_t pos); bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte maxv=255); +//udp.cpp +void notify(byte callMode, bool followUp=false); +void realtimeLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC); +void handleNotifications(); +void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w); + //usermod.cpp void userSetup(); void userConnected(); diff --git a/wled00/html_settings.h b/wled00/html_settings.h index fa0195334..009dda502 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -252,16 +252,16 @@ Sync button toggles both send and receive:
//sync settings const char PAGE_settings_sync[] PROGMEM = R"=====( -Sync Settings - -

WLED Software Update

Installed version: 0.9.1
Download the latest binary:

)====="; +

WLED Software Update

Installed version: 0.10.0p
Download the latest binary:

)====="; //new user welcome page diff --git a/wled00/html_settings.h b/wled00/html_settings.h index b44f29421..1e6db0d03 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -470,7 +470,7 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
Enable ArduinoOTA:

About

-WLED version 0.9.1

+WLED version 0.10.0p

Contributors, dependencies and special thanks
A huge thank you to everyone who helped me create WLED!

(c) 2016-2020 Christian Schwinne
diff --git a/wled00/html_ui.h b/wled00/html_ui.h index 45cd9da93..981e38454 100644 --- a/wled00/html_ui.h +++ b/wled00/html_ui.h @@ -10,1500 +10,1688 @@ * 4. update length value */ -const uint16_t PAGE_index_L = 23873; //length of the binary payload +const uint16_t PAGE_index_L = 26884; //length of the binary payload const uint8_t PAGE_index[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x08, 0x6d, 0xb9, 0x4d, 0x5e, 0x00, 0x03, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, - 0x68, 0x74, 0x6d, 0x00, 0xcc, 0x7d, 0x6b, 0x73, 0xda, 0xc8, 0xb6, 0xe8, 0xf7, 0xa9, 0xca, 0x7f, - 0x60, 0x3c, 0x75, 0x76, 0x92, 0xed, 0x60, 0x49, 0xbc, 0x8c, 0x93, 0x38, 0x67, 0xb7, 0x84, 0x00, - 0x01, 0x02, 0x04, 0x48, 0x80, 0x4f, 0xed, 0x0f, 0x42, 0x08, 0x21, 0x10, 0x08, 0x24, 0x81, 0x80, - 0xa9, 0xb9, 0xbf, 0xfd, 0xae, 0x6e, 0x3d, 0x10, 0x2f, 0xdb, 0x99, 0x9c, 0x5d, 0x75, 0x98, 0x31, - 0xd0, 0xaf, 0xd5, 0xab, 0xd7, 0x7b, 0x2d, 0xb5, 0x9d, 0xef, 0xbf, 0x97, 0x5a, 0x5c, 0x6f, 0xd8, - 0xe6, 0x53, 0x53, 0x6f, 0x61, 0xfd, 0xf8, 0xf0, 0xdb, 0xf7, 0xf8, 0x53, 0x57, 0xc7, 0xf8, 0x73, - 0xa1, 0x7b, 0x6a, 0x6a, 0xa9, 0x2e, 0xf4, 0xe7, 0xbb, 0xad, 0xa9, 0xfb, 0x2b, 0xdb, 0xf1, 0xee, - 0x52, 0x9a, 0xbd, 0xf4, 0xf4, 0xa5, 0xf7, 0x7c, 0xe7, 0x9b, 0x63, 0x6f, 0xfa, 0x3c, 0xd6, 0xb7, - 0xa6, 0xa6, 0xa7, 0x49, 0xe3, 0x4b, 0xca, 0x5c, 0x9a, 0x9e, 0xa9, 0x5a, 0x69, 0x57, 0x53, 0x2d, - 0xfd, 0x99, 0xf9, 0x92, 0x5a, 0x40, 0xcf, 0x62, 0xb3, 0x88, 0x3a, 0xee, 0x62, 0xb0, 0xda, 0x54, - 0x75, 0x5c, 0x1d, 0xc0, 0x6c, 0xbc, 0x49, 0xba, 0x78, 0x77, 0xb6, 0x9d, 0x37, 0xd5, 0x17, 0x7a, - 0x5a, 0xb3, 0x2d, 0xdb, 0x49, 0xec, 0xf8, 0x47, 0x86, 0xbc, 0x12, 0x40, 0xa2, 0x91, 0xbd, 0xee, - 0xde, 0x85, 0x4b, 0xd5, 0xd5, 0xca, 0xd2, 0xd3, 0x0b, 0x7b, 0x64, 0xc2, 0x87, 0xaf, 0x8f, 0xd2, - 0xd0, 0x91, 0xd6, 0xd4, 0x95, 0x3a, 0xb2, 0x74, 0xb2, 0xd2, 0x32, 0x97, 0xf3, 0x94, 0xa3, 0x5b, - 0xcf, 0x77, 0xee, 0x14, 0x4e, 0xa4, 0x6d, 0xbc, 0x94, 0x09, 0x80, 0xee, 0x52, 0x53, 0x47, 0x9f, - 0x3c, 0xdf, 0x8d, 0x55, 0x4f, 0xfd, 0x6a, 0x2e, 0x54, 0x43, 0xa7, 0x76, 0x69, 0x3c, 0xf0, 0x6d, - 0xa4, 0xba, 0x7a, 0x21, 0xf7, 0x05, 0x21, 0xc4, 0x22, 0xc4, 0x23, 0x1e, 0xde, 0xf1, 0x67, 0x05, - 0x71, 0x15, 0xfc, 0xad, 0x6c, 0xc0, 0x9b, 0x60, 0x49, 0xbd, 0xb9, 0xd6, 0xe4, 0xa6, 0x76, 0x1d, - 0xf7, 0x95, 0x64, 0x4b, 0xe8, 0x94, 0x05, 0xfc, 0x55, 0x0a, 0x66, 0x1b, 0x64, 0x6e, 0x95, 0x6a, - 0x53, 0x43, 0xdc, 0xc3, 0x33, 0xb5, 0x0e, 0x5f, 0x96, 0x5b, 0x02, 0x33, 0x83, 0x2e, 0xaa, 0xed, - 0xb7, 0x76, 0x46, 0xb3, 0xa2, 0x23, 0x59, 0xdc, 0xf1, 0x4f, 0x95, 0x82, 0x26, 0x71, 0xf5, 0x52, - 0x1f, 0x4d, 0x57, 0xa8, 0xf4, 0x92, 0x99, 0x14, 0xdb, 0xe2, 0x8c, 0xed, 0x66, 0xa5, 0x3e, 0x5d, - 0x94, 0xea, 0x19, 0xba, 0xae, 0xbe, 0x70, 0x19, 0x63, 0xc2, 0x3d, 0x4d, 0xb9, 0xe5, 0xda, 0xde, - 0xd8, 0x4d, 0x03, 0x75, 0x8c, 0xe1, 0xe3, 0x41, 0xdc, 0xa1, 0x7d, 0xd3, 0x92, 0xc7, 0x52, 0xd5, - 0x1a, 0x98, 0xc8, 0x6a, 0x65, 0xc4, 0x12, 0x2a, 0x15, 0xb2, 0xbc, 0xb2, 0x6e, 0x56, 0x91, 0x4e, - 0x23, 0x82, 0x88, 0x55, 0xee, 0xcd, 0xbb, 0x1b, 0x69, 0xc1, 0x71, 0x77, 0x14, 0xa6, 0x86, 0x67, - 0x7a, 0x96, 0xfe, 0xa3, 0xdf, 0xe0, 0x4b, 0xdf, 0xa9, 0xe0, 0x3b, 0x74, 0xba, 0x9a, 0x63, 0xae, - 0xbc, 0x1f, 0x93, 0xcd, 0x52, 0xf3, 0x4c, 0x7b, 0x99, 0x9a, 0xe8, 0xfa, 0x78, 0xa4, 0x6a, 0xf3, - 0x4f, 0x9f, 0xff, 0xfc, 0xeb, 0x3b, 0x15, 0x8e, 0xe2, 0x79, 0xde, 0x9e, 0x2c, 0xf8, 0xd7, 0x04, - 0x18, 0x91, 0x9e, 0xa8, 0x9a, 0x9e, 0xfa, 0xf3, 0xc3, 0x6f, 0x61, 0x63, 0x61, 0x5a, 0xfb, 0xaf, - 0xa9, 0xbb, 0xbe, 0x00, 0x34, 0x74, 0xef, 0xbe, 0x7d, 0xf8, 0xcd, 0x75, 0xb4, 0xaf, 0xa9, 0x8d, - 0x63, 0x7d, 0x22, 0x24, 0xc6, 0x7c, 0x32, 0x35, 0x15, 0xc3, 0x07, 0x42, 0x93, 0x35, 0xbe, 0x3d, - 0x99, 0x7c, 0x8b, 0x04, 0x83, 0xc8, 0x45, 0x44, 0xfb, 0x31, 0xfd, 0x54, 0xe9, 0x18, 0x88, 0x50, - 0x1e, 0xb1, 0x2e, 0xbc, 0xb9, 0xe4, 0x6b, 0xc5, 0x91, 0x42, 0x0a, 0xdf, 0x7a, 0xb1, 0x6d, 0x79, - 0x5f, 0xdc, 0xe3, 0x2f, 0x1c, 0x59, 0x40, 0xfa, 0x8c, 0x52, 0x9e, 0x46, 0x42, 0xbf, 0xe9, 0x0d, - 0x07, 0x84, 0x83, 0x36, 0xee, 0xec, 0xe0, 0xaf, 0x72, 0x67, 0xc2, 0x1a, 0xdd, 0xce, 0x4b, 0xa6, - 0x7c, 0xd0, 0x70, 0x7b, 0xed, 0xe3, 0x77, 0xc2, 0x48, 0xb2, 0x9e, 0x65, 0x97, 0xa3, 0xaa, 0xb5, - 0xc0, 0x4d, 0x0f, 0xaf, 0xec, 0xc3, 0xe6, 0xac, 0x32, 0x5f, 0xe6, 0x07, 0x6b, 0xaa, 0x32, 0xb5, - 0x86, 0xa4, 0x6d, 0x0c, 0xf1, 0xd4, 0x26, 0x96, 0x8b, 0x12, 0xec, 0x50, 0x10, 0x19, 0x15, 0x8f, - 0xc1, 0x50, 0xa5, 0x4c, 0x90, 0x9a, 0xe3, 0xb7, 0x1a, 0xd2, 0x86, 0x88, 0x79, 0xb2, 0x47, 0x83, - 0x4e, 0x0e, 0x9a, 0xc3, 0x31, 0xee, 0xac, 0xe3, 0x45, 0x9c, 0xbd, 0x44, 0xa8, 0x97, 0x5d, 0xec, - 0xb6, 0xc3, 0x0c, 0x0f, 0xf0, 0xe6, 0x04, 0x15, 0x05, 0x0f, 0x95, 0x5f, 0xfc, 0x45, 0xc5, 0x35, - 0x46, 0xfd, 0x72, 0x0e, 0x77, 0x56, 0x06, 0xe4, 0xf0, 0x46, 0x88, 0x24, 0x8d, 0xca, 0xcc, 0x66, - 0xd8, 0x67, 0x2c, 0x68, 0xbe, 0x58, 0xe4, 0x3c, 0xf8, 0x68, 0xe5, 0xba, 0x24, 0x37, 0xa4, 0xdc, - 0x80, 0xdd, 0x6a, 0x59, 0x8c, 0x9f, 0x63, 0x9c, 0x1c, 0x8a, 0x1c, 0x51, 0x84, 0x8d, 0x2a, 0x30, - 0x28, 0x63, 0x24, 0x5e, 0x90, 0x8b, 0x3b, 0xb9, 0x36, 0x5a, 0xcd, 0xb9, 0x03, 0x1e, 0xd6, 0x5d, - 0x24, 0xfa, 0x7c, 0xed, 0x2a, 0x89, 0x3b, 0xd7, 0x29, 0x8f, 0x31, 0xcb, 0xb3, 0xa8, 0x24, 0x52, - 0x45, 0x1a, 0x16, 0x97, 0xf0, 0xff, 0xf1, 0x40, 0xe2, 0x25, 0x44, 0x5f, 0x02, 0x3c, 0xf0, 0x9b, - 0x86, 0x35, 0x86, 0xb4, 0x59, 0x1f, 0x7f, 0x12, 0xbe, 0x57, 0x71, 0x67, 0x17, 0xa3, 0xce, 0x56, - 0xf0, 0x30, 0x2b, 0x61, 0x6e, 0xf2, 0x48, 0x68, 0xa1, 0x6c, 0xae, 0xb4, 0x34, 0xda, 0x2d, 0x56, - 0xcc, 0x09, 0x94, 0x61, 0x6f, 0xb8, 0x55, 0xae, 0xb1, 0x35, 0x98, 0x56, 0x69, 0x95, 0xeb, 0x8c, - 0xa6, 0x2d, 0x9d, 0xa7, 0x72, 0x83, 0xc3, 0xd4, 0xdc, 0x08, 0x5e, 0x6e, 0x96, 0x35, 0xed, 0x4d, - 0x7d, 0x91, 0x73, 0xda, 0xe6, 0x6e, 0xd3, 0x98, 0xe7, 0xf6, 0x83, 0x99, 0x78, 0xdf, 0x14, 0x73, - 0xf9, 0xd2, 0xcc, 0xd2, 0xdb, 0xfd, 0x1c, 0x55, 0x9d, 0x73, 0xba, 0x24, 0x51, 0x54, 0x96, 0xa2, - 0xfc, 0x10, 0xbf, 0xdb, 0xf0, 0x6d, 0x0c, 0xbf, 0x79, 0x7f, 0x13, 0xfe, 0x2c, 0x84, 0xdf, 0xc8, - 0xe5, 0xa8, 0x99, 0xd5, 0xba, 0x80, 0xcf, 0x52, 0xf7, 0xe2, 0xe4, 0xd0, 0xa1, 0xc4, 0x6a, 0xd1, - 0x9e, 0x6c, 0x76, 0x4f, 0xf9, 0x6a, 0x46, 0x9b, 0x0c, 0x3b, 0x4f, 0x52, 0xf5, 0x60, 0x4c, 0x6a, - 0x9d, 0xc7, 0x7c, 0xd5, 0x9b, 0xeb, 0x0c, 0x5b, 0x18, 0x56, 0x6d, 0x77, 0x5c, 0xe8, 0x64, 0xd5, - 0xea, 0x60, 0x38, 0xd6, 0x76, 0xcc, 0xb2, 0xaa, 0xc8, 0xe3, 0x56, 0xe7, 0x90, 0xaf, 0xb6, 0x7c, - 0x8d, 0xe9, 0xec, 0x7b, 0x55, 0x10, 0x26, 0x99, 0xf5, 0x33, 0x55, 0xb6, 0xa8, 0x01, 0x17, 0x4b, - 0x84, 0x7e, 0xff, 0xd1, 0x17, 0xc0, 0x9f, 0x50, 0x14, 0x42, 0xc5, 0x33, 0x7e, 0x02, 0x37, 0x4b, - 0x5a, 0x3e, 0xec, 0x63, 0x4f, 0x96, 0x00, 0xeb, 0x9a, 0x87, 0x39, 0x1b, 0xaf, 0x3f, 0xbe, 0xb0, - 0x14, 0x66, 0x5b, 0x52, 0xd8, 0x67, 0x94, 0x14, 0xaa, 0x88, 0x4a, 0x75, 0xbf, 0x81, 0xb0, 0xaa, - 0xf0, 0xb0, 0x0e, 0x8c, 0xe5, 0x94, 0xef, 0x48, 0x15, 0x61, 0xcf, 0x9b, 0x35, 0x83, 0x57, 0x84, - 0x9e, 0x7c, 0x68, 0x1e, 0xc4, 0x01, 0xc8, 0x24, 0x86, 0xbb, 0x17, 0xa8, 0xc2, 0x5a, 0x38, 0x08, - 0x5c, 0x9d, 0xca, 0xac, 0x2d, 0xd3, 0xe9, 0xd7, 0x57, 0x43, 0x05, 0xe0, 0xdc, 0x23, 0x4e, 0xdc, - 0x8b, 0x46, 0x7d, 0xa6, 0x28, 0xb2, 0x53, 0xf7, 0x81, 0x2e, 0xcd, 0x01, 0x90, 0x5d, 0x74, 0xb0, - 0xf9, 0xe0, 0x24, 0xd4, 0x42, 0x2c, 0xa8, 0x2a, 0x27, 0x77, 0x84, 0x0e, 0x2f, 0xb3, 0xa6, 0x38, - 0x15, 0xcc, 0x61, 0x8f, 0xef, 0xf2, 0x1d, 0xa1, 0x2b, 0x1f, 0xca, 0x5d, 0x9e, 0x11, 0x0f, 0xda, - 0x01, 0xce, 0xc2, 0xa1, 0x92, 0x30, 0xa3, 0xd6, 0xf6, 0x4c, 0xb4, 0x64, 0x56, 0xd9, 0x16, 0xd6, - 0x48, 0xe6, 0xfa, 0x94, 0xba, 0xee, 0xd7, 0xbd, 0xe4, 0x3e, 0xd5, 0x16, 0x05, 0xe3, 0xeb, 0x27, - 0x45, 0x51, 0xba, 0x6e, 0x70, 0xfe, 0x1a, 0x8f, 0xca, 0x52, 0x0b, 0x21, 0x8b, 0xc7, 0xf2, 0x8a, - 0x6a, 0x12, 0x3f, 0x40, 0x5d, 0x2d, 0x8b, 0x86, 0x88, 0xdd, 0x95, 0x0e, 0xf7, 0xa8, 0x55, 0x2c, - 0xce, 0xa4, 0x2a, 0xdf, 0x6e, 0xe7, 0xd0, 0xe3, 0x21, 0x14, 0x38, 0x83, 0x55, 0xa8, 0x47, 0xbe, - 0xb4, 0xc6, 0xe7, 0x07, 0x24, 0x25, 0x4c, 0xcb, 0x9e, 0x30, 0xa8, 0x1a, 0xfc, 0xa0, 0x3c, 0x95, - 0x81, 0xcd, 0x39, 0x96, 0xf5, 0x87, 0x6d, 0x80, 0xb3, 0xa8, 0xed, 0x73, 0x6c, 0x6d, 0x3f, 0x64, - 0x9a, 0x25, 0xed, 0x1e, 0xf5, 0xb4, 0x8c, 0x78, 0x10, 0xfa, 0xe5, 0x43, 0x8e, 0x15, 0x7d, 0x31, - 0xd3, 0x84, 0xcf, 0xe6, 0x01, 0xc6, 0xb8, 0xe1, 0x4c, 0x30, 0x86, 0x55, 0x01, 0xe6, 0x0a, 0x7b, - 0xa1, 0x52, 0xee, 0x48, 0x21, 0xac, 0x22, 0x0b, 0x74, 0xd8, 0xd5, 0xf7, 0x2e, 0xc5, 0x4f, 0x45, - 0xb5, 0xc2, 0x3c, 0x95, 0xc0, 0x67, 0xdd, 0xb7, 0xad, 0x1a, 0x2f, 0x31, 0xc5, 0x51, 0x65, 0x2a, - 0x76, 0xdb, 0x7b, 0xd7, 0x11, 0x7b, 0x53, 0x4b, 0x00, 0xc7, 0xd2, 0x6a, 0xec, 0xc4, 0xf6, 0x21, - 0x3f, 0xac, 0xb0, 0x53, 0x45, 0x2a, 0x95, 0xfb, 0xbc, 0x82, 0x3a, 0xca, 0xac, 0x8c, 0x14, 0x70, - 0x3e, 0xfd, 0x52, 0x8e, 0xea, 0x21, 0x89, 0xf3, 0x59, 0xa1, 0x2b, 0x71, 0xee, 0x5a, 0x9c, 0xf9, - 0xf9, 0x56, 0x55, 0xa6, 0x24, 0xde, 0xcd, 0xb5, 0x78, 0x97, 0x92, 0xaa, 0x72, 0xae, 0xd5, 0xf3, - 0xf7, 0x75, 0xd3, 0x43, 0xfc, 0x54, 0xf0, 0xeb, 0xdd, 0xb9, 0x4f, 0xf5, 0x2d, 0xbe, 0x75, 0x58, - 0x2d, 0x1b, 0xfb, 0xe2, 0x46, 0x2a, 0x0f, 0xf3, 0x0d, 0xce, 0xcf, 0x2b, 0x73, 0xb4, 0x69, 0xec, - 0x9f, 0x96, 0xad, 0x99, 0xc7, 0xb3, 0x98, 0xee, 0x42, 0x09, 0xf8, 0xd5, 0x22, 0xe6, 0x1e, 0x04, - 0x27, 0x83, 0x69, 0xca, 0x77, 0xc5, 0x8e, 0xb8, 0xd3, 0xfa, 0xe5, 0x5d, 0x8e, 0x2d, 0xef, 0x86, - 0x4a, 0x19, 0x69, 0x2d, 0x24, 0x69, 0x20, 0x1b, 0xc2, 0xb2, 0x61, 0xf0, 0xcb, 0xda, 0x4c, 0xa6, - 0xc3, 0xb3, 0x67, 0xcb, 0x40, 0xab, 0xf8, 0xbc, 0x33, 0x71, 0x9f, 0xa0, 0xc9, 0x12, 0x99, 0x5e, - 0x5f, 0x71, 0x73, 0x93, 0x4a, 0x67, 0x3e, 0xe3, 0x8c, 0xb9, 0x5e, 0x5d, 0x58, 0x95, 0x8e, 0xc2, - 0x4a, 0x1d, 0xf9, 0x65, 0x55, 0x9d, 0xe6, 0x6a, 0x9c, 0x29, 0xbe, 0x54, 0x3a, 0xc5, 0x22, 0x9c, - 0x65, 0x58, 0x66, 0xf8, 0x6c, 0x73, 0x96, 0xbb, 0x6f, 0xce, 0xc6, 0x9d, 0xf2, 0xce, 0x28, 0x8a, - 0xc0, 0x1b, 0xc2, 0x6b, 0x86, 0x56, 0x05, 0xae, 0x5c, 0x87, 0xf3, 0xb8, 0x32, 0xaf, 0x54, 0xd4, - 0x4e, 0x4e, 0xaf, 0x4e, 0xf3, 0xab, 0xce, 0x5c, 0x91, 0x1a, 0xdc, 0x7c, 0xd5, 0x35, 0x79, 0xa3, - 0x32, 0xf3, 0x57, 0x3a, 0x3f, 0x8c, 0xd6, 0x86, 0xb0, 0xf2, 0x15, 0x9d, 0x9b, 0x47, 0xfc, 0xa6, - 0xa9, 0xc2, 0xb0, 0x34, 0x43, 0x0d, 0x15, 0xf1, 0x39, 0xd4, 0xc7, 0x26, 0xae, 0xa3, 0xe9, 0x48, - 0x2a, 0xb2, 0x25, 0x83, 0xdf, 0x22, 0x29, 0xc7, 0x96, 0x7c, 0xbe, 0x85, 0xba, 0x2e, 0x0b, 0xf2, - 0xb9, 0x45, 0x5d, 0xe0, 0xb9, 0xaf, 0x55, 0x6a, 0x66, 0x91, 0xad, 0xcd, 0x86, 0x14, 0x6e, 0x37, - 0x7b, 0x52, 0xa6, 0xb9, 0xd7, 0x36, 0xa8, 0x57, 0x64, 0xdb, 0x06, 0x3f, 0x41, 0xbd, 0x1c, 0xdb, - 0xf6, 0x79, 0x90, 0x09, 0x97, 0x15, 0xa7, 0xc3, 0x09, 0xea, 0x00, 0x1d, 0x0e, 0x5a, 0x06, 0xf3, - 0xbc, 0x6c, 0x80, 0xec, 0x74, 0x08, 0x5d, 0x2a, 0xac, 0x2f, 0xef, 0x9b, 0x40, 0xaf, 0x9a, 0x29, - 0x9a, 0x2c, 0xc8, 0x56, 0xd9, 0x10, 0x77, 0x8a, 0x34, 0x2c, 0xb1, 0x65, 0xa1, 0x54, 0xf2, 0xc7, - 0x8b, 0xd2, 0x5e, 0xec, 0xc1, 0xde, 0x0d, 0xae, 0x2e, 0x09, 0x9c, 0xcf, 0x4b, 0xfc, 0x5e, 0x90, - 0x5e, 0x0c, 0xad, 0x85, 0xc7, 0x91, 0xaf, 0x0c, 0x90, 0xc1, 0x73, 0x48, 0x19, 0x56, 0x90, 0xdf, - 0xe9, 0x22, 0xbf, 0x58, 0x7d, 0x31, 0x8a, 0x33, 0xde, 0x2f, 0xb2, 0x9c, 0x6f, 0xce, 0x39, 0xe4, - 0xb2, 0x3c, 0x2b, 0x9a, 0x7c, 0x65, 0x58, 0x2d, 0x19, 0x78, 0x5c, 0x2c, 0x2b, 0xbe, 0xc0, 0x22, - 0xa9, 0x7a, 0x7f, 0x38, 0x3c, 0x8d, 0xfa, 0x87, 0x22, 0xd5, 0x67, 0x5c, 0xb6, 0x02, 0x60, 0x4b, - 0xbe, 0xde, 0x04, 0x5c, 0x60, 0x1b, 0x78, 0xab, 0xf8, 0x02, 0x67, 0xd8, 0xc2, 0x08, 0x19, 0x72, - 0x89, 0x9b, 0x73, 0xac, 0x84, 0xc7, 0x8a, 0x7c, 0x07, 0xd9, 0x32, 0xf4, 0xcb, 0xdc, 0xfc, 0x27, - 0xe7, 0x2f, 0x6b, 0xa3, 0x76, 0xb4, 0x1f, 0x56, 0x31, 0x1f, 0x39, 0x54, 0x4e, 0x2a, 0x31, 0x92, - 0xa8, 0x20, 0x36, 0x07, 0xae, 0x89, 0xed, 0x62, 0xb9, 0x12, 0xa7, 0x40, 0xf3, 0x0e, 0xc8, 0x55, - 0x57, 0xa4, 0x43, 0xbd, 0x02, 0xbd, 0x09, 0x64, 0x0b, 0xf7, 0x85, 0xb2, 0x73, 0xe0, 0x77, 0xf2, - 0x80, 0xdd, 0x6b, 0xd5, 0xda, 0x41, 0x63, 0x40, 0xde, 0x40, 0xf7, 0x86, 0x07, 0xa0, 0x31, 0xc8, - 0xe1, 0xb0, 0x8a, 0x0e, 0xb1, 0x9e, 0xce, 0x9a, 0x1c, 0xf0, 0x03, 0x74, 0x14, 0xe4, 0x12, 0xce, - 0xcf, 0x57, 0x59, 0xdc, 0x17, 0xe9, 0xa9, 0x2f, 0xa0, 0xf6, 0x6c, 0x98, 0x95, 0x3b, 0xda, 0x50, - 0x99, 0xa2, 0x4e, 0xcb, 0xd4, 0x96, 0x20, 0xff, 0xcb, 0xda, 0xc1, 0x86, 0xb0, 0x70, 0x18, 0xc9, - 0x9b, 0x33, 0xef, 0xed, 0xc1, 0xbc, 0xec, 0x3b, 0x55, 0x4e, 0xa2, 0x60, 0x9c, 0xaa, 0xb1, 0xbe, - 0x33, 0x54, 0x5e, 0x14, 0x83, 0x93, 0x2c, 0x05, 0x64, 0x4d, 0x95, 0x5f, 0xca, 0x72, 0x19, 0x58, - 0xb9, 0x00, 0xf9, 0xb5, 0x64, 0xab, 0x26, 0xb0, 0x8a, 0xb2, 0xe0, 0x39, 0x75, 0x67, 0x0c, 0x64, - 0xd8, 0xa7, 0x6d, 0x86, 0x30, 0xd9, 0x70, 0x8f, 0x52, 0x2e, 0xd3, 0x64, 0xf8, 0x41, 0xa5, 0x9d, - 0x3f, 0xcc, 0x5e, 0xf8, 0xa2, 0x21, 0xa0, 0xe2, 0x7c, 0x48, 0x37, 0x9b, 0x1c, 0xef, 0xb6, 0x0f, - 0x45, 0x57, 0xe8, 0x49, 0x4d, 0x34, 0xd3, 0x42, 0x38, 0xe5, 0x48, 0x17, 0x22, 0xdd, 0x98, 0x2a, - 0x56, 0x1f, 0xd5, 0x38, 0x99, 0xd8, 0x79, 0x65, 0x72, 0xaf, 0xa0, 0x82, 0xcb, 0x15, 0x7c, 0xf0, - 0xd7, 0x1c, 0x0e, 0x79, 0xf8, 0xfd, 0x3b, 0x74, 0xf2, 0xc0, 0xef, 0xb5, 0x6c, 0xc3, 0xe7, 0x41, - 0x06, 0xb5, 0x6a, 0x13, 0xe8, 0xd0, 0xe7, 0xf3, 0xad, 0x31, 0xc7, 0x9b, 0x82, 0x59, 0xa6, 0x7b, - 0xf3, 0xfc, 0xb0, 0x2f, 0x33, 0x89, 0x36, 0xf3, 0xe2, 0x71, 0xf7, 0x13, 0xda, 0xaa, 0x75, 0xe9, - 0x55, 0x71, 0xeb, 0xa1, 0x86, 0x13, 0xcf, 0x3b, 0x5f, 0x17, 0xb6, 0x29, 0x65, 0xd0, 0x32, 0x3b, - 0x40, 0xad, 0x69, 0xbd, 0x7e, 0xe8, 0xd3, 0x01, 0xbf, 0xf3, 0x32, 0xf0, 0xbb, 0xe1, 0x60, 0x4f, - 0x53, 0x97, 0x48, 0xf0, 0x68, 0x85, 0x3c, 0xc4, 0x3c, 0x3a, 0x60, 0x9e, 0x81, 0xde, 0x64, 0xc1, - 0xaf, 0x4c, 0x9b, 0x3d, 0x51, 0x11, 0x3a, 0xf2, 0x8c, 0x0d, 0x79, 0x0f, 0xf2, 0x6f, 0xf1, 0x7b, - 0x71, 0x29, 0xf8, 0xda, 0x8c, 0x3f, 0x88, 0x25, 0x71, 0xaf, 0x71, 0xb5, 0x2e, 0x57, 0x66, 0x7a, - 0xd9, 0x97, 0x3a, 0x8f, 0x06, 0x4a, 0x47, 0xda, 0x55, 0xcd, 0x3c, 0x5f, 0x9e, 0xe4, 0xe6, 0xa8, - 0xbb, 0xea, 0xc3, 0xcf, 0x13, 0xb7, 0x43, 0x52, 0x0d, 0x74, 0xbd, 0x0a, 0xd9, 0xc2, 0x40, 0x64, - 0x15, 0x51, 0x74, 0x7d, 0x45, 0x63, 0x95, 0x51, 0x6e, 0x55, 0xde, 0x2a, 0x7a, 0x99, 0x99, 0x65, - 0xfb, 0x8d, 0xbe, 0x40, 0xd7, 0xe6, 0xc6, 0x54, 0xcc, 0x4a, 0xe0, 0x31, 0x5e, 0xfa, 0x4a, 0x77, - 0x38, 0xaf, 0xc9, 0xc3, 0xa9, 0x00, 0x3a, 0x3a, 0x9a, 0xe4, 0x10, 0xf0, 0x86, 0x43, 0xed, 0xc7, - 0xfe, 0x86, 0x18, 0x09, 0x11, 0xd5, 0xb1, 0xec, 0x3e, 0x81, 0x48, 0x23, 0x34, 0x02, 0x1f, 0x8b, - 0x24, 0x3f, 0xe9, 0x17, 0xb4, 0x4a, 0xe8, 0x17, 0x66, 0x82, 0x19, 0xc8, 0x5d, 0x0d, 0xec, 0x1f, - 0x3e, 0x53, 0x73, 0x9a, 0xb4, 0x7b, 0x17, 0x32, 0x29, 0x87, 0x3c, 0xeb, 0x85, 0x32, 0x0c, 0xeb, - 0xb1, 0x3f, 0x19, 0x72, 0xa8, 0xcc, 0xd6, 0xba, 0x03, 0x7b, 0xdb, 0xd8, 0xb9, 0x23, 0xb0, 0xc9, - 0x85, 0xae, 0x6c, 0x49, 0x32, 0x6f, 0xd5, 0x74, 0xb3, 0xb8, 0xad, 0xec, 0xdc, 0x6d, 0x23, 0xbb, - 0xaa, 0x75, 0x15, 0xe4, 0xd6, 0xf6, 0x5a, 0x01, 0x94, 0x4d, 0xe2, 0x7b, 0xf6, 0xb2, 0xb6, 0xf7, - 0xcf, 0xdb, 0x4c, 0x97, 0x76, 0x99, 0xa6, 0xec, 0x35, 0x90, 0x8d, 0x40, 0xae, 0xe5, 0xc7, 0x16, - 0xfd, 0x52, 0x69, 0x1d, 0x3c, 0x25, 0xb0, 0x85, 0xc9, 0xf6, 0xec, 0xa9, 0xb0, 0x3b, 0xd3, 0x05, - 0xf6, 0xac, 0x8d, 0xca, 0x4a, 0xf7, 0x20, 0x87, 0x30, 0xdd, 0x28, 0xc8, 0x88, 0xf8, 0x4b, 0x72, - 0x83, 0x86, 0x81, 0xe3, 0x43, 0x4c, 0x1c, 0xde, 0x04, 0x1e, 0x2e, 0x81, 0x06, 0x87, 0x58, 0xb7, - 0x31, 0x8d, 0xf6, 0x58, 0x07, 0xe5, 0x48, 0xc7, 0xad, 0xa6, 0xcf, 0x57, 0x6b, 0x3e, 0xf1, 0x8d, - 0x81, 0xac, 0x9a, 0x44, 0x47, 0x97, 0x17, 0xbe, 0x63, 0xa6, 0x2d, 0x81, 0x66, 0x11, 0x7d, 0xb2, - 0x60, 0x5f, 0xf7, 0xe5, 0x29, 0xcd, 0x42, 0xfc, 0xa1, 0xd4, 0x76, 0x35, 0xad, 0xc6, 0x0c, 0x3d, - 0xa0, 0x8f, 0xa0, 0xef, 0x73, 0xdb, 0x2a, 0x3b, 0x6e, 0x88, 0x55, 0xba, 0xca, 0x85, 0xf8, 0x53, - 0xe6, 0x3c, 0x8b, 0xb6, 0x52, 0x66, 0xb6, 0xf7, 0x74, 0xd1, 0x8a, 0xe9, 0xfa, 0x22, 0xf7, 0xe4, - 0x9e, 0x69, 0xd8, 0x22, 0xcf, 0xf2, 0x05, 0xa0, 0x9b, 0x5b, 0xe9, 0x16, 0xfb, 0x12, 0xb6, 0xaf, - 0x07, 0xa5, 0x81, 0x8c, 0x72, 0x86, 0x3d, 0xbc, 0xd4, 0xd1, 0x54, 0x16, 0x58, 0xc6, 0x6f, 0x97, - 0x40, 0xa7, 0x95, 0x9e, 0xfb, 0xd8, 0x99, 0xed, 0x16, 0xf5, 0x01, 0xdd, 0xad, 0xed, 0xe4, 0x90, - 0xd6, 0x2c, 0xd3, 0xdc, 0xd2, 0x62, 0x33, 0x57, 0xec, 0xf0, 0xf1, 0x9c, 0x27, 0xaf, 0xde, 0xe9, - 0x36, 0xca, 0x66, 0xf1, 0xa5, 0xc1, 0x69, 0xcb, 0xd6, 0x94, 0x97, 0x4a, 0x68, 0xc5, 0x81, 0x54, - 0x36, 0x9a, 0x12, 0xc0, 0xcf, 0x88, 0x2c, 0xd0, 0xb1, 0x1a, 0xf8, 0x1f, 0xce, 0xa1, 0x32, 0x6e, - 0x49, 0x21, 0xf6, 0x70, 0x8e, 0x44, 0xe3, 0x2c, 0xde, 0x08, 0x68, 0x78, 0x94, 0x9d, 0x9d, 0xbc, - 0x6c, 0xee, 0xe4, 0x4e, 0x13, 0xeb, 0x6f, 0x37, 0xa1, 0xdf, 0x33, 0x6d, 0x00, 0xf4, 0x51, 0xca, - 0x6c, 0x40, 0x6b, 0xf0, 0x6b, 0xd5, 0xf6, 0x2c, 0x3f, 0xae, 0xec, 0x6c, 0xad, 0xd2, 0xcb, 0x01, - 0xfe, 0x92, 0xdc, 0x31, 0x73, 0xdb, 0xa6, 0xba, 0x71, 0xd6, 0x05, 0xef, 0xea, 0x18, 0x5a, 0xc9, - 0x10, 0x87, 0xd0, 0xf7, 0xed, 0xb9, 0xb6, 0x1f, 0x70, 0x06, 0x55, 0x99, 0xd1, 0x46, 0xb3, 0x5b, - 0xdc, 0x74, 0xa6, 0x92, 0x6c, 0xd4, 0x37, 0x6b, 0xa3, 0x9d, 0x71, 0xc8, 0x27, 0x0b, 0x69, 0x53, - 0x2f, 0x77, 0xdf, 0x39, 0xd4, 0xb4, 0x7a, 0xa9, 0xa8, 0xb6, 0xbb, 0x88, 0x69, 0xec, 0xf3, 0x95, - 0x32, 0x0e, 0xb2, 0x0c, 0x1e, 0x87, 0x97, 0x25, 0x9c, 0x61, 0x61, 0x3b, 0xc5, 0x06, 0xf1, 0x23, - 0x0b, 0x52, 0xd0, 0x11, 0x70, 0xbc, 0xd8, 0xf7, 0x10, 0x44, 0x68, 0x38, 0xce, 0xa4, 0xf0, 0x44, - 0x2a, 0xc8, 0x86, 0x58, 0x22, 0x49, 0x3e, 0x8e, 0xb8, 0x70, 0x70, 0x8a, 0xb3, 0x2b, 0xfe, 0x80, - 0x63, 0x0d, 0xde, 0xc7, 0xd2, 0x0c, 0xf6, 0xf0, 0x45, 0x66, 0x55, 0xbf, 0x86, 0xe7, 0x83, 0x5e, - 0xe2, 0xb8, 0x17, 0xe2, 0x3e, 0x12, 0xbc, 0xb2, 0x03, 0x2a, 0xaf, 0xe1, 0x78, 0x6d, 0x85, 0xf5, - 0x14, 0x52, 0x96, 0x06, 0x0e, 0xf6, 0x80, 0xb8, 0x16, 0xe2, 0x72, 0xa8, 0x27, 0x11, 0x7f, 0x5e, - 0xe6, 0x3b, 0x45, 0x96, 0xed, 0xf0, 0x83, 0xda, 0x8e, 0xb7, 0x50, 0x2c, 0x87, 0x9a, 0x42, 0xf4, - 0x76, 0x2f, 0xe2, 0xef, 0x25, 0x4c, 0x73, 0x16, 0xcb, 0xe5, 0x41, 0xec, 0x35, 0x89, 0x5e, 0xca, - 0x98, 0xe6, 0x6c, 0x64, 0x4f, 0xd9, 0x83, 0x9c, 0x39, 0xd7, 0xe5, 0xda, 0x41, 0x8e, 0x63, 0x21, - 0x64, 0x32, 0xf7, 0x94, 0xcf, 0x71, 0x93, 0x6d, 0x11, 0x81, 0x4b, 0x64, 0x51, 0x73, 0xb8, 0x51, - 0xba, 0xe2, 0x93, 0x58, 0x6d, 0xa2, 0xdc, 0xd4, 0x9f, 0xb3, 0x8a, 0x56, 0x15, 0xbb, 0x9a, 0xc0, - 0x76, 0x25, 0xad, 0xdd, 0xd5, 0x76, 0x2c, 0x33, 0xe6, 0xdb, 0xdd, 0xa6, 0xd2, 0x98, 0xb3, 0x07, - 0xb0, 0x30, 0xf9, 0xea, 0x94, 0x59, 0x76, 0xe6, 0x2f, 0x52, 0xfb, 0x30, 0xcc, 0xc8, 0x2c, 0xe8, - 0xcb, 0x74, 0x2c, 0x35, 0x21, 0xc6, 0x90, 0xf9, 0x97, 0xca, 0xcb, 0x8e, 0xd6, 0xd1, 0x4b, 0x5e, - 0xf7, 0x21, 0xed, 0x1a, 0x5a, 0x8f, 0x90, 0xb1, 0xb2, 0x10, 0x8d, 0x14, 0x80, 0x64, 0xe5, 0xee, - 0x11, 0x9e, 0xce, 0x0a, 0x8c, 0xbc, 0x91, 0xaa, 0xa2, 0x4f, 0xb9, 0xda, 0x46, 0xe1, 0x24, 0xb2, - 0x37, 0xb5, 0xe1, 0x9f, 0xc0, 0x87, 0x81, 0xff, 0xd7, 0x76, 0x35, 0xbf, 0x5c, 0x97, 0x69, 0xab, - 0xae, 0x75, 0xe5, 0x39, 0xa7, 0x68, 0x02, 0xec, 0x39, 0x6a, 0xf5, 0x56, 0xac, 0xd4, 0xb3, 0xf3, - 0x7d, 0xd8, 0x83, 0x2b, 0x6b, 0xb5, 0x1a, 0xa7, 0xec, 0xba, 0x73, 0xab, 0x47, 0xf4, 0x1b, 0x68, - 0x4f, 0xdd, 0xbb, 0x40, 0xdf, 0xba, 0x82, 0x59, 0x54, 0x35, 0xd0, 0x1a, 0x95, 0x0c, 0xd4, 0x09, - 0xe2, 0xe2, 0x7e, 0xf9, 0x18, 0xbb, 0x33, 0x3c, 0xc4, 0x41, 0xe2, 0x9e, 0x67, 0x43, 0xbf, 0x9c, - 0xad, 0x05, 0x3a, 0x0c, 0x31, 0xb1, 0x76, 0x16, 0xe7, 0xc8, 0x81, 0x0d, 0x30, 0xb5, 0x6a, 0x15, - 0xcb, 0x6c, 0xe0, 0xbb, 0xfb, 0x65, 0x92, 0x63, 0x08, 0x0b, 0x1c, 0x4f, 0x89, 0x7e, 0x53, 0xa9, - 0x95, 0x84, 0x7d, 0xad, 0xcd, 0xf4, 0xc9, 0x27, 0xaa, 0xaf, 0xa9, 0xc9, 0xd0, 0xaa, 0x99, 0x43, - 0xab, 0x0d, 0x6d, 0x71, 0xd6, 0xd8, 0x75, 0x32, 0x9d, 0x79, 0x87, 0x1e, 0xcf, 0x5f, 0x20, 0x70, - 0x13, 0x67, 0xb8, 0xcf, 0x27, 0xe3, 0x5e, 0x17, 0xf2, 0x01, 0x53, 0x9c, 0x41, 0xdf, 0x0c, 0x64, - 0x1a, 0xf2, 0x93, 0x1c, 0x82, 0xfc, 0x64, 0x2f, 0x80, 0xbf, 0x13, 0x0e, 0x8d, 0xa7, 0x27, 0xf3, - 0x45, 0x17, 0x7b, 0xe5, 0x49, 0xad, 0xe7, 0xef, 0x26, 0xf3, 0x1a, 0x37, 0xe9, 0xd5, 0x2a, 0x2f, - 0xfc, 0xb8, 0x0a, 0x01, 0x67, 0x15, 0x60, 0x56, 0xc4, 0x41, 0x9e, 0x93, 0x96, 0xf4, 0xbe, 0xcd, - 0x85, 0xf3, 0x24, 0xbe, 0x1e, 0xc1, 0x03, 0x38, 0xc4, 0x1f, 0xac, 0x29, 0xca, 0x41, 0xb4, 0xc8, - 0x19, 0x3e, 0x16, 0x3a, 0x1a, 0xec, 0x1e, 0xce, 0xaf, 0xa4, 0x20, 0x07, 0x88, 0xce, 0xd1, 0x39, - 0xfa, 0x64, 0xe1, 0x20, 0x85, 0xf6, 0x4d, 0x64, 0xca, 0xbd, 0x2b, 0x71, 0xca, 0xa1, 0xef, 0x34, - 0x4d, 0x6d, 0xd1, 0x3c, 0x60, 0x99, 0x52, 0x6b, 0xfa, 0x60, 0x41, 0x37, 0x4b, 0x4a, 0xbe, 0xbe, - 0xdf, 0xf4, 0x86, 0x99, 0xa6, 0xaf, 0xd0, 0x4c, 0x53, 0xdb, 0xf3, 0x53, 0x1d, 0x62, 0x16, 0x79, - 0xa6, 0x65, 0xdb, 0x73, 0x23, 0x9c, 0x3b, 0xcc, 0xd4, 0x7c, 0xe1, 0xb1, 0xd9, 0xeb, 0xd2, 0xb0, - 0xa6, 0xa6, 0x55, 0x9a, 0xb3, 0x39, 0xe4, 0x0d, 0xfa, 0x44, 0x98, 0x0a, 0x83, 0x66, 0xb3, 0xa7, - 0x68, 0xf7, 0xcd, 0xc3, 0xb8, 0x5b, 0x61, 0xc7, 0x79, 0x62, 0x6f, 0xa4, 0x12, 0xf0, 0x51, 0x86, - 0xfc, 0xae, 0xe6, 0x04, 0x75, 0x1c, 0xc8, 0xed, 0x40, 0xcf, 0xb0, 0xef, 0xe5, 0x7b, 0xf0, 0x29, - 0x89, 0x0e, 0xe5, 0xb3, 0x7d, 0x9c, 0x1f, 0xa3, 0xf2, 0x10, 0xd7, 0xdc, 0x94, 0xf8, 0x3b, 0xd6, - 0x3b, 0xf2, 0x1a, 0x42, 0xfc, 0x01, 0xe7, 0xcf, 0x21, 0xce, 0x92, 0xb0, 0xbe, 0xf1, 0x58, 0xdf, - 0xa6, 0x38, 0x0e, 0xc1, 0x7e, 0xb2, 0x79, 0xc0, 0xf9, 0x9b, 0x08, 0xf9, 0x1b, 0x9c, 0xaf, 0x27, - 0x32, 0x28, 0xf8, 0x54, 0x58, 0xdc, 0x2f, 0x69, 0x64, 0xac, 0x09, 0xb1, 0x2d, 0xf8, 0xf9, 0x29, - 0xd0, 0x88, 0xc1, 0x9f, 0x3c, 0xec, 0x5f, 0xee, 0x96, 0x15, 0x43, 0x60, 0xfb, 0x90, 0x13, 0x39, - 0x75, 0xe6, 0xa5, 0x6f, 0xf0, 0x3b, 0x11, 0x8b, 0x12, 0x63, 0xd4, 0x14, 0x4a, 0x75, 0x39, 0x65, - 0x92, 0x71, 0x90, 0x35, 0x78, 0x5a, 0x67, 0xdc, 0xf5, 0xda, 0xb4, 0xfb, 0xf5, 0xe9, 0x90, 0x05, - 0x3f, 0xbd, 0x5e, 0xdb, 0x68, 0x5d, 0xb3, 0x6c, 0xfc, 0x03, 0x78, 0xbe, 0x40, 0x6e, 0xb8, 0xea, - 0x2b, 0x60, 0x87, 0x14, 0x6b, 0x18, 0xc8, 0x2f, 0xf8, 0x27, 0xb0, 0x0f, 0x0e, 0x36, 0x0e, 0x2d, - 0x8c, 0x6c, 0x19, 0xcc, 0x10, 0xba, 0x9a, 0xd7, 0xc5, 0xfe, 0x1b, 0x64, 0x30, 0xf0, 0xdf, 0x33, - 0xc8, 0x77, 0x66, 0x41, 0xdc, 0x08, 0x7d, 0x11, 0x0f, 0xcd, 0x70, 0x7e, 0x6c, 0x6f, 0xf9, 0x48, - 0x6e, 0x23, 0xfe, 0x77, 0x4f, 0xdb, 0x78, 0xbc, 0xb6, 0xc7, 0x79, 0x84, 0x08, 0xbe, 0x7d, 0xda, - 0xea, 0x2d, 0x25, 0xd0, 0x19, 0x61, 0x3a, 0x86, 0xb8, 0xa9, 0x5f, 0xb6, 0x9a, 0x89, 0x76, 0xb3, - 0x2f, 0x6b, 0x90, 0x07, 0xd2, 0x90, 0x03, 0x86, 0x76, 0x96, 0x3e, 0x6d, 0x67, 0x59, 0x7b, 0x51, - 0x83, 0xef, 0xe0, 0xc8, 0xee, 0x37, 0x3b, 0xd7, 0xaa, 0x75, 0x5c, 0xb5, 0x66, 0xbe, 0x3c, 0x76, - 0xb3, 0xb2, 0x8a, 0x46, 0x92, 0x3a, 0x96, 0x21, 0x2e, 0xdc, 0x47, 0xb0, 0xcf, 0xf7, 0x0a, 0xdb, - 0x5b, 0x1a, 0x55, 0xa6, 0xde, 0x18, 0xfc, 0x40, 0xb5, 0x73, 0xc8, 0xdd, 0x0f, 0x00, 0xc6, 0x79, - 0x1b, 0xd8, 0x6c, 0x81, 0x8f, 0x08, 0xf7, 0x92, 0x47, 0x15, 0x73, 0xb8, 0xa8, 0x4c, 0x5d, 0x8b, - 0xda, 0xac, 0x64, 0x09, 0xa2, 0xa5, 0x40, 0x9e, 0xc0, 0x86, 0xe7, 0xb1, 0x3c, 0xe1, 0xf8, 0x4e, - 0xb8, 0x15, 0x87, 0x1e, 0xe3, 0xa1, 0x59, 0xec, 0xfb, 0x49, 0x6c, 0x00, 0x76, 0x6c, 0x08, 0xf1, - 0x23, 0x0d, 0xf4, 0x32, 0x85, 0x41, 0xa7, 0xd5, 0xb3, 0x0c, 0x53, 0x62, 0xf3, 0x60, 0x63, 0xc7, - 0x6d, 0x88, 0xab, 0x06, 0xe5, 0x79, 0x31, 0xdb, 0xa4, 0x79, 0x5d, 0xe2, 0x84, 0xcb, 0x33, 0x19, - 0x76, 0xbd, 0xcc, 0x19, 0x4b, 0x75, 0x5e, 0x66, 0xbb, 0xfc, 0x94, 0x95, 0xfa, 0xf6, 0xb2, 0xce, - 0x4a, 0x75, 0x8e, 0xf8, 0x14, 0xf0, 0x41, 0x6c, 0x96, 0x1a, 0x48, 0xed, 0x19, 0xda, 0x8b, 0xa8, - 0x04, 0x71, 0x28, 0xb6, 0x5b, 0x80, 0xdf, 0x80, 0xdd, 0x41, 0x7c, 0xb9, 0xd7, 0x66, 0xcd, 0xae, - 0x96, 0x05, 0xb9, 0xcc, 0x96, 0x0f, 0x22, 0xfb, 0x2e, 0x1e, 0x5f, 0xb1, 0x51, 0x33, 0xfb, 0x51, - 0x80, 0x54, 0x42, 0x88, 0x3e, 0xa9, 0xb5, 0x1b, 0xf9, 0x42, 0xb9, 0xcc, 0x0f, 0x37, 0x0d, 0x88, - 0x97, 0x4e, 0xdb, 0x4a, 0x64, 0x67, 0xe6, 0x1d, 0xbf, 0xda, 0x4c, 0xae, 0x85, 0xcf, 0xa7, 0x75, - 0xe4, 0xa7, 0x7b, 0xf2, 0xb6, 0x31, 0x1f, 0xca, 0x78, 0xdd, 0x49, 0x1b, 0x55, 0x9c, 0xa3, 0xad, - 0x92, 0x40, 0xbe, 0x39, 0x84, 0xeb, 0x35, 0x06, 0xc2, 0xf5, 0x0a, 0x03, 0x35, 0x49, 0x99, 0xdc, - 0xbf, 0x25, 0xdf, 0x0e, 0xea, 0x92, 0x1a, 0x44, 0xe0, 0xb3, 0x82, 0xb3, 0x9c, 0xe7, 0x08, 0x25, - 0x71, 0x16, 0xd7, 0x2d, 0xe0, 0xec, 0xc3, 0xec, 0x59, 0xfb, 0x70, 0xd6, 0x1e, 0x9c, 0xb5, 0x71, - 0xec, 0x1a, 0xe4, 0x44, 0x53, 0xbe, 0xd3, 0xea, 0x42, 0xfc, 0xc8, 0xfb, 0x6a, 0xcd, 0x98, 0x57, - 0x39, 0x34, 0xb7, 0x2a, 0x4c, 0x34, 0x16, 0xe4, 0x4f, 0x8b, 0x58, 0x7e, 0x55, 0xb5, 0xb2, 0x97, - 0x03, 0x79, 0xdb, 0x22, 0x68, 0x0f, 0x49, 0x7b, 0x71, 0x94, 0x3f, 0xce, 0x67, 0xdd, 0xd1, 0xa0, - 0x94, 0xa3, 0x3a, 0x51, 0x5e, 0x05, 0x32, 0x59, 0x62, 0x87, 0x02, 0xd7, 0x19, 0x8a, 0x30, 0xf7, - 0xac, 0x86, 0xf0, 0x78, 0x6f, 0x70, 0x20, 0xb3, 0x04, 0xa6, 0x6b, 0xad, 0xf7, 0x47, 0xf9, 0x0d, - 0xf6, 0xc3, 0xf0, 0xfb, 0x0e, 0x7c, 0x0f, 0x64, 0x7b, 0x2f, 0x87, 0xf5, 0x80, 0x80, 0x9e, 0x63, - 0x54, 0xa7, 0x71, 0x3d, 0xb6, 0x84, 0xed, 0x99, 0x8f, 0xeb, 0x46, 0x60, 0xc7, 0x24, 0x6d, 0x09, - 0xf4, 0xd9, 0x57, 0x7d, 0xbe, 0x5f, 0x86, 0xd0, 0x26, 0x53, 0x2f, 0xdd, 0xd7, 0xeb, 0x88, 0x7b, - 0xe2, 0x0b, 0x46, 0xcf, 0xf0, 0x67, 0xa5, 0xbe, 0x24, 0x0e, 0x51, 0x75, 0x68, 0xb7, 0x73, 0xb6, - 0x8d, 0x2a, 0x74, 0x6f, 0xcd, 0xb6, 0x4a, 0x68, 0x37, 0x2f, 0x75, 0xc5, 0x20, 0x54, 0xee, 0x6e, - 0x29, 0x4b, 0x6a, 0x28, 0x68, 0xe3, 0x92, 0xd2, 0x2a, 0xea, 0xf2, 0x25, 0x11, 0xe2, 0x1b, 0x61, - 0xc7, 0xb3, 0x75, 0xbf, 0xb2, 0x5e, 0xaf, 0x9d, 0x7b, 0xc6, 0x46, 0x5c, 0x81, 0x2a, 0xac, 0x21, - 0xce, 0x81, 0xd0, 0xa9, 0xda, 0x0f, 0x90, 0x9a, 0x23, 0xa3, 0xfd, 0x84, 0xed, 0x6d, 0xa9, 0x4c, - 0xea, 0x8b, 0x1a, 0x7e, 0xee, 0x31, 0x42, 0x6c, 0x11, 0x09, 0x3e, 0x5a, 0x22, 0xce, 0x25, 0x95, - 0x5b, 0xb6, 0x07, 0xf6, 0xb5, 0x03, 0x76, 0x77, 0x27, 0x5b, 0xe0, 0x7f, 0x1f, 0x11, 0xe4, 0x51, - 0x3c, 0xce, 0xa7, 0x02, 0x5f, 0x64, 0xe1, 0x1c, 0x03, 0x62, 0xb0, 0x8e, 0x08, 0xfb, 0x61, 0x7b, - 0x8c, 0x8e, 0xf3, 0x4b, 0xd0, 0x86, 0x58, 0xb3, 0x0e, 0xb1, 0xd9, 0x8b, 0x42, 0x49, 0x68, 0x2f, - 0x14, 0x70, 0x9c, 0xe8, 0xce, 0x44, 0xa3, 0xee, 0x08, 0x07, 0xb0, 0xbf, 0x6b, 0xc8, 0xad, 0xb0, - 0x2d, 0xf5, 0x21, 0x16, 0xb3, 0x20, 0x82, 0xeb, 0xd5, 0x60, 0xae, 0x0c, 0xbc, 0x56, 0x94, 0xf5, - 0x5e, 0xdc, 0x83, 0x6d, 0x5e, 0x2b, 0x3d, 0xf0, 0xb7, 0xd6, 0x8b, 0x22, 0x9a, 0xed, 0x27, 0x84, - 0x5a, 0x6b, 0x0a, 0xfb, 0x0c, 0x18, 0xc7, 0x35, 0x35, 0x65, 0x52, 0x58, 0x2b, 0xd6, 0xe8, 0x7e, - 0xcd, 0xc8, 0x33, 0xd1, 0x08, 0x8b, 0x90, 0x42, 0x09, 0xe8, 0xd1, 0x42, 0x68, 0x27, 0xe3, 0xd8, - 0xaf, 0x8a, 0x38, 0x2d, 0x28, 0x67, 0x13, 0xbf, 0x20, 0x12, 0x3c, 0x83, 0xf8, 0xe0, 0x76, 0x3e, - 0x0b, 0x67, 0x1a, 0x90, 0x58, 0x0d, 0xf2, 0x81, 0x77, 0xe4, 0x59, 0x07, 0x64, 0x43, 0xdc, 0x59, - 0x56, 0xe0, 0x2c, 0xfc, 0xb2, 0x81, 0x73, 0x78, 0x88, 0xad, 0x40, 0xc9, 0x2a, 0x9d, 0x85, 0x11, - 0xcb, 0xa4, 0xcc, 0x77, 0x0a, 0x10, 0x4b, 0x74, 0xaa, 0xc6, 0xe3, 0xbd, 0x75, 0x08, 0x73, 0x76, - 0x36, 0xcc, 0xe9, 0x67, 0x67, 0x6d, 0x43, 0x04, 0x62, 0x0c, 0x9e, 0x18, 0xf0, 0x37, 0xd8, 0x4f, - 0x56, 0x66, 0xb5, 0x42, 0x87, 0x7f, 0x0a, 0xe0, 0xed, 0x8a, 0x04, 0x7e, 0x8f, 0x09, 0xe1, 0x9b, - 0xbe, 0xdd, 0x46, 0xb4, 0xce, 0x03, 0xad, 0xca, 0xbb, 0x69, 0x07, 0x94, 0xff, 0xbe, 0x3d, 0xd3, - 0x32, 0x72, 0xc7, 0x18, 0x04, 0x6d, 0xb0, 0xf3, 0xb3, 0x21, 0x69, 0x23, 0x1c, 0x40, 0x73, 0x5b, - 0xca, 0x30, 0xda, 0x0a, 0xda, 0xcf, 0x03, 0xfa, 0x80, 0xbf, 0x06, 0x79, 0xec, 0x21, 0x56, 0x43, - 0xa2, 0x8f, 0xb2, 0xa8, 0x44, 0xfc, 0x37, 0xce, 0xa3, 0x4b, 0xd8, 0xa7, 0x62, 0x7e, 0x37, 0x25, - 0x99, 0xb4, 0x9b, 0x3b, 0xad, 0x0a, 0x31, 0x37, 0xe6, 0xf7, 0x7b, 0xea, 0x02, 0x3d, 0x2c, 0x0f, - 0xb5, 0x9e, 0x36, 0x60, 0x7d, 0xde, 0x68, 0xf3, 0xf4, 0x53, 0x7d, 0x08, 0xa1, 0x35, 0xf0, 0xcf, - 0xe2, 0xe9, 0x62, 0x8f, 0xf7, 0x1f, 0x7b, 0x3d, 0x7f, 0x65, 0x08, 0xa5, 0xfb, 0xf5, 0xe1, 0x86, - 0x5d, 0x0a, 0xdb, 0x1c, 0xf0, 0x78, 0x84, 0xd7, 0xa0, 0xda, 0x0e, 0xe0, 0x14, 0x29, 0xb7, 0xa6, - 0x28, 0x52, 0x65, 0x35, 0x59, 0x16, 0x96, 0xbd, 0xde, 0xae, 0x49, 0x0d, 0xdc, 0x62, 0xaf, 0x44, - 0xb3, 0x56, 0x59, 0x66, 0xeb, 0x90, 0x57, 0x74, 0xba, 0x45, 0x0c, 0x63, 0xd3, 0xa0, 0x65, 0xb0, - 0x1d, 0x92, 0x02, 0xed, 0x0d, 0x81, 0x49, 0x03, 0xcf, 0xda, 0xb4, 0x17, 0xad, 0x23, 0xa1, 0x3e, - 0xc8, 0xcb, 0x16, 0xcb, 0x0b, 0xd6, 0x1f, 0x09, 0xe1, 0x67, 0x7d, 0x1e, 0xd8, 0xe5, 0x1a, 0xd8, - 0xed, 0x32, 0x27, 0x09, 0x55, 0xc8, 0x05, 0xd9, 0xd6, 0x7c, 0x74, 0x6f, 0xb4, 0x0b, 0x10, 0x9f, - 0xf2, 0x8f, 0x94, 0x8d, 0x75, 0xa8, 0x82, 0x3a, 0xe6, 0x12, 0x72, 0xb4, 0x47, 0x05, 0x75, 0x5d, - 0xc6, 0x44, 0x3c, 0xd8, 0xc0, 0xed, 0x3d, 0xd3, 0x1b, 0x06, 0xaa, 0xe5, 0xe3, 0x7a, 0x2f, 0x0d, - 0xf1, 0x01, 0xe8, 0x03, 0x68, 0x11, 0x17, 0x84, 0x06, 0x16, 0xd0, 0x70, 0x50, 0xf3, 0x35, 0xb6, - 0x89, 0x9f, 0xbb, 0x80, 0xde, 0x03, 0x5d, 0xb2, 0x6c, 0x2f, 0xf8, 0xac, 0xf9, 0xcd, 0x66, 0xbb, - 0x27, 0x3e, 0x75, 0x16, 0xa3, 0x7b, 0xb7, 0xea, 0xb3, 0x46, 0x9b, 0x16, 0xd1, 0xae, 0x98, 0xb5, - 0xc7, 0xed, 0x7b, 0x83, 0x1f, 0xb2, 0xad, 0x95, 0xf6, 0xd4, 0x87, 0xd8, 0xdc, 0x1c, 0xf5, 0x50, - 0xbb, 0x6b, 0x3c, 0xd9, 0x16, 0x44, 0x5c, 0x95, 0xea, 0x3d, 0x03, 0x21, 0x38, 0xd5, 0xe2, 0x33, - 0xb6, 0x2a, 0xb1, 0xf5, 0xc3, 0x80, 0x1e, 0xf7, 0x98, 0x0a, 0xea, 0x7a, 0x8e, 0x17, 0xd5, 0xe1, - 0xcb, 0x03, 0xac, 0x0f, 0x0e, 0x3e, 0x1f, 0x30, 0xdb, 0x3e, 0xa9, 0x8b, 0x75, 0xa4, 0x40, 0x96, - 0xc1, 0x2f, 0x5d, 0xd4, 0x9d, 0x77, 0xe2, 0xb2, 0x89, 0xeb, 0x29, 0x3e, 0xf0, 0x6f, 0xa7, 0x65, - 0xcb, 0xd7, 0xea, 0x3a, 0x67, 0x6d, 0xe6, 0x65, 0xf1, 0xd2, 0xae, 0x1d, 0x7f, 0x60, 0xcf, 0xd0, - 0xff, 0x4e, 0xcf, 0xfc, 0x71, 0xd4, 0x6e, 0x3c, 0x6d, 0x6b, 0x67, 0x6b, 0x88, 0xff, 0xe7, 0x3a, - 0x38, 0x9e, 0x34, 0x20, 0xcb, 0x23, 0xcf, 0xaf, 0x38, 0x19, 0xeb, 0xe2, 0xb2, 0xe9, 0x57, 0xc0, - 0x4c, 0x49, 0x45, 0xca, 0x28, 0x6d, 0xdb, 0xc3, 0x1c, 0xeb, 0x1f, 0x82, 0x7a, 0x7b, 0xf8, 0xfc, - 0x01, 0x9c, 0x14, 0xb7, 0xc5, 0xcf, 0x96, 0x0a, 0x3e, 0x8e, 0xc6, 0x50, 0x40, 0xe3, 0xbd, 0xc6, - 0x61, 0xb3, 0xd0, 0x16, 0x7b, 0x7c, 0x1b, 0x55, 0x21, 0x0e, 0x45, 0x45, 0xbf, 0x28, 0x16, 0xc3, - 0xf9, 0x0a, 0x9e, 0x4f, 0x4b, 0x64, 0x3e, 0xec, 0x31, 0x67, 0x41, 0xc6, 0xb9, 0x5d, 0xe9, 0x40, - 0xe1, 0xb8, 0xb4, 0x2d, 0x4a, 0x2c, 0xdd, 0x3b, 0x50, 0xc1, 0xfa, 0xd0, 0xde, 0x26, 0xe8, 0xd9, - 0x08, 0xec, 0xca, 0xac, 0xec, 0x6b, 0x4b, 0x21, 0xa8, 0x21, 0x42, 0x4c, 0x4e, 0x74, 0x85, 0x11, - 0xa0, 0x0f, 0xe2, 0x51, 0x46, 0xdc, 0x6b, 0x38, 0x16, 0x60, 0x30, 0xef, 0xb1, 0x3e, 0x60, 0x1d, - 0x2a, 0xe3, 0xf8, 0xc0, 0xd7, 0x0e, 0xa8, 0xb0, 0xd9, 0x9b, 0xb3, 0x43, 0x55, 0xd1, 0x86, 0x45, - 0xd3, 0x52, 0xeb, 0x6d, 0xf1, 0x45, 0xd9, 0x1d, 0xf6, 0x75, 0x88, 0x54, 0xe1, 0xfb, 0x58, 0xd9, - 0xcd, 0xf6, 0x75, 0xc5, 0xb6, 0x8b, 0x3b, 0x6b, 0x50, 0x6d, 0x0b, 0xeb, 0x3d, 0xe4, 0xb9, 0x7d, - 0x98, 0x5f, 0x51, 0x34, 0xad, 0x68, 0x3a, 0xf5, 0x37, 0xd7, 0x02, 0x76, 0xe5, 0x33, 0xfe, 0xe7, - 0x10, 0x2f, 0x01, 0x45, 0xd9, 0xc1, 0xfb, 0xe5, 0xe0, 0x5d, 0x36, 0xb0, 0x17, 0xd6, 0x50, 0xa2, - 0xba, 0xe9, 0xf4, 0xac, 0x3d, 0xc0, 0x36, 0x55, 0xe8, 0xe5, 0x58, 0xb0, 0xdb, 0xe7, 0xb2, 0xf0, - 0xd2, 0x93, 0x13, 0x6d, 0xc5, 0x8a, 0xea, 0x08, 0x61, 0xdd, 0x60, 0x7c, 0xda, 0xf6, 0xfc, 0xd8, - 0x8f, 0x53, 0x8e, 0x1b, 0xc7, 0x90, 0x3a, 0xed, 0x31, 0x95, 0x6d, 0x5e, 0xac, 0x2c, 0xe5, 0xff, - 0x68, 0x9c, 0x6a, 0x94, 0x3b, 0x9c, 0x64, 0x49, 0xa4, 0x0e, 0xb1, 0xa6, 0xee, 0x15, 0xc4, 0xc8, - 0x25, 0xf0, 0x97, 0x0b, 0x54, 0xc2, 0xb5, 0x7f, 0xfe, 0x5d, 0xcf, 0x30, 0xd8, 0x9d, 0xd4, 0x87, - 0x18, 0x1e, 0xc7, 0x85, 0x0b, 0x51, 0x3a, 0x7d, 0x86, 0x81, 0xe9, 0x1a, 0xd4, 0x5c, 0x86, 0x9c, - 0x54, 0x2a, 0x1e, 0x44, 0x7a, 0xde, 0x2b, 0xb3, 0x67, 0x31, 0xbb, 0x31, 0xaf, 0xd5, 0x58, 0xfb, - 0x45, 0x80, 0xc4, 0x04, 0x62, 0x66, 0x49, 0xe0, 0xfd, 0x75, 0xad, 0x3b, 0xcc, 0x82, 0x44, 0x8b, - 0xa5, 0x2e, 0xeb, 0xb6, 0x7a, 0x53, 0x24, 0x4b, 0x38, 0xb7, 0xcc, 0x51, 0x73, 0xa5, 0xdc, 0x51, - 0xe6, 0xe1, 0xba, 0x9d, 0x1b, 0xd6, 0x58, 0x86, 0x87, 0x66, 0x05, 0xb9, 0x0d, 0x6e, 0xd8, 0x96, - 0xac, 0xbc, 0x2e, 0xcd, 0xbb, 0x02, 0xd5, 0x16, 0x24, 0xbe, 0xa7, 0x41, 0xae, 0x6b, 0x7b, 0x8a, - 0x69, 0xbb, 0x4d, 0xdf, 0x6f, 0x74, 0x66, 0x52, 0xb6, 0xe7, 0x87, 0xcf, 0xaf, 0x20, 0x7e, 0x21, - 0xf9, 0x0e, 0x7e, 0x7e, 0x87, 0xfb, 0x24, 0xad, 0x57, 0x93, 0xe4, 0x5e, 0x0d, 0x62, 0x20, 0x24, - 0x89, 0x03, 0x90, 0xef, 0x2d, 0x7e, 0xbe, 0x01, 0x72, 0x5d, 0x5a, 0xdf, 0x5b, 0x15, 0x6a, 0x3b, - 0xbb, 0xbf, 0xe7, 0x47, 0x2b, 0xd4, 0x6b, 0xe6, 0xc0, 0x49, 0x4d, 0xeb, 0xb9, 0xc2, 0x63, 0x57, - 0x5e, 0x14, 0x66, 0x5d, 0x9b, 0xf5, 0x5c, 0x88, 0x49, 0x6a, 0xf7, 0x13, 0xd4, 0x3d, 0xd4, 0x2b, - 0x06, 0x3f, 0xa2, 0x36, 0x83, 0xfb, 0x6c, 0xa6, 0x92, 0xd1, 0x77, 0x9c, 0xe7, 0xb0, 0xec, 0xa3, - 0xe7, 0x07, 0xae, 0x3c, 0x28, 0x05, 0xb2, 0xb5, 0x97, 0x7c, 0x6e, 0x37, 0xf0, 0x8b, 0xc5, 0x27, - 0xc8, 0x0b, 0xa3, 0x07, 0x90, 0x19, 0x83, 0xdb, 0x66, 0xc8, 0x33, 0xc9, 0x92, 0x8a, 0xea, 0x14, - 0xd8, 0x8d, 0x52, 0x18, 0x97, 0x93, 0x67, 0x30, 0x42, 0xe2, 0x29, 0x74, 0xf0, 0x3c, 0xf3, 0xd0, - 0xa6, 0x9a, 0x28, 0xf1, 0x00, 0xf3, 0x5e, 0xbc, 0x7e, 0xcf, 0x80, 0xb3, 0xaf, 0x3e, 0x68, 0xc5, - 0xeb, 0x18, 0xfc, 0xe0, 0xae, 0x29, 0xc3, 0x38, 0xd7, 0xc1, 0x6d, 0x05, 0xb7, 0x05, 0xf2, 0xe4, - 0x9a, 0xc6, 0xed, 0xba, 0x0f, 0xed, 0x32, 0x1e, 0x47, 0x4e, 0xdc, 0xe6, 0x5c, 0x3c, 0xdf, 0x09, - 0x8a, 0x51, 0xe4, 0x6e, 0x03, 0x9e, 0x3f, 0x88, 0xd7, 0xd7, 0xf1, 0x78, 0x49, 0x89, 0xdb, 0x64, - 0x3d, 0x4f, 0xf6, 0xab, 0xc6, 0xf0, 0x39, 0x42, 0x08, 0x02, 0xef, 0xd8, 0x46, 0xc7, 0x36, 0x7b, - 0x5c, 0x5f, 0xe3, 0xa3, 0xf5, 0xc1, 0x7e, 0x04, 0x5e, 0x30, 0xbe, 0x0e, 0xf0, 0x0b, 0x4f, 0x64, - 0x63, 0xa3, 0xa7, 0xe3, 0xd5, 0xaa, 0xc1, 0x82, 0x1d, 0x15, 0xd8, 0x16, 0x82, 0x70, 0x7a, 0xe6, - 0x73, 0x13, 0xd4, 0xa8, 0xa0, 0x03, 0xf0, 0x1b, 0xb5, 0x33, 0x2c, 0xb2, 0x79, 0x01, 0x75, 0xe7, - 0xac, 0xe4, 0x97, 0x65, 0x43, 0x71, 0x59, 0xd5, 0xaf, 0x88, 0xe8, 0x65, 0xcd, 0x82, 0x39, 0x69, - 0x1b, 0x63, 0x83, 0xcd, 0x0e, 0xab, 0x3b, 0xc3, 0xd8, 0x73, 0x35, 0x43, 0xd8, 0xa0, 0x99, 0xcb, - 0xf5, 0xb0, 0xd1, 0xb6, 0xfa, 0x5c, 0xdf, 0xae, 0x39, 0xc8, 0xde, 0x70, 0xf6, 0xb0, 0xee, 0x1a, - 0x31, 0x3f, 0xd7, 0xa8, 0xec, 0x92, 0x82, 0x1c, 0x79, 0x19, 0xd7, 0x28, 0x4d, 0x5e, 0x2d, 0x54, - 0xcf, 0x1d, 0xf9, 0x23, 0x05, 0x57, 0x35, 0xd0, 0x71, 0x5d, 0x15, 0x95, 0x12, 0xfc, 0xf3, 0x61, - 0x1c, 0xe2, 0xbc, 0xa8, 0x8d, 0x0d, 0x3b, 0x79, 0xc8, 0x1c, 0xb5, 0x71, 0x3d, 0x01, 0x14, 0x3a, - 0x6e, 0xe3, 0x7a, 0x1f, 0x47, 0xc7, 0x6d, 0x48, 0x71, 0xc8, 0x73, 0x3a, 0xec, 0x0b, 0x58, 0x7c, - 0x95, 0x83, 0xf0, 0x48, 0x38, 0xb6, 0x0d, 0xc0, 0xa7, 0x64, 0x1f, 0xdb, 0x3e, 0x8c, 0x73, 0xf3, - 0xb8, 0x1d, 0x5c, 0x22, 0x3a, 0x8e, 0xc3, 0x7e, 0x7d, 0x5c, 0x12, 0x88, 0xdb, 0x06, 0x9e, 0x5f, - 0x8c, 0xdb, 0xb0, 0x1f, 0x36, 0x40, 0x0c, 0xb8, 0x6c, 0x06, 0x55, 0xac, 0xfe, 0x0b, 0x68, 0x8f, - 0xda, 0x7f, 0xda, 0x08, 0x25, 0x7e, 0x23, 0x22, 0xb6, 0x8f, 0x2a, 0x32, 0xd2, 0x0c, 0xf6, 0x80, - 0x2a, 0x73, 0x34, 0xf2, 0xd9, 0x0d, 0x3e, 0xbd, 0x28, 0xa1, 0x0d, 0x2a, 0xb1, 0xd1, 0x9a, 0xe8, - 0xb3, 0xfb, 0xd2, 0x1f, 0x33, 0xa3, 0x4a, 0x79, 0x8f, 0x20, 0x79, 0x78, 0x91, 0xd8, 0x25, 0xaa, - 0xca, 0x38, 0x88, 0x9f, 0xa2, 0x6a, 0x2d, 0x9a, 0x53, 0x19, 0x65, 0xc0, 0xbe, 0x56, 0xc6, 0xd6, - 0x68, 0xa1, 0xec, 0x87, 0x83, 0x8e, 0xf5, 0xc2, 0xb1, 0xa6, 0xde, 0x65, 0x6b, 0xc3, 0xcc, 0x53, - 0x73, 0x94, 0x79, 0xda, 0x90, 0xfa, 0x7a, 0xa5, 0x88, 0x46, 0x06, 0x4b, 0xe3, 0xbd, 0x5e, 0x7c, - 0xd6, 0x42, 0x95, 0x1c, 0x86, 0xb7, 0x47, 0x15, 0x1e, 0x8d, 0x11, 0x6e, 0x4b, 0xb8, 0xf2, 0x6a, - 0xa2, 0xea, 0x1c, 0x7f, 0xd6, 0x10, 0x48, 0x01, 0xe0, 0xd6, 0x24, 0xeb, 0x08, 0x8e, 0xf8, 0xca, - 0x0b, 0xce, 0x23, 0xde, 0xf7, 0xfa, 0x9c, 0x9a, 0xd8, 0xce, 0x42, 0xf5, 0x3e, 0x7d, 0xc4, 0x77, - 0x84, 0x3e, 0x7e, 0xfe, 0xf6, 0xe1, 0xb7, 0xbf, 0x3e, 0xfc, 0xf6, 0xe1, 0x37, 0x7c, 0x63, 0x0d, - 0x5f, 0x39, 0xf2, 0xec, 0x8d, 0x36, 0x4d, 0xab, 0xe4, 0xb6, 0xd2, 0xd7, 0xd4, 0x42, 0x5d, 0x9a, - 0xab, 0x8d, 0x45, 0xee, 0x16, 0x45, 0x33, 0x47, 0xf6, 0x78, 0x8f, 0x67, 0x2e, 0x54, 0xc7, 0x30, - 0x61, 0x0e, 0x0d, 0x03, 0xf8, 0x4a, 0x93, 0xe1, 0xd8, 0x9b, 0xe5, 0x38, 0xb8, 0x6a, 0xf6, 0x35, - 0xf5, 0x07, 0xc3, 0x30, 0xdf, 0xce, 0x6e, 0x30, 0x55, 0x75, 0x6b, 0xab, 0x7b, 0xa6, 0xa6, 0x7e, - 0x49, 0x29, 0xba, 0x33, 0x56, 0x97, 0xf0, 0xc5, 0x55, 0x97, 0x6e, 0xda, 0xd5, 0x1d, 0x73, 0x12, - 0xcd, 0x76, 0xcd, 0x83, 0xfe, 0x35, 0xc5, 0x3c, 0xae, 0x76, 0xd0, 0x13, 0x42, 0xf3, 0xa7, 0xa6, - 0xa7, 0x43, 0xd3, 0xd3, 0x77, 0x5e, 0x5a, 0xb5, 0x4c, 0x03, 0xf6, 0xd5, 0xf4, 0xa5, 0xa7, 0x3b, - 0xd0, 0x89, 0xef, 0xa6, 0xcd, 0x4d, 0x2f, 0x1d, 0xa0, 0xae, 0xa9, 0x96, 0x65, 0x6f, 0xbc, 0xaf, - 0xa9, 0xa5, 0xbd, 0xd4, 0x13, 0xa3, 0x1b, 0xd8, 0x04, 0x36, 0xb2, 0x74, 0x2d, 0x31, 0xb6, 0xb0, - 0x0f, 0x37, 0x06, 0xdc, 0xab, 0xfd, 0x57, 0xe7, 0x46, 0xdb, 0xab, 0xab, 0xf4, 0xd4, 0x34, 0xa6, - 0x80, 0xdd, 0xd4, 0x8b, 0xc8, 0xe0, 0x39, 0x70, 0xbe, 0x95, 0xea, 0x00, 0xae, 0x49, 0x4a, 0x7f, - 0x39, 0x92, 0x71, 0xaa, 0xe3, 0xf9, 0x70, 0x60, 0x9a, 0xfe, 0x2f, 0x98, 0x42, 0xae, 0xff, 0xc5, - 0xad, 0x95, 0xed, 0x9a, 0x01, 0x27, 0x26, 0xe6, 0x4e, 0x1f, 0x43, 0x8f, 0xbd, 0xd5, 0x1d, 0x57, - 0x73, 0x6c, 0xcb, 0x4a, 0x8f, 0xf4, 0xa9, 0xba, 0x35, 0xf1, 0x2e, 0x21, 0x26, 0x04, 0xfc, 0x2a, - 0xc9, 0x1b, 0x86, 0x5e, 0xed, 0x52, 0x74, 0x2a, 0x83, 0xdf, 0x8f, 0xd4, 0xfc, 0x63, 0x3c, 0x1e, - 0x47, 0xd3, 0xbd, 0x31, 0xe1, 0xfa, 0x35, 0xba, 0x92, 0x4e, 0x72, 0x00, 0x2c, 0x32, 0x5f, 0x53, - 0x9b, 0xd5, 0x4a, 0x77, 0x34, 0xd5, 0xd5, 0xcf, 0x38, 0x95, 0x23, 0x9c, 0x0a, 0x64, 0x63, 0xe3, - 0x79, 0xf6, 0x12, 0x43, 0x04, 0x16, 0x58, 0xe6, 0x52, 0x8f, 0x71, 0xd3, 0x36, 0x8e, 0x8b, 0xf7, - 0x5e, 0xd9, 0x66, 0x08, 0x9e, 0x2c, 0x78, 0xb0, 0xd4, 0x91, 0x6e, 0xb9, 0xe7, 0xf2, 0xb4, 0x52, - 0xc7, 0x63, 0x73, 0x69, 0x7c, 0x4d, 0x15, 0x4f, 0xf0, 0x27, 0x4b, 0xfe, 0xc0, 0xb7, 0x13, 0xc9, - 0x32, 0xbc, 0xea, 0x92, 0x42, 0x23, 0x1b, 0x70, 0x00, 0x74, 0x1f, 0x33, 0x04, 0x2f, 0x27, 0x20, - 0x6f, 0x2e, 0x29, 0x4e, 0x7f, 0x14, 0x0a, 0x05, 0x4c, 0x6b, 0x07, 0x96, 0x2e, 0x0d, 0x90, 0x82, - 0x31, 0x20, 0x0a, 0x84, 0xc5, 0xb2, 0x69, 0xa5, 0x1d, 0x2b, 0xc6, 0x6e, 0xe4, 0x98, 0x64, 0x93, - 0x08, 0x9d, 0xc4, 0x51, 0x1f, 0x7c, 0x47, 0xc5, 0x04, 0xb9, 0x8e, 0x84, 0x67, 0xaf, 0x82, 0x93, - 0x58, 0xfa, 0xc4, 0x0b, 0xbe, 0x85, 0x88, 0x9c, 0xaa, 0x0b, 0xe0, 0x92, 0xc9, 0x64, 0xa0, 0xeb, - 0x90, 0x36, 0x97, 0x63, 0x7d, 0x07, 0xe4, 0x8c, 0x37, 0xc0, 0x57, 0x26, 0xdd, 0x8b, 0x6b, 0x80, - 0x1f, 0x83, 0x6b, 0x80, 0x1f, 0x63, 0x26, 0xe0, 0x9b, 0x83, 0x98, 0xcc, 0xa0, 0xd5, 0xd6, 0x29, - 0x67, 0x32, 0x01, 0xba, 0x98, 0x0f, 0xe9, 0x58, 0xcc, 0xa0, 0x63, 0x6c, 0xba, 0x2b, 0x4b, 0x05, - 0x58, 0xe6, 0x92, 0x8c, 0x8d, 0x2c, 0x5b, 0x9b, 0x7f, 0x3b, 0x72, 0x20, 0x4d, 0xe8, 0x8d, 0x0f, - 0x7b, 0xa4, 0xba, 0x87, 0x6f, 0x7d, 0x12, 0x51, 0xc1, 0x5f, 0xd2, 0xb0, 0x9c, 0x28, 0x59, 0x74, - 0xde, 0x50, 0x6c, 0x1f, 0x0b, 0xff, 0xf5, 0x0e, 0xc1, 0x0a, 0x8e, 0xe7, 0x5a, 0xe6, 0x18, 0xb4, - 0x09, 0x9f, 0xf2, 0xc3, 0x6f, 0x78, 0xea, 0x51, 0xd2, 0xc8, 0x57, 0xb0, 0x3a, 0xfa, 0xf0, 0x53, - 0x76, 0xb5, 0xfb, 0x7c, 0x5d, 0x72, 0x1f, 0x40, 0x0f, 0xc9, 0xea, 0xa4, 0xf0, 0xa4, 0x19, 0x40, - 0x1a, 0xa3, 0x9f, 0x0f, 0x91, 0x8f, 0xb9, 0x1a, 0x22, 0xb1, 0x30, 0xc7, 0x63, 0x4b, 0xbf, 0x01, - 0x71, 0x62, 0x11, 0x76, 0x4e, 0x2c, 0x5b, 0x85, 0xb3, 0x11, 0x86, 0x5d, 0x15, 0xdd, 0xa4, 0xa8, - 0x46, 0x70, 0x26, 0x13, 0x6c, 0xc1, 0x12, 0x87, 0x70, 0x6c, 0x0f, 0x4e, 0xf0, 0x89, 0x1e, 0xeb, - 0xc6, 0xe7, 0x68, 0x24, 0x94, 0x92, 0x78, 0x56, 0x8a, 0x7e, 0xc8, 0xba, 0xf1, 0xf6, 0xfa, 0x8e, - 0x28, 0xef, 0x25, 0x0c, 0xa6, 0x18, 0x41, 0x09, 0x25, 0x83, 0x88, 0xfe, 0x2d, 0x36, 0xde, 0x3c, - 0x72, 0xa0, 0x3e, 0x96, 0xb9, 0xd5, 0xf1, 0x25, 0xe4, 0xa4, 0xf1, 0x09, 0x04, 0x25, 0x06, 0x18, - 0xea, 0xec, 0xa9, 0x2d, 0x1a, 0xd9, 0x0e, 0xf0, 0x0b, 0x0e, 0x9d, 0xd0, 0x01, 0x10, 0x06, 0x0c, - 0xe6, 0x8a, 0xf9, 0x0f, 0xa4, 0xfa, 0x94, 0xc8, 0x13, 0xd3, 0xf2, 0x30, 0x84, 0xb1, 0x63, 0xaf, - 0xd2, 0xee, 0x54, 0x1d, 0xdb, 0xfe, 0x27, 0x62, 0xa0, 0xc2, 0x1f, 0xec, 0x33, 0x8e, 0x87, 0x04, - 0x3d, 0x7e, 0x5d, 0xc1, 0x4f, 0xd5, 0xeb, 0x14, 0xd9, 0x23, 0x7a, 0x47, 0x93, 0x74, 0x89, 0xa5, - 0xb9, 0x9c, 0x82, 0xe7, 0xc1, 0x3c, 0x0e, 0x59, 0x8e, 0xc1, 0x25, 0x8e, 0x1a, 0xd2, 0x21, 0xc9, - 0xba, 0x90, 0x61, 0x37, 0x3d, 0xd5, 0x1f, 0x9a, 0xa6, 0x1d, 0xf7, 0xb7, 0x57, 0x89, 0xfd, 0x63, - 0x2b, 0x82, 0x2d, 0x66, 0xf8, 0x46, 0x87, 0xdf, 0xf0, 0x92, 0xd4, 0xf5, 0x57, 0x4c, 0x8c, 0x6b, - 0x90, 0x02, 0xfb, 0x5e, 0x0c, 0x85, 0x3d, 0xa0, 0x41, 0x26, 0x7f, 0x8d, 0x02, 0x5f, 0xa7, 0xd8, - 0x75, 0xdc, 0xe0, 0x56, 0x36, 0x9b, 0x4d, 0x1c, 0x41, 0xd7, 0xf5, 0x2b, 0x00, 0x1e, 0x70, 0x50, - 0xb0, 0xd5, 0x6f, 0x40, 0x08, 0x2c, 0xea, 0xa9, 0x32, 0x04, 0x10, 0xde, 0x5a, 0x96, 0xfa, 0xdd, - 0x5c, 0xe0, 0x0b, 0xf1, 0x2a, 0x71, 0x91, 0xd7, 0x20, 0xe0, 0xcb, 0xe9, 0x2a, 0x48, 0x38, 0xc1, - 0x3e, 0x9d, 0x5e, 0x06, 0x56, 0xec, 0x94, 0xe1, 0x61, 0x0b, 0xc4, 0x5e, 0xfb, 0xb4, 0x55, 0x9d, - 0x4f, 0x30, 0xed, 0xf3, 0x3f, 0xf1, 0x18, 0x16, 0xa8, 0x48, 0xcc, 0xc9, 0x28, 0xee, 0x4c, 0xa5, - 0x53, 0xc1, 0x24, 0x6f, 0xf5, 0x25, 0x55, 0x00, 0x22, 0x7e, 0x8e, 0x7b, 0x46, 0x5e, 0xd8, 0xf3, - 0x39, 0x56, 0xf4, 0x34, 0xb1, 0xe6, 0x67, 0x0b, 0xbe, 0x5d, 0xb7, 0x58, 0x9f, 0x12, 0x18, 0x78, - 0xbb, 0x2f, 0x29, 0x02, 0xfb, 0x3e, 0x5c, 0x6c, 0x42, 0xfb, 0x33, 0x15, 0xa3, 0x97, 0x26, 0xf8, - 0x7d, 0x7e, 0x8f, 0x57, 0xc7, 0x7c, 0x08, 0xef, 0xe8, 0x27, 0x2c, 0x54, 0x28, 0xae, 0x47, 0x15, - 0x71, 0x74, 0x1c, 0xab, 0x6d, 0x2f, 0x95, 0x37, 0x49, 0x1e, 0xdc, 0x15, 0x23, 0xf1, 0x39, 0xe9, - 0x6d, 0x19, 0x26, 0x14, 0xa4, 0x91, 0xbd, 0xc3, 0xd2, 0x4d, 0x3a, 0x03, 0x65, 0x48, 0x43, 0xd7, - 0x85, 0x11, 0xc0, 0x68, 0x03, 0x2a, 0xfe, 0xd7, 0x94, 0xba, 0xf1, 0xec, 0x6f, 0x17, 0xc1, 0xcc, - 0x9b, 0xc7, 0xfa, 0x83, 0x9f, 0x4c, 0x20, 0x96, 0x72, 0x13, 0x42, 0x9d, 0x8e, 0x5d, 0x67, 0xb8, - 0x31, 0x69, 0x13, 0xcc, 0x5c, 0x1b, 0x5c, 0x46, 0x14, 0x59, 0x86, 0x3e, 0x60, 0x61, 0xdb, 0xde, - 0x34, 0xf5, 0x67, 0xea, 0xba, 0x79, 0x4d, 0xca, 0xc3, 0xe4, 0x4b, 0x8a, 0xf9, 0xfc, 0xcf, 0x87, - 0xbc, 0xfb, 0x39, 0xa5, 0x43, 0x10, 0x93, 0x06, 0xff, 0x95, 0x8a, 0x69, 0x9b, 0x8e, 0x03, 0x8a, - 0xd8, 0xb6, 0xc3, 0x7f, 0xe9, 0xc8, 0x8b, 0x44, 0xb8, 0x45, 0xa6, 0x27, 0x19, 0x07, 0xe0, 0x43, - 0x82, 0xd5, 0xbc, 0x6e, 0xab, 0x5e, 0x8d, 0xee, 0xae, 0x04, 0x09, 0x37, 0x75, 0xf3, 0xd2, 0xad, - 0xc7, 0xd6, 0x7a, 0x62, 0xe9, 0xb8, 0x4d, 0xac, 0x7d, 0x1a, 0xe2, 0xe4, 0x85, 0x9b, 0xf0, 0xb5, - 0xb3, 0x8d, 0xeb, 0x99, 0x93, 0x7d, 0x3a, 0x14, 0x9e, 0xc4, 0xc8, 0x31, 0xe2, 0xc0, 0xe4, 0xb4, - 0x57, 0xaa, 0x66, 0x7a, 0x7b, 0x6c, 0xe0, 0x9e, 0xf2, 0x17, 0x36, 0xef, 0xd1, 0x25, 0x62, 0x46, - 0xfc, 0x5f, 0x5a, 0xdf, 0x02, 0x08, 0xf7, 0x4c, 0x3e, 0x5d, 0x4f, 0xdd, 0x63, 0x73, 0x97, 0xf4, - 0x4b, 0x91, 0x43, 0x3a, 0x92, 0x25, 0x8a, 0x95, 0x01, 0x27, 0x6d, 0xbe, 0x3f, 0x19, 0x8a, 0xbb, - 0x4e, 0x82, 0xa3, 0x80, 0xd7, 0x01, 0xa1, 0xc8, 0xa9, 0x2f, 0xe3, 0xa4, 0x3f, 0xc2, 0xad, 0x99, - 0x20, 0x7d, 0x81, 0x99, 0x99, 0xa7, 0x23, 0x7b, 0xa2, 0xd1, 0x4c, 0x3c, 0x9a, 0x2f, 0x26, 0x46, - 0x3d, 0x5b, 0x75, 0x89, 0x46, 0x1d, 0xcf, 0x7f, 0x9d, 0x0b, 0xf9, 0x7c, 0x9e, 0xd8, 0x83, 0x5d, - 0x3a, 0xe4, 0xe1, 0x13, 0x61, 0xe1, 0x99, 0xf7, 0xbf, 0x16, 0xed, 0x84, 0x62, 0xec, 0xa8, 0x63, - 0x73, 0x03, 0x54, 0x0b, 0xa2, 0xd2, 0xa3, 0xca, 0x15, 0x82, 0xf6, 0x85, 0xe4, 0xc4, 0x07, 0xcd, - 0xc4, 0x02, 0x92, 0x0f, 0xa4, 0xe6, 0x8a, 0xd5, 0x19, 0x7c, 0x4a, 0xe7, 0x03, 0x53, 0x17, 0x49, - 0x28, 0x88, 0x18, 0x01, 0x7c, 0xe9, 0xa8, 0x5e, 0x63, 0x63, 0x40, 0x8f, 0x07, 0x77, 0x6a, 0xfb, - 0x27, 0x44, 0xc1, 0xc4, 0x86, 0x54, 0x70, 0xa1, 0x86, 0x38, 0xaa, 0x63, 0xdd, 0x5c, 0x82, 0x5c, - 0xe4, 0xdd, 0x2f, 0xc9, 0x46, 0x2a, 0x83, 0xdf, 0x1c, 0x1d, 0xab, 0xfd, 0x39, 0x4c, 0xdd, 0x71, - 0x6c, 0xe7, 0x02, 0xe8, 0x15, 0x4a, 0x8f, 0x32, 0xb7, 0x77, 0x8b, 0x60, 0xfe, 0x6b, 0xae, 0xef, - 0x27, 0x0e, 0xe4, 0x01, 0x6e, 0x34, 0x8a, 0x8d, 0xa2, 0x63, 0x2f, 0x52, 0x7f, 0x1e, 0xa3, 0x83, - 0x54, 0x82, 0xa7, 0x7f, 0x61, 0xe6, 0x1f, 0x07, 0x03, 0xea, 0xa4, 0x12, 0xa8, 0xfc, 0x75, 0x1a, - 0x96, 0x86, 0x32, 0x8c, 0xc1, 0x46, 0x9a, 0xf3, 0xf1, 0xe3, 0x09, 0x9f, 0xd4, 0x11, 0x98, 0xa3, - 0x4d, 0x90, 0x95, 0x12, 0x0b, 0x95, 0xc5, 0x10, 0xe3, 0x0d, 0xb2, 0x41, 0xe8, 0x4d, 0xf8, 0xc6, - 0x90, 0xcd, 0x9c, 0xc8, 0x12, 0x90, 0x91, 0x13, 0x29, 0xcf, 0xe5, 0x72, 0x97, 0x82, 0xf2, 0x3a, - 0xbb, 0x62, 0xf1, 0x48, 0xc7, 0x8a, 0x60, 0x2e, 0x57, 0x1b, 0xef, 0x7f, 0xbc, 0xfd, 0x4a, 0x7f, - 0x06, 0xb9, 0x30, 0xf4, 0x7f, 0x13, 0x77, 0x19, 0x6a, 0x1c, 0xce, 0x55, 0x54, 0xe8, 0xd6, 0xf4, - 0xf3, 0xf0, 0x2e, 0x93, 0xa1, 0x4f, 0x45, 0x32, 0x68, 0xc6, 0x76, 0x30, 0x0a, 0x53, 0xa2, 0x2f, - 0x57, 0xb9, 0x76, 0x9a, 0xe7, 0x5e, 0x4d, 0xf6, 0x2e, 0xd0, 0xfb, 0x3a, 0xb1, 0xb5, 0x8d, 0x7b, - 0x2d, 0x59, 0xbc, 0x3a, 0xfb, 0x6b, 0x6c, 0x3c, 0x82, 0xc4, 0xc1, 0xd9, 0x2c, 0x97, 0x24, 0x17, - 0x81, 0xbd, 0xb5, 0x39, 0x06, 0x73, 0x6a, 0x5d, 0x23, 0xd3, 0x9b, 0x0d, 0x70, 0xbe, 0xc4, 0x29, - 0xc9, 0x02, 0xc7, 0x18, 0xa9, 0x9f, 0x68, 0x70, 0xcf, 0xc1, 0xff, 0x9f, 0xdf, 0x8b, 0x84, 0x37, - 0xdd, 0x2c, 0x46, 0x27, 0x69, 0x7c, 0xa0, 0xcf, 0x11, 0x2a, 0x41, 0xeb, 0x3a, 0x67, 0x4f, 0x44, - 0x20, 0x30, 0x20, 0x97, 0x48, 0xbe, 0xc2, 0xbf, 0x64, 0x70, 0xf2, 0x18, 0xd9, 0xb4, 0x6b, 0x28, - 0xe3, 0x2a, 0x07, 0x69, 0xbc, 0x93, 0x54, 0x97, 0xec, 0x7d, 0x3f, 0x79, 0x12, 0x7b, 0x45, 0xa4, - 0x49, 0xc4, 0x0c, 0xa1, 0x0b, 0xbf, 0x02, 0xee, 0x7f, 0x87, 0x7e, 0xd7, 0x73, 0xc8, 0xc7, 0x20, - 0x5c, 0xbb, 0x85, 0xb1, 0xfb, 0xd3, 0x64, 0x39, 0x97, 0xf7, 0x10, 0xbf, 0xeb, 0xba, 0x70, 0xa3, - 0x10, 0x74, 0x03, 0x15, 0xc8, 0x91, 0xac, 0x34, 0x84, 0x54, 0xe7, 0xa1, 0xfa, 0x4f, 0x42, 0xd8, - 0x44, 0xa5, 0x89, 0xbf, 0x03, 0xe1, 0xef, 0x09, 0x75, 0xe1, 0x16, 0x53, 0x92, 0x72, 0x9a, 0x66, - 0x32, 0x09, 0xef, 0xeb, 0xe3, 0x1a, 0xca, 0x49, 0xc8, 0x70, 0x1a, 0x53, 0x10, 0x1d, 0x8b, 0xe6, - 0x9c, 0x71, 0x23, 0xb2, 0x5e, 0x39, 0xfa, 0xcc, 0x81, 0x26, 0x62, 0xe0, 0x60, 0x97, 0x91, 0x63, - 0x46, 0x30, 0xce, 0x32, 0xfb, 0x60, 0x7c, 0x05, 0x81, 0x47, 0x40, 0xac, 0x93, 0xb2, 0x59, 0x18, - 0xd2, 0x46, 0xfb, 0x14, 0x42, 0x7f, 0xfa, 0x4a, 0x0e, 0x8b, 0xeb, 0x0e, 0x7f, 0xd0, 0x34, 0x9d, - 0xc8, 0x61, 0xbd, 0xd3, 0x7c, 0xad, 0x78, 0x62, 0x5a, 0x99, 0xd3, 0x93, 0x64, 0x2f, 0x3d, 0xf6, - 0xd3, 0x0d, 0x7d, 0x3c, 0x4d, 0xd8, 0xa2, 0xea, 0xe8, 0xa5, 0xa2, 0x9d, 0x8e, 0x1c, 0x63, 0x90, - 0xfc, 0x4f, 0x9d, 0xe5, 0x18, 0x0b, 0xa6, 0xc7, 0x1b, 0x47, 0x8d, 0x82, 0x42, 0xe2, 0x8e, 0x23, - 0xfb, 0x84, 0x71, 0xc4, 0xbf, 0xb6, 0x9a, 0xde, 0x9a, 0xae, 0x39, 0x32, 0x2d, 0xe2, 0x56, 0xa7, - 0xe6, 0x78, 0xac, 0x2f, 0x13, 0xb3, 0x8e, 0xfa, 0x19, 0xab, 0x67, 0x76, 0x0c, 0x96, 0x00, 0xfe, - 0x3b, 0x21, 0x5a, 0x3a, 0x59, 0x76, 0x3b, 0x8b, 0xba, 0x23, 0x72, 0x3d, 0x9e, 0x0b, 0xdc, 0x59, - 0xed, 0xe1, 0xaf, 0x08, 0xd4, 0x59, 0x89, 0x08, 0x9f, 0xae, 0xf8, 0x9e, 0x0a, 0x51, 0x80, 0xcd, - 0x5a, 0x73, 0xd3, 0xfe, 0x71, 0x7d, 0x98, 0x8e, 0xc4, 0x45, 0x10, 0x3c, 0x7e, 0x91, 0xdc, 0x27, - 0x78, 0x9c, 0xb9, 0xaa, 0x2b, 0x67, 0x11, 0xfc, 0x59, 0x01, 0x27, 0x04, 0x3b, 0x3a, 0x85, 0x9b, - 0x4d, 0x40, 0x82, 0xe6, 0x05, 0x8f, 0xc3, 0x5c, 0xd9, 0x4a, 0xd8, 0xb1, 0x5c, 0x42, 0xd9, 0x82, - 0xaa, 0xf5, 0x1b, 0x21, 0x01, 0x31, 0xdf, 0x57, 0xfa, 0xaf, 0x74, 0x25, 0x15, 0x1d, 0xff, 0x2a, - 0x72, 0xf2, 0xd7, 0xbd, 0xdd, 0xad, 0x71, 0xbf, 0x5b, 0x58, 0xdf, 0x36, 0xde, 0xa4, 0xf8, 0xe5, - 0x3b, 0xb4, 0x52, 0xd0, 0x5a, 0xba, 0xcf, 0x1f, 0xa7, 0x9e, 0xb7, 0xfa, 0x4a, 0x51, 0xbe, 0xef, - 0x3f, 0xf8, 0xd9, 0x07, 0xdb, 0x31, 0xa8, 0x0c, 0xc8, 0x18, 0x9e, 0xff, 0x31, 0x15, 0xfc, 0x16, - 0xfc, 0x47, 0xb0, 0xbd, 0x1f, 0x53, 0x81, 0xae, 0x87, 0x0d, 0x6c, 0xd0, 0x9e, 0x3f, 0x92, 0x63, - 0x7e, 0xfc, 0xf1, 0x7d, 0x65, 0x5b, 0x7b, 0x03, 0x38, 0x4a, 0x5c, 0x24, 0x80, 0x04, 0xd1, 0xc1, - 0xf6, 0x1a, 0xde, 0xf3, 0xf4, 0x97, 0x3c, 0xfd, 0x91, 0xfa, 0xf1, 0x1d, 0xc3, 0xfb, 0x71, 0xf7, - 0x19, 0x30, 0x4d, 0x3b, 0x3a, 0x20, 0xee, 0x9d, 0x8a, 0x49, 0xa8, 0x5b, 0x99, 0x73, 0xf1, 0x39, - 0x9a, 0x90, 0x0c, 0x5d, 0xc0, 0xc1, 0x4e, 0x21, 0x19, 0x17, 0xa5, 0xc3, 0x58, 0x0e, 0x2b, 0xc6, - 0x49, 0xc5, 0x22, 0x01, 0x21, 0xd8, 0xed, 0xeb, 0xc9, 0xc6, 0x57, 0x62, 0x9b, 0xf0, 0x01, 0x02, - 0x21, 0x36, 0x89, 0x81, 0x1c, 0x80, 0x1f, 0x57, 0xfe, 0x2e, 0x14, 0xcd, 0xbd, 0xe5, 0x45, 0x48, - 0xba, 0x11, 0xe8, 0x6d, 0x90, 0xaf, 0xd2, 0x89, 0xba, 0x89, 0xbd, 0x22, 0xbf, 0x70, 0xfe, 0xe7, - 0xdb, 0xe6, 0x23, 0x59, 0x6b, 0x49, 0x78, 0x84, 0x25, 0x38, 0x01, 0xdd, 0xf9, 0xf7, 0xb9, 0x13, - 0xf9, 0x45, 0xd3, 0x93, 0x3f, 0x8d, 0x35, 0x4f, 0x0d, 0x22, 0xa6, 0x7a, 0xf4, 0x43, 0x5f, 0x35, - 0x85, 0xc9, 0xb4, 0xf4, 0x88, 0x15, 0x18, 0xa3, 0x8c, 0x7b, 0x85, 0xd6, 0xa1, 0x1a, 0xe4, 0x03, - 0x6d, 0xbd, 0x26, 0xf7, 0x98, 0x84, 0x13, 0x53, 0xb7, 0xc6, 0xd7, 0x84, 0x3f, 0x39, 0x78, 0xab, - 0xff, 0x06, 0xd5, 0x8e, 0xb1, 0xed, 0x09, 0xed, 0x82, 0x2a, 0xd9, 0xad, 0x35, 0x71, 0x70, 0x69, - 0x2e, 0x97, 0xf8, 0x39, 0xd3, 0x0a, 0xcc, 0x4d, 0x50, 0x7b, 0xfb, 0x92, 0x7a, 0x7d, 0x01, 0x1c, - 0xfc, 0x74, 0x41, 0xea, 0xcf, 0xd4, 0xab, 0x8a, 0x1e, 0x55, 0xd0, 0x8d, 0x13, 0xd3, 0x98, 0x25, - 0xd5, 0x44, 0x42, 0xfd, 0x53, 0x19, 0x8f, 0x1e, 0x48, 0x9c, 0x58, 0xa4, 0x60, 0x1e, 0x7d, 0x7c, - 0x46, 0xf0, 0xb0, 0xdb, 0xb9, 0x49, 0xeb, 0x43, 0x9f, 0x33, 0x37, 0x9e, 0xe8, 0x84, 0xa6, 0xe8, - 0xaa, 0x70, 0x04, 0x53, 0x56, 0xae, 0xe7, 0xde, 0x90, 0xde, 0xd3, 0xda, 0x72, 0xb1, 0x58, 0x4c, - 0x44, 0xce, 0x63, 0x7d, 0xa2, 0x6e, 0xac, 0x10, 0xe7, 0x07, 0xd7, 0xb3, 0x1d, 0x7d, 0xfc, 0x1e, - 0x25, 0x88, 0xc4, 0xf5, 0x6a, 0xea, 0xf2, 0xe0, 0xaa, 0xdb, 0x50, 0x45, 0x7f, 0x11, 0x0e, 0xc1, - 0xe7, 0x75, 0x70, 0xc5, 0x2c, 0x73, 0x09, 0x2e, 0x34, 0xee, 0xcb, 0xc9, 0x69, 0x99, 0xe9, 0x3c, - 0x09, 0x2d, 0x14, 0x92, 0xcf, 0xbc, 0x32, 0xc5, 0x93, 0xca, 0xf4, 0xad, 0x14, 0xe3, 0x8a, 0x76, - 0x1f, 0x1f, 0x78, 0x65, 0x03, 0x75, 0xbc, 0xa5, 0xc8, 0x01, 0x5e, 0x53, 0xd5, 0x9a, 0x5c, 0x88, - 0x46, 0xb0, 0x2a, 0x40, 0x2b, 0x59, 0x2f, 0x1b, 0x9f, 0x3f, 0xb8, 0x4b, 0x1c, 0x22, 0xf2, 0xf4, - 0xc5, 0xe4, 0x31, 0xde, 0x77, 0x8a, 0x90, 0x42, 0x53, 0x3d, 0x88, 0xe4, 0x6f, 0xf9, 0xd6, 0xab, - 0x71, 0xe2, 0x79, 0xa0, 0x91, 0xcd, 0x24, 0x24, 0x37, 0xee, 0x0d, 0xbd, 0xf6, 0xe5, 0xd6, 0xaf, - 0x3d, 0xe4, 0xd2, 0xa6, 0x73, 0xeb, 0x84, 0x34, 0xd8, 0x7f, 0x3c, 0x46, 0x51, 0x56, 0x36, 0x7f, - 0x6d, 0x23, 0xfa, 0x44, 0x53, 0xb6, 0x57, 0x41, 0xbc, 0x1f, 0x42, 0x40, 0x12, 0x62, 0x3d, 0x6e, - 0xd2, 0xfd, 0xa4, 0xfa, 0x75, 0x79, 0xc0, 0x28, 0xf4, 0x4e, 0x3c, 0x67, 0xa1, 0x4f, 0xe1, 0xc3, - 0xfe, 0xf3, 0x37, 0xb9, 0x7a, 0x5a, 0xea, 0x8c, 0x80, 0x86, 0xc1, 0x68, 0x14, 0xd6, 0xe5, 0x5f, - 0x0f, 0x79, 0x5f, 0x91, 0x42, 0x4c, 0xeb, 0xb8, 0xca, 0x77, 0xc4, 0x6f, 0xe5, 0x6e, 0x71, 0x6f, - 0xb0, 0x71, 0xf8, 0x67, 0x75, 0x12, 0x48, 0x1d, 0x7b, 0xe2, 0x75, 0x89, 0x27, 0xb5, 0x31, 0x88, - 0x4b, 0x0e, 0x60, 0xca, 0xc7, 0x95, 0x91, 0x6f, 0x57, 0xe3, 0xc3, 0xdb, 0x5c, 0x89, 0xe8, 0x16, - 0x3e, 0x95, 0x09, 0xb8, 0xf3, 0xff, 0x52, 0xa7, 0xc4, 0xbc, 0x42, 0x84, 0xa0, 0x52, 0x74, 0xc1, - 0xd8, 0xaf, 0xe4, 0x3b, 0x58, 0xba, 0x77, 0x80, 0x48, 0xf8, 0xa0, 0xe3, 0xdc, 0xaf, 0xea, 0xc4, - 0x0b, 0x72, 0xa0, 0xb8, 0x50, 0x7c, 0x77, 0xf7, 0xed, 0x06, 0x3f, 0xaf, 0x67, 0x6b, 0x6f, 0xa1, - 0x73, 0xdc, 0xe2, 0xa2, 0x40, 0x9c, 0x04, 0x70, 0x6d, 0x41, 0xc0, 0xbb, 0xa7, 0xa3, 0x41, 0x39, - 0x11, 0x99, 0xa0, 0x71, 0xac, 0xb4, 0x9f, 0xc4, 0xc9, 0x57, 0x83, 0x91, 0x48, 0x86, 0x89, 0xc3, - 0xcb, 0x86, 0xc1, 0xc6, 0x65, 0x8e, 0x12, 0x3d, 0x7e, 0xcd, 0xe5, 0xc3, 0xa7, 0xaf, 0x61, 0xad, - 0xe0, 0xd6, 0xf0, 0x2b, 0x43, 0xa1, 0x9d, 0x8c, 0x9f, 0xe6, 0x87, 0x41, 0x4d, 0x10, 0xd3, 0x5f, - 0xb5, 0x1f, 0x71, 0x39, 0x74, 0x34, 0x8a, 0xd7, 0x8f, 0x12, 0x97, 0x3b, 0x62, 0xa9, 0x3a, 0x51, - 0x01, 0xdd, 0x38, 0xd5, 0xc2, 0x84, 0x91, 0xbb, 0x69, 0x11, 0xdf, 0x95, 0x9c, 0x16, 0x7e, 0x22, - 0x39, 0x3d, 0xf1, 0xcf, 0x7f, 0x33, 0x42, 0x7c, 0x77, 0x6e, 0x9a, 0xa0, 0x5d, 0xf8, 0x38, 0x2c, - 0x26, 0x85, 0x79, 0x91, 0x7c, 0x93, 0x9f, 0x5c, 0xf0, 0x79, 0x53, 0x90, 0xf5, 0xdd, 0x4a, 0x5d, - 0x8e, 0x83, 0xb0, 0xe1, 0xba, 0xa8, 0xfe, 0x6b, 0xa1, 0x8f, 0x4d, 0x35, 0xa5, 0x5a, 0x56, 0x0a, - 0x66, 0xa6, 0x3e, 0x25, 0x1e, 0x0b, 0x14, 0x72, 0x79, 0xfc, 0xc4, 0xef, 0xcf, 0x8b, 0xa7, 0xbf, - 0x11, 0x21, 0x83, 0x7b, 0x3d, 0xa7, 0xf7, 0x5b, 0x12, 0x37, 0x2d, 0x1e, 0xa6, 0xa7, 0xfb, 0x1e, - 0x31, 0xbb, 0x52, 0xc7, 0x38, 0x0e, 0xbe, 0x85, 0x16, 0x93, 0xc9, 0xd3, 0x21, 0x5e, 0x7f, 0x04, - 0x38, 0xb5, 0xb5, 0xc5, 0x8d, 0x8d, 0xe0, 0x7f, 0x48, 0xa1, 0xc2, 0x3f, 0x48, 0xf5, 0x9d, 0x8a, - 0xfe, 0x86, 0x19, 0xb9, 0xb0, 0x64, 0x2f, 0x61, 0xe7, 0xf1, 0xf3, 0x9d, 0xbd, 0x6c, 0xc0, 0xe7, - 0xa7, 0xcf, 0xf8, 0xef, 0x80, 0xc1, 0xd8, 0xd8, 0xdc, 0xa6, 0x4c, 0xe8, 0xd6, 0xb6, 0x77, 0x29, - 0xcd, 0x52, 0x5d, 0x17, 0x66, 0x04, 0x8f, 0xc5, 0xee, 0x7e, 0xe0, 0x89, 0x38, 0xda, 0xc1, 0x7f, - 0x19, 0x2b, 0x25, 0x0b, 0x0f, 0x0f, 0x0f, 0xdf, 0x29, 0x98, 0x8f, 0x41, 0x2e, 0xed, 0xf0, 0x2f, - 0x60, 0x11, 0x00, 0x67, 0x0b, 0x53, 0x04, 0x05, 0x68, 0x87, 0xbe, 0x89, 0xf9, 0x76, 0xf7, 0xa3, - 0x6b, 0x3b, 0xce, 0xfe, 0x4b, 0x04, 0x2a, 0xb5, 0xd4, 0xf5, 0xb1, 0x9b, 0xaa, 0xa9, 0x5b, 0xb5, - 0x4b, 0xe0, 0xfc, 0x1e, 0x40, 0xfe, 0x4e, 0xc5, 0x80, 0x63, 0xec, 0x42, 0xe0, 0xe1, 0xa5, 0x9d, - 0x3b, 0x82, 0x2d, 0x30, 0x88, 0xfc, 0x1d, 0xb3, 0xc4, 0x38, 0x7e, 0xdc, 0x7d, 0xa5, 0x7b, 0xe4, - 0x2d, 0xf1, 0x4a, 0xd2, 0x1d, 0xb2, 0x14, 0x03, 0x08, 0x29, 0x89, 0xab, 0x75, 0x77, 0x40, 0x1a, - 0xcd, 0x32, 0xb5, 0x39, 0x06, 0x6b, 0x18, 0x96, 0x4e, 0x7a, 0x81, 0x40, 0x31, 0x64, 0xc3, 0xba, - 0xfb, 0xf1, 0xdd, 0x8c, 0x9a, 0xe4, 0x72, 0xcf, 0xdd, 0x8f, 0x7f, 0xfc, 0xb1, 0xd3, 0xe9, 0xe2, - 0xe4, 0xdb, 0x77, 0xca, 0x84, 0xd4, 0x36, 0x81, 0x45, 0xf0, 0x40, 0xf2, 0xee, 0x07, 0x01, 0xf3, - 0x9d, 0x5a, 0xc1, 0xa1, 0x82, 0xdd, 0xae, 0xa2, 0xd0, 0xb4, 0x2e, 0xf6, 0x6f, 0x5a, 0x98, 0x3b, - 0x57, 0x37, 0xcc, 0xa8, 0x99, 0xdb, 0x1b, 0xf6, 0xcc, 0xc5, 0x3b, 0x36, 0xec, 0xee, 0x97, 0xda, - 0xc5, 0x96, 0xb8, 0xf3, 0xe6, 0xa6, 0x0c, 0x53, 0xb8, 0xbd, 0x29, 0x5e, 0xf9, 0xf6, 0x9e, 0x97, - 0x44, 0x6e, 0x84, 0x77, 0x59, 0x6e, 0xee, 0x9a, 0x63, 0xe8, 0x57, 0x68, 0xeb, 0x90, 0xc5, 0x37, - 0x36, 0x8e, 0xb7, 0xf2, 0xcd, 0x25, 0x58, 0x9f, 0x07, 0x30, 0x00, 0x24, 0x23, 0x7f, 0xc0, 0x7f, - 0xdd, 0x2e, 0xf5, 0x9c, 0xfa, 0x48, 0xb9, 0xba, 0x87, 0xef, 0x8f, 0xb9, 0x1f, 0xbf, 0xdd, 0xe2, - 0xec, 0x6b, 0x84, 0xe6, 0xec, 0xe5, 0xc4, 0x34, 0xde, 0x3c, 0x35, 0xe8, 0xe9, 0xa5, 0x6c, 0x69, - 0xa2, 0x3d, 0xd6, 0x6f, 0xf3, 0x37, 0x3b, 0x7e, 0xe5, 0xd0, 0x5c, 0x0a, 0x2f, 0x3e, 0xdf, 0x37, - 0x52, 0xc9, 0x48, 0x93, 0x43, 0x63, 0x43, 0x24, 0x3e, 0x06, 0x33, 0x1d, 0xdf, 0xfd, 0x60, 0x49, - 0x74, 0xb4, 0xd4, 0x5d, 0x17, 0x83, 0x38, 0x55, 0x13, 0xd3, 0x22, 0xf3, 0x4f, 0x71, 0x4a, 0x25, - 0x2e, 0x7a, 0x45, 0xf2, 0x17, 0x88, 0xc2, 0xe9, 0xe2, 0x44, 0xb5, 0x37, 0x82, 0x43, 0xa2, 0x22, - 0x8c, 0x4d, 0x30, 0x06, 0x5b, 0x13, 0x52, 0x4c, 0x71, 0xad, 0x1a, 0x3a, 0x75, 0x0f, 0x7a, 0xb0, - 0x8a, 0xd9, 0x4b, 0x32, 0xf5, 0xf9, 0x6e, 0xb3, 0x1a, 0x83, 0xdb, 0xed, 0x39, 0xaa, 0x69, 0x7d, - 0xf2, 0xa6, 0xa6, 0x0b, 0x63, 0x60, 0x04, 0x9f, 0xef, 0x32, 0xf9, 0xfc, 0x1d, 0xfe, 0x0b, 0x8a, - 0xcf, 0x77, 0xcc, 0x5d, 0x8a, 0xa4, 0xd0, 0x77, 0xa4, 0xe0, 0x7d, 0x97, 0xda, 0xaa, 0xd6, 0x06, - 0x5a, 0x4c, 0xa6, 0x78, 0x97, 0xa2, 0xae, 0x62, 0x14, 0x5a, 0x48, 0xa0, 0x75, 0x44, 0xa3, 0x5b, - 0x9f, 0x26, 0x79, 0x24, 0x49, 0x10, 0x8e, 0x2e, 0x59, 0x81, 0x15, 0x73, 0xb4, 0xe7, 0x3b, 0x75, - 0x84, 0x6f, 0xcb, 0x8d, 0x2c, 0x75, 0x39, 0xc7, 0x70, 0x82, 0x89, 0x57, 0x40, 0x24, 0xf7, 0x4f, - 0x81, 0x39, 0x8d, 0x2e, 0xbe, 0xdc, 0x25, 0x59, 0xc3, 0x61, 0xc7, 0xea, 0xde, 0x25, 0x78, 0x1b, - 0xc6, 0x6c, 0x27, 0xb3, 0x82, 0xaa, 0x76, 0x3c, 0x0b, 0x2c, 0x22, 0x3e, 0x4d, 0xe2, 0x14, 0xd1, - 0x44, 0xff, 0x92, 0xcf, 0xc1, 0xa5, 0xcc, 0xbb, 0x1f, 0x7d, 0xec, 0xa1, 0xf1, 0x1f, 0x98, 0x5c, - 0x2e, 0x75, 0xeb, 0x92, 0xdd, 0x6f, 0x73, 0xac, 0x7f, 0xb1, 0xff, 0x29, 0xff, 0xc8, 0x51, 0x3e, - 0x4d, 0x54, 0xcb, 0xd5, 0x7f, 0x8e, 0x8d, 0xf4, 0x7f, 0x80, 0x8d, 0x89, 0x25, 0xa4, 0xe8, 0x7b, - 0xee, 0x04, 0xa0, 0x33, 0xa1, 0x89, 0x2b, 0xee, 0xd3, 0x47, 0x48, 0x46, 0x21, 0x0c, 0xa1, 0x3f, - 0x7e, 0xfe, 0x16, 0x7b, 0xab, 0x8b, 0x70, 0x28, 0x9c, 0xf3, 0xed, 0x8c, 0xf2, 0xaf, 0xc1, 0x54, - 0xdf, 0x01, 0x53, 0xfd, 0x49, 0x98, 0x5a, 0xf1, 0x6d, 0x98, 0x78, 0xce, 0xcf, 0xc0, 0x9c, 0xd0, - 0xea, 0x9b, 0x30, 0xf1, 0x9c, 0x9f, 0x82, 0x39, 0x21, 0xb7, 0xd2, 0x5f, 0x87, 0x89, 0x6b, 0x00, - 0x37, 0x61, 0xa6, 0x70, 0xe9, 0xfc, 0x1c, 0x30, 0x4d, 0xbf, 0xcd, 0xa8, 0x60, 0x4e, 0x0c, 0xf8, - 0xfb, 0xc8, 0x79, 0x9f, 0x00, 0xbc, 0x8d, 0x30, 0x9e, 0xf3, 0x7e, 0x22, 0x60, 0x2c, 0xde, 0x82, - 0x19, 0xcc, 0xf9, 0x19, 0x98, 0x98, 0xbd, 0x6f, 0xc1, 0xc4, 0x73, 0x7e, 0x02, 0x66, 0x11, 0x9f, - 0xec, 0x0d, 0x98, 0x64, 0xce, 0xbb, 0x61, 0x3a, 0xcb, 0xf1, 0xeb, 0xf0, 0x70, 0x11, 0x20, 0x95, - 0xbc, 0x8e, 0x4d, 0x22, 0xf9, 0xd4, 0xf5, 0xe7, 0xbe, 0x69, 0x86, 0x5c, 0xd4, 0xbb, 0xfb, 0xd1, - 0xb9, 0xaa, 0xeb, 0x24, 0x60, 0x75, 0xad, 0x64, 0x50, 0x17, 0x22, 0x86, 0xeb, 0x98, 0x9a, 0x95, - 0x82, 0xa8, 0x2f, 0x81, 0x5f, 0x50, 0xb5, 0xef, 0x5a, 0xb6, 0xf7, 0x89, 0xc6, 0x40, 0x99, 0x2b, - 0x6e, 0xfb, 0x9d, 0xeb, 0x19, 0xbc, 0x3e, 0xf3, 0xf7, 0xd7, 0x67, 0xf0, 0xfa, 0xec, 0x35, 0xf7, - 0x7d, 0x61, 0xc2, 0x89, 0x85, 0x05, 0x8a, 0x59, 0x10, 0xab, 0x10, 0xa7, 0x9f, 0x7a, 0x97, 0xcb, - 0x0e, 0xaf, 0x56, 0x87, 0xfe, 0x7a, 0x94, 0x8d, 0xfc, 0x75, 0xf8, 0x14, 0xe9, 0x18, 0x16, 0xe3, - 0xa9, 0x41, 0x34, 0x1d, 0x0c, 0xb5, 0x83, 0x9d, 0xce, 0xec, 0x7c, 0xd8, 0x1b, 0xe4, 0x0b, 0xdf, - 0x83, 0x47, 0x13, 0x3f, 0x4a, 0x41, 0xa9, 0xf6, 0x3b, 0x15, 0xb6, 0x8f, 0x23, 0x3c, 0xbe, 0x2b, - 0xf4, 0x7b, 0x72, 0x80, 0x0a, 0xa0, 0xdf, 0x76, 0x99, 0x18, 0x83, 0xf0, 0x32, 0xe1, 0x2d, 0xcf, - 0x78, 0x41, 0x9b, 0x60, 0x7e, 0xca, 0x5d, 0x41, 0x1a, 0x71, 0xc5, 0xbb, 0x05, 0x17, 0xc7, 0xde, - 0x15, 0xd1, 0x64, 0x33, 0xf9, 0xbf, 0x15, 0xd1, 0x74, 0xf1, 0xd6, 0x6f, 0xf8, 0x48, 0x32, 0xe7, - 0x27, 0xa3, 0x9c, 0xff, 0x84, 0x7b, 0xbc, 0x45, 0x3e, 0x5c, 0x24, 0xc4, 0xcf, 0x64, 0xf6, 0xb7, - 0x49, 0x18, 0x9c, 0x38, 0xbc, 0xa6, 0xf7, 0x2e, 0x82, 0xe6, 0xe8, 0xa7, 0xbf, 0x45, 0x50, 0x21, - 0x42, 0xe6, 0x0d, 0xa2, 0xc6, 0xf3, 0xfe, 0x0f, 0x13, 0x76, 0x11, 0x86, 0xe9, 0x6f, 0xd3, 0x34, - 0x73, 0xc5, 0x86, 0x11, 0xe3, 0x81, 0xe7, 0x4c, 0x76, 0x23, 0xfa, 0xc4, 0x8c, 0x78, 0x83, 0xc0, - 0x80, 0x75, 0x71, 0x15, 0xe6, 0xb5, 0x1c, 0x60, 0xb2, 0xb3, 0x4c, 0x97, 0xe8, 0x4e, 0x98, 0xc3, - 0x43, 0xee, 0x9e, 0x98, 0x16, 0xf8, 0xc7, 0x4b, 0x35, 0xec, 0xea, 0xc6, 0x02, 0xdf, 0x55, 0x7b, - 0x2b, 0x42, 0x75, 0x75, 0x03, 0x77, 0xdf, 0x84, 0x9f, 0x98, 0xb7, 0xf1, 0x02, 0x7e, 0xbf, 0xaa, - 0xfe, 0x65, 0x75, 0x6b, 0x3b, 0x10, 0xb0, 0xbe, 0x62, 0x00, 0x48, 0x60, 0xec, 0x36, 0x48, 0x26, - 0x74, 0x4e, 0x75, 0x8c, 0x43, 0x8a, 0xdc, 0x21, 0x74, 0xc1, 0xc6, 0x86, 0x84, 0xbf, 0xb4, 0xcb, - 0xd8, 0xe6, 0xe1, 0x67, 0x53, 0xa7, 0x24, 0x85, 0x54, 0x12, 0xde, 0x03, 0xc3, 0xfe, 0x86, 0x63, - 0x78, 0x15, 0x40, 0xe6, 0x1d, 0x9e, 0xe1, 0x55, 0x00, 0xd9, 0x0b, 0xd7, 0xf0, 0x93, 0x00, 0x72, - 0x18, 0x40, 0x2e, 0x06, 0x10, 0x72, 0xf9, 0x27, 0x81, 0xe4, 0x31, 0x90, 0xfc, 0x2f, 0x60, 0x51, - 0xc0, 0x00, 0x0a, 0xbf, 0x00, 0xe0, 0x11, 0x03, 0x78, 0xfc, 0x05, 0x00, 0x45, 0x0c, 0xa0, 0xf8, - 0x8b, 0x74, 0x78, 0xc2, 0x40, 0x9e, 0x7e, 0x01, 0x0b, 0x26, 0x08, 0x35, 0xe8, 0x5f, 0x01, 0x11, - 0x08, 0xe5, 0xaf, 0x48, 0x25, 0x43, 0xc4, 0x92, 0xc9, 0xfc, 0x22, 0x35, 0x18, 0x22, 0x9c, 0xcc, - 0xaf, 0x48, 0x27, 0x43, 0xc4, 0x93, 0xc9, 0xfd, 0x0a, 0x08, 0x22, 0x9c, 0xcc, 0xaf, 0x48, 0x27, - 0x43, 0xc4, 0x93, 0x29, 0x9c, 0xd3, 0x23, 0xf8, 0x25, 0x82, 0x10, 0x4a, 0xf0, 0x38, 0x03, 0x3f, - 0x3a, 0xc2, 0xc6, 0xa7, 0x1b, 0x3c, 0xf2, 0xc5, 0x36, 0x3d, 0x76, 0x5b, 0x81, 0x27, 0x21, 0xf3, - 0x46, 0xf6, 0xee, 0x2e, 0xb4, 0x4e, 0x3d, 0x52, 0xe2, 0x49, 0xfa, 0xab, 0xb0, 0xe8, 0xd3, 0x0d, - 0xc3, 0x27, 0x77, 0xa5, 0x2e, 0x4f, 0x36, 0x21, 0x0f, 0x7b, 0x60, 0x23, 0xec, 0x63, 0xf0, 0x20, - 0x31, 0x8f, 0x04, 0x97, 0x08, 0xb1, 0xe4, 0x92, 0x29, 0x58, 0x7e, 0x30, 0x70, 0x29, 0xa6, 0x90, - 0xd2, 0xa0, 0xd7, 0x55, 0xb7, 0x3a, 0x29, 0x19, 0xbb, 0xa1, 0xd9, 0x7e, 0x08, 0x81, 0xe0, 0xa5, - 0x6f, 0x9f, 0x2b, 0xa0, 0x48, 0x4a, 0xdb, 0x6b, 0xd6, 0xeb, 0x07, 0xd3, 0xf6, 0xb7, 0x0e, 0xc6, - 0x0d, 0xff, 0xf6, 0xc1, 0xca, 0xa6, 0xe3, 0x7a, 0xa9, 0x15, 0xc1, 0xe1, 0x6b, 0x2a, 0x11, 0x0d, - 0x00, 0x3e, 0xee, 0x65, 0x08, 0x10, 0xe0, 0x15, 0xdc, 0x9e, 0x38, 0xd6, 0x83, 0x88, 0x8b, 0x67, - 0x72, 0x47, 0x67, 0x7e, 0x17, 0x42, 0x6f, 0xa8, 0x37, 0x81, 0xeb, 0xef, 0x02, 0x9e, 0x89, 0x80, - 0xe7, 0x63, 0xe0, 0xd9, 0x08, 0x38, 0xae, 0xb3, 0xa6, 0xf0, 0x25, 0xcd, 0xeb, 0x1b, 0x78, 0xef, - 0xda, 0x80, 0x7e, 0x88, 0xb6, 0x28, 0xe4, 0x1f, 0xf2, 0x38, 0x6f, 0xd2, 0x57, 0xb8, 0x97, 0x39, - 0x1e, 0x06, 0x66, 0xfc, 0x70, 0xc3, 0x2d, 0x13, 0x97, 0x67, 0xce, 0x76, 0x7b, 0xe7, 0x76, 0x6f, - 0x6c, 0x46, 0x3f, 0x3c, 0xc2, 0x66, 0xaf, 0x97, 0xb5, 0x82, 0x1a, 0xfb, 0xc8, 0xf6, 0x02, 0xb1, - 0xc0, 0x5f, 0x2e, 0x35, 0x10, 0xff, 0x92, 0xa9, 0xb9, 0x9c, 0x27, 0xb5, 0xcf, 0x5e, 0xe9, 0xcb, - 0x9e, 0x3a, 0x82, 0xd0, 0xe5, 0x56, 0xd5, 0x33, 0xcc, 0x52, 0x6e, 0x14, 0x5b, 0x71, 0xcd, 0xec, - 0x46, 0xb1, 0xf5, 0xed, 0x4d, 0x99, 0xbf, 0x55, 0x6a, 0x0d, 0xf3, 0x91, 0xbf, 0xbd, 0x6b, 0xe6, - 0xd6, 0xae, 0xd9, 0xdc, 0xe8, 0x95, 0x5a, 0x7a, 0xa8, 0xc7, 0x7f, 0x7b, 0xdb, 0xec, 0xad, 0x6d, - 0xe9, 0x9c, 0x76, 0x7b, 0xdb, 0x38, 0xfa, 0xba, 0x51, 0x59, 0x4e, 0x04, 0x6a, 0xe4, 0x17, 0x42, - 0xae, 0x54, 0x22, 0xe3, 0x5f, 0xec, 0x3e, 0x8e, 0x7d, 0x88, 0xff, 0x09, 0x95, 0x0f, 0xbf, 0x51, - 0xff, 0xfc, 0xfd, 0xc3, 0x6f, 0xff, 0x4c, 0x99, 0x8e, 0xfd, 0x30, 0x73, 0x53, 0xdb, 0xdc, 0x43, - 0xee, 0x81, 0xc6, 0x1d, 0x19, 0x9a, 0x29, 0xa4, 0xe1, 0xed, 0x29, 0x55, 0x23, 0xbf, 0x11, 0x52, - 0x52, 0x97, 0xa6, 0x6e, 0xe1, 0x91, 0x86, 0xa9, 0x41, 0x94, 0xaf, 0x8f, 0x53, 0x9b, 0x25, 0x44, - 0xe2, 0x29, 0xb1, 0xdd, 0x48, 0x65, 0x82, 0x35, 0x86, 0xe9, 0x4d, 0x37, 0xa3, 0x07, 0xcd, 0x5e, - 0x50, 0x33, 0x15, 0xaf, 0xa2, 0x02, 0xb0, 0x30, 0x46, 0x7d, 0xf8, 0xed, 0xf7, 0xe8, 0xdf, 0x6b, - 0xf9, 0xe4, 0x7d, 0xd1, 0x3f, 0xff, 0x79, 0x67, 0x8f, 0x66, 0xc0, 0xc8, 0xbb, 0xe7, 0x67, 0xac, - 0x13, 0xf6, 0x24, 0xa5, 0xef, 0xf0, 0xd5, 0x28, 0xf7, 0x1f, 0xff, 0xb8, 0xc3, 0x80, 0x27, 0xe6, - 0x12, 0x92, 0xb8, 0xdf, 0xa3, 0x41, 0x30, 0xf1, 0x1b, 0x4b, 0xff, 0xef, 0xe0, 0xe3, 0x21, 0x9c, - 0xfa, 0x0c, 0xb9, 0xef, 0xd7, 0xbb, 0x08, 0xec, 0x11, 0x52, 0xb0, 0xfa, 0x1f, 0xff, 0x08, 0x3e, - 0x1f, 0xd4, 0xc5, 0xf8, 0xbf, 0x83, 0xaf, 0x9f, 0xf4, 0xcf, 0x5f, 0xbd, 0x07, 0x40, 0x0a, 0xaf, - 0xfc, 0x8b, 0x64, 0x23, 0x5f, 0x62, 0xac, 0x00, 0xa5, 0x8d, 0xab, 0x83, 0x02, 0x3a, 0x26, 0xa0, - 0xf5, 0x6d, 0xab, 0x3a, 0x29, 0xed, 0x39, 0x31, 0xfa, 0xd7, 0x17, 0xf3, 0x19, 0xde, 0xa6, 0xcf, - 0xff, 0xf3, 0xef, 0x2f, 0x1b, 0x78, 0xfb, 0x16, 0xff, 0xfb, 0x33, 0xab, 0xe0, 0x44, 0x78, 0x85, - 0xfd, 0x65, 0xf9, 0xc5, 0xf9, 0x62, 0x7e, 0x71, 0x9f, 0x55, 0xc7, 0xd8, 0x10, 0x91, 0xf9, 0xa2, - 0x3e, 0x6f, 0xbe, 0x4d, 0x6c, 0xe7, 0x93, 0x79, 0xec, 0x7b, 0xb0, 0xf4, 0xa5, 0xe1, 0x4d, 0xbf, - 0xfd, 0x7f, 0xce, 0xae, 0xc5, 0xb9, 0x6d, 0x1b, 0xe9, 0xff, 0x2b, 0x11, 0x2f, 0xf5, 0x10, 0x16, - 0xf4, 0x72, 0xbf, 0x66, 0x5a, 0x2a, 0x18, 0x4e, 0xe2, 0x24, 0x4d, 0xee, 0xf2, 0xe8, 0xc5, 0x69, - 0x7a, 0x77, 0x8e, 0xeb, 0xa1, 0x29, 0x4a, 0x62, 0x4d, 0x93, 0x3a, 0x92, 0x92, 0xa5, 0x8a, 0xfa, - 0xdf, 0xbf, 0xdf, 0x2e, 0xf8, 0x80, 0x24, 0x3a, 0xed, 0x75, 0xda, 0x88, 0x24, 0x1e, 0x0b, 0x60, - 0xdf, 0xbb, 0x00, 0xe9, 0xb3, 0xa7, 0x61, 0xaf, 0x37, 0x16, 0xf3, 0xfe, 0x62, 0x99, 0xcd, 0xed, - 0xec, 0x32, 0xbc, 0x12, 0xdc, 0x14, 0x93, 0x8f, 0x97, 0x51, 0xd4, 0x51, 0x41, 0xdf, 0x9f, 0x87, - 0xd1, 0x24, 0x0d, 0xe2, 0x93, 0x13, 0x7b, 0x5e, 0x76, 0x2b, 0x8a, 0xb2, 0x43, 0x53, 0x2b, 0xe4, - 0x04, 0xb1, 0x7c, 0x1e, 0x3c, 0x32, 0x8a, 0xc6, 0x55, 0xfb, 0xb1, 0x08, 0xa7, 0xb6, 0x1d, 0x2b, - 0xf4, 0x4a, 0x16, 0xb6, 0x10, 0x27, 0x27, 0xab, 0x24, 0x9c, 0x3c, 0x1a, 0x76, 0x94, 0x8a, 0xa9, - 0x48, 0xe8, 0xd9, 0xc5, 0x55, 0x73, 0x73, 0x4e, 0x31, 0xcf, 0x09, 0xbe, 0x7c, 0x00, 0xad, 0x92, - 0x44, 0x81, 0x67, 0xe0, 0x99, 0xe6, 0x14, 0x2b, 0x9a, 0xa8, 0x90, 0x76, 0xaa, 0x1a, 0x4a, 0xd4, - 0x64, 0xcb, 0x05, 0x35, 0x41, 0x03, 0x8c, 0xe4, 0x42, 0xd7, 0x59, 0x4e, 0xa5, 0xfb, 0x1a, 0x20, - 0x28, 0xbf, 0xc8, 0xe9, 0xb0, 0xa6, 0x1d, 0x83, 0x9a, 0x19, 0xdf, 0x36, 0x10, 0x68, 0x8c, 0x54, - 0x75, 0x46, 0x42, 0xc8, 0xf4, 0xe4, 0x24, 0x71, 0xbd, 0x4b, 0xaf, 0x9c, 0x66, 0x6f, 0x74, 0xd5, - 0x55, 0xb1, 0xe3, 0x29, 0xa5, 0x96, 0xae, 0xa7, 0x2e, 0xe3, 0x2b, 0xc7, 0x2b, 0xe7, 0x2c, 0x64, - 0xa2, 0x52, 0xa6, 0x60, 0xa4, 0xe2, 0xe0, 0xfe, 0x91, 0x3f, 0x4e, 0x83, 0x7c, 0x99, 0xc6, 0x8f, - 0xa2, 0x7e, 0x0c, 0x5f, 0xe1, 0x3d, 0xfd, 0x25, 0xa6, 0x5c, 0x46, 0x35, 0xaa, 0x94, 0x87, 0x07, - 0x2f, 0xc7, 0xd0, 0x90, 0xb0, 0x20, 0x53, 0x7a, 0xc6, 0x81, 0xab, 0xd1, 0xe4, 0x04, 0xa8, 0xbd, - 0x0d, 0x36, 0x47, 0xc5, 0x54, 0x28, 0xa3, 0x5d, 0xcd, 0x07, 0xef, 0x34, 0x1f, 0x10, 0x36, 0x99, - 0x17, 0x10, 0xc5, 0x3f, 0x0a, 0x44, 0x7e, 0x99, 0x5c, 0xa9, 0x00, 0x3f, 0xd5, 0x24, 0xf2, 0xa6, - 0x47, 0xa4, 0x7b, 0x68, 0x5a, 0xe7, 0x58, 0x6a, 0x0b, 0x37, 0xe7, 0x6e, 0xae, 0xf9, 0xd6, 0x5f, - 0xa6, 0x74, 0x46, 0x55, 0x05, 0x62, 0x47, 0xe0, 0x03, 0xd5, 0xd2, 0xf8, 0x27, 0x84, 0x5a, 0x61, - 0x16, 0xb8, 0xe5, 0xb5, 0x0f, 0x33, 0x98, 0x44, 0x2b, 0x70, 0x7b, 0x3f, 0x9f, 0x07, 0x71, 0xff, - 0x26, 0x8c, 0x27, 0xf6, 0x51, 0x9d, 0x70, 0x60, 0x2b, 0xc9, 0x74, 0x26, 0xcb, 0x5c, 0x4e, 0xd5, - 0x80, 0xb6, 0x86, 0x8b, 0x60, 0x6d, 0xbb, 0x4e, 0x56, 0xcc, 0x8a, 0xb8, 0x58, 0x14, 0x8f, 0x45, - 0x91, 0x2e, 0xe6, 0x45, 0x72, 0x9f, 0x15, 0x77, 0xb1, 0x5f, 0xc4, 0xf9, 0x7d, 0x01, 0x71, 0xba, - 0xf4, 0xe7, 0x57, 0xc5, 0xef, 0x49, 0x52, 0xfc, 0x9a, 0xa4, 0x93, 0x41, 0x08, 0xa4, 0x9b, 0x52, - 0x91, 0xd9, 0xb9, 0xd8, 0x76, 0xf2, 0xfe, 0xf5, 0x24, 0x4c, 0xf3, 0x0d, 0xd6, 0x56, 0xdd, 0xaa, - 0xce, 0x10, 0x6c, 0x31, 0x52, 0x2a, 0xd1, 0xe4, 0x22, 0x26, 0x09, 0x40, 0xb4, 0x06, 0x2d, 0x24, - 0x6e, 0x15, 0x16, 0xf3, 0x71, 0x4e, 0x0d, 0x89, 0x71, 0xc7, 0xa2, 0x81, 0xf6, 0x06, 0xdd, 0x9a, - 0x0e, 0x17, 0x1a, 0x8f, 0x15, 0x82, 0xfb, 0xfa, 0xc3, 0x0d, 0xe1, 0xef, 0xc1, 0xe4, 0x7d, 0x45, - 0x6f, 0x10, 0xae, 0x28, 0xf2, 0x9a, 0xfe, 0xfd, 0x3c, 0x79, 0x4b, 0xbb, 0xc0, 0xe7, 0x5e, 0x06, - 0x0c, 0x50, 0xed, 0x7e, 0x49, 0x03, 0xfb, 0x25, 0xad, 0x43, 0x23, 0xfc, 0x9d, 0x0d, 0x05, 0x90, - 0x1b, 0x9c, 0x02, 0xc9, 0x68, 0x98, 0x28, 0xaf, 0x6f, 0x99, 0xf5, 0x12, 0x65, 0x8c, 0x56, 0x9e, - 0xa0, 0x04, 0xea, 0x17, 0xd9, 0x18, 0xd2, 0x58, 0x0b, 0x60, 0x22, 0xaa, 0x85, 0xc6, 0xc4, 0x2e, - 0x89, 0xd0, 0x35, 0x34, 0x21, 0x70, 0x34, 0xb0, 0x46, 0x17, 0x95, 0xe0, 0x47, 0x54, 0xfc, 0x13, - 0x34, 0x73, 0x7b, 0xdf, 0xcc, 0x2d, 0xef, 0xeb, 0x23, 0xcc, 0xb4, 0xe0, 0x31, 0xf4, 0x07, 0xd1, - 0xf7, 0x2e, 0x59, 0x05, 0xe7, 0x34, 0xa7, 0x3d, 0x64, 0xad, 0x08, 0x59, 0x92, 0x35, 0x95, 0xd8, - 0x62, 0x2e, 0x16, 0xdb, 0x1d, 0x9a, 0xa6, 0x45, 0xc3, 0xd2, 0x98, 0x4a, 0x97, 0x59, 0x42, 0x5a, - 0xe0, 0x71, 0x2e, 0xd6, 0x4a, 0xe0, 0x11, 0xb5, 0x4f, 0x83, 0xa9, 0x2e, 0x8a, 0x6c, 0x40, 0x61, - 0xf1, 0x8f, 0xec, 0x58, 0xe6, 0x46, 0x13, 0xdd, 0xbd, 0xc3, 0x48, 0x4f, 0x49, 0xfd, 0x58, 0x9c, - 0x7d, 0xd6, 0xdd, 0x68, 0x50, 0xc8, 0x75, 0x9b, 0xac, 0x1f, 0x95, 0x25, 0x45, 0x01, 0xc6, 0xe1, - 0xce, 0x7d, 0x3f, 0xcb, 0x3e, 0x05, 0xeb, 0x5c, 0xc5, 0x45, 0x61, 0x61, 0x6a, 0xd4, 0xfc, 0xd0, - 0x88, 0xc4, 0x7a, 0x45, 0x47, 0x50, 0x6a, 0x2c, 0x87, 0x1a, 0xcb, 0x7c, 0x89, 0x1b, 0xd8, 0xd0, - 0x72, 0xd0, 0x4e, 0x5a, 0xf9, 0xd6, 0xcd, 0x62, 0x61, 0xd6, 0x1e, 0x29, 0x2e, 0x94, 0x9e, 0x9c, - 0x74, 0xc0, 0xc7, 0x6a, 0xda, 0x07, 0x2f, 0xe4, 0x76, 0x28, 0x5c, 0x2a, 0xec, 0x5a, 0x8b, 0xb5, - 0xe5, 0xd0, 0xdd, 0x6e, 0x57, 0x23, 0x64, 0x42, 0xce, 0x79, 0x9a, 0x2c, 0xb3, 0x68, 0x73, 0x41, - 0x99, 0xb2, 0x38, 0x48, 0x5f, 0x7f, 0x7a, 0xf7, 0x56, 0x23, 0x24, 0x66, 0xe9, 0x08, 0xab, 0x42, - 0x68, 0xe2, 0xeb, 0x6b, 0xfa, 0xa2, 0x0d, 0xaf, 0xb3, 0x41, 0x6a, 0x62, 0x11, 0x57, 0x0c, 0x31, - 0xaa, 0x15, 0xf3, 0xed, 0xe8, 0x4a, 0x53, 0x1f, 0x96, 0x10, 0xa8, 0x06, 0xd9, 0x88, 0xe8, 0x8b, - 0xc8, 0xf3, 0x03, 0x7b, 0x70, 0xee, 0x2d, 0xc0, 0x2d, 0xc1, 0xe3, 0x81, 0x04, 0x0c, 0x00, 0x39, - 0x64, 0xf0, 0x7e, 0xb6, 0xbc, 0xd1, 0x68, 0x82, 0x4b, 0x24, 0x63, 0x37, 0x21, 0xe9, 0xf0, 0x26, - 0x93, 0x97, 0xf4, 0x4a, 0xe4, 0xdb, 0x10, 0x7e, 0x28, 0x66, 0x63, 0x07, 0x72, 0x22, 0x33, 0x52, - 0x3e, 0x9a, 0x99, 0xda, 0x2a, 0x25, 0x09, 0x76, 0x54, 0x96, 0x65, 0x8c, 0xd2, 0xe6, 0x11, 0x16, - 0x53, 0x88, 0xcb, 0xe0, 0x4a, 0xc5, 0x0d, 0x2a, 0x38, 0xff, 0xd5, 0x61, 0x4e, 0xb3, 0x08, 0x97, - 0xe5, 0x7d, 0x07, 0xfa, 0x3d, 0x20, 0xb4, 0x83, 0xa5, 0xf3, 0x74, 0xb3, 0xcd, 0xb9, 0x5b, 0x69, - 0x3b, 0x60, 0x39, 0xe2, 0x9d, 0xef, 0xe5, 0x3e, 0xa9, 0x8b, 0xed, 0x4e, 0x2b, 0xcc, 0x98, 0xd0, - 0x4f, 0x46, 0x0c, 0x78, 0xca, 0x16, 0x41, 0x14, 0x71, 0x7c, 0x63, 0x95, 0x92, 0xae, 0x67, 0xfc, - 0xac, 0x92, 0x55, 0xe8, 0x50, 0x9e, 0x02, 0x23, 0xcc, 0x53, 0x34, 0xd8, 0x11, 0xce, 0x7e, 0x5d, - 0x93, 0xfb, 0xe6, 0xb8, 0x25, 0xce, 0xca, 0xc1, 0x8b, 0x82, 0x89, 0x1c, 0xbb, 0x9e, 0x7b, 0x04, - 0xf5, 0xfd, 0x85, 0x6d, 0x1d, 0xbf, 0x7f, 0x31, 0xfa, 0xe1, 0x87, 0x1f, 0x06, 0x0c, 0xcb, 0x92, - 0x07, 0x68, 0x6f, 0x70, 0x69, 0xce, 0xcc, 0x69, 0xb1, 0x9d, 0xc4, 0x14, 0x34, 0x22, 0x74, 0xf3, - 0x5f, 0x1f, 0x4e, 0xc6, 0x34, 0xa0, 0x09, 0x02, 0x54, 0x8b, 0x85, 0x46, 0x05, 0x14, 0x65, 0x2d, - 0xfa, 0x5a, 0xa8, 0x1a, 0x25, 0x41, 0x2a, 0xa3, 0xd6, 0xa7, 0xf0, 0x93, 0x0c, 0x9a, 0x5e, 0xe6, - 0x7d, 0x9a, 0xe2, 0x15, 0x29, 0x15, 0x42, 0xe6, 0x6b, 0xf2, 0x88, 0x3e, 0xa9, 0xa1, 0x9c, 0xc1, - 0x4e, 0xcb, 0x6b, 0xfc, 0x34, 0x46, 0xe0, 0xa7, 0x03, 0x4d, 0xfe, 0xba, 0x9f, 0xcd, 0xc3, 0x69, - 0xae, 0x75, 0x39, 0x1c, 0xc5, 0x45, 0x12, 0x83, 0xa3, 0x5e, 0x84, 0x93, 0x77, 0xc9, 0x32, 0x86, - 0x01, 0x6c, 0x29, 0x34, 0x75, 0xf1, 0xb3, 0x46, 0x75, 0xc9, 0x50, 0x6c, 0x3f, 0x75, 0xbb, 0xe0, - 0xb7, 0x99, 0xd2, 0xec, 0x90, 0x1a, 0x7e, 0x4d, 0xda, 0x4f, 0xee, 0x31, 0xd7, 0x8b, 0xcf, 0x3f, - 0xbe, 0x8c, 0x02, 0x72, 0xb9, 0x30, 0xaf, 0xda, 0xca, 0x76, 0x6c, 0xeb, 0xfa, 0x1a, 0x11, 0xa2, - 0xe7, 0xe7, 0xa4, 0xca, 0xaf, 0x2d, 0x66, 0x3a, 0x31, 0xd6, 0xa2, 0xf4, 0x73, 0x3d, 0x46, 0x58, - 0xab, 0x5c, 0x80, 0xce, 0x0c, 0xfd, 0x4a, 0x03, 0x9c, 0x9c, 0xa4, 0x7d, 0x3a, 0xf6, 0x14, 0x4f, - 0xb4, 0x86, 0x85, 0x20, 0xf4, 0x7a, 0x9f, 0x30, 0x1d, 0x42, 0x80, 0x0c, 0x8b, 0x02, 0x4b, 0x17, - 0x32, 0x6b, 0xe6, 0xfe, 0xb3, 0xa9, 0x76, 0x59, 0xc7, 0xc0, 0x07, 0xc9, 0xd4, 0x8c, 0xcc, 0x41, - 0xe9, 0xec, 0x41, 0x20, 0x2a, 0x27, 0xab, 0x66, 0x03, 0xf0, 0x32, 0xe9, 0x63, 0x52, 0xc5, 0xa5, - 0x56, 0x53, 0x46, 0xd5, 0x91, 0x56, 0x0a, 0x44, 0x45, 0x34, 0x03, 0x1b, 0xe0, 0x80, 0x45, 0x14, - 0xe6, 0xa4, 0x3c, 0x09, 0xc5, 0xcd, 0x42, 0xc0, 0x62, 0x64, 0xa1, 0x6b, 0x9c, 0x93, 0xb2, 0x76, - 0xb5, 0xd9, 0xfa, 0x4c, 0xd1, 0x27, 0xcf, 0xc9, 0x36, 0x0a, 0xa0, 0xac, 0x1c, 0xb8, 0x8a, 0x93, - 0xc4, 0x67, 0x47, 0xb6, 0xef, 0x03, 0x8b, 0x79, 0x40, 0x80, 0x09, 0x1c, 0x38, 0x59, 0xe6, 0xdc, - 0xc1, 0x1c, 0xc2, 0x7c, 0xaa, 0x64, 0x4d, 0xe3, 0x2c, 0x84, 0xcd, 0x90, 0x1f, 0x80, 0x17, 0x78, - 0x04, 0x40, 0x56, 0xd8, 0xdf, 0x23, 0x0b, 0xfc, 0x04, 0x19, 0x32, 0x51, 0xe0, 0x9e, 0x49, 0x1f, - 0x82, 0x5a, 0x99, 0x53, 0x42, 0x59, 0x8b, 0xf3, 0xe3, 0x57, 0x6b, 0x37, 0x23, 0x0d, 0xc2, 0xb8, - 0xc6, 0x77, 0xaa, 0x78, 0xf5, 0xcd, 0x6a, 0xe1, 0xd0, 0xa7, 0xa0, 0x40, 0x2e, 0x59, 0x1d, 0x98, - 0x35, 0xe7, 0x08, 0xcf, 0xf2, 0x74, 0xe9, 0xe7, 0x49, 0xca, 0xae, 0x41, 0x35, 0xb0, 0x8c, 0xe0, - 0x2a, 0xfa, 0xea, 0x25, 0x16, 0xca, 0xa6, 0x62, 0x8c, 0x7e, 0x9d, 0x88, 0x5d, 0xd4, 0xb4, 0x7f, - 0xad, 0x97, 0x79, 0x5e, 0x01, 0x01, 0x8f, 0x47, 0x28, 0xf6, 0x1f, 0x80, 0x45, 0x7d, 0xa9, 0x6b, - 0x07, 0x92, 0x97, 0x1a, 0x63, 0x0b, 0xd7, 0xfe, 0xcd, 0x4e, 0xa5, 0x2f, 0xbf, 0xe5, 0xa9, 0xcb, - 0x1c, 0x30, 0xe8, 0xef, 0x4c, 0x12, 0xe2, 0x31, 0x9a, 0x87, 0x2e, 0x6f, 0x61, 0x6a, 0x50, 0x9e, - 0x95, 0xbe, 0x77, 0xaa, 0x3e, 0xda, 0xc6, 0x1c, 0x7d, 0x99, 0x30, 0x19, 0x3a, 0x69, 0x3f, 0x06, - 0x61, 0x9e, 0xa3, 0x2f, 0xcd, 0xb0, 0x7e, 0x60, 0xb6, 0xd3, 0x3d, 0xf5, 0x40, 0xa3, 0xfd, 0x81, - 0x24, 0x62, 0xb0, 0x1c, 0x5c, 0x83, 0x8b, 0x9d, 0x19, 0x13, 0xe3, 0x3e, 0x20, 0x57, 0x26, 0xc9, - 0x1d, 0x17, 0x8d, 0x3b, 0x5b, 0xa3, 0x99, 0xe8, 0x32, 0x53, 0x56, 0xb6, 0x22, 0x26, 0x55, 0x3e, - 0xd8, 0x13, 0x48, 0x0a, 0xc2, 0x59, 0xfc, 0x41, 0x9b, 0x69, 0x00, 0xf5, 0x4f, 0x4e, 0x66, 0xc0, - 0x60, 0xe9, 0xf1, 0xfb, 0xb0, 0x1e, 0x1d, 0x70, 0x5d, 0x87, 0x1c, 0x38, 0x9f, 0x22, 0x13, 0xdb, - 0x53, 0xbe, 0xb4, 0x23, 0x35, 0x73, 0x0f, 0x78, 0xac, 0x94, 0xe3, 0x76, 0x0d, 0x58, 0xbd, 0xf0, - 0x66, 0x49, 0x4f, 0x38, 0xed, 0x1d, 0x6d, 0x4f, 0x88, 0x36, 0xbf, 0xd0, 0x03, 0x17, 0x44, 0xe0, - 0x43, 0xad, 0xa7, 0xc6, 0x79, 0x7f, 0x4a, 0xe9, 0x2f, 0xe6, 0x4f, 0xc4, 0x4d, 0x7b, 0x22, 0x6e, - 0xd6, 0x89, 0xf1, 0x5f, 0x61, 0x72, 0xd6, 0x97, 0x73, 0x15, 0x1a, 0x80, 0x10, 0x4b, 0x1e, 0xf0, - 0xbd, 0x5c, 0x18, 0x61, 0x5f, 0xa5, 0x1d, 0x10, 0xe4, 0x88, 0xed, 0x51, 0x53, 0x98, 0xd7, 0xda, - 0x65, 0x99, 0xa2, 0xb2, 0xf1, 0x4c, 0xe5, 0x04, 0x5e, 0x49, 0x19, 0xcf, 0x4d, 0x28, 0x9e, 0x5b, - 0x5e, 0x4e, 0x2f, 0x27, 0x57, 0x7d, 0x4a, 0x07, 0x5c, 0x29, 0xbe, 0xe5, 0xfc, 0xd2, 0x4e, 0x53, - 0xb1, 0x73, 0x7d, 0x72, 0xb2, 0x60, 0xa7, 0x5c, 0x2d, 0xca, 0x6e, 0x8d, 0x33, 0x56, 0x0b, 0xd8, - 0x82, 0x9d, 0x0f, 0xad, 0xac, 0xe6, 0x86, 0x7e, 0x99, 0x9b, 0xfa, 0x45, 0xcf, 0x76, 0xce, 0xec, - 0x76, 0x11, 0x52, 0x42, 0x64, 0xe6, 0xce, 0x4d, 0x95, 0xa2, 0xa1, 0xd8, 0x46, 0x19, 0x17, 0x81, - 0xbf, 0x31, 0x83, 0x45, 0x1d, 0xe3, 0x96, 0xc3, 0x80, 0x27, 0x0e, 0xc5, 0xb9, 0x56, 0xa0, 0x12, - 0xc1, 0x35, 0xa9, 0x06, 0x04, 0xe5, 0xa5, 0xf3, 0x4d, 0xe8, 0xcf, 0x38, 0x3c, 0x07, 0x16, 0xe1, - 0xac, 0x4f, 0x61, 0x96, 0x26, 0xf8, 0xb7, 0x52, 0x55, 0x30, 0x0c, 0x2b, 0x35, 0x84, 0x31, 0x08, - 0xdc, 0xa0, 0x2c, 0x70, 0x86, 0x84, 0x63, 0x5a, 0xc6, 0xaa, 0xf6, 0x12, 0xef, 0xd4, 0x70, 0x7c, - 0xf7, 0x74, 0x35, 0xbe, 0xeb, 0x76, 0xf5, 0x50, 0x1b, 0x35, 0xbf, 0xbc, 0xbb, 0x92, 0x37, 0x6a, - 0x73, 0x40, 0xab, 0x7b, 0x05, 0xcc, 0xdd, 0xb8, 0x1b, 0x43, 0x4e, 0xf6, 0x1e, 0xd0, 0x1c, 0x1e, - 0xb4, 0x73, 0x43, 0xb1, 0xa2, 0x43, 0x4b, 0x1a, 0xeb, 0x75, 0xdd, 0xbb, 0xf6, 0xb4, 0xdb, 0x95, - 0x8b, 0xcb, 0xfb, 0x2b, 0xb5, 0xc1, 0xd2, 0x6f, 0xa0, 0xe6, 0x6b, 0x7c, 0x6e, 0x1a, 0x7c, 0xba, - 0x9d, 0xb4, 0x28, 0x36, 0x0d, 0xaa, 0xfa, 0x20, 0xc9, 0x9d, 0x2d, 0x9c, 0x94, 0x85, 0x65, 0x79, - 0x39, 0xeb, 0x76, 0x09, 0xc0, 0xae, 0x5c, 0xc2, 0xf5, 0xc1, 0x12, 0xae, 0xf5, 0x12, 0x22, 0x38, - 0x8b, 0x98, 0xbe, 0xcf, 0x22, 0xcc, 0x2a, 0xf5, 0x5e, 0x71, 0x4c, 0xdb, 0x18, 0x9f, 0x7b, 0x31, - 0x35, 0x28, 0x4a, 0xf3, 0x02, 0x7c, 0x9f, 0x6f, 0xf4, 0x2c, 0x75, 0x9d, 0x9c, 0xf6, 0x7a, 0x8d, - 0x4b, 0x3a, 0x79, 0x3a, 0x2b, 0x93, 0x07, 0x93, 0x71, 0xf8, 0x14, 0xa6, 0x0c, 0x83, 0x99, 0xd1, - 0xcd, 0x92, 0x7d, 0x64, 0x7b, 0x0d, 0x55, 0x45, 0xb7, 0xf2, 0x1c, 0x0a, 0xf7, 0x90, 0xab, 0xec, - 0x5b, 0x15, 0x89, 0x16, 0x4b, 0x76, 0xeb, 0xd6, 0x60, 0xd6, 0x0d, 0x3e, 0x9c, 0x23, 0xa6, 0xbc, - 0xad, 0x35, 0x9f, 0xdb, 0x59, 0xb7, 0xeb, 0xf0, 0x93, 0x93, 0x0b, 0x7b, 0x2d, 0x9b, 0x86, 0xc2, - 0x39, 0x2f, 0x8a, 0x07, 0xda, 0x42, 0x02, 0x8c, 0x86, 0x62, 0xeb, 0x2b, 0xf0, 0x13, 0x05, 0x00, - 0xe5, 0xfa, 0x43, 0x34, 0x98, 0xf5, 0x46, 0x50, 0x63, 0xbd, 0x1e, 0x3f, 0x4c, 0x4e, 0x4e, 0x26, - 0xdd, 0xee, 0xf8, 0x06, 0x4c, 0x71, 0xbb, 0xf3, 0xe1, 0x3e, 0xf8, 0x60, 0x49, 0x56, 0xa8, 0x9e, - 0x66, 0x1a, 0xa8, 0x3c, 0x9f, 0x8c, 0xb0, 0xbe, 0x78, 0x75, 0x46, 0x84, 0x9c, 0x3b, 0x53, 0xbd, - 0xf8, 0xc2, 0xf1, 0x01, 0xcf, 0xdb, 0x93, 0x9c, 0xf7, 0xd0, 0x5b, 0x94, 0xb3, 0x8a, 0xb3, 0x20, - 0xcd, 0x9f, 0x07, 0xa4, 0x4f, 0x31, 0x00, 0x74, 0x19, 0xab, 0x12, 0x2c, 0x4a, 0x9e, 0x13, 0x0d, - 0xa7, 0x0d, 0xdd, 0xc9, 0x85, 0x5e, 0x08, 0x83, 0x92, 0x77, 0x20, 0xc1, 0x07, 0x9b, 0xae, 0xa4, - 0xb8, 0xb5, 0xdd, 0x9a, 0x3c, 0x85, 0xe3, 0xd1, 0x34, 0x02, 0xa1, 0xc1, 0x4a, 0xbd, 0xde, 0x95, - 0xa0, 0xa6, 0x3e, 0xb5, 0xdb, 0x41, 0x71, 0x2d, 0x58, 0xda, 0xae, 0x2b, 0x59, 0x5c, 0xf6, 0x1f, - 0x88, 0x62, 0x84, 0xdc, 0x17, 0x51, 0x2d, 0x33, 0x31, 0x0f, 0x55, 0x86, 0xb5, 0x4d, 0x46, 0x0b, - 0xa1, 0xac, 0x06, 0xa8, 0x38, 0xac, 0x2d, 0x0a, 0x8a, 0x47, 0x63, 0x49, 0xf7, 0xfc, 0x53, 0x21, - 0x7a, 0x26, 0x9a, 0xfe, 0x81, 0xb0, 0x2a, 0x85, 0x48, 0x96, 0x85, 0x7c, 0xd5, 0xd0, 0x0c, 0xa1, - 0x50, 0xa0, 0xc7, 0x81, 0x57, 0x4f, 0x20, 0xb0, 0x22, 0x8b, 0xd5, 0x5b, 0xd5, 0xba, 0x7c, 0x77, - 0x86, 0x1f, 0xdd, 0x9c, 0x72, 0x45, 0x1c, 0x52, 0x1f, 0x0f, 0x4e, 0xdd, 0x31, 0x34, 0xad, 0x3e, - 0x30, 0xd5, 0xe9, 0x52, 0x40, 0x71, 0x64, 0x32, 0x6c, 0xfc, 0xb9, 0x0f, 0x46, 0xd6, 0x4f, 0x99, - 0xce, 0xc3, 0x38, 0x71, 0xdf, 0xda, 0x09, 0x64, 0xba, 0x74, 0x38, 0xf7, 0x35, 0x06, 0x8c, 0xbe, - 0x7d, 0x50, 0x04, 0x7b, 0x31, 0x2d, 0xe3, 0x68, 0x8e, 0x67, 0x6a, 0x5c, 0x1d, 0xb4, 0x2b, 0x0a, - 0x8a, 0xf7, 0x65, 0x8a, 0x1f, 0xc3, 0x27, 0xa6, 0x47, 0xb6, 0x5d, 0x39, 0xda, 0xc3, 0x9d, 0x2f, - 0x6d, 0x57, 0x3e, 0x36, 0x32, 0x03, 0x74, 0x26, 0x1b, 0x54, 0x2b, 0x99, 0x6a, 0x5c, 0x5a, 0x23, - 0x58, 0xfc, 0x60, 0xb7, 0xd3, 0xf1, 0x90, 0x99, 0xb9, 0xf9, 0xb8, 0x47, 0x45, 0xb8, 0x17, 0x55, - 0xca, 0x8d, 0x09, 0x42, 0xe0, 0x92, 0x3c, 0x21, 0xe9, 0x63, 0xb3, 0x57, 0x3d, 0x60, 0x15, 0x94, - 0x10, 0x76, 0x29, 0x25, 0x18, 0xdc, 0x3f, 0xca, 0x6d, 0x02, 0x21, 0x37, 0x7d, 0xfa, 0x76, 0xac, - 0x1d, 0x33, 0x40, 0xe0, 0xa4, 0xac, 0xdd, 0x70, 0xad, 0xd8, 0x73, 0x8e, 0x40, 0x88, 0x12, 0x86, - 0xba, 0x83, 0x77, 0x41, 0x46, 0x0b, 0x9c, 0xed, 0x5d, 0xa6, 0x57, 0x07, 0x3e, 0x54, 0x5e, 0xf9, - 0x79, 0x71, 0xe3, 0xd3, 0x70, 0xb3, 0xea, 0x49, 0x7a, 0xac, 0x30, 0x10, 0xd2, 0xa5, 0x72, 0x84, - 0x18, 0xa8, 0x72, 0x55, 0xe2, 0x06, 0x6b, 0x77, 0xd5, 0x1a, 0xcd, 0x18, 0xc7, 0x18, 0x06, 0xd5, - 0x89, 0x81, 0xe4, 0xdf, 0x4c, 0xdb, 0xc3, 0x59, 0xa8, 0x8c, 0x3e, 0x93, 0xa3, 0xa3, 0xdd, 0xf2, - 0x81, 0xfc, 0x55, 0xa2, 0x18, 0xfd, 0x9d, 0xf6, 0x80, 0x69, 0x5a, 0x6a, 0x7f, 0xa5, 0x33, 0x85, - 0x75, 0x86, 0x96, 0xaa, 0xea, 0x07, 0xaa, 0xa9, 0x73, 0x3e, 0xb9, 0x39, 0x85, 0xfe, 0x2c, 0xc8, - 0x5f, 0x04, 0x69, 0xb8, 0x0a, 0x26, 0x17, 0xf4, 0xe2, 0xd3, 0xab, 0x34, 0xb9, 0xe3, 0x04, 0x92, - 0xf6, 0xda, 0xc9, 0x55, 0x83, 0xe7, 0xe8, 0x1a, 0x21, 0xd3, 0x2f, 0x61, 0x14, 0x1d, 0x07, 0x52, - 0x75, 0xa9, 0xcd, 0x59, 0x44, 0xb3, 0xf8, 0x63, 0xe0, 0x07, 0x80, 0x5f, 0x42, 0xfd, 0x4a, 0xa5, - 0x8e, 0x1a, 0x29, 0xe5, 0x12, 0x77, 0xca, 0x69, 0xe6, 0x6c, 0xed, 0x6d, 0xcd, 0x5d, 0xe7, 0xfa, - 0x99, 0xf1, 0x61, 0x3c, 0x37, 0x2d, 0xc1, 0x6c, 0xd5, 0xad, 0x22, 0x5f, 0x93, 0x5b, 0x31, 0xe8, - 0xba, 0x0f, 0x3f, 0x31, 0xb7, 0xe2, 0xaa, 0x9b, 0x50, 0x41, 0x20, 0x4d, 0x14, 0x8f, 0x24, 0x67, - 0xcd, 0x30, 0xf0, 0x48, 0x5f, 0x39, 0x36, 0x0f, 0xfb, 0xd9, 0x26, 0xf6, 0x6b, 0xcf, 0xfb, 0x67, - 0x3e, 0x72, 0xc4, 0x2b, 0x22, 0x2c, 0xb9, 0x94, 0x8a, 0x74, 0xde, 0x80, 0x84, 0x23, 0x90, 0x8f, - 0x92, 0x55, 0x25, 0x99, 0xe4, 0x9e, 0x20, 0xbd, 0x69, 0xc2, 0x05, 0xf0, 0x5d, 0xa7, 0x19, 0xb5, - 0x0c, 0x1f, 0x24, 0xfb, 0x1b, 0xd5, 0x04, 0x11, 0x0a, 0x50, 0x76, 0x08, 0xe3, 0xc0, 0xac, 0xd6, - 0x6b, 0x63, 0x4f, 0xc4, 0x58, 0x9a, 0x07, 0x5f, 0x44, 0x17, 0x30, 0x09, 0x8b, 0x22, 0x82, 0x5f, - 0x72, 0x80, 0x32, 0x1f, 0x5e, 0x8a, 0x9e, 0x28, 0x5c, 0x95, 0xbc, 0x61, 0xe2, 0x95, 0x9a, 0x16, - 0xc5, 0x04, 0x6a, 0x67, 0x2f, 0x66, 0xe1, 0xf0, 0xf2, 0x4e, 0x2d, 0x48, 0xeb, 0xff, 0x69, 0x76, - 0x89, 0xd4, 0x3b, 0x9b, 0x93, 0x97, 0x51, 0x49, 0x87, 0x3f, 0xec, 0x64, 0xc3, 0xb1, 0x12, 0xd4, - 0x98, 0x97, 0x08, 0x0b, 0x2d, 0xa7, 0x25, 0xb1, 0x89, 0x26, 0xf3, 0xba, 0x62, 0x69, 0xd0, 0x75, - 0x21, 0xcf, 0xb4, 0xf6, 0xe2, 0x8f, 0x9d, 0x2d, 0xa3, 0xc9, 0x01, 0x41, 0x4a, 0x62, 0x3d, 0x50, - 0x6b, 0xb3, 0x2b, 0x27, 0x5c, 0x8a, 0xfb, 0x0e, 0xf9, 0xb4, 0xea, 0xdf, 0x5a, 0x5c, 0x76, 0xac, - 0x19, 0xc6, 0x6b, 0x66, 0x6d, 0x4c, 0xce, 0xdf, 0x63, 0x3a, 0x93, 0x28, 0xea, 0x90, 0x65, 0x6b, - 0xa5, 0xc2, 0x01, 0x4f, 0x93, 0xb6, 0x1e, 0xc9, 0xce, 0x35, 0x14, 0x86, 0xca, 0x4b, 0x35, 0xd5, - 0x0c, 0x0c, 0x2c, 0xb2, 0xd6, 0x3d, 0xaf, 0xc5, 0xc2, 0xaf, 0x30, 0xde, 0x56, 0x6f, 0x53, 0xb4, - 0x3b, 0xa5, 0xe5, 0xa0, 0xe2, 0x22, 0xf6, 0x16, 0x40, 0x48, 0x69, 0xdc, 0xab, 0x95, 0xda, 0x77, - 0xea, 0xc1, 0x5a, 0x7b, 0x0e, 0x73, 0xa4, 0xd3, 0x15, 0x1b, 0x79, 0x03, 0x17, 0x94, 0x93, 0x11, - 0x7f, 0x10, 0x1c, 0xdf, 0x6b, 0x2e, 0x5e, 0x23, 0x78, 0x4d, 0xc5, 0x18, 0x1e, 0xdb, 0x0c, 0xb6, - 0x3e, 0x3c, 0xd0, 0xac, 0xf7, 0x27, 0x27, 0x6b, 0xde, 0xea, 0xe0, 0x40, 0x03, 0x37, 0xee, 0x6f, - 0x30, 0x84, 0x6b, 0xc8, 0x0d, 0xfb, 0x04, 0x8e, 0xbd, 0x51, 0xa1, 0x34, 0xd9, 0x51, 0x85, 0x88, - 0x3d, 0xef, 0xd1, 0xc2, 0xa7, 0xf0, 0xbd, 0x46, 0x5c, 0x73, 0x4b, 0x1c, 0x1c, 0x1e, 0x85, 0xc6, - 0xd0, 0xf5, 0x1a, 0xf0, 0x50, 0x03, 0x96, 0x6f, 0xf0, 0x44, 0x61, 0x28, 0x25, 0x02, 0xe0, 0x65, - 0x87, 0x2c, 0x0e, 0x3a, 0x49, 0x95, 0xa9, 0x95, 0xc4, 0xb8, 0x34, 0x5d, 0x3b, 0xdb, 0x93, 0x85, - 0x6a, 0xeb, 0x69, 0x55, 0x14, 0x23, 0xce, 0xa3, 0x52, 0x8b, 0xb6, 0xa0, 0x95, 0x40, 0x3e, 0x43, - 0xdc, 0x4a, 0xc1, 0x6e, 0x82, 0x68, 0x73, 0x2a, 0x57, 0xf0, 0x75, 0x8d, 0x88, 0x8d, 0xc7, 0xe5, - 0xbc, 0x3c, 0x9c, 0x79, 0x8a, 0x04, 0x80, 0x1a, 0x5c, 0x66, 0x1a, 0x67, 0xb7, 0xca, 0x6c, 0x3b, - 0xbe, 0xd5, 0x6d, 0x70, 0xb1, 0x6f, 0xf7, 0x43, 0xbd, 0x1b, 0xb9, 0x82, 0xc5, 0x23, 0x4f, 0xbe, - 0x25, 0x6c, 0x5e, 0xe9, 0xb0, 0x99, 0x3c, 0xf5, 0xcd, 0xc9, 0xc9, 0x5b, 0x7b, 0xc3, 0x99, 0x53, - 0x5a, 0xa7, 0xba, 0xc1, 0xcc, 0x3b, 0x71, 0x93, 0x29, 0x3b, 0x07, 0x7e, 0x2e, 0x54, 0x3e, 0xbe, - 0x50, 0x17, 0x47, 0xa8, 0x1b, 0x0b, 0xfb, 0x5c, 0x5d, 0x88, 0xb2, 0xe3, 0xf8, 0xc6, 0x1c, 0xe9, - 0x5c, 0xde, 0x3c, 0xe0, 0xd4, 0x9e, 0x9b, 0x84, 0xde, 0xed, 0x68, 0xa0, 0x0e, 0xb4, 0x4b, 0xe2, - 0xbe, 0xae, 0xf6, 0x60, 0x9c, 0x6b, 0x4a, 0x9a, 0x9a, 0xd9, 0xb7, 0x16, 0xa1, 0xab, 0x4b, 0x89, - 0x05, 0xe5, 0x1d, 0x05, 0xc1, 0xd7, 0x5a, 0x16, 0xce, 0x61, 0xe5, 0xe9, 0x64, 0x79, 0xbd, 0xb5, - 0x29, 0x5a, 0xaa, 0x78, 0x17, 0x47, 0x3b, 0x04, 0xb9, 0x18, 0x7f, 0x82, 0xd3, 0xc6, 0x69, 0xb2, - 0x5d, 0xa3, 0x83, 0xdf, 0x9a, 0x1b, 0x1a, 0xb4, 0xc4, 0xf1, 0xa1, 0x7d, 0xdd, 0x57, 0x00, 0xf1, - 0x5d, 0xab, 0xb9, 0x2b, 0xcb, 0x6d, 0x92, 0xbd, 0x9b, 0x4a, 0x92, 0xc7, 0x0f, 0xbb, 0x6a, 0x41, - 0xe9, 0x94, 0xd3, 0x86, 0xeb, 0x91, 0xb7, 0x16, 0x3c, 0xe8, 0xad, 0xbd, 0xb7, 0x0d, 0x65, 0x11, - 0xc0, 0xe1, 0xaf, 0x90, 0x09, 0x1f, 0x2d, 0xd8, 0x33, 0x34, 0xdc, 0xbe, 0x59, 0xe6, 0x46, 0xfb, - 0x8e, 0x3a, 0xb1, 0x5a, 0x6d, 0x8a, 0xc9, 0xca, 0x07, 0x61, 0x35, 0x14, 0xe8, 0x47, 0xad, 0xd2, - 0x72, 0xfd, 0xa0, 0xb5, 0x5a, 0x73, 0x5b, 0x14, 0xb4, 0x1f, 0xc5, 0x40, 0x0e, 0x50, 0x0d, 0x7f, - 0xae, 0x19, 0xed, 0xc6, 0xc8, 0x83, 0x55, 0x9e, 0x86, 0xde, 0xbb, 0xdd, 0xee, 0x9a, 0x2d, 0x8f, - 0x14, 0x01, 0x63, 0xfa, 0xb4, 0x8a, 0x8a, 0xc7, 0x29, 0x42, 0xb9, 0xb6, 0x0d, 0x01, 0xf8, 0x59, - 0x0c, 0xaa, 0x01, 0x7f, 0xff, 0xd7, 0xc1, 0xb7, 0xee, 0x2a, 0xd4, 0x23, 0xbc, 0xb3, 0x37, 0x8d, - 0x7b, 0x29, 0xb7, 0x74, 0x6c, 0x9b, 0x56, 0xed, 0xec, 0x1f, 0x24, 0x28, 0xd1, 0x54, 0x5b, 0x58, - 0x7b, 0xbf, 0xc0, 0x40, 0x97, 0x30, 0xb1, 0x58, 0xaa, 0x67, 0xb3, 0xf6, 0x81, 0xcd, 0xd7, 0xa6, - 0x89, 0x41, 0x12, 0xb8, 0x52, 0x42, 0x92, 0x70, 0xb4, 0x61, 0xbf, 0xdc, 0x9d, 0x17, 0x32, 0xd3, - 0x27, 0x9e, 0x77, 0x12, 0x58, 0xf0, 0x4b, 0xed, 0x6d, 0x4c, 0x1f, 0x93, 0xff, 0x2a, 0x84, 0x9c, - 0x14, 0x23, 0x9f, 0x52, 0x38, 0x03, 0x0c, 0xdd, 0xa4, 0xe9, 0x2e, 0xb6, 0xbb, 0x9d, 0xb6, 0x02, - 0x6b, 0x65, 0x81, 0xdf, 0xb3, 0x60, 0x92, 0xdc, 0xc7, 0x96, 0xbc, 0x2d, 0x9f, 0x08, 0xb5, 0x16, - 0x42, 0x6e, 0xfd, 0xb4, 0x5c, 0x58, 0xf2, 0x05, 0x1d, 0x13, 0x59, 0xfa, 0x73, 0x2c, 0x26, 0xcd, - 0x2d, 0xf9, 0x4b, 0xf9, 0xa8, 0x1b, 0x3e, 0x2f, 0x9f, 0x30, 0x8a, 0x85, 0xc8, 0xa0, 0x1e, 0x86, - 0x76, 0xb4, 0x2b, 0x52, 0xe7, 0x34, 0xe7, 0xa0, 0x94, 0x60, 0x9a, 0x57, 0x5e, 0xe2, 0x74, 0x19, - 0x4e, 0x94, 0xfd, 0xce, 0xcb, 0xe7, 0xfd, 0xd4, 0x8b, 0x27, 0xc9, 0x9d, 0x2d, 0xba, 0x23, 0xd1, - 0xcf, 0x93, 0x32, 0xcf, 0xf7, 0xed, 0x13, 0x73, 0xbf, 0xe9, 0x3b, 0xb1, 0xab, 0xb6, 0x32, 0xf5, - 0xb6, 0xf0, 0x35, 0x53, 0xf9, 0xfa, 0x9a, 0x64, 0xc8, 0x36, 0x03, 0x0c, 0xa5, 0x13, 0x87, 0x65, - 0x26, 0xcf, 0xe6, 0x6d, 0xcd, 0xba, 0xf2, 0x30, 0x7c, 0x10, 0x46, 0x2c, 0x72, 0xb4, 0x8b, 0x60, - 0x9e, 0xe4, 0xb8, 0xd1, 0x24, 0x65, 0x8f, 0xeb, 0x72, 0x2d, 0x5f, 0x5c, 0xf1, 0x1a, 0xe4, 0x76, - 0xe1, 0x65, 0x19, 0x3c, 0x21, 0xa7, 0x33, 0xda, 0x89, 0x9d, 0xcc, 0xdb, 0xc0, 0x19, 0xca, 0xc5, - 0x84, 0x78, 0xdf, 0x0a, 0xf1, 0x00, 0xc8, 0x1c, 0x98, 0x89, 0x34, 0xb3, 0xab, 0x3d, 0x1e, 0x60, - 0x66, 0xa5, 0xb9, 0xea, 0x4d, 0x62, 0x5b, 0x13, 0x95, 0x34, 0xa0, 0x26, 0x48, 0x46, 0x3e, 0x3e, - 0x9f, 0xee, 0x9b, 0x7c, 0xd2, 0x05, 0x97, 0xc3, 0x2b, 0x07, 0x01, 0x0a, 0xe5, 0x09, 0xa3, 0x10, - 0x3d, 0xff, 0x25, 0xe3, 0xfa, 0xfe, 0xdf, 0x08, 0xd8, 0xea, 0xd9, 0x90, 0x0b, 0xf1, 0x9c, 0xde, - 0xf5, 0x01, 0xde, 0xcf, 0xb9, 0x1a, 0x5e, 0x3d, 0x8d, 0x90, 0xdd, 0x87, 0xbc, 0x99, 0xc6, 0x5b, - 0x39, 0x62, 0x4b, 0x7f, 0x81, 0xe2, 0xd1, 0xda, 0xe1, 0xcb, 0x0b, 0xe7, 0xc6, 0xae, 0x72, 0xa8, - 0xf2, 0xf2, 0x56, 0xfe, 0x22, 0xcf, 0xe5, 0xf3, 0x36, 0x1c, 0x69, 0xd2, 0xeb, 0x65, 0xbd, 0xa1, - 0x93, 0x6f, 0xb6, 0xde, 0x99, 0xb1, 0x2e, 0x3e, 0x3d, 0xfb, 0xf8, 0xc9, 0x12, 0x3a, 0x27, 0x32, - 0x66, 0xa0, 0xb7, 0x1a, 0xf6, 0x2f, 0xce, 0x43, 0x7d, 0xde, 0x7d, 0xf8, 0xfc, 0x72, 0xbf, 0xcb, - 0xb9, 0xee, 0xf2, 0xfc, 0xc1, 0x2e, 0x2f, 0xdf, 0xbf, 0xb0, 0x84, 0xbc, 0xff, 0x73, 0x93, 0xdd, - 0x81, 0x18, 0x3b, 0x18, 0xdd, 0x26, 0xcc, 0xfd, 0xdc, 0xd8, 0x9a, 0xf2, 0x6d, 0xe4, 0xd8, 0x5b, - 0x85, 0x33, 0x8f, 0xdc, 0x62, 0xfa, 0x9b, 0x24, 0xcf, 0x66, 0x04, 0x33, 0x51, 0x83, 0x5f, 0x6d, - 0xdb, 0xed, 0xf8, 0x73, 0xb8, 0xc6, 0x41, 0x81, 0x59, 0xa4, 0x50, 0x72, 0xa2, 0x2f, 0x4e, 0x33, - 0x6f, 0xea, 0xa5, 0xe1, 0x20, 0xd4, 0x9b, 0xbf, 0x60, 0xdd, 0x58, 0x0d, 0xc2, 0x9f, 0xe6, 0xe0, - 0x93, 0x22, 0xfc, 0x29, 0x99, 0xe0, 0xc7, 0x9b, 0x18, 0xb5, 0xa9, 0x3a, 0x78, 0xe7, 0xb9, 0x8a, - 0x4a, 0xe1, 0x91, 0xc4, 0x6e, 0xaa, 0x19, 0xc5, 0x4f, 0xa2, 0xae, 0x35, 0x18, 0x58, 0xdd, 0xb4, - 0x3f, 0x4f, 0xb2, 0x1c, 0x97, 0x05, 0x84, 0x8a, 0x92, 0xb6, 0xb8, 0xcd, 0x02, 0x2f, 0xf5, 0xe7, - 0xdd, 0xdc, 0x31, 0x4e, 0x90, 0xbc, 0x3a, 0xde, 0x55, 0x4a, 0x7b, 0xf1, 0x53, 0x35, 0xfa, 0x7e, - 0xe8, 0x0e, 0x9d, 0x51, 0x1d, 0xf9, 0x9e, 0x2a, 0x96, 0xce, 0x9f, 0xde, 0x0c, 0x50, 0x23, 0xd3, - 0xfd, 0x47, 0xeb, 0xdd, 0x23, 0xab, 0x6b, 0xe7, 0xdd, 0xe4, 0x94, 0x4b, 0xfd, 0x24, 0x83, 0x8f, - 0x28, 0xba, 0x16, 0x95, 0x06, 0x55, 0x69, 0x16, 0xc6, 0x65, 0xe9, 0x33, 0x94, 0x27, 0x5c, 0x4b, - 0xbf, 0x43, 0x5c, 0xc3, 0xf2, 0xba, 0x0f, 0x23, 0x6e, 0x85, 0x11, 0x9b, 0x31, 0xd7, 0x63, 0xd3, - 0xde, 0xa7, 0x92, 0xac, 0xf3, 0x32, 0x8d, 0xaa, 0x59, 0x2f, 0x6c, 0xde, 0x4b, 0x90, 0x5b, 0xde, - 0xa6, 0x74, 0xac, 0x30, 0x85, 0x92, 0xd0, 0x8c, 0x60, 0xc9, 0x35, 0x82, 0x84, 0xb5, 0xdc, 0xe0, - 0x77, 0x23, 0xf5, 0xdf, 0xeb, 0xd8, 0xd6, 0x9f, 0x4e, 0xb7, 0xf8, 0x83, 0x89, 0x68, 0x05, 0xaa, - 0x23, 0x46, 0x04, 0x1c, 0x10, 0xd4, 0x92, 0xa5, 0x36, 0x21, 0xae, 0x98, 0xc5, 0xa4, 0xfd, 0xb7, - 0xbc, 0x6b, 0xfa, 0x1a, 0x16, 0xda, 0xf9, 0x0c, 0x3f, 0x80, 0xe4, 0x35, 0x49, 0xc3, 0x59, 0x48, - 0xb1, 0x6e, 0x47, 0x77, 0xf4, 0xc3, 0xd4, 0xa7, 0xe1, 0x5a, 0xe6, 0x70, 0x7d, 0xcd, 0x49, 0x28, - 0x4b, 0xa6, 0x4e, 0x20, 0xe9, 0x83, 0x7a, 0x8e, 0x45, 0x1f, 0x7c, 0xb0, 0x38, 0xc5, 0x99, 0xdc, - 0x06, 0xfa, 0x3b, 0x11, 0x96, 0x73, 0x26, 0xf5, 0xb3, 0x63, 0xd1, 0x2b, 0x86, 0xd6, 0xee, 0xcf, - 0xc1, 0xe6, 0xcf, 0x8f, 0x31, 0xec, 0xde, 0xd9, 0x9f, 0x84, 0x3e, 0x9d, 0x4e, 0x01, 0x5d, 0xec, - 0x1e, 0xef, 0x9d, 0x37, 0x51, 0xdb, 0xb5, 0x33, 0x04, 0xa2, 0x40, 0x76, 0xe7, 0x7b, 0x09, 0xf4, - 0x72, 0x1e, 0x5a, 0xea, 0x85, 0x3a, 0x55, 0xe5, 0x6e, 0xc7, 0x5a, 0xe7, 0x47, 0xf5, 0x2c, 0x4d, - 0xbd, 0x0d, 0x25, 0x26, 0xa3, 0x0d, 0xfb, 0x44, 0x72, 0x5b, 0xe6, 0xc9, 0xbf, 0x7d, 0x32, 0xdc, - 0x89, 0xfe, 0x9d, 0xb7, 0xb0, 0xf7, 0x0d, 0x70, 0x7d, 0x2c, 0x45, 0xc8, 0xdf, 0xf7, 0x14, 0x5b, - 0x4d, 0xe5, 0xc0, 0x26, 0x2d, 0xa7, 0x41, 0xb2, 0x64, 0xd6, 0x07, 0xe1, 0x6a, 0x4b, 0x40, 0x31, - 0x53, 0x60, 0x58, 0x82, 0x9c, 0x2c, 0x41, 0xf0, 0xa0, 0x25, 0xc8, 0xf7, 0x52, 0x4f, 0x07, 0x96, - 0x20, 0x30, 0x2d, 0xc1, 0x75, 0xfd, 0x1a, 0xe3, 0xb3, 0x78, 0x06, 0x27, 0x72, 0x7f, 0xee, 0xa5, - 0x4b, 0x58, 0x9b, 0xf5, 0xfe, 0xfd, 0x3c, 0x08, 0x22, 0x6e, 0x59, 0x32, 0x21, 0xec, 0x11, 0x9d, - 0x86, 0x49, 0xfc, 0xdb, 0xfb, 0x30, 0xe3, 0x7c, 0xe2, 0x61, 0xeb, 0x17, 0x21, 0x7d, 0x79, 0x0d, - 0x20, 0xdd, 0x1e, 0x50, 0xd4, 0xcd, 0x7b, 0x76, 0xe0, 0xf6, 0x12, 0x07, 0x6e, 0x65, 0xd2, 0xcb, - 0xc5, 0x37, 0x54, 0x86, 0x7f, 0x7c, 0xb3, 0x93, 0xc6, 0x92, 0xaa, 0x64, 0x97, 0x89, 0xb2, 0x52, - 0x14, 0x08, 0x47, 0x24, 0x0b, 0x4c, 0x62, 0x49, 0x47, 0x8b, 0xf4, 0xf7, 0x5c, 0x7e, 0xe1, 0x67, - 0x8a, 0x40, 0x35, 0x97, 0x7c, 0xe4, 0xcf, 0xbb, 0xc8, 0x90, 0x13, 0x10, 0x11, 0xf4, 0xd6, 0x3c, - 0x5b, 0xc9, 0x4c, 0x25, 0x83, 0xb3, 0x5e, 0x4c, 0xa9, 0x0a, 0x76, 0x2d, 0xf6, 0x11, 0x60, 0x87, - 0xfd, 0x39, 0x85, 0x3b, 0xa7, 0xb6, 0xa1, 0x01, 0xe0, 0xaa, 0x52, 0x0e, 0x65, 0x30, 0x1a, 0x0e, - 0x4f, 0xed, 0xac, 0x47, 0x9b, 0x59, 0xfa, 0xe3, 0x5d, 0xd0, 0x25, 0x42, 0xfa, 0x2a, 0xeb, 0xc6, - 0x72, 0x4e, 0xbf, 0x5f, 0x95, 0x4c, 0xc6, 0x86, 0x25, 0xf5, 0xd7, 0x51, 0x12, 0x59, 0x7e, 0x3c, - 0x28, 0x79, 0x58, 0x3a, 0x65, 0xf5, 0xa1, 0x14, 0x8b, 0xbf, 0x04, 0x43, 0xd2, 0x0a, 0xc0, 0xe0, - 0xdd, 0xcc, 0x62, 0x8f, 0x99, 0x9e, 0xe8, 0x0b, 0x36, 0x5e, 0xf4, 0x23, 0x5d, 0xe8, 0x95, 0x23, - 0xb9, 0x0d, 0x27, 0x4e, 0xe5, 0x72, 0x70, 0xf3, 0x8c, 0x5e, 0xdc, 0x92, 0xdb, 0x64, 0x3a, 0xa5, - 0x13, 0xdf, 0xd6, 0xf0, 0x1b, 0x96, 0x90, 0x64, 0xa1, 0xdf, 0x6e, 0xb5, 0x6a, 0xb1, 0x68, 0x69, - 0x4b, 0x9f, 0x24, 0x6e, 0x6d, 0x5d, 0x96, 0x95, 0x5f, 0x49, 0x41, 0x29, 0x49, 0xad, 0x60, 0x10, - 0xad, 0x8b, 0x86, 0xd4, 0x2e, 0x8f, 0x25, 0x33, 0x33, 0xc5, 0x76, 0x27, 0x7f, 0x3c, 0x90, 0x9d, - 0x5a, 0x72, 0x00, 0x95, 0xb4, 0x3c, 0x00, 0xd3, 0x26, 0x51, 0x2e, 0x27, 0xce, 0x2b, 0xdb, 0x97, - 0x73, 0x99, 0x0d, 0xce, 0x24, 0x3c, 0xff, 0xee, 0xa8, 0xff, 0x9d, 0xa8, 0x85, 0x7c, 0x9e, 0x45, - 0xb6, 0xd5, 0x3d, 0xe2, 0x6b, 0x80, 0xeb, 0x5a, 0x92, 0x3f, 0xb2, 0x2c, 0xe9, 0x9b, 0xf6, 0x02, - 0x13, 0xde, 0xe9, 0x19, 0xb7, 0x6a, 0x99, 0x72, 0xda, 0x99, 0x97, 0x97, 0xdf, 0xc4, 0xb4, 0xa4, - 0x0f, 0xfb, 0x2f, 0xfd, 0x8d, 0x03, 0x06, 0xab, 0xa7, 0xce, 0x1f, 0x21, 0xed, 0x7e, 0xb6, 0xad, - 0xbf, 0x59, 0xdd, 0x0a, 0xeb, 0x18, 0x88, 0xa0, 0x43, 0x57, 0x32, 0x90, 0xb7, 0xd5, 0xa7, 0x2b, - 0x1e, 0x56, 0x69, 0xe5, 0x60, 0x51, 0xd5, 0xb2, 0x7d, 0x2c, 0x56, 0x8e, 0xb2, 0xfe, 0x32, 0x4d, - 0x2f, 0xec, 0xaf, 0x88, 0x21, 0x77, 0x7f, 0xb8, 0x08, 0x2d, 0x1b, 0xed, 0x40, 0xb5, 0xca, 0x2c, - 0x91, 0x57, 0x89, 0x11, 0x1f, 0x5c, 0x3f, 0xa4, 0x56, 0xcc, 0x03, 0x3d, 0x96, 0xdb, 0xd4, 0x49, - 0x59, 0x4b, 0x56, 0x42, 0x76, 0xb1, 0x9a, 0x55, 0xca, 0xb2, 0x2a, 0xfa, 0xc0, 0x8f, 0x30, 0x41, - 0x7e, 0x37, 0x6a, 0xec, 0x9d, 0x87, 0xe0, 0xdf, 0x99, 0x57, 0x25, 0x64, 0xeb, 0x3c, 0xa2, 0xc1, - 0xbe, 0xd0, 0x1b, 0x7e, 0x8c, 0x7a, 0xe8, 0x9c, 0x42, 0xd2, 0xa7, 0xaf, 0x2e, 0x41, 0xac, 0x13, - 0xfa, 0xde, 0x11, 0x1d, 0x51, 0xa8, 0x55, 0x0e, 0xa4, 0x3a, 0xd3, 0x6a, 0x01, 0xcc, 0x11, 0x29, - 0xaf, 0x97, 0xd5, 0xb2, 0x9a, 0xed, 0x29, 0x05, 0x3c, 0x1a, 0x3a, 0x63, 0x9c, 0xa3, 0xa9, 0x9d, - 0xf7, 0x52, 0x04, 0x2d, 0x74, 0x17, 0xf4, 0x42, 0x51, 0x1e, 0x71, 0xe6, 0xc9, 0x7a, 0xb9, 0x17, - 0x9f, 0xd9, 0x01, 0xf9, 0xf3, 0xf3, 0x76, 0xb5, 0xa1, 0x9d, 0x7b, 0x72, 0x25, 0x6d, 0xff, 0x94, - 0xfe, 0x78, 0xd2, 0xa0, 0xd4, 0x1f, 0x30, 0xf2, 0xac, 0x41, 0x96, 0x1a, 0xd2, 0x1d, 0x96, 0xad, - 0xd7, 0xff, 0xdf, 0x14, 0xe1, 0xc2, 0x69, 0xde, 0x0d, 0x4e, 0xe1, 0xfd, 0x44, 0x70, 0x39, 0xfb, - 0x49, 0xac, 0xfd, 0xb7, 0x58, 0x6e, 0xe7, 0xa0, 0x52, 0xe6, 0x18, 0x40, 0x41, 0xe9, 0x41, 0x74, - 0xba, 0x14, 0xe4, 0x7a, 0x07, 0x3b, 0xca, 0x0f, 0xd4, 0xe6, 0xe3, 0xbf, 0xa6, 0xae, 0xee, 0x8d, - 0x9e, 0xd2, 0x76, 0xd8, 0x24, 0x58, 0x7f, 0x98, 0xda, 0xd6, 0x37, 0x74, 0x0e, 0x50, 0x2d, 0xbc, - 0x34, 0x0b, 0x5e, 0xd1, 0xe7, 0x9b, 0xa8, 0x5f, 0xe5, 0x56, 0xb9, 0x01, 0xeb, 0xb3, 0xd8, 0x31, - 0xd2, 0xfe, 0xff, 0x32, 0xc5, 0x8e, 0x7a, 0xbd, 0x89, 0x73, 0xca, 0x0b, 0x3f, 0x31, 0x7c, 0x92, - 0x7f, 0x9b, 0x47, 0x9f, 0x9a, 0x18, 0x06, 0x6d, 0x08, 0xd5, 0x17, 0x14, 0x3b, 0xd9, 0x67, 0x12, - 0x2a, 0x41, 0xef, 0xc1, 0xfd, 0x5d, 0x59, 0xb6, 0xeb, 0x5c, 0xf6, 0xbe, 0x7c, 0xe9, 0x5e, 0xb9, - 0x5f, 0xbe, 0x4c, 0x4e, 0xbf, 0x7c, 0xe9, 0xe3, 0xd2, 0xfd, 0xc6, 0x15, 0xc5, 0x5e, 0x05, 0x95, - 0x58, 0xf2, 0x1f, 0xca, 0xba, 0xfc, 0xf2, 0x25, 0x2b, 0xbe, 0x7c, 0xb1, 0xaf, 0xba, 0x90, 0xad, - 0xbf, 0x43, 0x9a, 0x2e, 0x25, 0x1e, 0xb3, 0x87, 0x1e, 0x71, 0x0f, 0x98, 0xc2, 0xb5, 0xe4, 0x3f, - 0xff, 0xe7, 0xbe, 0x0f, 0x82, 0xfa, 0x0f, 0x6f, 0xc3, 0x7c, 0x0c, 0x66, 0x2f, 0xd7, 0xa4, 0x64, - 0x67, 0x37, 0x56, 0xf7, 0x1f, 0x10, 0xe9, 0xfc, 0xb0, 0xd8, 0xb3, 0xba, 0xff, 0x04, 0xcf, 0xec, - 0x97, 0x43, 0x07, 0x71, 0xf3, 0xe4, 0xa8, 0x58, 0x37, 0x47, 0x80, 0x63, 0xfd, 0x8a, 0xb5, 0xff, - 0xcd, 0x2d, 0x86, 0x6b, 0x5a, 0x74, 0x8a, 0x02, 0xfb, 0x72, 0xd8, 0xfb, 0xc1, 0xeb, 0x4d, 0x9f, - 0xf5, 0x5e, 0x5d, 0x6d, 0xe1, 0x90, 0x5b, 0x32, 0x3c, 0x2c, 0x3d, 0xa3, 0xd2, 0x6c, 0x1f, 0xa8, - 0xd5, 0x8d, 0xe1, 0x06, 0x57, 0xff, 0x5b, 0x8f, 0x41, 0x70, 0xef, 0x6b, 0x2d, 0xaa, 0x46, 0x51, - 0x4b, 0xa3, 0xb0, 0xfa, 0x9f, 0x5b, 0xf8, 0x5f, 0x6b, 0x51, 0x35, 0x9a, 0x1f, 0xc4, 0x6a, 0x2c, - 0x1a, 0x49, 0x7c, 0xae, 0x5f, 0xb6, 0xea, 0x8c, 0xca, 0xf4, 0x8b, 0x7e, 0x57, 0x07, 0x5c, 0x3d, - 0x04, 0x57, 0x0f, 0xe5, 0x0a, 0xff, 0x3c, 0x67, 0xb4, 0x93, 0x55, 0x7c, 0x4f, 0x2f, 0xb8, 0xe5, - 0xe0, 0x6c, 0x08, 0xfd, 0x16, 0x36, 0xda, 0xd9, 0xfa, 0xfc, 0xa1, 0x22, 0xe8, 0x5e, 0xd8, 0x41, - 0xa7, 0x03, 0xc7, 0x00, 0xb8, 0x6e, 0x29, 0x05, 0x4a, 0xdb, 0xdb, 0x6a, 0xa6, 0x6c, 0xeb, 0x11, - 0xac, 0x1f, 0xae, 0xcb, 0xa2, 0x87, 0xea, 0x76, 0xe3, 0xb9, 0x19, 0xab, 0x62, 0xbe, 0x2d, 0x7e, - 0xc9, 0xd1, 0xde, 0x3b, 0x85, 0x47, 0x47, 0x67, 0x70, 0x73, 0x4a, 0xa4, 0x22, 0x54, 0x1f, 0x18, - 0x2c, 0x60, 0x52, 0xf9, 0x5b, 0xf9, 0xfd, 0xee, 0xf1, 0x40, 0xc7, 0x45, 0xb9, 0x10, 0x3a, 0xba, - 0xab, 0x66, 0xad, 0xf2, 0xfa, 0x70, 0x01, 0x83, 0x20, 0x16, 0x74, 0x0f, 0x1a, 0xd7, 0xcb, 0x3f, - 0x6c, 0x4c, 0x0c, 0x78, 0xd8, 0xb8, 0x5e, 0xb3, 0xd1, 0x18, 0xde, 0x37, 0xbd, 0x62, 0x9f, 0xe5, - 0xf4, 0xf9, 0x5e, 0xcc, 0x78, 0x9e, 0x57, 0x6d, 0x57, 0xe4, 0x5a, 0x65, 0x2b, 0xb3, 0xa5, 0x95, - 0xf2, 0xf9, 0x40, 0xdc, 0xcc, 0xaa, 0x9b, 0x1b, 0x7d, 0x62, 0xb0, 0x9a, 0xcc, 0x3e, 0x64, 0x6b, - 0x5e, 0x35, 0xcb, 0xaa, 0x9b, 0x95, 0xd1, 0x9e, 0xc7, 0xe0, 0xf6, 0xbc, 0xcb, 0xf4, 0x40, 0x8f, - 0xa8, 0x3c, 0x93, 0x98, 0x23, 0xea, 0xbc, 0x7f, 0x44, 0x6c, 0xca, 0x9f, 0x6f, 0xb0, 0x51, 0x0c, - 0x56, 0x0b, 0x27, 0x8f, 0xd8, 0x5d, 0xd1, 0xaf, 0x88, 0x21, 0x6a, 0xae, 0x56, 0xaa, 0x72, 0xb8, - 0x50, 0x87, 0x84, 0x3c, 0xd7, 0x9f, 0x1a, 0x3a, 0xb0, 0x36, 0xd5, 0x1e, 0x3d, 0x75, 0xbd, 0xcc, - 0xaf, 0xd4, 0x51, 0x6c, 0x54, 0x56, 0x48, 0x5b, 0x27, 0xf2, 0xe8, 0x34, 0x6e, 0xc2, 0x47, 0x47, - 0xf7, 0x07, 0x80, 0x6b, 0x1c, 0x07, 0x66, 0x2e, 0xa4, 0x8a, 0x38, 0x31, 0xe7, 0x79, 0x5e, 0xe5, - 0xbf, 0xe6, 0x8c, 0xd6, 0x4f, 0xc9, 0x47, 0x60, 0xab, 0xc5, 0xdf, 0xed, 0xcf, 0x07, 0x4f, 0x86, - 0xec, 0xf1, 0xb2, 0x0f, 0xca, 0x1e, 0x2f, 0x1b, 0x7f, 0xf8, 0xba, 0x6c, 0x23, 0xe0, 0x37, 0xd2, - 0x6b, 0x31, 0x02, 0x36, 0x31, 0xe8, 0xd1, 0xa1, 0xbd, 0x18, 0x36, 0xa8, 0x97, 0xd0, 0x19, 0x0b, - 0xbe, 0x0b, 0x4f, 0x13, 0xf2, 0x61, 0xf9, 0x9e, 0x1e, 0x05, 0x3d, 0xfb, 0x2a, 0xfd, 0xe6, 0x49, - 0x69, 0x0e, 0x60, 0xd5, 0xcf, 0xbe, 0xfb, 0xee, 0xf4, 0x12, 0x6e, 0xb1, 0xcc, 0xf0, 0x5f, 0x24, - 0xe3, 0xab, 0x4b, 0xff, 0x4a, 0xce, 0x74, 0x31, 0x1e, 0x65, 0x59, 0xc5, 0xc5, 0x37, 0xba, 0xb8, - 0x6c, 0x49, 0x55, 0x54, 0xac, 0x91, 0x0b, 0x8a, 0x7f, 0x4a, 0x5e, 0x83, 0x8c, 0x47, 0x0b, 0xe1, - 0x15, 0xa4, 0x03, 0x74, 0xe5, 0x15, 0xcc, 0xf8, 0x8e, 0xbc, 0xf5, 0x1b, 0xbe, 0x0b, 0x4b, 0x0b, - 0xe9, 0xad, 0x75, 0x06, 0x03, 0x4e, 0x5d, 0x63, 0x33, 0xcb, 0x12, 0x4f, 0x85, 0x3d, 0xda, 0x5b, - 0x0c, 0x31, 0x7b, 0x4a, 0xa4, 0x86, 0x88, 0xe2, 0xbd, 0x41, 0x58, 0xe5, 0x6b, 0xc2, 0x32, 0x55, - 0x93, 0x39, 0x81, 0x1a, 0x9a, 0xc9, 0x92, 0x04, 0x05, 0x76, 0x0c, 0xfb, 0x3e, 0xf0, 0xba, 0x76, - 0xfc, 0x34, 0x75, 0x9f, 0x38, 0xc3, 0xbd, 0x6c, 0x4a, 0x4c, 0x0d, 0x52, 0xa0, 0x0c, 0x0d, 0xce, - 0xcc, 0x8a, 0x94, 0x2a, 0x12, 0xf8, 0xf9, 0xa8, 0xf8, 0xbf, 0x32, 0x1c, 0x83, 0x22, 0x7b, 0x32, - 0x3c, 0x0d, 0xa0, 0xcb, 0xc8, 0x82, 0xfa, 0xd0, 0x67, 0x74, 0x8d, 0x76, 0x0d, 0x21, 0x5f, 0x67, - 0x51, 0x2b, 0x21, 0x35, 0xfd, 0x92, 0x9a, 0x7e, 0xb1, 0xb2, 0xcf, 0x7a, 0x01, 0xc8, 0x01, 0x3c, - 0x50, 0x5a, 0xc2, 0x8d, 0x1d, 0x8a, 0x4d, 0x42, 0x95, 0x3e, 0x1d, 0x05, 0xbd, 0x1f, 0xb0, 0xba, - 0xe0, 0x34, 0x19, 0xa4, 0xe3, 0x7a, 0x5c, 0xc0, 0x2f, 0x87, 0x0d, 0x65, 0xe4, 0x7c, 0x07, 0xfb, - 0x5d, 0x8d, 0x1a, 0x3d, 0x80, 0x75, 0x75, 0x76, 0x9a, 0xf7, 0x23, 0xcd, 0x3d, 0xa7, 0x76, 0x80, - 0x41, 0x86, 0x43, 0x37, 0x70, 0xce, 0x86, 0x43, 0x0c, 0x5c, 0x4e, 0x22, 0xe8, 0x26, 0xd5, 0x78, - 0x67, 0x18, 0x8f, 0x32, 0x12, 0xa2, 0x6d, 0xcc, 0x18, 0x4b, 0xe5, 0xca, 0xc1, 0xd9, 0x8e, 0xb4, - 0x35, 0x2d, 0x96, 0x72, 0x68, 0x26, 0x83, 0xf3, 0x59, 0x66, 0x65, 0xe8, 0xfd, 0x43, 0x40, 0x98, - 0x07, 0xc0, 0x00, 0x03, 0x0d, 0x88, 0x76, 0x7d, 0x6a, 0xc2, 0xa0, 0xed, 0xdc, 0x63, 0x21, 0x0c, - 0xea, 0x0c, 0x6b, 0x6d, 0x74, 0x2a, 0x47, 0xc8, 0x38, 0xfa, 0x57, 0x9e, 0x91, 0xe1, 0x03, 0x2c, - 0x74, 0xb8, 0x45, 0x9f, 0xb2, 0x19, 0x9b, 0xa6, 0x29, 0x97, 0x76, 0xd2, 0x9f, 0x17, 0x45, 0xd2, - 0xcf, 0xe8, 0x67, 0x45, 0x3f, 0x9e, 0xa8, 0xb2, 0xcf, 0x15, 0x6c, 0x1d, 0x9d, 0x27, 0xd5, 0xf1, - 0x70, 0xb3, 0x3f, 0x2f, 0x05, 0xac, 0xdf, 0x8e, 0x0d, 0x43, 0xbe, 0x6d, 0xa3, 0x1b, 0x79, 0x9b, - 0x55, 0x5e, 0x67, 0xa6, 0xe3, 0xd8, 0x46, 0x1e, 0x0d, 0xe7, 0x0f, 0x0d, 0x67, 0xe6, 0x33, 0x84, - 0xf7, 0xc6, 0x7c, 0x8e, 0xc5, 0xae, 0x1e, 0xff, 0x10, 0x95, 0xb5, 0x56, 0x3d, 0x42, 0x9e, 0x21, - 0xab, 0x94, 0x4a, 0xdf, 0x7a, 0x8e, 0x71, 0xd0, 0xc2, 0x73, 0x47, 0x20, 0x91, 0xb7, 0x13, 0x25, - 0x8d, 0xa2, 0xaf, 0x2f, 0x0c, 0xfc, 0x7e, 0xbc, 0xb0, 0xb9, 0x66, 0x3a, 0x5e, 0x58, 0xd4, 0x70, - 0xc1, 0xfe, 0xc2, 0xb2, 0x83, 0x85, 0x45, 0x6d, 0x0b, 0xa3, 0xf1, 0xff, 0xa7, 0x85, 0x55, 0xe2, - 0xf0, 0x47, 0x0b, 0xab, 0x6d, 0xe5, 0x57, 0xb8, 0x18, 0x6d, 0xca, 0xc9, 0x93, 0xc7, 0x07, 0x57, - 0x11, 0xdd, 0x28, 0x98, 0xa4, 0x9b, 0x59, 0x75, 0x73, 0xc3, 0x51, 0xdf, 0x3e, 0xc8, 0x56, 0xae, - 0xae, 0x8e, 0xe7, 0xab, 0x11, 0xf1, 0xb4, 0x1d, 0xa8, 0xff, 0xf4, 0x83, 0x75, 0xe0, 0x93, 0x41, - 0x76, 0xff, 0xbf, 0xb9, 0x27, 0xed, 0x6e, 0xdb, 0xb8, 0xf6, 0xf3, 0xcb, 0x39, 0xf9, 0x0f, 0x23, - 0x24, 0x35, 0x01, 0x13, 0xdc, 0xe4, 0xa5, 0x29, 0x28, 0x4a, 0xc7, 0x71, 0x9c, 0x17, 0xf7, 0x39, - 0x8e, 0x4f, 0x65, 0x37, 0xc9, 0x51, 0x75, 0x6c, 0x2e, 0xa0, 0x84, 0x06, 0x02, 0x58, 0x00, 0x94, - 0xa8, 0xca, 0xfc, 0xef, 0xef, 0x2e, 0x33, 0x83, 0x19, 0x2c, 0x14, 0xed, 0xa6, 0x7d, 0xef, 0x34, - 0x95, 0x89, 0xd9, 0xe7, 0xce, 0x9d, 0x3b, 0x77, 0x9b, 0x3b, 0x6e, 0x3a, 0xf9, 0x87, 0x8b, 0xf7, - 0x56, 0x7c, 0xa0, 0x87, 0xc8, 0xb9, 0xe3, 0xd7, 0xa1, 0xfc, 0xca, 0xe8, 0xeb, 0x11, 0x7f, 0x79, - 0xb0, 0x0d, 0x27, 0x45, 0xa1, 0xab, 0x3e, 0x78, 0xb0, 0x7f, 0x5d, 0xe8, 0x1b, 0xbf, 0x1e, 0x9f, - 0xfb, 0x78, 0x6d, 0xf0, 0x20, 0x6c, 0x3f, 0x45, 0x61, 0x2a, 0x42, 0xf2, 0x34, 0xf2, 0x10, 0xc5, - 0xe3, 0x1c, 0x70, 0x33, 0x05, 0x7c, 0x4c, 0x00, 0x07, 0x33, 0x60, 0xe3, 0x22, 0xb9, 0x44, 0x8a, - 0x45, 0xd9, 0x0f, 0x92, 0x20, 0x30, 0x83, 0x20, 0xd1, 0xcf, 0x3c, 0xfa, 0xe7, 0x82, 0xff, 0x99, - 0x79, 0x95, 0xa6, 0x76, 0x43, 0x10, 0x26, 0x23, 0x61, 0x98, 0x17, 0x16, 0x10, 0x47, 0x7f, 0x7c, - 0xf8, 0x0b, 0xc1, 0x02, 0xe1, 0x20, 0x3f, 0x0e, 0xcf, 0x11, 0x0c, 0xf2, 0xe3, 0xd1, 0x39, 0x43, - 0x70, 0xfa, 0xe9, 0xf5, 0x70, 0xe5, 0xf8, 0xe3, 0xb1, 0x6c, 0x24, 0xb6, 0x1b, 0x29, 0x5b, 0x28, - 0xab, 0x9b, 0x7d, 0xce, 0x2b, 0xab, 0xb6, 0xa3, 0x3c, 0xf4, 0xa5, 0x3a, 0xda, 0xb9, 0x4e, 0x00, - 0xb0, 0x3d, 0xd6, 0x09, 0x0f, 0x59, 0xbd, 0x9d, 0xee, 0x5d, 0x2b, 0x28, 0xa3, 0xd6, 0x8a, 0x75, - 0x2a, 0x50, 0x4d, 0x21, 0x7b, 0xde, 0x75, 0xfe, 0xc0, 0xbf, 0x62, 0xf8, 0x25, 0xf1, 0xbe, 0x6c, - 0x74, 0x3f, 0xbc, 0x0f, 0x8b, 0x26, 0xc4, 0x47, 0x55, 0x60, 0x89, 0xbc, 0x70, 0xe6, 0x18, 0xc8, - 0x8b, 0x5f, 0x04, 0xc2, 0xb4, 0x19, 0xf1, 0xef, 0xab, 0xbb, 0x3f, 0xe2, 0xc3, 0x5c, 0x2a, 0x00, - 0x45, 0xee, 0xf1, 0x0e, 0xd5, 0x76, 0x39, 0x00, 0x34, 0xd6, 0x88, 0x2f, 0x69, 0x0f, 0xdf, 0x9f, - 0x46, 0x75, 0x32, 0x3e, 0xec, 0x13, 0xe6, 0xae, 0xc9, 0x03, 0x02, 0x70, 0x58, 0x99, 0xb0, 0x2a, - 0xfe, 0xff, 0xe9, 0x7f, 0x59, 0xc9, 0xaa, 0xf4, 0x87, 0x8d, 0x3c, 0x4b, 0xa9, 0x3a, 0xa5, 0x1b, - 0xac, 0xda, 0x34, 0xc6, 0xb1, 0xa6, 0xde, 0x6a, 0x03, 0x99, 0x83, 0x4a, 0xbe, 0x00, 0xca, 0x94, - 0xca, 0x46, 0xc7, 0xe7, 0x18, 0x7a, 0xce, 0x57, 0x4b, 0xd4, 0xec, 0x1b, 0xaa, 0xc5, 0xa7, 0xfd, - 0xa7, 0x4f, 0x9f, 0x1a, 0xd9, 0x4b, 0x2b, 0xfb, 0xd1, 0xa3, 0xfe, 0xa3, 0x47, 0x8f, 0xca, 0xec, - 0xa1, 0x9d, 0xfd, 0x64, 0x68, 0x66, 0x2d, 0xcd, 0xac, 0xa7, 0x95, 0x86, 0x87, 0x43, 0x2b, 0xfb, - 0x9b, 0x4a, 0xc3, 0x4b, 0x3b, 0x7b, 0x34, 0xac, 0x0e, 0xf9, 0xdc, 0xe0, 0x05, 0x1d, 0x43, 0x1d, - 0x18, 0x10, 0x63, 0x61, 0x9d, 0x7f, 0x80, 0x1e, 0x21, 0x31, 0x38, 0x28, 0xe0, 0x86, 0xc0, 0xde, - 0x20, 0xfa, 0x35, 0x16, 0x40, 0xa6, 0x4b, 0x16, 0x19, 0x37, 0xc3, 0x8b, 0xb7, 0x5c, 0xa2, 0xb6, - 0x5c, 0xa2, 0xb7, 0x5c, 0xa2, 0xb7, 0x5c, 0xe3, 0xa0, 0xb9, 0x5e, 0xa6, 0xea, 0x65, 0xba, 0x5e, - 0xa6, 0xea, 0x59, 0x13, 0x62, 0x01, 0x29, 0x90, 0xe6, 0x90, 0x80, 0x0d, 0x64, 0x8d, 0x43, 0x0e, - 0x89, 0x69, 0x23, 0x7d, 0x63, 0xcb, 0x90, 0xd9, 0x78, 0xb3, 0x6b, 0x58, 0x91, 0x1a, 0x56, 0xa4, - 0x87, 0x15, 0xe9, 0x61, 0x6d, 0x4b, 0x6d, 0x2f, 0x86, 0x8a, 0x9f, 0x66, 0x6d, 0x3a, 0xed, 0x74, - 0x87, 0x9e, 0xd8, 0x56, 0x60, 0x17, 0x7d, 0xfe, 0x01, 0x3d, 0x54, 0xd4, 0xd8, 0x12, 0xa9, 0xb7, - 0x75, 0xfd, 0x63, 0xbb, 0xd1, 0x41, 0x5a, 0x1b, 0x88, 0xa5, 0x21, 0xcc, 0xff, 0x81, 0x14, 0xf8, - 0xf7, 0x9a, 0x1f, 0x00, 0x5c, 0xe9, 0xc7, 0x8f, 0xc8, 0x84, 0x4b, 0x4d, 0x64, 0xf7, 0xf0, 0x61, - 0x06, 0xff, 0x4f, 0x98, 0x71, 0xe5, 0x27, 0xa8, 0xc2, 0xb1, 0xbc, 0xb1, 0x31, 0x71, 0xa5, 0xc0, - 0x4f, 0x8f, 0x51, 0x21, 0xa3, 0x0d, 0x32, 0x4f, 0xd8, 0x3b, 0x7c, 0xc8, 0x1e, 0x95, 0x7a, 0x2f, - 0xde, 0xb7, 0x0d, 0xa3, 0x49, 0x0c, 0x52, 0xe3, 0xe4, 0x51, 0xff, 0x69, 0x1b, 0x02, 0x63, 0x89, - 0x7c, 0x07, 0x32, 0x60, 0xfe, 0xf5, 0x76, 0x97, 0x41, 0x83, 0x7b, 0x56, 0x16, 0x8d, 0xb0, 0x66, - 0xd1, 0xe0, 0xb0, 0xfe, 0x6f, 0xd3, 0x55, 0xa0, 0x46, 0xf9, 0x23, 0xa5, 0xf8, 0x9f, 0x61, 0xea, - 0xe0, 0x53, 0xcd, 0x22, 0x56, 0x48, 0xfe, 0xc9, 0x04, 0x82, 0xea, 0x95, 0xa6, 0x91, 0xbd, 0x67, - 0x66, 0xd4, 0xf1, 0xb3, 0x4d, 0x90, 0xfb, 0xd9, 0x2d, 0xfc, 0xd9, 0x04, 0x09, 0x40, 0xf4, 0x96, - 0xfe, 0xca, 0x61, 0x83, 0xb8, 0xa5, 0x06, 0x0e, 0x3f, 0xab, 0x5a, 0xef, 0x66, 0xdd, 0xf8, 0xfd, - 0xda, 0xff, 0x4f, 0x56, 0x95, 0xe7, 0xdd, 0x88, 0xf4, 0xb1, 0x53, 0x18, 0x5d, 0x0a, 0xe2, 0x55, - 0x15, 0x31, 0xe1, 0xa4, 0xa6, 0x1b, 0x2e, 0xe4, 0x82, 0x8a, 0xaf, 0xa4, 0x34, 0x2b, 0x2c, 0x94, - 0x72, 0x5c, 0x3a, 0x39, 0xd0, 0x34, 0x7a, 0x06, 0x4a, 0x8d, 0x8b, 0xde, 0x24, 0xe9, 0x1a, 0x09, - 0x83, 0x43, 0x46, 0xbd, 0x52, 0xf8, 0xd6, 0x32, 0x77, 0x81, 0x12, 0xf7, 0x50, 0x6b, 0x8c, 0x2b, - 0xda, 0xe8, 0xec, 0x61, 0xf4, 0xe9, 0xba, 0x7b, 0x8a, 0xfd, 0x41, 0xbd, 0xd7, 0xe6, 0x23, 0xa7, - 0xa1, 0x11, 0xbb, 0x34, 0x23, 0xb6, 0x61, 0xb8, 0x73, 0xe9, 0xf8, 0xf9, 0xc3, 0xdd, 0x38, 0xee, - 0xe4, 0xce, 0x4e, 0x1c, 0x77, 0xae, 0x9d, 0xad, 0xd1, 0x55, 0xa9, 0x82, 0x77, 0xdd, 0x8c, 0xf4, - 0x3a, 0xd1, 0xf9, 0x24, 0x47, 0xb7, 0x68, 0xa5, 0x76, 0xa7, 0xbb, 0x64, 0x2d, 0xfe, 0x3f, 0x51, - 0x9b, 0xff, 0x4f, 0x78, 0x15, 0x15, 0x3f, 0xa4, 0xe9, 0x6f, 0xc8, 0x61, 0x44, 0x45, 0x30, 0x23, - 0x6f, 0x55, 0x47, 0x89, 0xae, 0xfc, 0xcc, 0xee, 0x44, 0x3b, 0xab, 0xc1, 0xe8, 0xc2, 0x2c, 0x0b, - 0xd9, 0xb5, 0xcc, 0x48, 0xa7, 0xcd, 0xcf, 0x5e, 0x52, 0xcf, 0xe8, 0x81, 0xfb, 0x52, 0xc1, 0x6a, - 0x64, 0x9d, 0x66, 0xf3, 0x49, 0xb9, 0x65, 0x28, 0x63, 0xa2, 0xb4, 0x4d, 0xfc, 0x29, 0xfb, 0xd5, - 0xdd, 0xc0, 0xe0, 0x5c, 0x87, 0x29, 0x35, 0x0e, 0xcf, 0x31, 0x6a, 0xa2, 0x25, 0x02, 0x3a, 0xc9, - 0xf1, 0xcf, 0x35, 0xfe, 0x99, 0x1a, 0xae, 0x2d, 0x4c, 0x8c, 0x4a, 0x75, 0x2f, 0xef, 0x01, 0x1a, - 0x04, 0x6d, 0x13, 0x8e, 0xa7, 0x41, 0x2a, 0x2e, 0xd3, 0xb5, 0xac, 0xae, 0x4a, 0x83, 0xcd, 0x4b, - 0xbd, 0x97, 0xad, 0x6e, 0x9b, 0x01, 0x47, 0x0d, 0x20, 0xdc, 0xfa, 0x40, 0x2b, 0xd2, 0x75, 0x71, - 0x42, 0x85, 0xf8, 0xf7, 0x44, 0x25, 0x06, 0x66, 0xe2, 0xd9, 0x9d, 0x76, 0x4e, 0x0a, 0xfe, 0xe9, - 0x73, 0x70, 0xd7, 0x3c, 0xb8, 0x03, 0xfa, 0x62, 0x64, 0xac, 0x0a, 0x33, 0xe7, 0xbc, 0xb1, 0x6b, - 0x7a, 0x18, 0xc6, 0xb1, 0x5c, 0xb3, 0xa2, 0xaa, 0x6b, 0x56, 0xf4, 0x79, 0xae, 0x59, 0x91, 0xc9, - 0x90, 0xa5, 0x49, 0xab, 0x0d, 0x1e, 0x8f, 0x1a, 0x03, 0x61, 0xc6, 0x2e, 0xfb, 0x22, 0x44, 0x39, - 0xfd, 0x0b, 0xb8, 0x77, 0x52, 0x04, 0x67, 0xc5, 0xb9, 0xd7, 0x07, 0xec, 0x7a, 0x31, 0x85, 0x3d, - 0x64, 0x9e, 0x62, 0xa9, 0x31, 0x21, 0xaa, 0x1f, 0xa0, 0x51, 0x13, 0x7b, 0xf0, 0xdd, 0x04, 0x6a, - 0x7d, 0xfc, 0x48, 0xff, 0x00, 0x87, 0x07, 0xa3, 0x53, 0x0e, 0x7a, 0x69, 0x15, 0x19, 0xa1, 0x04, - 0x72, 0xdc, 0x0d, 0xc9, 0x8d, 0x9d, 0x86, 0xa6, 0xa3, 0x44, 0x01, 0xa7, 0x6d, 0x63, 0x8b, 0xd8, - 0x27, 0xca, 0xe3, 0x91, 0x09, 0x86, 0xe5, 0xd2, 0x84, 0x83, 0x26, 0x6f, 0x08, 0x80, 0x4f, 0x9b, - 0x38, 0x1f, 0xdf, 0x89, 0x82, 0x1a, 0x94, 0x1b, 0x27, 0x75, 0x58, 0xa0, 0x55, 0x1b, 0xbb, 0xf1, - 0x69, 0xa5, 0xe4, 0xf5, 0x98, 0x50, 0x5b, 0xd2, 0x20, 0x63, 0x54, 0x1b, 0x23, 0x36, 0x62, 0x73, - 0xf4, 0x52, 0xe1, 0x14, 0x12, 0xa7, 0x0c, 0xcb, 0x55, 0x8d, 0x68, 0xd4, 0x1b, 0x8d, 0x87, 0x47, - 0x09, 0x5e, 0xdd, 0x21, 0x65, 0x94, 0xce, 0x3e, 0x4b, 0xba, 0xa3, 0xf3, 0xb1, 0xcb, 0x5b, 0xc8, - 0xd3, 0xa3, 0x93, 0xd0, 0x0b, 0x7d, 0x84, 0x2f, 0x60, 0xcc, 0x7c, 0x5a, 0xc0, 0x48, 0x4c, 0xa7, - 0x51, 0x13, 0x1f, 0x68, 0x11, 0xa1, 0xdb, 0x68, 0x32, 0x1c, 0x47, 0x47, 0x99, 0x0e, 0x57, 0xd4, - 0xed, 0x7a, 0x19, 0x90, 0x31, 0x73, 0x29, 0xd2, 0xca, 0x4c, 0x4c, 0x52, 0xf0, 0x7b, 0xce, 0xc8, - 0x1c, 0xa4, 0xbd, 0xec, 0xf6, 0x64, 0x5b, 0x26, 0xea, 0xbb, 0x19, 0x63, 0x66, 0x66, 0x63, 0x66, - 0x75, 0xf8, 0x59, 0x88, 0xcf, 0x03, 0xd5, 0xb5, 0x43, 0xca, 0x25, 0xd6, 0xbd, 0xe3, 0xb3, 0xbe, - 0xa8, 0xae, 0x20, 0x85, 0xc1, 0x33, 0x05, 0x60, 0x83, 0xae, 0x91, 0x4d, 0xaa, 0x3c, 0x19, 0x98, - 0x72, 0x62, 0x75, 0xe0, 0xe2, 0x70, 0x71, 0x1a, 0xb7, 0x29, 0x34, 0x1e, 0xaf, 0xe1, 0x40, 0xc7, - 0x02, 0x30, 0xc7, 0x94, 0x87, 0x9f, 0x56, 0x37, 0x56, 0x1d, 0x8f, 0x2a, 0x2d, 0x1a, 0x90, 0x47, - 0xb8, 0xa7, 0xcd, 0x70, 0x4f, 0x11, 0xee, 0x18, 0x3b, 0xc9, 0x80, 0x7b, 0x8a, 0x70, 0xd7, 0x9a, - 0x4f, 0x7b, 0x40, 0x0a, 0x43, 0xd8, 0xd9, 0x38, 0x31, 0x9d, 0x8d, 0x13, 0xbc, 0x20, 0x66, 0x88, - 0xa0, 0xd5, 0x31, 0xa6, 0x49, 0xc5, 0x4f, 0x54, 0xc1, 0x38, 0x8c, 0x95, 0xfb, 0xb5, 0x7d, 0x9e, - 0x90, 0x13, 0xa8, 0xa3, 0x1c, 0x3d, 0xcd, 0xa6, 0x8c, 0x13, 0xa2, 0x02, 0xc3, 0x0a, 0xdd, 0xe5, - 0x43, 0x61, 0x66, 0x5c, 0xed, 0x90, 0x04, 0xab, 0xb2, 0xb8, 0xf2, 0xf0, 0xa8, 0x9f, 0x19, 0x9c, - 0x41, 0x94, 0xbb, 0x5e, 0xbf, 0x7e, 0x9c, 0x2a, 0xe7, 0xe8, 0xa6, 0x83, 0x76, 0xe8, 0x3b, 0x14, - 0xbd, 0xd0, 0x91, 0x0e, 0x4e, 0x95, 0x13, 0x57, 0x6a, 0x8a, 0x43, 0x9a, 0xba, 0x7a, 0x8f, 0x8c, - 0xc2, 0x35, 0x1b, 0x3d, 0x86, 0xc6, 0x41, 0x5b, 0xcf, 0x6d, 0x3c, 0xde, 0x2b, 0xa0, 0x6b, 0xe3, - 0xb0, 0xbc, 0x3b, 0xe9, 0x54, 0x3a, 0xa1, 0x8b, 0xb4, 0xb5, 0xb1, 0x48, 0x8f, 0xe6, 0x12, 0xbb, - 0x3d, 0xe9, 0x51, 0xda, 0x52, 0x9e, 0x5d, 0x9e, 0xcd, 0xe2, 0x8d, 0x6c, 0x86, 0x04, 0x89, 0xc9, - 0x0d, 0xa0, 0x42, 0x36, 0x64, 0xdf, 0xd3, 0x96, 0xb6, 0xd9, 0x81, 0xfa, 0xbe, 0xa6, 0x91, 0x4c, - 0x55, 0xf7, 0x6a, 0x45, 0x32, 0x33, 0x02, 0x57, 0xe0, 0xa1, 0x50, 0x4a, 0x2a, 0x8b, 0xe8, 0xba, - 0x22, 0x0f, 0x50, 0xe3, 0x6f, 0xf8, 0x75, 0x12, 0x25, 0x9d, 0x28, 0x89, 0x23, 0xe9, 0xcb, 0x5f, - 0x52, 0x20, 0x48, 0x98, 0x69, 0xde, 0x4a, 0xae, 0x8b, 0xf9, 0x88, 0x9a, 0xcc, 0x59, 0x2a, 0x47, - 0xd4, 0xcd, 0x33, 0x14, 0x0c, 0x25, 0x17, 0x51, 0x8e, 0x25, 0xac, 0x3b, 0x55, 0x82, 0xf8, 0x03, - 0x12, 0x2a, 0xf3, 0x99, 0x15, 0x5f, 0x7d, 0x15, 0x4e, 0xc5, 0xf2, 0xe6, 0x2d, 0x68, 0x2f, 0xf2, - 0x35, 0x97, 0x20, 0x43, 0xb9, 0x00, 0x99, 0xd1, 0x88, 0x9d, 0x75, 0x0b, 0x73, 0x7b, 0xd3, 0x8d, - 0xfe, 0xa2, 0xe2, 0xdc, 0xc8, 0x93, 0x7a, 0x34, 0x1c, 0x2a, 0x29, 0x87, 0x7e, 0x1a, 0xf2, 0x69, - 0xf0, 0x8d, 0xaf, 0xa5, 0x13, 0x76, 0x7d, 0x34, 0x25, 0x93, 0xd2, 0x01, 0xd2, 0xd0, 0xd5, 0xc0, - 0x59, 0x69, 0x48, 0x43, 0x76, 0x12, 0x09, 0xc1, 0x50, 0xa5, 0x22, 0xd0, 0xf9, 0xb6, 0x33, 0x54, - 0x00, 0x1b, 0xaa, 0xf4, 0x25, 0x0c, 0xe4, 0x87, 0x76, 0x15, 0x0c, 0x9c, 0x69, 0x52, 0x44, 0xa5, - 0x5b, 0xa1, 0x6f, 0x4a, 0xdc, 0x3c, 0x48, 0x53, 0xa0, 0x0c, 0x46, 0x87, 0xbe, 0x7a, 0xa0, 0xe1, - 0xa9, 0x2f, 0xb9, 0x40, 0xc2, 0x20, 0x3a, 0x81, 0x16, 0x85, 0x7f, 0x5d, 0xf8, 0x17, 0x85, 0xff, - 0xbe, 0xf0, 0xaf, 0x8a, 0x89, 0xeb, 0x5e, 0x9b, 0xfc, 0xbb, 0x5f, 0x58, 0xb1, 0x09, 0x99, 0x77, - 0xce, 0xab, 0x31, 0x5c, 0x54, 0x98, 0x0c, 0x42, 0xae, 0xd2, 0x89, 0x66, 0xb2, 0x72, 0xa1, 0xf5, - 0xba, 0xe3, 0x2c, 0xba, 0xcc, 0x36, 0xa8, 0x28, 0x22, 0xb2, 0x40, 0xa3, 0xdc, 0xfa, 0xcc, 0x25, - 0x3c, 0xd8, 0xfa, 0xc8, 0x5d, 0xd3, 0x1d, 0xaf, 0xac, 0xae, 0x88, 0x0d, 0x4d, 0x2b, 0xbc, 0x1c, - 0xc1, 0x49, 0x58, 0x46, 0xf0, 0xf8, 0xc7, 0x3a, 0xcc, 0x6e, 0x4f, 0xe9, 0x95, 0x02, 0x32, 0xff, - 0x8e, 0xed, 0x1b, 0xf3, 0x7c, 0x4d, 0x0c, 0x6f, 0x9e, 0x49, 0xea, 0x4d, 0x3e, 0x16, 0x4e, 0xcc, - 0x81, 0xcf, 0x31, 0xdc, 0x88, 0x6e, 0x09, 0xe6, 0xb8, 0xb8, 0x25, 0x72, 0x7a, 0x92, 0xb9, 0x9e, - 0xe5, 0xe1, 0xee, 0x7c, 0xf7, 0xd3, 0x8f, 0xcf, 0x39, 0xa2, 0x39, 0x86, 0x2b, 0x0f, 0x17, 0xce, - 0x39, 0xca, 0x85, 0xd1, 0xd6, 0xe0, 0x5a, 0x27, 0x00, 0x85, 0xc9, 0xd2, 0xbc, 0x62, 0x50, 0x81, - 0x09, 0xc0, 0x7f, 0x01, 0xc2, 0xd0, 0x35, 0xde, 0x66, 0x28, 0x2f, 0x64, 0xd1, 0xc2, 0x68, 0x60, - 0xbe, 0x2f, 0xf0, 0xa8, 0x73, 0x2f, 0x8a, 0xc9, 0x1d, 0xe3, 0xd5, 0x65, 0xe1, 0x3f, 0x2f, 0x37, - 0x6e, 0x70, 0x55, 0xf8, 0xeb, 0x28, 0x00, 0x81, 0x64, 0xe5, 0xeb, 0xeb, 0x5e, 0x41, 0xe1, 0xff, - 0x40, 0xd8, 0x1a, 0x7c, 0xed, 0x9f, 0x12, 0x46, 0x20, 0x33, 0xff, 0x33, 0x22, 0x53, 0xf0, 0x4f, - 0x54, 0x4b, 0x47, 0x71, 0x70, 0x27, 0x23, 0xf9, 0xbd, 0x03, 0x49, 0xfc, 0xaf, 0x3e, 0x2f, 0xe7, - 0xb3, 0x6c, 0xfe, 0x06, 0xc4, 0xd9, 0xe0, 0x7b, 0x9f, 0xdc, 0x9c, 0xde, 0x21, 0x87, 0xff, 0x0f, - 0xfe, 0xfd, 0x43, 0xb8, 0x79, 0x09, 0x0d, 0xff, 0xe2, 0x83, 0x4c, 0xfa, 0x36, 0x85, 0xaf, 0xe0, - 0xd7, 0xad, 0x7f, 0x1d, 0x66, 0x39, 0xe1, 0x25, 0x45, 0x00, 0x05, 0x01, 0x1f, 0x5d, 0xe0, 0xab, - 0x1c, 0x80, 0x0e, 0x4d, 0x47, 0x31, 0xe2, 0x40, 0x78, 0xf4, 0x7b, 0xa3, 0xa3, 0xf7, 0xa5, 0x3b, - 0x56, 0xe1, 0xe1, 0x09, 0x03, 0x13, 0x44, 0x9a, 0x0f, 0xe9, 0xf2, 0x12, 0x0b, 0xac, 0xc9, 0x05, - 0x85, 0x30, 0x28, 0x40, 0x6e, 0x0c, 0x17, 0x6f, 0x68, 0x43, 0xe7, 0x93, 0xf7, 0x88, 0xb2, 0x5b, - 0x7c, 0x6f, 0x50, 0x06, 0x21, 0xfd, 0x0b, 0x9e, 0x18, 0x74, 0xc3, 0x41, 0x5c, 0xcb, 0x90, 0xa2, - 0x18, 0xea, 0x25, 0x0f, 0x06, 0x03, 0x23, 0xb4, 0x68, 0x3e, 0x05, 0xd0, 0x14, 0x45, 0x3e, 0xa0, - 0xd7, 0x02, 0xe8, 0x86, 0x44, 0x35, 0xc0, 0x28, 0xa1, 0xfc, 0xef, 0x11, 0x60, 0xb4, 0xf8, 0xd4, - 0x00, 0xa3, 0x4e, 0x39, 0x07, 0x38, 0x03, 0xbc, 0x20, 0xec, 0x97, 0x09, 0xd8, 0xda, 0x3d, 0x41, - 0x47, 0x0d, 0x8d, 0x39, 0xcd, 0xa1, 0x64, 0x73, 0x86, 0xe3, 0xe4, 0xa8, 0x50, 0xfc, 0x4c, 0xa2, - 0xc2, 0x92, 0x64, 0x64, 0xee, 0x1d, 0x67, 0xfd, 0x30, 0x01, 0x64, 0x26, 0x67, 0x9e, 0x89, 0xf9, - 0x81, 0xa1, 0xcb, 0x7c, 0x0a, 0x41, 0xa4, 0x9d, 0x7d, 0xe8, 0xa4, 0x67, 0x2d, 0x41, 0x44, 0x81, - 0xad, 0xdc, 0xac, 0x7f, 0x93, 0x45, 0x85, 0xcc, 0xf3, 0x1a, 0x35, 0xfe, 0xc8, 0xb9, 0x66, 0x74, - 0x55, 0x1d, 0x38, 0xc4, 0x2d, 0xef, 0xdd, 0x3b, 0xa0, 0x47, 0xcf, 0x4f, 0x4f, 0x03, 0xba, 0xb8, - 0xb6, 0xbe, 0x9a, 0x31, 0x5d, 0x1c, 0x3d, 0xf1, 0x6f, 0x30, 0x4c, 0x1b, 0xfa, 0x14, 0x8d, 0x79, - 0xe8, 0xa6, 0x26, 0x41, 0x39, 0x87, 0xf0, 0x5d, 0xbb, 0x93, 0xd0, 0x14, 0x13, 0x99, 0xa0, 0x99, - 0x64, 0x82, 0x60, 0x20, 0x03, 0xd4, 0x1c, 0xa0, 0x88, 0x59, 0x70, 0x88, 0x38, 0x4d, 0x32, 0xc8, - 0xa5, 0xaa, 0xad, 0x03, 0xc0, 0x53, 0x8c, 0xd9, 0xda, 0x94, 0x0b, 0xbf, 0x01, 0x8d, 0x79, 0xa6, - 0x5b, 0x38, 0xd8, 0xda, 0xcb, 0xb0, 0xc5, 0x67, 0xeb, 0x4f, 0x9b, 0xca, 0xd8, 0x52, 0x1a, 0x9e, - 0x62, 0xf3, 0xa6, 0x62, 0x18, 0x29, 0x0f, 0x6f, 0x8e, 0xe2, 0x15, 0x37, 0x28, 0x13, 0x4f, 0x28, - 0xe0, 0xe7, 0x4f, 0xd9, 0x3b, 0x85, 0x86, 0xc1, 0xda, 0x67, 0x64, 0x0d, 0x22, 0x9f, 0xc3, 0xa0, - 0x04, 0xed, 0x23, 0x7a, 0x4d, 0x05, 0x1e, 0x3c, 0x38, 0xe0, 0x1f, 0xd0, 0xfd, 0xeb, 0xe9, 0x6b, - 0xea, 0x9c, 0x0d, 0x3a, 0x41, 0xea, 0xcb, 0x20, 0x62, 0x3b, 0x1a, 0xf9, 0x96, 0x4b, 0x6c, 0x35, - 0x26, 0xee, 0x28, 0xfb, 0xbd, 0xcc, 0x01, 0x20, 0xe0, 0x3c, 0x83, 0xa9, 0x9f, 0xc8, 0xc9, 0x04, - 0x73, 0x3f, 0x64, 0xa2, 0xdd, 0x54, 0x1d, 0xa7, 0x2d, 0x69, 0x3a, 0x2a, 0x97, 0xae, 0x77, 0x15, - 0xbb, 0x96, 0x85, 0xae, 0x56, 0xc5, 0x6d, 0x53, 0xa1, 0x35, 0xfc, 0x46, 0x39, 0x83, 0xfe, 0x99, - 0xd2, 0xdf, 0x39, 0x5e, 0xb1, 0x04, 0x30, 0x84, 0x3a, 0x62, 0x50, 0xe4, 0xe2, 0x15, 0xe0, 0x03, - 0x89, 0xc0, 0x80, 0xad, 0x39, 0x24, 0xc8, 0xdc, 0xed, 0xd6, 0x8c, 0x4c, 0x4a, 0x88, 0x15, 0x2d, - 0xdd, 0xd1, 0x71, 0xa1, 0xe4, 0x6e, 0xb3, 0x53, 0x46, 0x70, 0xc7, 0x51, 0x92, 0x5a, 0x88, 0xd7, - 0x1e, 0x50, 0x67, 0x37, 0x70, 0x4f, 0x82, 0xbf, 0xf5, 0xdd, 0xbf, 0x2d, 0xba, 0x68, 0xd3, 0x3b, - 0x09, 0xce, 0xc2, 0x17, 0xe7, 0xee, 0x59, 0xb7, 0x77, 0x7e, 0xc2, 0x49, 0x5f, 0x0f, 0xca, 0xb0, - 0x58, 0x27, 0x5a, 0xdf, 0x38, 0xf4, 0xdd, 0xe2, 0x6c, 0x74, 0x7e, 0x82, 0x7f, 0x74, 0xd0, 0x21, - 0xaf, 0x07, 0x89, 0x87, 0xe7, 0x27, 0x5d, 0xfc, 0x1b, 0xa0, 0xdd, 0x6f, 0xb8, 0x35, 0xbc, 0x57, - 0x0d, 0x97, 0x56, 0x0c, 0xe9, 0xf7, 0x7d, 0xb4, 0x09, 0x17, 0x74, 0x75, 0xa6, 0xae, 0xab, 0x0c, - 0x07, 0x85, 0xf7, 0xb0, 0x50, 0x19, 0x06, 0x69, 0x31, 0xe2, 0xa9, 0x86, 0x78, 0x3d, 0xc8, 0xb5, - 0x37, 0x16, 0xb9, 0x9f, 0x55, 0xb6, 0x93, 0x61, 0x31, 0x44, 0x75, 0xa4, 0xb4, 0x1a, 0x3e, 0x9f, - 0x26, 0x49, 0x5a, 0x88, 0x39, 0x3d, 0x82, 0x2a, 0x1f, 0xd2, 0x9b, 0xc2, 0x7f, 0xba, 0x33, 0x07, - 0x78, 0x36, 0xa6, 0x6c, 0x89, 0xe7, 0xc7, 0x7d, 0x89, 0x14, 0x00, 0xb7, 0x13, 0x29, 0x42, 0xd1, - 0xf7, 0x24, 0x0c, 0xe2, 0xbe, 0xbc, 0x03, 0x48, 0x97, 0xb5, 0xad, 0xcc, 0xd6, 0x43, 0xdf, 0x6c, - 0xd1, 0xac, 0x01, 0x2d, 0x40, 0x06, 0x62, 0x8c, 0x95, 0xdc, 0xcf, 0x34, 0xc5, 0xd5, 0x7d, 0x30, - 0x01, 0x6c, 0x52, 0xcc, 0x29, 0xf6, 0x1c, 0x55, 0x60, 0x6e, 0x09, 0xde, 0x6c, 0x82, 0x3e, 0x4a, - 0x67, 0xe4, 0x90, 0x8f, 0x6f, 0x14, 0xe0, 0xed, 0x49, 0x22, 0x9a, 0x41, 0x15, 0x4f, 0xb2, 0xc9, - 0xe8, 0xa8, 0x2a, 0xbb, 0x1a, 0x81, 0x94, 0x4a, 0xb9, 0x15, 0x10, 0xc0, 0xfc, 0x08, 0xee, 0x90, - 0x74, 0xd1, 0xbd, 0x64, 0x58, 0x08, 0x35, 0x11, 0x44, 0x6c, 0x03, 0x46, 0x27, 0x6b, 0x79, 0x1d, - 0x07, 0x9f, 0x50, 0x71, 0x9b, 0x21, 0xf4, 0x2c, 0x8e, 0x5d, 0xb3, 0x4a, 0x18, 0x74, 0x48, 0x0e, - 0x39, 0x33, 0xdf, 0xd4, 0x39, 0xef, 0x00, 0x82, 0x59, 0x0b, 0xb3, 0x9e, 0x9c, 0x85, 0xe7, 0x01, - 0x07, 0x44, 0xc6, 0xbd, 0x5c, 0xeb, 0x2d, 0xc4, 0x0a, 0x53, 0x49, 0xd9, 0x30, 0xd6, 0xd4, 0x24, - 0xec, 0xf3, 0x03, 0xc2, 0xae, 0x6e, 0x88, 0xd7, 0x86, 0x46, 0xbe, 0xf6, 0x3c, 0x83, 0xf6, 0x4a, - 0x95, 0x7b, 0x23, 0xc0, 0xc7, 0x16, 0x12, 0x44, 0x7d, 0x3a, 0x2f, 0x1e, 0x3c, 0x40, 0x9c, 0xfb, - 0x71, 0x5d, 0x90, 0x62, 0xfb, 0xa7, 0x59, 0x1e, 0x66, 0xc0, 0x92, 0x58, 0x12, 0x89, 0x31, 0xb6, - 0xa2, 0x59, 0x13, 0x66, 0x96, 0x40, 0x2d, 0x06, 0x87, 0x79, 0xcb, 0x9b, 0x0b, 0x1b, 0x48, 0x65, - 0xc6, 0x18, 0x33, 0xce, 0x1c, 0x73, 0x2f, 0x59, 0x14, 0xff, 0x9e, 0xd5, 0x00, 0xb0, 0x00, 0x3e, - 0xcd, 0xe3, 0x35, 0xf4, 0x2d, 0x1d, 0x20, 0x59, 0x65, 0x8e, 0x6d, 0x53, 0xb4, 0x3c, 0x8f, 0xa7, - 0x8b, 0x7c, 0x55, 0x84, 0x5a, 0x37, 0xf8, 0x5f, 0x3f, 0xe5, 0x39, 0x97, 0xed, 0xe2, 0xdb, 0xc0, - 0x20, 0xe5, 0x21, 0xa7, 0x4b, 0xc4, 0x16, 0x0e, 0xda, 0x7c, 0x3d, 0x2b, 0xb2, 0x90, 0x1c, 0x76, - 0x35, 0xa5, 0x58, 0xdb, 0xa2, 0x5b, 0x68, 0x79, 0x60, 0xf2, 0xce, 0xa7, 0xdb, 0x8f, 0x8c, 0xcb, - 0x61, 0x82, 0x07, 0x3d, 0x08, 0xa8, 0xc0, 0x3a, 0x05, 0xb5, 0xf9, 0x39, 0xc0, 0x06, 0x97, 0x17, - 0x84, 0x81, 0x3f, 0xd0, 0x83, 0x51, 0x3f, 0x24, 0x41, 0x47, 0x25, 0x32, 0x60, 0x84, 0xdc, 0x20, - 0xac, 0x54, 0xaf, 0xec, 0x0f, 0xef, 0x2e, 0xe9, 0xcb, 0xde, 0xec, 0x6d, 0xd8, 0x67, 0xc6, 0xa1, - 0xb2, 0xff, 0x65, 0x8c, 0x5f, 0xbc, 0x78, 0xc9, 0xb0, 0x9c, 0xc8, 0xbb, 0x1b, 0x0d, 0x85, 0x6e, - 0xc2, 0xd9, 0xff, 0x44, 0xc5, 0xbb, 0x7d, 0x8a, 0xd2, 0x74, 0x9e, 0xd1, 0x88, 0x26, 0xce, 0xd5, - 0x34, 0x89, 0x56, 0xeb, 0x98, 0x6d, 0x27, 0x72, 0xe3, 0xeb, 0xb0, 0xa6, 0x2e, 0x45, 0x44, 0x6a, - 0x26, 0x24, 0xac, 0xc9, 0xd3, 0x40, 0x84, 0x75, 0x2d, 0xb2, 0xf4, 0x76, 0x9f, 0x29, 0x1b, 0xcd, - 0x8f, 0xda, 0x9b, 0xe7, 0xf0, 0x00, 0xaa, 0x79, 0x5d, 0xa7, 0x8d, 0xe6, 0x14, 0x4a, 0x5b, 0x1e, - 0x9e, 0x38, 0xd5, 0x1b, 0xfa, 0x4e, 0xe0, 0x34, 0xdc, 0xaa, 0x77, 0xc6, 0x67, 0xd6, 0xd5, 0x6f, - 0xf3, 0xe2, 0x77, 0x79, 0xed, 0xbb, 0x41, 0xc7, 0x8d, 0x4a, 0x2b, 0x35, 0x62, 0x60, 0x35, 0x01, - 0x9d, 0x1a, 0x30, 0x8d, 0x22, 0xcc, 0x12, 0x0b, 0x72, 0x30, 0x32, 0x91, 0x0d, 0x70, 0xac, 0x69, - 0x0a, 0x78, 0xf0, 0x68, 0x40, 0x01, 0x8b, 0x0a, 0x3b, 0xf1, 0x9a, 0xa9, 0x52, 0x8d, 0x84, 0xa0, - 0x9d, 0x0f, 0x16, 0x11, 0x08, 0x67, 0x08, 0xc2, 0x11, 0xc5, 0x45, 0xac, 0xdc, 0x83, 0x06, 0x32, - 0x6d, 0x9c, 0x95, 0x14, 0xd0, 0xa6, 0x8c, 0x75, 0xeb, 0x5c, 0x45, 0xb0, 0xd0, 0x40, 0x53, 0xd1, - 0x25, 0x75, 0x57, 0xb1, 0xe9, 0x86, 0x8a, 0xa1, 0xdf, 0xc2, 0x74, 0x57, 0x41, 0x7c, 0x9e, 0x83, - 0x4b, 0xa2, 0x77, 0x71, 0xdb, 0xed, 0x6a, 0x7f, 0x89, 0x3e, 0xa8, 0x83, 0x39, 0x2b, 0x5a, 0x1e, - 0x5a, 0xc8, 0x5f, 0xf2, 0xca, 0x83, 0x43, 0xf2, 0x4e, 0x55, 0xfb, 0x78, 0x78, 0xec, 0x16, 0x76, - 0xb5, 0xb5, 0xba, 0xdd, 0xdd, 0x9b, 0x93, 0xcd, 0x13, 0x18, 0x8c, 0x62, 0x32, 0x44, 0x1f, 0x85, - 0x23, 0x8a, 0xbc, 0x34, 0x21, 0x9f, 0x9f, 0x27, 0xc3, 0xe3, 0xe2, 0xa4, 0xe8, 0x4d, 0xd0, 0x66, - 0xd9, 0x3b, 0x7c, 0x08, 0xbc, 0xc0, 0x32, 0x78, 0x22, 0x4b, 0x74, 0x27, 0x87, 0xd0, 0x7b, 0xef, - 0xc9, 0x10, 0x12, 0x41, 0xa2, 0xed, 0x02, 0x39, 0xe2, 0x3b, 0x7e, 0x69, 0x2f, 0xf2, 0xfc, 0x69, - 0xb9, 0x52, 0x79, 0xf3, 0x4a, 0x19, 0xe8, 0x5c, 0x2e, 0x12, 0xf1, 0x5c, 0xbc, 0x24, 0x7d, 0x19, - 0x9a, 0x63, 0x41, 0xde, 0x3b, 0xd5, 0x6b, 0xec, 0xbe, 0x2e, 0x26, 0x7d, 0x48, 0xa5, 0x59, 0x14, - 0x0d, 0x2f, 0x35, 0x56, 0x04, 0xb9, 0x7b, 0xc5, 0x8b, 0x91, 0xc3, 0xd2, 0x35, 0x93, 0xe6, 0x71, - 0x48, 0xea, 0x2b, 0x3c, 0x23, 0x38, 0x09, 0x5d, 0x26, 0x5d, 0x8d, 0x13, 0x25, 0xf2, 0x72, 0x0c, - 0x77, 0x38, 0xf3, 0x4e, 0x1c, 0xa9, 0x7b, 0x0c, 0xa4, 0xfa, 0x0e, 0x8e, 0xf5, 0xed, 0x39, 0x05, - 0x99, 0xcf, 0x4c, 0xa7, 0x25, 0x00, 0x08, 0xa5, 0x01, 0x09, 0xf6, 0x39, 0x64, 0x7b, 0xe6, 0xaf, - 0x51, 0xef, 0xe4, 0xb1, 0x50, 0x3a, 0x58, 0x4d, 0x2f, 0x42, 0x81, 0xcf, 0x57, 0x90, 0x6f, 0x53, - 0x2e, 0x26, 0x82, 0x1e, 0xd5, 0xf5, 0x45, 0x92, 0xbe, 0x0e, 0x6f, 0x4e, 0xc3, 0x0b, 0x9d, 0x34, - 0xe6, 0x32, 0x51, 0xfe, 0x53, 0x62, 0x94, 0x8a, 0x9f, 0x95, 0x1f, 0x51, 0xfe, 0xea, 0xba, 0xfc, - 0xc2, 0x68, 0x55, 0xa7, 0x30, 0x68, 0x3b, 0xe5, 0xed, 0x05, 0xc6, 0xdc, 0xc2, 0x62, 0x20, 0x11, - 0x51, 0x9d, 0xbf, 0x5c, 0xcc, 0x6e, 0x2a, 0x7d, 0xdc, 0xe0, 0xf3, 0xc1, 0xd8, 0xf1, 0xd9, 0xd0, - 0x87, 0xff, 0x9d, 0xcb, 0x64, 0x90, 0x58, 0xa7, 0x20, 0x4e, 0x60, 0x8b, 0x67, 0x54, 0x5c, 0x65, - 0x24, 0xf1, 0x77, 0xeb, 0x0c, 0x52, 0x9f, 0x0e, 0x65, 0x02, 0x3f, 0xfa, 0x18, 0x2e, 0xbe, 0xdf, - 0x40, 0xaa, 0x4a, 0x9c, 0x43, 0xaa, 0xf1, 0x89, 0xef, 0x17, 0x2d, 0xf8, 0x15, 0xa2, 0xdc, 0x2c, - 0xc5, 0x2f, 0x10, 0xc8, 0xe7, 0x89, 0x26, 0xa2, 0x37, 0x92, 0x19, 0x18, 0x76, 0x8e, 0x55, 0x9b, - 0x66, 0x23, 0xe1, 0xc5, 0x73, 0x54, 0xca, 0x60, 0x92, 0x2f, 0x00, 0x49, 0xcc, 0xaf, 0xf4, 0x06, - 0x68, 0xe8, 0xbb, 0x04, 0x83, 0x56, 0x70, 0x0a, 0x6c, 0x41, 0x80, 0xa8, 0x51, 0x7d, 0x45, 0xef, - 0x71, 0x57, 0x66, 0x8f, 0x85, 0xd5, 0x51, 0x04, 0x49, 0x24, 0x3d, 0x0a, 0x22, 0xa4, 0x38, 0xce, - 0x52, 0xd6, 0xee, 0x13, 0xcf, 0xe6, 0x36, 0x72, 0x42, 0xbe, 0xb8, 0xa3, 0x05, 0x96, 0x73, 0xc2, - 0x37, 0x9d, 0xa1, 0x2e, 0xe2, 0x1c, 0x3e, 0x57, 0x62, 0x28, 0x64, 0x5c, 0xe7, 0x2b, 0xf9, 0xe0, - 0x33, 0x54, 0xf9, 0xf2, 0x0b, 0x56, 0x34, 0x8a, 0xc3, 0xa7, 0x43, 0x1f, 0x3e, 0x6c, 0x6d, 0x1f, - 0x0f, 0xf2, 0xcb, 0x2f, 0x64, 0xc3, 0x9a, 0xf3, 0x66, 0x4d, 0xe3, 0x5f, 0xd1, 0x09, 0x24, 0x8a, - 0xa3, 0xe2, 0x56, 0xba, 0x59, 0x7b, 0xd8, 0x5e, 0xb4, 0x14, 0xee, 0x81, 0x3e, 0x60, 0x2f, 0x23, - 0xe0, 0x57, 0x12, 0xf1, 0xe0, 0x01, 0x8d, 0xe4, 0x3b, 0x04, 0x25, 0x14, 0xeb, 0x99, 0xa0, 0x3d, - 0x16, 0x8f, 0x86, 0xb0, 0xe3, 0xb1, 0x6e, 0x16, 0x02, 0xd7, 0x91, 0x17, 0x7f, 0xce, 0x53, 0x62, - 0xab, 0x08, 0x61, 0xb0, 0xeb, 0x2d, 0xfd, 0x67, 0x0c, 0x20, 0x4d, 0x50, 0xa7, 0xc5, 0x1d, 0xa2, - 0x0d, 0xc9, 0x35, 0x66, 0x4e, 0xc0, 0xc4, 0x0d, 0x29, 0x0f, 0xf5, 0x6f, 0x6f, 0x5f, 0x2e, 0xdc, - 0xce, 0x3c, 0x8f, 0x3b, 0x5e, 0x19, 0x7f, 0x16, 0xda, 0x4a, 0x33, 0xe1, 0x46, 0xb4, 0x32, 0x22, - 0x12, 0x47, 0x50, 0x4f, 0xe9, 0x21, 0x04, 0x9a, 0xde, 0xb0, 0xe5, 0xf9, 0x02, 0xed, 0x6f, 0x7c, - 0xe2, 0x96, 0xef, 0xcb, 0xf2, 0x33, 0xa9, 0x13, 0x41, 0x5e, 0xc5, 0xb0, 0xc4, 0xf8, 0x9f, 0xe7, - 0xf0, 0x28, 0xed, 0x87, 0x5f, 0xbf, 0xfc, 0x42, 0xbe, 0x12, 0x29, 0x1f, 0xd0, 0xe1, 0x34, 0x42, - 0xb3, 0x77, 0x45, 0x14, 0xd3, 0xa0, 0x69, 0xa1, 0xfa, 0x30, 0x5f, 0x53, 0xcd, 0x6e, 0xb0, 0x68, - 0x34, 0x43, 0xf5, 0xfa, 0xb5, 0x86, 0x07, 0xfe, 0x29, 0x5f, 0xb7, 0x70, 0x0d, 0xb8, 0xf9, 0xe2, - 0xf0, 0x09, 0xe6, 0x2e, 0xea, 0x41, 0x6e, 0xd8, 0x6b, 0x87, 0x16, 0x4c, 0x99, 0x31, 0x5a, 0x56, - 0xd2, 0xe7, 0x85, 0x67, 0xa0, 0xd6, 0x60, 0xe9, 0xcc, 0xaf, 0x1d, 0x4f, 0x82, 0x45, 0xde, 0x6b, - 0x9d, 0x0c, 0xc7, 0xd5, 0x25, 0xaa, 0x4c, 0xbd, 0x98, 0xce, 0x5e, 0x7a, 0x5f, 0x7e, 0x01, 0xb3, - 0x51, 0xcf, 0x09, 0x55, 0x96, 0x29, 0xff, 0xf6, 0xf6, 0xb9, 0x0a, 0xdb, 0xee, 0x96, 0x6f, 0x0e, - 0x79, 0x0d, 0x4b, 0xa5, 0x32, 0x6b, 0x0b, 0xa6, 0x32, 0x70, 0xd9, 0x74, 0x0c, 0x78, 0x24, 0x3c, - 0x4d, 0xe9, 0x3a, 0x40, 0xbe, 0x23, 0xa6, 0x64, 0xb7, 0x41, 0x1f, 0x37, 0x47, 0xa2, 0x1b, 0x62, - 0x31, 0x6f, 0x55, 0x4f, 0xf0, 0x49, 0x36, 0x36, 0x9a, 0xc7, 0xc9, 0x98, 0x3d, 0x74, 0x01, 0x1b, - 0x54, 0x23, 0x35, 0x40, 0xa8, 0xb7, 0x92, 0x08, 0x02, 0x6a, 0x87, 0xd4, 0xda, 0x66, 0x3f, 0x32, - 0x51, 0x3e, 0x43, 0xe9, 0xeb, 0x51, 0x43, 0x6e, 0x44, 0x4a, 0x52, 0x9e, 0xc9, 0x4b, 0xf8, 0x7e, - 0xff, 0x9c, 0x7b, 0xc7, 0xb5, 0xed, 0xf3, 0xd3, 0x68, 0x6e, 0x27, 0xbf, 0x4a, 0xd3, 0xe2, 0xb2, - 0x63, 0x2c, 0x1e, 0x14, 0xe3, 0x65, 0xa2, 0xf7, 0xe8, 0xa4, 0xce, 0xab, 0xd3, 0xeb, 0x45, 0x50, - 0x88, 0x9b, 0x6c, 0x40, 0x52, 0x1a, 0xa7, 0x9a, 0x05, 0x71, 0x2b, 0x8c, 0x65, 0x63, 0x63, 0x4e, - 0xf9, 0x65, 0x7a, 0xf3, 0x16, 0x9f, 0x66, 0x72, 0x29, 0x3c, 0xa0, 0x08, 0x51, 0xa2, 0x56, 0x44, - 0x8d, 0x26, 0x49, 0x01, 0x7c, 0x9a, 0x76, 0xa2, 0x7c, 0xd2, 0x09, 0x7b, 0xd8, 0x94, 0x8f, 0x43, - 0xe0, 0xd4, 0xa0, 0x25, 0x4a, 0x34, 0x57, 0x8e, 0x1b, 0x3e, 0x11, 0x0e, 0xfd, 0x80, 0xb3, 0x0f, - 0x7b, 0x46, 0x18, 0xcf, 0xe3, 0x70, 0x9a, 0x29, 0xfc, 0x97, 0x23, 0xe4, 0x36, 0x79, 0xc6, 0xc0, - 0x13, 0x5f, 0x11, 0x47, 0x0c, 0x8d, 0x74, 0x90, 0x8f, 0xee, 0x50, 0x26, 0x7b, 0x16, 0xb2, 0x41, - 0xa2, 0xa5, 0x34, 0x71, 0x69, 0x02, 0x56, 0x9b, 0x1b, 0x85, 0x14, 0x63, 0xa7, 0x19, 0x4c, 0xb1, - 0xb0, 0x47, 0xba, 0x69, 0xc2, 0x2c, 0x1a, 0x2d, 0xa3, 0x95, 0x00, 0x7a, 0x76, 0xf8, 0xa7, 0xe1, - 0xd0, 0xab, 0x21, 0x08, 0x16, 0x22, 0x95, 0x04, 0x43, 0x94, 0xb7, 0xbc, 0x06, 0x70, 0xe7, 0x79, - 0x0a, 0x40, 0x92, 0x81, 0x8a, 0x52, 0x41, 0xb7, 0xcd, 0x01, 0xce, 0x11, 0x9c, 0x3c, 0x7d, 0xf1, - 0x06, 0xa0, 0x80, 0x97, 0x9d, 0xc2, 0x25, 0x50, 0x95, 0x4b, 0x51, 0x5c, 0x86, 0x02, 0x8f, 0xf7, - 0xbe, 0x78, 0xb9, 0xa4, 0x8f, 0x28, 0xcf, 0xd7, 0xf4, 0x74, 0x5c, 0x0e, 0x88, 0x92, 0xfb, 0x50, - 0x70, 0x06, 0x38, 0x22, 0x6e, 0x53, 0x38, 0x3c, 0x5f, 0x9c, 0xbe, 0xe9, 0x77, 0x2c, 0x1a, 0xab, - 0x47, 0x44, 0xc0, 0xad, 0x0e, 0xa9, 0x75, 0x25, 0x2d, 0x30, 0xec, 0x51, 0xaa, 0x04, 0x0f, 0x2f, - 0xaa, 0xb1, 0xed, 0x8c, 0x31, 0xac, 0x52, 0x92, 0x69, 0x42, 0xf5, 0x46, 0x99, 0x9b, 0x33, 0xf9, - 0x20, 0x1a, 0x8f, 0xeb, 0xe4, 0x38, 0x44, 0x04, 0x2f, 0x76, 0x9c, 0xbf, 0x7c, 0x6a, 0x21, 0xf5, - 0xb8, 0xc5, 0xbb, 0x44, 0x68, 0x7c, 0xbe, 0xe0, 0x56, 0x54, 0xbd, 0x6e, 0x57, 0x1f, 0x1c, 0xa8, - 0x31, 0x9a, 0x50, 0x91, 0xb3, 0x5b, 0xc5, 0x66, 0x20, 0xd1, 0xd1, 0x17, 0xaa, 0xb1, 0x40, 0x3f, - 0x5a, 0xe0, 0x50, 0x71, 0x0b, 0x43, 0xde, 0xc4, 0xea, 0xd1, 0xab, 0xf6, 0x1f, 0x75, 0x47, 0xd4, - 0x3a, 0x0c, 0x17, 0x28, 0xc4, 0x07, 0xeb, 0x69, 0xde, 0xf0, 0xc2, 0x69, 0x79, 0x2e, 0x31, 0x9f, - 0x5f, 0xfe, 0xc6, 0xef, 0x40, 0xf2, 0xcc, 0xc5, 0xd7, 0x77, 0xd1, 0x76, 0xe7, 0x7b, 0x89, 0xd0, - 0x18, 0x96, 0xa1, 0xe7, 0xb5, 0xcd, 0xa7, 0x8b, 0x63, 0x68, 0xc1, 0xc5, 0x1c, 0xcf, 0xc1, 0x46, - 0x70, 0xf8, 0xc8, 0x10, 0xc1, 0x6e, 0x52, 0x81, 0x83, 0x03, 0xc7, 0xd9, 0xb6, 0x3f, 0xa7, 0x88, - 0x23, 0x69, 0x78, 0x4f, 0x71, 0xe7, 0x9b, 0xcc, 0x62, 0x19, 0x67, 0xd0, 0x99, 0x62, 0xdc, 0x80, - 0xe2, 0xd2, 0xee, 0xdd, 0xac, 0xa8, 0x2f, 0x3d, 0xde, 0x10, 0x87, 0x65, 0x3c, 0x28, 0xc7, 0xe5, - 0xe5, 0x60, 0xf9, 0xe1, 0xba, 0x3f, 0x35, 0xbe, 0x93, 0x1d, 0x5e, 0xc0, 0x42, 0x36, 0xb5, 0x4f, - 0x9f, 0x76, 0x27, 0xd4, 0x07, 0x36, 0x40, 0x66, 0x00, 0xfa, 0x41, 0x6f, 0x54, 0x16, 0x8b, 0x63, - 0xba, 0xef, 0x2e, 0x5e, 0xbd, 0xf8, 0xee, 0x68, 0x00, 0x5f, 0x2a, 0x2d, 0x5d, 0x99, 0x49, 0x03, - 0x59, 0x5a, 0xd5, 0x91, 0x2b, 0x60, 0x3f, 0x7e, 0x88, 0xfc, 0x60, 0x62, 0x2f, 0xc3, 0xce, 0xf7, - 0x10, 0xbf, 0xbe, 0x53, 0x2c, 0x63, 0x6f, 0xb4, 0xd5, 0xaf, 0x21, 0xaa, 0xd5, 0xc1, 0x51, 0x6d, - 0x6b, 0xaf, 0x4c, 0xbf, 0x0a, 0x13, 0x05, 0x19, 0x63, 0xb8, 0x7b, 0x0e, 0x67, 0xf7, 0xf3, 0x8c, - 0xe5, 0x70, 0x1a, 0x06, 0x93, 0xae, 0xf6, 0x1a, 0x8b, 0x84, 0xd3, 0xa0, 0x84, 0x72, 0x0d, 0xdc, - 0xff, 0x0d, 0x9c, 0xd3, 0x0a, 0xc4, 0x49, 0x13, 0xda, 0xc8, 0x39, 0x94, 0x29, 0x9f, 0x09, 0xec, - 0x8b, 0x6c, 0xb5, 0xf3, 0xad, 0x4e, 0x7a, 0x8e, 0xdb, 0x9e, 0x17, 0x54, 0xf9, 0x9d, 0x41, 0x9c, - 0xaf, 0xe6, 0x3b, 0x81, 0xdc, 0x30, 0x08, 0xa8, 0xf2, 0x79, 0xb0, 0x35, 0xf6, 0xc2, 0xa5, 0x98, - 0xad, 0xac, 0x71, 0x00, 0x3b, 0xe4, 0x1c, 0x1b, 0xab, 0x07, 0x7c, 0xb6, 0x81, 0x56, 0x88, 0xda, - 0x6d, 0x99, 0xc0, 0x84, 0x8f, 0x70, 0x1f, 0xe5, 0xb4, 0x81, 0x04, 0x8c, 0x82, 0xc3, 0x7f, 0x84, - 0xc0, 0xa5, 0xba, 0xcd, 0x55, 0xbc, 0x81, 0xab, 0xc0, 0x29, 0xba, 0x42, 0x4d, 0x0a, 0x84, 0x52, - 0x71, 0x1d, 0x65, 0xc5, 0x7a, 0x1a, 0x7b, 0xfa, 0xd1, 0xc6, 0x1d, 0xd4, 0x62, 0x9e, 0x2c, 0xf5, - 0x14, 0xe6, 0x15, 0x9a, 0x80, 0x9e, 0x42, 0x9a, 0x80, 0x49, 0x9a, 0x30, 0x54, 0x34, 0x61, 0x47, - 0x9b, 0x0b, 0xa4, 0x83, 0xb2, 0xcd, 0x45, 0xa5, 0xcd, 0x85, 0x49, 0x14, 0xf9, 0xa5, 0xca, 0x47, - 0x7f, 0x54, 0x6d, 0x36, 0x10, 0x63, 0x90, 0xfd, 0x15, 0x39, 0xfe, 0x4b, 0x88, 0xd6, 0xe4, 0x50, - 0x2c, 0x94, 0xb7, 0xc3, 0x3e, 0x34, 0x19, 0xea, 0x57, 0x9e, 0x93, 0x87, 0x66, 0x2a, 0x34, 0x19, - 0xca, 0xfc, 0x1e, 0x34, 0xd9, 0x7a, 0x48, 0x15, 0x5f, 0x71, 0xfd, 0xa0, 0xce, 0xd4, 0xba, 0x34, - 0x24, 0xdf, 0x53, 0xef, 0x78, 0x16, 0x07, 0x36, 0x4f, 0xe4, 0xd1, 0x66, 0x9d, 0x63, 0xc7, 0x13, - 0x29, 0xc5, 0x36, 0x73, 0x01, 0x1d, 0xf9, 0xe6, 0x7a, 0xa5, 0xad, 0x4e, 0xf5, 0x21, 0xe1, 0x1f, - 0xa7, 0x9b, 0xe8, 0x6a, 0x7d, 0x25, 0x78, 0x87, 0x88, 0x74, 0xa9, 0x5f, 0x11, 0x16, 0x18, 0x85, - 0xf4, 0x12, 0xd8, 0x19, 0x39, 0x2b, 0xe4, 0xd4, 0x4c, 0x5d, 0x04, 0x72, 0x28, 0x38, 0x15, 0x21, - 0xc3, 0x11, 0x08, 0x57, 0xe7, 0x4a, 0xa9, 0xd1, 0x14, 0xa8, 0x9a, 0xb4, 0x18, 0x35, 0xf9, 0x51, - 0xb2, 0xbc, 0x19, 0xb0, 0x51, 0x6e, 0x58, 0xf2, 0x15, 0xab, 0x2c, 0xbd, 0x80, 0xd6, 0xb0, 0x6a, - 0xc8, 0xda, 0x1d, 0xf1, 0x70, 0x34, 0x1c, 0x0a, 0xbc, 0x82, 0x07, 0xcd, 0x18, 0xd9, 0x9a, 0x29, - 0x50, 0x69, 0x9e, 0xe4, 0x18, 0xa0, 0x16, 0x64, 0x7f, 0xe0, 0xbb, 0x30, 0xbd, 0x0b, 0x75, 0xe7, - 0xe1, 0x4f, 0xc3, 0x45, 0x78, 0xe1, 0xb3, 0x9a, 0x03, 0xd6, 0x5d, 0xd5, 0xda, 0xfe, 0xc1, 0x17, - 0x5f, 0x3d, 0x7e, 0xfc, 0xd8, 0x4a, 0xf2, 0x70, 0xe1, 0x42, 0xf3, 0xe5, 0x95, 0x16, 0x29, 0xa9, - 0xc3, 0x58, 0x2f, 0x5d, 0x76, 0x3a, 0xde, 0xd9, 0xb0, 0x2e, 0xad, 0xc2, 0x60, 0x60, 0x48, 0x2d, - 0xd2, 0x19, 0x12, 0x1c, 0x83, 0xad, 0x62, 0x52, 0x60, 0x4c, 0xae, 0xb6, 0xd8, 0x1f, 0x08, 0xad, - 0xf3, 0x6d, 0xfe, 0xc1, 0x63, 0xf8, 0xa8, 0x69, 0x13, 0x79, 0xd8, 0xab, 0x6a, 0x58, 0xad, 0x0a, - 0x54, 0x0b, 0x79, 0x6c, 0xa6, 0x2f, 0x34, 0x04, 0x99, 0xc1, 0xcc, 0xb7, 0xe3, 0x72, 0x50, 0x79, - 0xcf, 0x91, 0xb8, 0x09, 0xc5, 0x81, 0x5a, 0xd1, 0xca, 0x73, 0x89, 0x0f, 0x78, 0x88, 0x25, 0x44, - 0xdf, 0xf2, 0x0f, 0x36, 0xa2, 0x50, 0xdb, 0x13, 0xab, 0xb4, 0x33, 0xc2, 0x82, 0x8e, 0x04, 0x08, - 0x16, 0x6a, 0x1d, 0x2a, 0x90, 0xb6, 0x0f, 0x9e, 0x38, 0x60, 0x91, 0xa0, 0x04, 0x13, 0x52, 0xbc, - 0x7d, 0x66, 0x4a, 0xd5, 0x2b, 0x60, 0x5a, 0xcd, 0xf7, 0x83, 0xef, 0x6a, 0x6e, 0x56, 0xc5, 0x51, - 0x52, 0xaf, 0xc0, 0xd3, 0x7a, 0xb2, 0x7f, 0xa5, 0xa4, 0x42, 0x6a, 0x0b, 0x9f, 0x25, 0xbd, 0x86, - 0x39, 0x0f, 0x5c, 0xa6, 0xca, 0x44, 0x90, 0x65, 0xfd, 0x03, 0xb6, 0xa8, 0x63, 0x71, 0x0f, 0xf5, - 0x31, 0x54, 0x04, 0xc9, 0xfe, 0xc7, 0x8f, 0x34, 0xac, 0x63, 0x68, 0xda, 0x23, 0x98, 0x23, 0xaf, - 0x8a, 0x47, 0x00, 0x16, 0x2d, 0xa9, 0x79, 0x3b, 0x35, 0x51, 0x83, 0x86, 0x8e, 0x3f, 0xd8, 0x44, - 0x80, 0xa5, 0xc6, 0x26, 0xcc, 0x7b, 0xf7, 0xd2, 0x65, 0x80, 0xd6, 0xe9, 0x09, 0x3f, 0x07, 0xfc, - 0x06, 0x5f, 0x7b, 0xeb, 0xd8, 0xb2, 0x85, 0x8b, 0x9a, 0x48, 0x0f, 0x69, 0xa5, 0x94, 0xb5, 0x03, - 0x92, 0x01, 0xda, 0x9a, 0x78, 0x1d, 0x57, 0xeb, 0x27, 0xf1, 0xb3, 0xfd, 0xab, 0x9f, 0xde, 0x26, - 0xf3, 0x6a, 0x03, 0x4a, 0xc3, 0x59, 0x6f, 0xa5, 0xa9, 0x9d, 0xe5, 0x66, 0xd6, 0xc1, 0x55, 0xd0, - 0xaa, 0x49, 0xaf, 0x5d, 0x99, 0xf4, 0x15, 0x5e, 0x7f, 0x2c, 0x85, 0x71, 0xa2, 0x4c, 0x0d, 0xb4, - 0x96, 0x36, 0xfc, 0xb7, 0x59, 0xd4, 0xf1, 0xbc, 0x3d, 0x0b, 0x9f, 0xae, 0xc2, 0x70, 0xb1, 0x7f, - 0xf1, 0x97, 0xa8, 0x7c, 0xc8, 0xa3, 0xe2, 0x76, 0xff, 0x2a, 0x3f, 0x77, 0x34, 0x92, 0xb1, 0x6e, - 0xd7, 0x6b, 0xd0, 0xbf, 0xdd, 0xdc, 0x64, 0xd3, 0x55, 0x47, 0x01, 0x40, 0x92, 0x2c, 0x9c, 0x38, - 0xfb, 0x19, 0x6a, 0x29, 0x6c, 0x56, 0x24, 0xb9, 0xa1, 0x0d, 0x6d, 0x55, 0x10, 0xad, 0x40, 0x9e, - 0x6d, 0x54, 0x0e, 0x61, 0x03, 0x35, 0xc5, 0x10, 0x26, 0x56, 0x95, 0x42, 0xb5, 0xb4, 0x76, 0x85, - 0x10, 0x4e, 0xcd, 0xb5, 0xb4, 0xc7, 0xc7, 0xc7, 0x22, 0x82, 0x6d, 0x24, 0x86, 0x9b, 0x21, 0x10, - 0x97, 0x7a, 0xf3, 0xa4, 0x11, 0x02, 0x9a, 0x96, 0xc1, 0x81, 0x5e, 0x6a, 0x94, 0x6c, 0x4d, 0x33, - 0xec, 0x38, 0xdc, 0x88, 0x76, 0xe2, 0xd1, 0xc4, 0x9c, 0x81, 0x6c, 0xda, 0x2e, 0xd2, 0x1b, 0xed, - 0xd0, 0x3d, 0x81, 0x68, 0xbb, 0xa2, 0x23, 0xa8, 0x2e, 0x88, 0x33, 0x1e, 0xbe, 0x99, 0x02, 0x35, - 0xc5, 0xdb, 0x38, 0x63, 0x2e, 0xda, 0x8a, 0x92, 0x2e, 0xe7, 0x4a, 0xe4, 0x7d, 0x89, 0xce, 0x70, - 0x44, 0x24, 0x10, 0xf5, 0x09, 0x5b, 0x03, 0xe7, 0x2b, 0xbc, 0x94, 0x5b, 0xdb, 0xe1, 0xe8, 0x28, - 0x08, 0x67, 0x97, 0x3b, 0xf5, 0xc5, 0x4c, 0x2b, 0xbc, 0xa6, 0xf4, 0x46, 0x17, 0xae, 0x0f, 0xfd, - 0xf0, 0xe8, 0xdc, 0x26, 0x0b, 0x11, 0xa9, 0xdb, 0xb7, 0xfa, 0x53, 0x7e, 0x21, 0x2e, 0xfc, 0x3d, - 0x4f, 0x93, 0xb7, 0x75, 0xe5, 0x93, 0xa9, 0x25, 0x86, 0xbe, 0xae, 0x40, 0xf2, 0xf3, 0x05, 0xf0, - 0x66, 0xb3, 0x34, 0x0f, 0x25, 0xbb, 0x40, 0xdd, 0x5a, 0xea, 0x7b, 0xa5, 0x7e, 0x76, 0x35, 0x3d, - 0x34, 0x5a, 0xf7, 0xcc, 0xae, 0x6c, 0x85, 0x8f, 0xad, 0x9c, 0xf1, 0x59, 0x57, 0x2d, 0x49, 0x2f, - 0x0c, 0x44, 0xe9, 0x8b, 0xe0, 0xc0, 0x1e, 0x35, 0xea, 0x9d, 0x97, 0x1b, 0xb4, 0x7b, 0x76, 0xb0, - 0x4a, 0x78, 0xd8, 0x58, 0xc2, 0x5a, 0x96, 0x0e, 0xeb, 0x5c, 0xd7, 0x19, 0x2e, 0xa1, 0x9c, 0x1c, - 0x00, 0xbc, 0x33, 0xc0, 0x01, 0x0e, 0xe8, 0x1e, 0x55, 0x27, 0xe0, 0xaf, 0x0e, 0x95, 0x44, 0xde, - 0xd3, 0x2e, 0xba, 0x4a, 0xa1, 0xbf, 0xa0, 0x03, 0xdd, 0x74, 0xe4, 0x54, 0x65, 0x26, 0x13, 0x5c, - 0xf9, 0xd1, 0x47, 0x83, 0x8c, 0x04, 0x1a, 0x29, 0xa5, 0x71, 0x2a, 0x7f, 0x3e, 0xfd, 0xe9, 0xb5, - 0xf4, 0x62, 0x88, 0x96, 0xb7, 0xba, 0x9e, 0xd4, 0x0e, 0x85, 0x05, 0xfa, 0x24, 0xba, 0x30, 0x36, - 0x32, 0x1c, 0x5c, 0x85, 0xc5, 0x65, 0xba, 0x08, 0x88, 0xfb, 0xf5, 0xbf, 0xfc, 0xe2, 0x32, 0x9c, - 0x02, 0x2d, 0xc8, 0x03, 0xcc, 0x72, 0xa4, 0xe3, 0x69, 0x8f, 0x1e, 0x42, 0x0d, 0x80, 0x54, 0xae, - 0xf0, 0x66, 0x0e, 0x69, 0xd8, 0x68, 0xec, 0x63, 0x01, 0x1c, 0x71, 0x86, 0x97, 0x38, 0xde, 0xbd, - 0xfd, 0xbe, 0xf7, 0x0d, 0x9e, 0xc6, 0xd0, 0x04, 0xba, 0x06, 0x04, 0x08, 0x55, 0xd4, 0x70, 0x7f, - 0xf9, 0x05, 0x3d, 0xee, 0xec, 0x66, 0x68, 0x03, 0x39, 0xd6, 0x96, 0x05, 0xf8, 0xec, 0xa7, 0xbf, - 0x69, 0x1d, 0x99, 0xa9, 0xa4, 0xb2, 0xd0, 0x08, 0xcb, 0x61, 0x4f, 0x9c, 0xac, 0x5b, 0xc3, 0x24, - 0xd9, 0x9c, 0xa5, 0x41, 0x34, 0x91, 0x01, 0x2a, 0xd8, 0xe8, 0x20, 0x57, 0xb8, 0xa6, 0x15, 0x33, - 0x31, 0xc9, 0x33, 0x74, 0xa2, 0x9d, 0x17, 0xe8, 0x3b, 0x82, 0x43, 0x58, 0x81, 0x6c, 0x12, 0x1a, - 0x4a, 0x36, 0x2c, 0x8e, 0xa5, 0xfb, 0xf9, 0x7a, 0x3e, 0x47, 0xae, 0xd1, 0x56, 0x00, 0x23, 0xe5, - 0x23, 0xf0, 0xc8, 0x86, 0xd5, 0x02, 0x68, 0x85, 0xea, 0xa4, 0xd3, 0xf1, 0x6f, 0x27, 0x9d, 0x23, - 0x76, 0x58, 0x57, 0x32, 0xe5, 0xd0, 0x39, 0x96, 0xd6, 0xc9, 0xa3, 0x01, 0xe7, 0x10, 0x0f, 0x4d, - 0x1d, 0x85, 0xcb, 0x25, 0x60, 0x57, 0xae, 0x1f, 0x28, 0x15, 0x83, 0x01, 0x1b, 0xd2, 0x45, 0x9e, - 0x02, 0xf5, 0xd6, 0xf4, 0x33, 0x4a, 0x84, 0x59, 0xde, 0xb3, 0xbe, 0x50, 0xcb, 0x32, 0x11, 0x77, - 0x4e, 0x04, 0xd2, 0x89, 0xa1, 0x0f, 0xf3, 0xba, 0x23, 0xa0, 0x90, 0xb8, 0x9d, 0x9d, 0xa0, 0x52, - 0x7c, 0x5b, 0xeb, 0x3f, 0xcd, 0x0a, 0x57, 0x52, 0x06, 0x83, 0x6c, 0xd7, 0xba, 0x85, 0x99, 0x6e, - 0x90, 0xa6, 0x75, 0x8e, 0xf8, 0x14, 0x56, 0x12, 0x04, 0xd0, 0x41, 0x16, 0xac, 0xf0, 0x50, 0xed, - 0x56, 0x47, 0xd7, 0x8f, 0x16, 0xa2, 0xdb, 0xb1, 0x65, 0xc7, 0x5f, 0xdc, 0xb6, 0x72, 0xde, 0xd8, - 0x39, 0x6e, 0xc8, 0x23, 0x02, 0xd5, 0xed, 0x1c, 0x0d, 0xb8, 0x67, 0x92, 0xa1, 0x3a, 0x8a, 0xba, - 0x51, 0xe1, 0x15, 0x6f, 0xd2, 0x26, 0x68, 0x4a, 0xef, 0xfd, 0xda, 0xc4, 0x54, 0x15, 0xcf, 0xfe, - 0xdc, 0x17, 0xa2, 0x46, 0x79, 0x0d, 0xd2, 0x72, 0x14, 0xbb, 0x61, 0x5a, 0x76, 0x0d, 0x40, 0xbd, - 0x65, 0xa0, 0xda, 0x88, 0xd3, 0xe9, 0x56, 0x3b, 0x01, 0x00, 0x01, 0x1c, 0x8f, 0x1b, 0x32, 0x28, - 0x5a, 0x77, 0xc7, 0x42, 0xb0, 0x2d, 0x52, 0x3d, 0xe3, 0x81, 0xe7, 0xcd, 0x58, 0x84, 0x87, 0xc6, - 0xf7, 0xed, 0x58, 0x08, 0xa5, 0x5b, 0x5d, 0xa6, 0x12, 0xb7, 0xfb, 0xf8, 0x5b, 0xe2, 0x7b, 0xc2, - 0x27, 0x31, 0xa6, 0x50, 0xfb, 0x8d, 0xdc, 0x18, 0x66, 0x90, 0x90, 0x5b, 0x91, 0x30, 0x65, 0x05, - 0x92, 0x07, 0xa9, 0x1d, 0xe0, 0x8e, 0x9d, 0xef, 0xa8, 0xc4, 0x0c, 0xfd, 0x66, 0x90, 0x0b, 0xa9, - 0xf8, 0xf7, 0x28, 0xef, 0x19, 0x15, 0x03, 0x94, 0xac, 0x78, 0x29, 0xdd, 0x46, 0x1a, 0x7d, 0x83, - 0x12, 0x1a, 0xd9, 0xf1, 0x88, 0x91, 0xc1, 0x21, 0xc5, 0x70, 0xa6, 0x7a, 0x6a, 0x90, 0x8e, 0xfb, - 0x8a, 0x3e, 0x1d, 0xe0, 0xe8, 0xf4, 0x58, 0x8b, 0xa8, 0x88, 0x43, 0x63, 0x2c, 0xca, 0xb4, 0xcd, - 0xd5, 0xc3, 0x45, 0xde, 0xbf, 0xb9, 0x86, 0x74, 0xc3, 0x4a, 0x5c, 0xe6, 0xcc, 0x31, 0x05, 0x0f, - 0x61, 0xcb, 0x46, 0x4e, 0xf9, 0x40, 0x82, 0x21, 0x43, 0xdb, 0x8e, 0xcb, 0x3a, 0x90, 0x04, 0xcc, - 0x36, 0x56, 0x52, 0xd0, 0xa4, 0x23, 0x41, 0x72, 0x18, 0x6c, 0xa7, 0xc7, 0xdb, 0xd0, 0x8d, 0x80, - 0x34, 0x98, 0x47, 0xe9, 0xba, 0x00, 0x65, 0x67, 0x59, 0x84, 0x42, 0x33, 0x19, 0xf5, 0xf3, 0x7e, - 0x12, 0x73, 0x65, 0x65, 0x5e, 0xa7, 0x94, 0xc5, 0x3a, 0x93, 0xc3, 0x94, 0xc6, 0xfd, 0xbc, 0xbf, - 0x5e, 0xac, 0xa0, 0x6b, 0xf8, 0xc2, 0x0c, 0xdb, 0xaa, 0x9e, 0xf7, 0x57, 0x39, 0x9a, 0xac, 0xaa, - 0x56, 0x75, 0x4c, 0x6f, 0x1c, 0xd6, 0xfc, 0xf6, 0x2d, 0x19, 0xb0, 0xc8, 0x3c, 0x4b, 0x2a, 0x10, - 0x62, 0x3e, 0xfa, 0xab, 0x18, 0xb8, 0x05, 0x62, 0x37, 0x48, 0x8c, 0x17, 0x81, 0x52, 0x04, 0x34, - 0x35, 0x31, 0xcf, 0xd5, 0xa4, 0xa8, 0xab, 0xf9, 0x3c, 0x59, 0xe2, 0x5d, 0xf8, 0xb6, 0xd2, 0x61, - 0x43, 0xe9, 0xe9, 0xa6, 0xad, 0x74, 0x51, 0x2f, 0x8d, 0xc6, 0x21, 0x31, 0x18, 0x0d, 0x5b, 0xab, - 0xd8, 0x75, 0x08, 0xe3, 0x22, 0xda, 0x7a, 0x5c, 0x49, 0x3b, 0x2d, 0xcc, 0x27, 0xc0, 0xb7, 0xf2, - 0x16, 0x59, 0x90, 0x15, 0xb5, 0xc1, 0xee, 0x61, 0x6d, 0x6d, 0xc3, 0x88, 0x11, 0x2d, 0x5d, 0xb6, - 0x57, 0xa0, 0x95, 0x3a, 0x8c, 0x61, 0x9f, 0x63, 0x83, 0x84, 0x30, 0x8b, 0xb1, 0xe0, 0xeb, 0xf3, - 0x5b, 0xfc, 0x20, 0x2b, 0x87, 0x64, 0xaa, 0x22, 0x69, 0xe3, 0xc0, 0xa2, 0xe7, 0x5a, 0x36, 0xac, - 0x1a, 0x9d, 0x5e, 0xa7, 0x42, 0x0d, 0xe0, 0xc0, 0x38, 0xbf, 0x4a, 0xe1, 0x6d, 0xac, 0x4e, 0xda, - 0xb2, 0xe5, 0x4f, 0xb2, 0xbc, 0x23, 0x5c, 0x0e, 0x81, 0x5e, 0xa0, 0x7a, 0x09, 0x20, 0x10, 0xf6, - 0x7a, 0x92, 0x3d, 0x59, 0x9c, 0x85, 0xf7, 0xd8, 0xdc, 0x71, 0x07, 0xe2, 0x13, 0x4f, 0x31, 0x94, - 0x3c, 0x1b, 0x9e, 0xc3, 0x97, 0xe3, 0x5b, 0x69, 0xa3, 0x86, 0xb4, 0x43, 0x4a, 0x2b, 0xf7, 0xb7, - 0x14, 0x54, 0xd8, 0xef, 0x04, 0x0a, 0x20, 0xd4, 0x54, 0xd9, 0x47, 0xe7, 0x63, 0xcb, 0x94, 0x8f, - 0x6e, 0x24, 0x92, 0xbb, 0xb8, 0x47, 0xca, 0xd2, 0x4b, 0x2e, 0xdb, 0xc5, 0x9a, 0xe7, 0x2d, 0xd2, - 0x61, 0x73, 0xc5, 0xa8, 0x9f, 0x37, 0xe3, 0x61, 0x4d, 0x3c, 0x33, 0xaa, 0x44, 0x9b, 0xdf, 0x43, - 0x02, 0x95, 0xcc, 0xbc, 0xe5, 0x49, 0x13, 0xf5, 0x97, 0x1b, 0x62, 0x5d, 0x8d, 0xde, 0x56, 0xa4, - 0x4f, 0xb2, 0x19, 0x94, 0x7a, 0xd7, 0x2f, 0xf8, 0x60, 0x45, 0x91, 0x6f, 0x9e, 0xa5, 0x71, 0xfc, - 0x36, 0x5d, 0xb5, 0x30, 0xc8, 0xb5, 0x21, 0xb2, 0x91, 0xf6, 0x2d, 0x29, 0x84, 0x76, 0x35, 0xcc, - 0x7e, 0x64, 0x6c, 0xcc, 0x1d, 0x8c, 0xfa, 0xdf, 0x8c, 0x95, 0x46, 0x27, 0xef, 0x93, 0x65, 0xd1, - 0xe2, 0xc9, 0x7e, 0x7e, 0xf5, 0xe2, 0x3b, 0x69, 0x4e, 0xa6, 0xfe, 0xb8, 0x48, 0x0b, 0x6a, 0x13, - 0xc3, 0x38, 0x27, 0xe7, 0x78, 0x2d, 0x76, 0xb8, 0xb2, 0x4d, 0x6b, 0xa3, 0x54, 0x1a, 0xc1, 0x7a, - 0xb6, 0x30, 0xc4, 0xc6, 0x79, 0xd2, 0x66, 0x48, 0xff, 0x18, 0xa6, 0xd2, 0x07, 0xf8, 0xaf, 0x52, - 0x74, 0xcd, 0xfe, 0x4e, 0xcc, 0x00, 0x86, 0xbe, 0x20, 0x6f, 0x2b, 0x3c, 0xea, 0x21, 0xd1, 0x24, - 0x1b, 0xbb, 0xb4, 0x46, 0x36, 0xc1, 0x79, 0x38, 0x92, 0x6e, 0x26, 0xa5, 0x94, 0x04, 0x6d, 0xd5, - 0x0d, 0xac, 0x3c, 0xb2, 0xd7, 0x31, 0x0f, 0x8b, 0x4f, 0x80, 0x03, 0xf8, 0x47, 0x9d, 0xa9, 0xf1, - 0x33, 0x69, 0x2a, 0x35, 0xa8, 0x02, 0x42, 0x9a, 0x2d, 0xd0, 0x2c, 0x71, 0xf6, 0xc5, 0xaf, 0x68, - 0x4a, 0xe6, 0xa4, 0x9b, 0x28, 0x8e, 0x05, 0xdf, 0xaf, 0x5b, 0x2e, 0x05, 0x5d, 0xdf, 0x25, 0x50, - 0xf3, 0x61, 0xd2, 0x85, 0xdf, 0x40, 0x91, 0xf1, 0xd9, 0xd1, 0x3e, 0x49, 0x39, 0x52, 0x4d, 0xd7, - 0xda, 0xc3, 0x22, 0xa4, 0x3e, 0x60, 0x51, 0x16, 0xb2, 0x82, 0x0d, 0xad, 0x24, 0x06, 0x68, 0x49, - 0xa0, 0xc1, 0x60, 0xb7, 0xdb, 0xfd, 0x27, 0x8d, 0xaa, 0x1d, 0x69, 0x67, 0x2f, 0x4f, 0xb5, 0x03, - 0xf5, 0x5b, 0x02, 0x40, 0xeb, 0x7a, 0xaa, 0x50, 0xf8, 0x09, 0x24, 0x09, 0x39, 0xe7, 0x1c, 0x29, - 0x32, 0x1a, 0xda, 0x93, 0xb0, 0xb8, 0x49, 0xb3, 0xdf, 0x18, 0x06, 0x49, 0x7a, 0x43, 0x9e, 0x6f, - 0x68, 0xaf, 0x47, 0xef, 0x40, 0x60, 0x4b, 0xc3, 0x1d, 0x73, 0x7e, 0x8b, 0x45, 0x24, 0x54, 0x61, - 0x24, 0xe9, 0xfd, 0xcd, 0x8b, 0x38, 0xc5, 0x17, 0x6b, 0xa9, 0x93, 0x46, 0xd8, 0xe0, 0xf9, 0x4c, - 0xd0, 0xc1, 0x33, 0x1a, 0x7e, 0xa8, 0xb9, 0x10, 0x90, 0xd4, 0xe4, 0x24, 0xd3, 0xe1, 0x61, 0x2d, - 0x3e, 0xd1, 0x33, 0xe6, 0x41, 0x0c, 0x40, 0xec, 0x09, 0x50, 0x64, 0x8d, 0xae, 0xa3, 0xf0, 0x46, - 0xa1, 0x38, 0x79, 0x05, 0x1e, 0xe0, 0xbf, 0x8d, 0xb4, 0x2c, 0x96, 0xc5, 0x1b, 0xf4, 0x41, 0x2e, - 0x56, 0x22, 0x1d, 0x03, 0x2b, 0x86, 0x64, 0xac, 0xfb, 0x7b, 0x9b, 0xc9, 0xe6, 0x56, 0xe5, 0x81, - 0xca, 0x83, 0x06, 0xa6, 0x33, 0xbc, 0x57, 0x3a, 0x8b, 0xa7, 0xc9, 0x6f, 0x3b, 0xf5, 0x7d, 0x0d, - 0xea, 0x46, 0xd9, 0x9a, 0xa5, 0xe9, 0xb3, 0xe7, 0x7f, 0x35, 0xfd, 0x0d, 0x8f, 0x6a, 0x57, 0xcb, - 0x68, 0x89, 0x72, 0x2d, 0xac, 0x1b, 0x52, 0xc4, 0x50, 0x97, 0x5a, 0x31, 0xce, 0xb5, 0xe8, 0x52, - 0xad, 0x6a, 0xbd, 0x51, 0xa9, 0x33, 0x97, 0xcd, 0x52, 0xed, 0x23, 0xed, 0x7c, 0xe8, 0x71, 0xa7, - 0x2b, 0x5e, 0xb2, 0xad, 0xe1, 0x23, 0xd1, 0xee, 0x73, 0x60, 0xf9, 0x17, 0x98, 0xfd, 0x6d, 0x61, - 0xeb, 0x87, 0x37, 0x9e, 0x65, 0x5a, 0xaa, 0x19, 0xe0, 0xb5, 0xbd, 0xfd, 0x3f, 0x6c, 0x5d, 0xb7, - 0x06, 0xfa, 0x79, 0x86, 0xf6, 0x24, 0x6f, 0x33, 0xbc, 0x5a, 0x8d, 0x7f, 0x86, 0x21, 0xd8, 0xaa, - 0xff, 0x39, 0x66, 0x77, 0x23, 0xed, 0x93, 0x06, 0xb8, 0xd3, 0x48, 0xdc, 0x36, 0x40, 0x69, 0x2c, - 0xd6, 0xa2, 0x49, 0x0f, 0x90, 0x88, 0x6d, 0x28, 0x7b, 0xda, 0x6d, 0xc5, 0xe5, 0x34, 0xb6, 0x8c, - 0xb7, 0x56, 0xf3, 0x4d, 0x76, 0x5c, 0x7b, 0xfc, 0x63, 0x61, 0x1a, 0xee, 0x6a, 0x06, 0x5e, 0xcb, - 0x9c, 0xf9, 0xa1, 0x99, 0x25, 0x6a, 0xb4, 0x3c, 0xce, 0x93, 0xda, 0x26, 0x35, 0x3a, 0x52, 0x1b, - 0x50, 0x6e, 0x8f, 0x9a, 0x92, 0x01, 0x15, 0xae, 0xbd, 0x48, 0x50, 0x70, 0xb2, 0x72, 0x0a, 0x7a, - 0x97, 0x03, 0xd0, 0x2b, 0x50, 0xa1, 0xf2, 0xf0, 0x8b, 0x27, 0x30, 0xfa, 0x66, 0x4a, 0x13, 0x78, - 0xb6, 0x58, 0x28, 0xfb, 0xa6, 0xa5, 0x4f, 0xf8, 0x17, 0x27, 0x22, 0x7d, 0x7a, 0x72, 0xef, 0x4e, - 0x0b, 0x10, 0xed, 0x54, 0x24, 0x47, 0x8f, 0xa0, 0x0f, 0x5a, 0xaa, 0xaa, 0x30, 0x1b, 0x48, 0x0d, - 0x02, 0xa5, 0x81, 0xc8, 0x7d, 0x81, 0xea, 0x61, 0xfc, 0x15, 0xc6, 0xfb, 0x9d, 0xa4, 0x72, 0x55, - 0xcb, 0xa1, 0xfc, 0xc7, 0x8d, 0x87, 0x74, 0x8e, 0x61, 0xd5, 0xa3, 0x09, 0xf7, 0x0e, 0x8b, 0xbb, - 0x50, 0x00, 0x1a, 0x2b, 0xcd, 0xda, 0xf6, 0xde, 0x79, 0xd3, 0xdd, 0x91, 0x80, 0x9b, 0xa0, 0xef, - 0x74, 0x45, 0x9f, 0xe9, 0x4a, 0x1f, 0x97, 0xbb, 0x6d, 0x7c, 0xff, 0x97, 0xa6, 0x41, 0x3c, 0xbb, - 0x21, 0xa7, 0xcf, 0x3d, 0xc3, 0x5f, 0x23, 0x8d, 0x9b, 0x84, 0xbf, 0x4a, 0x33, 0x7a, 0xcf, 0x92, - 0x2e, 0x0c, 0xec, 0x22, 0xe0, 0x2a, 0xe7, 0xba, 0x23, 0x71, 0x58, 0xe1, 0x7b, 0x1d, 0xe0, 0xfb, - 0x80, 0x2b, 0x81, 0xe3, 0x09, 0x78, 0x9c, 0xcb, 0xe9, 0x75, 0x28, 0xae, 0xd6, 0x71, 0x11, 0xad, - 0xe2, 0xb0, 0x34, 0xeb, 0xe3, 0xcb, 0xf5, 0x18, 0x5a, 0x02, 0x8b, 0xc8, 0x87, 0xc1, 0x91, 0x11, - 0x72, 0xaa, 0xb2, 0xa3, 0xf6, 0xe5, 0xca, 0xcf, 0x0d, 0x9b, 0xbd, 0xea, 0xbc, 0xd7, 0xbb, 0x7f, - 0x01, 0x69, 0xc1, 0x86, 0x7b, 0xe3, 0x2d, 0xba, 0x60, 0x68, 0xbc, 0x45, 0xef, 0x8b, 0x1d, 0x5b, - 0x08, 0xb2, 0xf7, 0xdf, 0x42, 0xe8, 0xed, 0x81, 0x0a, 0xec, 0xeb, 0xbd, 0x87, 0xf2, 0x8b, 0x1b, - 0x19, 0xfa, 0xdd, 0x6a, 0xc3, 0xcb, 0x8d, 0xa5, 0x1d, 0x84, 0x92, 0x7b, 0x37, 0x2c, 0xed, 0x09, - 0x6e, 0x89, 0x9b, 0xd5, 0xc6, 0x41, 0x8c, 0x33, 0x5b, 0xbf, 0xd7, 0x30, 0x21, 0x71, 0x6e, 0xef, - 0x11, 0x7c, 0x9b, 0x45, 0x6e, 0x6d, 0x66, 0xb3, 0x2c, 0xba, 0xa7, 0xd3, 0xaa, 0x92, 0xca, 0xfb, - 0x8f, 0x08, 0x43, 0x48, 0xcd, 0x50, 0x12, 0xaf, 0x8f, 0x58, 0x81, 0x2b, 0xdf, 0xec, 0x33, 0x70, - 0x4b, 0x9c, 0xdf, 0x1f, 0x56, 0x5a, 0xac, 0x6f, 0xef, 0x3f, 0xda, 0xab, 0xff, 0x9a, 0x7e, 0x60, - 0xcf, 0x31, 0x30, 0x1b, 0xff, 0xfc, 0xd7, 0x7a, 0xff, 0xab, 0xd8, 0x11, 0x01, 0x32, 0xa1, 0x6d, - 0xa4, 0xb0, 0x41, 0x81, 0xc7, 0x48, 0x67, 0xb4, 0x10, 0xa0, 0x77, 0xae, 0x83, 0x9a, 0x33, 0x9a, - 0x0b, 0xde, 0x5f, 0xdb, 0x39, 0x19, 0x53, 0xa1, 0xe7, 0x41, 0x4d, 0xbc, 0xc9, 0x76, 0x5f, 0x85, - 0xd0, 0xac, 0x80, 0xfa, 0xb9, 0x7b, 0x6b, 0x58, 0x58, 0xb2, 0xfd, 0x3d, 0xf0, 0x8c, 0x80, 0xba, - 0x27, 0xb0, 0xdf, 0x9c, 0x32, 0xb0, 0xe9, 0x0a, 0xd6, 0x01, 0x29, 0x47, 0xff, 0x9d, 0x26, 0x70, - 0x92, 0x1b, 0xf2, 0x16, 0x6b, 0x38, 0x9b, 0xab, 0xa7, 0xd7, 0x18, 0x5f, 0xc6, 0x12, 0x53, 0x3f, - 0xd5, 0x70, 0x2e, 0xdb, 0x30, 0x5c, 0xba, 0x9b, 0x7d, 0x46, 0x60, 0xf0, 0xaf, 0x50, 0xba, 0x70, - 0x6c, 0x96, 0x87, 0x46, 0x08, 0x02, 0xd7, 0x29, 0x9e, 0x28, 0x70, 0x6c, 0xe4, 0x71, 0x0a, 0x47, - 0xb3, 0x83, 0x97, 0x7d, 0x04, 0x5e, 0x4f, 0xe6, 0x84, 0x46, 0x7a, 0x47, 0x3c, 0x9e, 0x1b, 0xd5, - 0xf1, 0x37, 0x47, 0xa5, 0xca, 0xb6, 0xc5, 0x88, 0xef, 0x46, 0xbd, 0x91, 0x57, 0x1a, 0xf2, 0xed, - 0x33, 0xee, 0x15, 0x47, 0xdc, 0x11, 0x7c, 0xc7, 0xb1, 0x1c, 0x00, 0xd9, 0x00, 0x22, 0xd1, 0x75, - 0xf8, 0x2c, 0x6b, 0x12, 0xea, 0x9d, 0x53, 0xb3, 0x9c, 0x00, 0x01, 0x9f, 0xee, 0x93, 0x1f, 0x88, - 0x77, 0x18, 0x17, 0x85, 0x80, 0x84, 0xc1, 0x59, 0x78, 0x92, 0x34, 0x59, 0x90, 0xf2, 0xa5, 0xca, - 0x5c, 0xf5, 0x07, 0x59, 0x51, 0xd1, 0xb7, 0x6e, 0xa4, 0xf0, 0xfa, 0x95, 0x53, 0x9b, 0xa2, 0x54, - 0x0a, 0xb3, 0x1b, 0xdb, 0x7d, 0x73, 0xfb, 0x65, 0x33, 0x4d, 0x83, 0xde, 0x8b, 0x30, 0x69, 0x15, - 0x28, 0x1b, 0xf2, 0xe5, 0x7d, 0xba, 0xd9, 0xf8, 0xdf, 0x7b, 0xd5, 0x8a, 0xb8, 0x86, 0x89, 0x73, - 0xb8, 0xda, 0xb0, 0x91, 0x92, 0xb5, 0xa9, 0x74, 0xeb, 0xc3, 0x28, 0xc6, 0x61, 0x8a, 0x27, 0xce, - 0x93, 0xd5, 0xa6, 0x9a, 0xc5, 0xc1, 0x99, 0x9d, 0xc7, 0x87, 0x9c, 0xb5, 0xa5, 0x5c, 0xd2, 0xc5, - 0x56, 0xba, 0x78, 0xd2, 0xd8, 0x85, 0x59, 0x52, 0xf5, 0x72, 0xa8, 0x7b, 0x31, 0x73, 0x65, 0x47, - 0x4f, 0x86, 0x9c, 0x4b, 0xc6, 0x76, 0xba, 0xd0, 0xc5, 0x51, 0xd5, 0xf4, 0x9b, 0x12, 0xe2, 0x60, - 0x02, 0xfc, 0x7c, 0x65, 0x0c, 0xb6, 0x0a, 0x96, 0xc1, 0x60, 0x54, 0x46, 0x74, 0xbe, 0xa7, 0xca, - 0x6e, 0x9d, 0xf4, 0xcf, 0xed, 0xfa, 0xe8, 0x4f, 0x70, 0xeb, 0xd1, 0xd7, 0x80, 0xd0, 0x9d, 0xe2, - 0x52, 0xea, 0x36, 0xca, 0x5b, 0x1a, 0xcf, 0x5d, 0x18, 0xad, 0x32, 0x47, 0xa0, 0xab, 0x41, 0x8c, - 0x5e, 0x6a, 0x4e, 0x96, 0x2c, 0x1c, 0xe5, 0x6f, 0x80, 0x28, 0x73, 0x77, 0x49, 0x47, 0x40, 0x4e, - 0x7f, 0xaf, 0x03, 0x7c, 0xd1, 0x11, 0x91, 0x16, 0x32, 0xfb, 0xb9, 0xf2, 0x5e, 0xe3, 0xd7, 0x90, - 0xec, 0xf7, 0xb6, 0xc5, 0x43, 0xf1, 0x64, 0xe8, 0x01, 0xe6, 0x3e, 0x21, 0xfa, 0xba, 0x48, 0x05, - 0x37, 0xd9, 0xbf, 0xb4, 0x6b, 0x55, 0x2b, 0xe1, 0x9b, 0x02, 0xb4, 0x35, 0x61, 0xe2, 0xc0, 0x93, - 0x72, 0xfe, 0x74, 0x96, 0xbb, 0x5c, 0x97, 0x2f, 0x20, 0x5e, 0x7a, 0x80, 0x8c, 0xdc, 0xb0, 0x9a, - 0x1c, 0x65, 0x4b, 0x94, 0xa9, 0xae, 0x45, 0x1a, 0xcb, 0x6b, 0x77, 0x7c, 0x19, 0x4f, 0xdf, 0xb2, - 0xaa, 0xd1, 0x22, 0x99, 0x8f, 0x11, 0x92, 0xe9, 0xa2, 0x65, 0x29, 0x74, 0xee, 0xb9, 0x61, 0x10, - 0x92, 0x65, 0x75, 0x72, 0x12, 0xda, 0x89, 0x08, 0x08, 0xf2, 0x8e, 0x79, 0x1d, 0xb1, 0xe3, 0x89, - 0xca, 0xf0, 0xe5, 0x73, 0x59, 0x6e, 0xe7, 0x32, 0xbf, 0xee, 0xf8, 0xa2, 0x83, 0x7f, 0x46, 0xec, - 0xca, 0x72, 0x5f, 0xdb, 0xa2, 0x11, 0xa5, 0xc7, 0x78, 0x5b, 0xb4, 0x44, 0xaa, 0x66, 0xd7, 0x16, - 0x1b, 0x0f, 0x15, 0xd9, 0x20, 0x8c, 0xa8, 0x34, 0xda, 0xc2, 0x5a, 0x43, 0x3e, 0xfc, 0x7b, 0x76, - 0x86, 0xeb, 0x92, 0xf9, 0xb4, 0x3c, 0x17, 0xfc, 0xcf, 0xcc, 0xb7, 0x90, 0xfa, 0xdc, 0x3f, 0xc3, - 0xff, 0xce, 0xb5, 0xc8, 0xc6, 0xb4, 0x4a, 0xfb, 0x7e, 0xb6, 0xb4, 0x0b, 0x75, 0xf6, 0x6a, 0x9a, - 0xdb, 0x35, 0x3c, 0x4b, 0x55, 0xf3, 0x87, 0xf7, 0x35, 0xbf, 0x57, 0x0f, 0xb2, 0xf9, 0x7f, 0x9d, - 0x01, 0x69, 0xe6, 0xd0, 0x1a, 0x39, 0x79, 0x71, 0x2c, 0x9e, 0xb4, 0xba, 0x74, 0x37, 0x95, 0xe7, - 0xad, 0xaf, 0x84, 0x4b, 0xf6, 0x32, 0x1b, 0xee, 0x79, 0x94, 0xc8, 0xfb, 0x3d, 0x11, 0xd3, 0x04, - 0xf3, 0xf6, 0x0e, 0xf0, 0x3e, 0xc6, 0x67, 0x9b, 0x7a, 0xa4, 0x23, 0xba, 0x51, 0x83, 0xb2, 0xd8, - 0xa8, 0xb9, 0xa7, 0xce, 0x18, 0xef, 0x1e, 0x99, 0x8d, 0x99, 0xbe, 0x00, 0xb5, 0xe6, 0x2a, 0xbe, - 0x01, 0x81, 0x4a, 0xe0, 0xcf, 0x9a, 0x67, 0x6b, 0xb2, 0x04, 0x96, 0x2d, 0xe7, 0x78, 0x76, 0x79, - 0xdb, 0xa5, 0x39, 0x2d, 0xe0, 0x00, 0xeb, 0x33, 0x8b, 0xd7, 0x99, 0xeb, 0x35, 0x8d, 0xd3, 0x31, - 0xc4, 0x89, 0x7d, 0x0a, 0x6a, 0xbe, 0xdf, 0x2c, 0x4c, 0xc3, 0x1b, 0x0c, 0xb0, 0x04, 0x9e, 0x41, - 0xef, 0x5e, 0xaa, 0xab, 0xe5, 0xef, 0x9f, 0x9b, 0xfc, 0xa5, 0x1d, 0x99, 0xa8, 0x83, 0x21, 0x1d, - 0x8a, 0x69, 0x94, 0xa0, 0xfb, 0xad, 0x2f, 0x5e, 0x43, 0xc9, 0xc7, 0xc4, 0x9a, 0x02, 0x32, 0x08, - 0x7d, 0x0f, 0x15, 0xa8, 0xcc, 0x66, 0x28, 0x5d, 0xa3, 0x7c, 0x71, 0x5b, 0xfe, 0x64, 0x63, 0xdf, - 0xa9, 0x90, 0xf7, 0xf1, 0xa4, 0x39, 0x5f, 0x86, 0x03, 0xb8, 0x19, 0x57, 0x00, 0x86, 0x5e, 0x66, - 0xe8, 0xac, 0xf7, 0x5f, 0x2a, 0x3c, 0x77, 0x25, 0x12, 0x06, 0x2c, 0x42, 0x43, 0x70, 0x0c, 0x90, - 0x47, 0x42, 0x61, 0xc3, 0x1e, 0x7b, 0x72, 0xc3, 0xdd, 0xd7, 0x6b, 0x11, 0x5f, 0x75, 0xec, 0x06, - 0x7d, 0x7d, 0x56, 0x69, 0xea, 0xd5, 0xb4, 0x73, 0xb7, 0x23, 0xf5, 0xbb, 0x40, 0x44, 0x3f, 0x7e, - 0x14, 0x66, 0x46, 0xf3, 0x1b, 0xc3, 0x2d, 0xe5, 0xac, 0xc7, 0x0c, 0xa0, 0xcc, 0x8e, 0x42, 0x70, - 0xd2, 0x96, 0x43, 0x25, 0xb8, 0x2a, 0xd0, 0xa8, 0x58, 0x19, 0x90, 0x7e, 0xdb, 0x90, 0xfe, 0x2b, - 0x1e, 0x48, 0x1a, 0xe2, 0x3b, 0xaf, 0x53, 0xcb, 0x6b, 0xc5, 0x8e, 0x77, 0xc6, 0x8b, 0x78, 0x5e, - 0xda, 0x65, 0x69, 0x55, 0x76, 0x5f, 0x29, 0x3e, 0x70, 0xf5, 0x5a, 0x92, 0xad, 0xb3, 0x66, 0xe7, - 0x5c, 0x64, 0xd3, 0x0b, 0x63, 0x01, 0x0e, 0x64, 0x71, 0x98, 0x73, 0x6d, 0x2d, 0xaa, 0x34, 0xea, - 0x53, 0x86, 0x8a, 0xde, 0xf8, 0x72, 0xc2, 0xd4, 0x17, 0xfa, 0x5e, 0x61, 0x04, 0x4d, 0x61, 0x2a, - 0x94, 0x10, 0xe9, 0xb1, 0x13, 0x7d, 0xe8, 0x57, 0xa1, 0x09, 0xe7, 0xff, 0x06, 0xb8, 0x8a, 0x63, - 0xd1, 0x56, 0xe2, 0x57, 0x28, 0x71, 0x8b, 0xfe, 0xf0, 0x77, 0xaa, 0x2d, 0x7c, 0x1e, 0x20, 0x99, - 0xa3, 0x23, 0x52, 0x0c, 0x73, 0xa9, 0x47, 0x05, 0x19, 0x63, 0xc1, 0xad, 0x04, 0x64, 0xe3, 0xa5, - 0xeb, 0x62, 0x03, 0x70, 0xfc, 0x20, 0x6f, 0x56, 0x71, 0x8c, 0xb3, 0xe6, 0x71, 0x6d, 0x57, 0x9b, - 0x0f, 0x35, 0xf8, 0xca, 0x89, 0x32, 0x7c, 0x77, 0x82, 0x97, 0x02, 0x4a, 0x6c, 0x1a, 0x70, 0x88, - 0x5a, 0xf7, 0x85, 0xe6, 0xb7, 0x28, 0x7a, 0xd5, 0x62, 0x03, 0x9b, 0x1c, 0xfa, 0x81, 0xc4, 0xae, - 0x9b, 0x3f, 0x5c, 0x6c, 0x06, 0x37, 0x9e, 0x8e, 0xcc, 0x76, 0xc8, 0xde, 0xa8, 0xf8, 0xf0, 0x93, - 0xdc, 0xf9, 0xe8, 0xb3, 0x8c, 0x17, 0x06, 0xd8, 0x35, 0x07, 0xaf, 0x11, 0xc8, 0x8c, 0x23, 0xa0, - 0x14, 0x3d, 0x79, 0x9b, 0x80, 0x2d, 0x5d, 0x90, 0xb9, 0x84, 0x5f, 0xfd, 0x11, 0x1f, 0x91, 0xf7, - 0xdf, 0x45, 0x17, 0x3d, 0x58, 0x5b, 0x92, 0x67, 0x61, 0x30, 0x23, 0x68, 0x6d, 0x39, 0xae, 0x5d, - 0x4e, 0x2f, 0x6f, 0xad, 0xdf, 0x0f, 0xeb, 0x0e, 0x70, 0xe5, 0x9d, 0x5d, 0xd7, 0xe0, 0x97, 0x78, - 0x57, 0x5e, 0x16, 0xd8, 0x0f, 0xf7, 0x99, 0xe7, 0xf3, 0xd4, 0x2e, 0x45, 0x92, 0x57, 0xe3, 0xff, - 0x28, 0x1c, 0x85, 0xb8, 0x03, 0xa0, 0xa2, 0x27, 0xd8, 0x4d, 0x04, 0x3c, 0xe9, 0x0d, 0x0b, 0xb9, - 0xfc, 0x66, 0xb5, 0xd8, 0x31, 0xec, 0x15, 0x74, 0x57, 0x3f, 0xb3, 0x8a, 0x74, 0x55, 0xf1, 0x76, - 0x40, 0x5f, 0x16, 0x10, 0x39, 0x76, 0x4d, 0x6e, 0x56, 0x34, 0xb6, 0x35, 0x4b, 0x8b, 0xf6, 0xb6, - 0x10, 0xd1, 0x6f, 0x60, 0x29, 0x47, 0x87, 0xc8, 0x74, 0x4b, 0x35, 0x05, 0xe1, 0x97, 0xdb, 0xaa, - 0xc5, 0x90, 0xd9, 0x5a, 0x02, 0x50, 0xf5, 0x71, 0xfd, 0x0f, 0x6a, 0xc8, 0xa9, 0x82, 0x21, 0x10, - 0xb3, 0xa2, 0x63, 0xa1, 0xc8, 0x72, 0xb5, 0x11, 0xd4, 0x82, 0xa5, 0x34, 0xc5, 0xd3, 0x68, 0xbd, - 0x41, 0x32, 0xbf, 0xaa, 0x1a, 0x74, 0xd5, 0x70, 0xaa, 0x26, 0x5d, 0xe3, 0xc8, 0xa0, 0x79, 0x68, - 0x98, 0x92, 0x7c, 0x07, 0x35, 0x3b, 0xf8, 0x02, 0x7d, 0xc7, 0x92, 0xf5, 0xeb, 0x65, 0x1e, 0xab, - 0x32, 0x12, 0x52, 0x3a, 0x30, 0x49, 0xdb, 0x12, 0x25, 0xb0, 0x42, 0xaf, 0x79, 0x8b, 0x49, 0x34, - 0xa9, 0xc5, 0xec, 0xe8, 0x70, 0x8c, 0x7c, 0x28, 0x88, 0xff, 0x58, 0x71, 0x39, 0xa0, 0xd5, 0x7a, - 0xf1, 0xab, 0x14, 0x8d, 0x6b, 0xe9, 0x0d, 0x36, 0x8d, 0x58, 0x6b, 0x07, 0x83, 0xa8, 0x97, 0x2f, - 0xa3, 0x67, 0xd5, 0x2b, 0xec, 0xea, 0x02, 0xc9, 0x11, 0xe2, 0x17, 0x50, 0xfd, 0xbd, 0xba, 0x68, - 0x2e, 0xbf, 0xab, 0x87, 0x74, 0x8d, 0x43, 0xc2, 0x7a, 0xf7, 0x75, 0x40, 0xc5, 0xd7, 0xab, 0x3d, - 0x4b, 0xab, 0xc8, 0x4a, 0xf5, 0xe2, 0x47, 0x03, 0x38, 0x59, 0xa2, 0x55, 0x41, 0x56, 0x47, 0xf4, - 0x45, 0xa7, 0x1f, 0x97, 0xc5, 0x55, 0x7c, 0xfc, 0xbf, 0x9e, 0x8c, 0x6f, 0xef, 0xb7, 0x13, 0x01, - 0x00, + 0x1f, 0x8b, 0x08, 0x08, 0x3e, 0xb4, 0xac, 0x5e, 0x00, 0x03, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2d, + 0x69, 0x33, 0x2e, 0x68, 0x74, 0x6d, 0x00, 0xcc, 0x7c, 0x6b, 0x73, 0xe2, 0xc8, 0xb2, 0xe0, 0xf7, + 0x89, 0x98, 0xff, 0xc0, 0x71, 0xc7, 0x6e, 0x77, 0x5f, 0x37, 0x46, 0xe2, 0x65, 0xdc, 0xaf, 0x38, + 0x25, 0x21, 0x9e, 0x16, 0x46, 0x80, 0x04, 0x78, 0xe3, 0x7e, 0x10, 0x42, 0x08, 0x81, 0x40, 0x58, + 0x12, 0x08, 0x98, 0x98, 0xfd, 0xed, 0x9b, 0x59, 0x7a, 0x20, 0x5e, 0xb6, 0x7b, 0xfa, 0x9e, 0x88, + 0x65, 0xa6, 0x81, 0x52, 0x55, 0x65, 0x65, 0xe5, 0x3b, 0xb3, 0xca, 0x7c, 0xff, 0x57, 0xf9, 0x89, + 0xef, 0x0d, 0xdb, 0x42, 0x6a, 0xea, 0x2d, 0xac, 0x9f, 0x7f, 0xfe, 0xf1, 0x3d, 0xfe, 0xd4, 0xd5, + 0x31, 0x7e, 0x2e, 0x74, 0x4f, 0x4d, 0x2d, 0xd5, 0x85, 0xfe, 0xe3, 0x66, 0x63, 0xea, 0xfe, 0xca, + 0x76, 0xbc, 0x9b, 0x94, 0x66, 0x2f, 0x3d, 0x7d, 0xe9, 0xfd, 0xb8, 0xf1, 0xcd, 0xb1, 0x37, 0xfd, + 0x31, 0xd6, 0x37, 0xa6, 0xa6, 0xa7, 0x69, 0xe3, 0x4b, 0xca, 0x5c, 0x9a, 0x9e, 0xa9, 0x5a, 0x69, + 0x57, 0x53, 0x2d, 0xfd, 0x07, 0xfb, 0x25, 0xb5, 0x80, 0x27, 0x8b, 0xf5, 0x22, 0x7a, 0x70, 0x13, + 0x83, 0xd5, 0xa6, 0xaa, 0xe3, 0xea, 0x00, 0x66, 0xed, 0x4d, 0xd2, 0xa5, 0x9b, 0x93, 0xe5, 0xbc, + 0xa9, 0xbe, 0xd0, 0xd3, 0x9a, 0x6d, 0xd9, 0x4e, 0x62, 0xc5, 0x0f, 0x59, 0xfa, 0x4a, 0x00, 0x89, + 0x7a, 0x76, 0xba, 0x7b, 0x13, 0x4e, 0x55, 0x57, 0x2b, 0x4b, 0x4f, 0x2f, 0xec, 0x91, 0x09, 0x1f, + 0xbe, 0x3e, 0x4a, 0xc3, 0x83, 0xb4, 0xa6, 0xae, 0xd4, 0x91, 0xa5, 0xd3, 0x99, 0x96, 0xb9, 0x9c, + 0xa7, 0x1c, 0xdd, 0xfa, 0x71, 0xe3, 0x4e, 0x61, 0x47, 0xda, 0xda, 0x4b, 0x99, 0x00, 0xe8, 0x26, + 0x35, 0x75, 0xf4, 0xc9, 0x8f, 0x9b, 0xb1, 0xea, 0xa9, 0x5f, 0xcd, 0x85, 0x6a, 0xe8, 0x99, 0x6d, + 0x1a, 0x3b, 0xbe, 0x8d, 0x54, 0x57, 0x2f, 0xe6, 0xbf, 0x10, 0x42, 0x38, 0x42, 0x04, 0x22, 0xc0, + 0x3b, 0x7e, 0x56, 0x09, 0x5f, 0xc5, 0x6f, 0x15, 0x03, 0xde, 0xea, 0x96, 0xd4, 0x9b, 0x6b, 0x2d, + 0x7e, 0x6a, 0x37, 0xf1, 0x59, 0x59, 0xb6, 0xea, 0x9d, 0x4a, 0x1d, 0xbf, 0x4a, 0xc1, 0x68, 0x83, + 0x8e, 0xad, 0x65, 0xda, 0x99, 0x21, 0x3e, 0x11, 0xd8, 0x46, 0x47, 0xa8, 0xc8, 0x4f, 0x75, 0x76, + 0x06, 0x8f, 0x32, 0x6d, 0xff, 0x69, 0x6b, 0xb4, 0xaa, 0x3a, 0x91, 0xc5, 0xad, 0xf0, 0x50, 0x2d, + 0x6a, 0x12, 0xdf, 0x2c, 0xf7, 0xc9, 0x74, 0x45, 0xca, 0xcf, 0xd9, 0x49, 0xa9, 0x2d, 0xce, 0xb8, + 0x6e, 0x4e, 0xea, 0x33, 0x25, 0xa9, 0x99, 0x65, 0x9a, 0xea, 0x33, 0x9f, 0x35, 0x26, 0xfc, 0xc3, + 0x94, 0x5f, 0xbe, 0xd8, 0x6b, 0xbb, 0x65, 0x90, 0x8e, 0x31, 0xbc, 0xdf, 0x8b, 0x5b, 0xb2, 0x6b, + 0x59, 0xf2, 0x58, 0xaa, 0x59, 0x03, 0x93, 0x58, 0x4f, 0x59, 0xb1, 0x4c, 0xca, 0xc5, 0x9c, 0xa0, + 0xbc, 0xb4, 0x6a, 0x44, 0x67, 0x08, 0x45, 0xc4, 0xaa, 0xf4, 0xe6, 0xdd, 0xb5, 0xb4, 0xe0, 0xf9, + 0x9b, 0x0c, 0x52, 0xc3, 0x33, 0x3d, 0x4b, 0xff, 0xd9, 0x7f, 0x14, 0xca, 0xdf, 0x33, 0xc1, 0x77, + 0x78, 0xe8, 0x6a, 0x8e, 0xb9, 0xf2, 0x7e, 0x4e, 0xd6, 0x4b, 0xcd, 0x33, 0xed, 0x65, 0x6a, 0xa2, + 0xeb, 0xe3, 0x91, 0xaa, 0xcd, 0x3f, 0x7d, 0xfe, 0xeb, 0xef, 0xef, 0x99, 0xb0, 0x17, 0xc7, 0x79, + 0x3b, 0x3a, 0xe1, 0xdf, 0x13, 0x60, 0x44, 0x7a, 0xa2, 0x6a, 0x7a, 0xea, 0xaf, 0x3f, 0xff, 0x08, + 0x1b, 0x0b, 0xd3, 0xda, 0x7d, 0x4d, 0xdd, 0xf4, 0xeb, 0x40, 0x43, 0xf7, 0xe6, 0xdb, 0x9f, 0x7f, + 0xb8, 0x8e, 0xf6, 0x35, 0xb5, 0x76, 0xac, 0x4f, 0x94, 0xc4, 0xc8, 0x27, 0x53, 0x53, 0x11, 0x3e, + 0x10, 0x9a, 0xce, 0xf1, 0xed, 0xc9, 0xe4, 0x5b, 0x24, 0x18, 0x54, 0x2e, 0x22, 0xda, 0x8f, 0x99, + 0x87, 0x6a, 0xc7, 0x20, 0x94, 0xf2, 0x84, 0x73, 0xe1, 0xcd, 0xa5, 0x5f, 0xab, 0x8e, 0x14, 0x52, + 0xf8, 0xda, 0x8b, 0x6b, 0xcb, 0xbb, 0xd2, 0x0e, 0xbf, 0xf0, 0x74, 0x02, 0x7d, 0x66, 0x94, 0x0b, + 0x0c, 0xa9, 0xf7, 0x5b, 0xde, 0x70, 0x40, 0x39, 0x68, 0xe3, 0xc3, 0x0e, 0x7e, 0x95, 0x3b, 0x13, + 0xce, 0xe8, 0x76, 0x9e, 0xb3, 0x95, 0xbd, 0x86, 0xed, 0x17, 0x1f, 0xdf, 0x29, 0x23, 0xe9, 0x7c, + 0x8e, 0x5b, 0x8e, 0x6a, 0xd6, 0x02, 0x9b, 0x1e, 0xce, 0xec, 0xc3, 0xe2, 0x9c, 0x32, 0x5f, 0x16, + 0x06, 0x2f, 0x99, 0xea, 0xd4, 0x1a, 0xd2, 0xb6, 0x31, 0xc4, 0xa1, 0x2d, 0x94, 0x8b, 0x32, 0xac, + 0x50, 0x14, 0x59, 0x15, 0xfb, 0xa0, 0xab, 0x5a, 0xa1, 0x48, 0xcd, 0xf1, 0xad, 0x41, 0xb4, 0x21, + 0x61, 0x1f, 0xec, 0xd1, 0xa0, 0x93, 0x87, 0xe6, 0x70, 0x8c, 0x0f, 0x9b, 0x38, 0x89, 0xb7, 0x97, + 0x84, 0xf4, 0x72, 0x8b, 0xed, 0x66, 0x98, 0x15, 0x00, 0xde, 0x9c, 0xa2, 0xa2, 0x60, 0x57, 0xe5, + 0xd9, 0x5f, 0x54, 0x5d, 0x63, 0xd4, 0xaf, 0xe4, 0xf1, 0x61, 0x75, 0x40, 0x37, 0x6f, 0x84, 0x48, + 0x32, 0xa4, 0xc2, 0xae, 0x87, 0x7d, 0xd6, 0x82, 0xe6, 0xb3, 0x45, 0xf7, 0x83, 0x5b, 0xab, 0x34, + 0x25, 0xf9, 0x51, 0xca, 0x0f, 0xb8, 0x8d, 0x96, 0x43, 0xfc, 0x1c, 0xe3, 0x68, 0x53, 0x74, 0x8b, + 0x22, 0x2c, 0x54, 0x85, 0x4e, 0x19, 0x91, 0x78, 0x26, 0x2e, 0x3e, 0xe4, 0xdb, 0x64, 0x35, 0xe7, + 0xf7, 0xd8, 0xad, 0xbb, 0x44, 0xf4, 0x85, 0xc6, 0x45, 0x12, 0x77, 0x2e, 0x53, 0x1e, 0x31, 0x2b, + 0x70, 0xa4, 0x2c, 0x66, 0x4a, 0x0c, 0x4c, 0x2e, 0xe3, 0xff, 0x71, 0x47, 0xe2, 0x55, 0x8f, 0xbe, + 0x04, 0x78, 0xe0, 0x9b, 0x86, 0x1a, 0x43, 0xdb, 0x9c, 0x8f, 0x9f, 0x94, 0xef, 0x35, 0x7c, 0xd8, + 0x45, 0xd4, 0xb9, 0x2a, 0x76, 0x73, 0x12, 0x72, 0x53, 0x20, 0xf5, 0x27, 0x92, 0xcb, 0x97, 0x97, + 0x46, 0xfb, 0x89, 0x13, 0xf3, 0xf5, 0x8c, 0x61, 0xaf, 0xf9, 0x55, 0xfe, 0x71, 0x63, 0xb0, 0x4f, + 0xe5, 0x55, 0xbe, 0x33, 0x9a, 0x3e, 0xe9, 0x42, 0x26, 0x3f, 0xd8, 0x4f, 0xcd, 0x75, 0xdd, 0xcb, + 0xcf, 0x72, 0xa6, 0xbd, 0x6e, 0x2e, 0xf2, 0x4e, 0xdb, 0xdc, 0xae, 0x1f, 0xe7, 0xf9, 0xdd, 0x60, + 0x26, 0xde, 0xb6, 0xc4, 0x7c, 0xa1, 0x3c, 0xb3, 0xf4, 0x76, 0x3f, 0x9f, 0xa9, 0xcd, 0x79, 0x5d, + 0x92, 0x32, 0x99, 0x5c, 0x26, 0xe3, 0x87, 0xf8, 0x5d, 0x87, 0x6f, 0x23, 0xfc, 0xd6, 0xed, 0x55, + 0xf8, 0xb3, 0x10, 0xfe, 0x63, 0x3e, 0x9f, 0x99, 0x59, 0x4f, 0x67, 0xf0, 0xb9, 0xcc, 0xad, 0x38, + 0xd9, 0x77, 0x32, 0x62, 0xad, 0x64, 0x4f, 0xd6, 0xdb, 0x87, 0x42, 0x2d, 0xab, 0x4d, 0x86, 0x9d, + 0x07, 0xa9, 0xb6, 0x37, 0x26, 0x8d, 0xce, 0x7d, 0xa1, 0xe6, 0xcd, 0x75, 0x96, 0x2b, 0x0e, 0x6b, + 0xb6, 0x3b, 0x2e, 0x76, 0x72, 0x6a, 0x6d, 0x30, 0x1c, 0x6b, 0x5b, 0x76, 0x59, 0x53, 0xe4, 0xf1, + 0x53, 0x67, 0x5f, 0xa8, 0x3d, 0xf9, 0x1a, 0xdb, 0xd9, 0xf5, 0x6a, 0x20, 0x4c, 0x32, 0xe7, 0x67, + 0x6b, 0x5c, 0x49, 0x03, 0x2e, 0x96, 0x29, 0xfd, 0xfe, 0xa3, 0x2f, 0x80, 0x3f, 0xc9, 0x64, 0x08, + 0x29, 0x9d, 0xf0, 0x13, 0xb8, 0x59, 0xd6, 0x0a, 0xe1, 0x33, 0xee, 0x68, 0x0a, 0xb0, 0xae, 0xb5, + 0x9f, 0x73, 0xf1, 0xfc, 0xc3, 0x0b, 0xa5, 0x30, 0xf7, 0x24, 0x85, 0xcf, 0x8c, 0xb2, 0x92, 0x29, + 0x91, 0x72, 0xd3, 0x7f, 0x24, 0xa8, 0x2a, 0x02, 0xcc, 0x03, 0x63, 0x39, 0x15, 0x3a, 0x52, 0xb5, + 0xbe, 0x13, 0xcc, 0x86, 0x21, 0x28, 0xf5, 0x9e, 0xbc, 0x6f, 0xed, 0xc5, 0x01, 0xc8, 0x24, 0xc2, + 0xdd, 0xd5, 0x33, 0xc5, 0x97, 0xfa, 0xbe, 0xce, 0x37, 0x33, 0xd9, 0x17, 0xcb, 0x74, 0xfa, 0xcd, + 0xd5, 0x50, 0x01, 0x38, 0xb7, 0x84, 0x17, 0x77, 0xa2, 0xd1, 0x9c, 0x29, 0x8a, 0xec, 0x34, 0x7d, + 0xa0, 0x4b, 0x6b, 0x00, 0x64, 0x17, 0x1d, 0x34, 0x1f, 0xbc, 0x44, 0x9e, 0x08, 0x07, 0xaa, 0xca, + 0xcb, 0x9d, 0x7a, 0x47, 0x90, 0x39, 0x53, 0x9c, 0xd6, 0xcd, 0x61, 0x4f, 0xe8, 0x0a, 0x9d, 0x7a, + 0x57, 0xde, 0x57, 0xba, 0x02, 0x2b, 0xee, 0xb5, 0x3d, 0xec, 0x85, 0x27, 0xe5, 0xfa, 0x2c, 0xf3, + 0x62, 0xcf, 0x44, 0x4b, 0xe6, 0x94, 0x4d, 0xf1, 0x85, 0xc8, 0x7c, 0x3f, 0xa3, 0xbe, 0xf4, 0x9b, + 0x5e, 0x72, 0x9d, 0xda, 0x53, 0x06, 0xfa, 0x5f, 0x1e, 0x14, 0x45, 0xe9, 0xba, 0xc1, 0xfe, 0x1b, + 0x02, 0xa9, 0x48, 0x4f, 0x84, 0x58, 0x02, 0xca, 0x2b, 0x69, 0x48, 0xc2, 0x80, 0x74, 0xb5, 0x1c, + 0x19, 0x12, 0x6e, 0x5b, 0xde, 0xdf, 0x92, 0xa7, 0x52, 0x69, 0x26, 0xd5, 0x84, 0x76, 0x3b, 0x4f, + 0xee, 0xf7, 0xa1, 0xc0, 0x19, 0x9c, 0x92, 0xb9, 0x17, 0xca, 0x2f, 0xb8, 0x7f, 0x40, 0x52, 0x42, + 0x5a, 0xf6, 0xea, 0x83, 0x9a, 0x21, 0x0c, 0x2a, 0x53, 0x19, 0xd8, 0x9c, 0xe7, 0x38, 0x7f, 0xd8, + 0x06, 0x38, 0x8b, 0xc6, 0x2e, 0xcf, 0x35, 0x76, 0x43, 0xb6, 0x55, 0xd6, 0x6e, 0x49, 0x4f, 0xcb, + 0x8a, 0xfb, 0x7a, 0xbf, 0xb2, 0xcf, 0x73, 0xa2, 0x2f, 0x66, 0x5b, 0xf0, 0xd9, 0xda, 0x43, 0x1f, + 0x3f, 0x9c, 0xd5, 0x8d, 0x61, 0xad, 0x0e, 0x63, 0xeb, 0xbb, 0x7a, 0xb5, 0xd2, 0x91, 0x42, 0x58, + 0x25, 0x0e, 0xe8, 0xb0, 0x6d, 0xee, 0xdc, 0x8c, 0x30, 0x15, 0xd5, 0x2a, 0xfb, 0x50, 0x06, 0x9f, + 0x75, 0xdb, 0xb6, 0x1a, 0x82, 0xc4, 0x96, 0x46, 0xd5, 0xa9, 0xd8, 0x6d, 0xef, 0x5c, 0x47, 0xec, + 0x4d, 0xad, 0x3a, 0x38, 0x96, 0xa7, 0xc7, 0xad, 0xd8, 0xde, 0x17, 0x86, 0x55, 0x6e, 0xaa, 0x48, + 0xe5, 0x4a, 0x5f, 0x50, 0x48, 0x47, 0x99, 0x55, 0x88, 0x02, 0xce, 0xa7, 0x5f, 0xce, 0x67, 0x7a, + 0x44, 0xe2, 0x7d, 0xae, 0xde, 0x95, 0x78, 0xf7, 0x45, 0x9c, 0xf9, 0x85, 0xa7, 0x9a, 0x9c, 0x91, + 0x04, 0x37, 0xff, 0x24, 0xb8, 0x19, 0xa9, 0x26, 0xe7, 0x9f, 0x7a, 0xfe, 0xae, 0x69, 0x7a, 0x44, + 0x98, 0xd6, 0xfd, 0x66, 0x77, 0xee, 0x67, 0xfa, 0x96, 0xf0, 0xb4, 0x5f, 0x2d, 0x1f, 0x77, 0xa5, + 0xb5, 0x54, 0x19, 0x16, 0x1e, 0x79, 0xbf, 0xa0, 0xcc, 0xc9, 0xfa, 0x71, 0xf7, 0xb0, 0x7c, 0x9a, + 0x79, 0x02, 0x87, 0x74, 0xaf, 0x97, 0x81, 0x5f, 0x4f, 0xd4, 0xdc, 0x83, 0xe0, 0x64, 0x91, 0xa6, + 0x42, 0x57, 0xec, 0x88, 0x5b, 0xad, 0x5f, 0xd9, 0xe6, 0xb9, 0xca, 0x76, 0xa8, 0x54, 0x88, 0xf6, + 0x44, 0x24, 0x0d, 0x64, 0xa3, 0xbe, 0x7c, 0x34, 0x84, 0x65, 0x63, 0x26, 0x33, 0xe1, 0xde, 0x73, + 0x15, 0xa0, 0x55, 0xbc, 0xdf, 0x99, 0xb8, 0x4b, 0xd0, 0x64, 0x49, 0x4c, 0xaf, 0xaf, 0xb8, 0xf9, + 0x49, 0xb5, 0x33, 0x9f, 0xf1, 0xc6, 0x5c, 0xaf, 0x2d, 0xac, 0x6a, 0x47, 0xe1, 0xa4, 0x8e, 0xfc, + 0xbc, 0xaa, 0x4d, 0xf3, 0x0d, 0xde, 0x14, 0x9f, 0xab, 0x9d, 0x52, 0x09, 0xf6, 0x32, 0xac, 0xb0, + 0x42, 0xae, 0x35, 0xcb, 0xdf, 0xb6, 0x66, 0xe3, 0x4e, 0x65, 0x6b, 0x94, 0x44, 0xe0, 0x0d, 0xe5, + 0x35, 0xcb, 0xa8, 0x75, 0xbe, 0xd2, 0x84, 0xfd, 0xb8, 0xb2, 0xa0, 0x54, 0xd5, 0x4e, 0x5e, 0xaf, + 0x4d, 0x0b, 0xab, 0xce, 0x5c, 0x91, 0x1e, 0xf9, 0xf9, 0xaa, 0x6b, 0x0a, 0x46, 0x75, 0xe6, 0xaf, + 0x74, 0x61, 0x18, 0xcd, 0x0d, 0x61, 0x15, 0xaa, 0x3a, 0x3f, 0x8f, 0xf8, 0xcd, 0x64, 0x8a, 0xc3, + 0xf2, 0x8c, 0x3c, 0xaa, 0x44, 0xc8, 0x93, 0x3e, 0x9a, 0xb8, 0x8e, 0xa6, 0x13, 0xa9, 0xc4, 0x95, + 0x0d, 0x61, 0x43, 0xa4, 0x3c, 0x57, 0xf6, 0x85, 0x27, 0xd2, 0x75, 0x39, 0x90, 0xcf, 0x0d, 0xe9, + 0x02, 0xcf, 0x7d, 0xad, 0xda, 0x30, 0x4b, 0x5c, 0x63, 0x36, 0xcc, 0x60, 0xbb, 0xd5, 0x93, 0xb2, + 0xad, 0x9d, 0xb6, 0x26, 0xbd, 0x12, 0xd7, 0x36, 0x84, 0x09, 0xe9, 0xe5, 0xb9, 0xb6, 0x2f, 0x80, + 0x4c, 0xb8, 0x9c, 0x38, 0x1d, 0x4e, 0x48, 0x07, 0xe8, 0xb0, 0xd7, 0xb2, 0xc8, 0xf3, 0x8a, 0x01, + 0xb2, 0xd3, 0xa1, 0x74, 0xa9, 0x72, 0xbe, 0xbc, 0x6b, 0x01, 0xbd, 0x1a, 0xa6, 0x68, 0x72, 0x20, + 0x5b, 0x15, 0x43, 0xdc, 0x2a, 0xd2, 0xb0, 0xcc, 0x55, 0xea, 0xe5, 0xb2, 0x3f, 0x5e, 0x94, 0x77, + 0x62, 0x0f, 0xd6, 0x7e, 0xe4, 0x9b, 0x52, 0x9d, 0xf7, 0x05, 0x49, 0xd8, 0xd5, 0xa5, 0x67, 0x43, + 0x7b, 0xc2, 0x7e, 0xe2, 0x2b, 0x03, 0x62, 0x08, 0x3c, 0x51, 0x86, 0x55, 0xe2, 0x77, 0xba, 0xc4, + 0x2f, 0xd5, 0x9e, 0x8d, 0xd2, 0x4c, 0xf0, 0x4b, 0x1c, 0xef, 0x9b, 0x73, 0x9e, 0xb8, 0x9c, 0xc0, + 0x89, 0xa6, 0x50, 0x1d, 0xd6, 0xca, 0x06, 0xf6, 0x8b, 0x15, 0xc5, 0xaf, 0x73, 0x44, 0xaa, 0xdd, + 0xee, 0xf7, 0x0f, 0xa3, 0xfe, 0xbe, 0x94, 0xe9, 0xb3, 0x2e, 0x57, 0x05, 0xb0, 0x65, 0x5f, 0x6f, + 0x01, 0x2e, 0xb0, 0x0c, 0xbc, 0x55, 0xfd, 0x3a, 0x6f, 0xd8, 0xf5, 0x11, 0x31, 0xe4, 0x32, 0x3f, + 0xe7, 0x39, 0x09, 0xfb, 0x4a, 0x42, 0x87, 0xd8, 0x32, 0x3c, 0x97, 0xf9, 0xf9, 0x2f, 0x8e, 0x5f, + 0x36, 0x46, 0xed, 0x68, 0x3d, 0x54, 0x31, 0x9f, 0x38, 0x99, 0xbc, 0x54, 0x66, 0x25, 0x51, 0x21, + 0x5c, 0x1e, 0x5c, 0x13, 0xd7, 0x45, 0xb9, 0x12, 0xa7, 0x40, 0xf3, 0x0e, 0xc8, 0x55, 0x57, 0x64, + 0x42, 0xbd, 0x02, 0xbd, 0x09, 0x64, 0x0b, 0x9f, 0x85, 0xb2, 0xb3, 0x17, 0xb6, 0xf2, 0x80, 0xdb, + 0x69, 0xb5, 0xc6, 0x5e, 0x63, 0x41, 0xde, 0x40, 0xf7, 0x86, 0x7b, 0xa0, 0x31, 0xc8, 0xe1, 0xb0, + 0x46, 0xf6, 0xb1, 0x9e, 0xce, 0x5a, 0x3c, 0xf0, 0x03, 0x74, 0x14, 0xe4, 0x12, 0xf6, 0x2f, 0xd4, + 0x38, 0x7c, 0x16, 0xe9, 0xa9, 0x5f, 0x27, 0xed, 0xd9, 0x30, 0x27, 0x77, 0xb4, 0xa1, 0x32, 0x25, + 0x9d, 0x27, 0x53, 0x5b, 0x82, 0xfc, 0x2f, 0x1b, 0x7b, 0x1b, 0xc2, 0xc2, 0x61, 0x24, 0x6f, 0xce, + 0xbc, 0xb7, 0x03, 0xf3, 0xb2, 0xeb, 0xd4, 0x78, 0x29, 0x03, 0xfd, 0x99, 0x06, 0xe7, 0x3b, 0x43, + 0xe5, 0x59, 0x31, 0x78, 0xc9, 0x52, 0x40, 0xd6, 0x54, 0xf9, 0xb9, 0x22, 0x57, 0x80, 0x95, 0x0b, + 0x90, 0x5f, 0x4b, 0xb6, 0x1a, 0x75, 0x4e, 0x51, 0x16, 0x02, 0xaf, 0x6e, 0x8d, 0x81, 0x0c, 0xeb, + 0xb4, 0xcd, 0x10, 0x26, 0x17, 0xae, 0x51, 0xce, 0x67, 0x5b, 0xac, 0x30, 0xa8, 0xb6, 0x0b, 0xfb, + 0xd9, 0xb3, 0x50, 0x32, 0xea, 0xa4, 0x34, 0x1f, 0x32, 0xad, 0x16, 0x2f, 0xb8, 0xed, 0x7d, 0xc9, + 0xad, 0xf7, 0xa4, 0x16, 0x99, 0x69, 0x21, 0x9c, 0x4a, 0xa4, 0x0b, 0x91, 0x6e, 0x4c, 0x15, 0xab, + 0x4f, 0x1a, 0xbc, 0x4c, 0xed, 0xbc, 0x32, 0xb9, 0x55, 0x48, 0xd1, 0xe5, 0x8b, 0x3e, 0xf8, 0x6b, + 0x1e, 0x43, 0x1e, 0x61, 0xf7, 0x0e, 0x9d, 0xdc, 0x0b, 0x3b, 0x2d, 0xf7, 0xe8, 0x0b, 0x20, 0x83, + 0x5a, 0xad, 0x05, 0x74, 0xe8, 0x0b, 0x85, 0xa7, 0x31, 0x2f, 0x98, 0x75, 0xb3, 0xc2, 0xf4, 0xe6, + 0x85, 0x61, 0x5f, 0x66, 0x13, 0x6d, 0xf6, 0xd9, 0xe3, 0x6f, 0x27, 0x8c, 0xd5, 0xe8, 0x32, 0xab, + 0xd2, 0xc6, 0x23, 0x8f, 0x4e, 0x3c, 0xee, 0x74, 0x5e, 0xd8, 0xce, 0x28, 0x83, 0x27, 0xb3, 0x03, + 0xd4, 0x9a, 0x36, 0x9b, 0xfb, 0x3e, 0x13, 0xf0, 0xbb, 0x20, 0x03, 0xbf, 0x1f, 0x1d, 0xf4, 0x34, + 0x4d, 0x89, 0x06, 0x8f, 0x56, 0xc8, 0x43, 0xe4, 0xd1, 0x1e, 0x79, 0x06, 0x7a, 0x93, 0x03, 0xbf, + 0x32, 0x6d, 0xf5, 0x44, 0xa5, 0xde, 0x91, 0x67, 0x5c, 0xc8, 0x7b, 0x90, 0x7f, 0x4b, 0xd8, 0x89, + 0xcb, 0xba, 0xaf, 0xcd, 0x84, 0xbd, 0x58, 0x16, 0x77, 0x1a, 0xdf, 0xe8, 0xf2, 0x15, 0xb6, 0x97, + 0x7b, 0x6e, 0x0a, 0x64, 0xa0, 0x74, 0xa4, 0x6d, 0xcd, 0x2c, 0x08, 0x95, 0x49, 0x7e, 0x4e, 0xba, + 0xab, 0x3e, 0xfc, 0x7b, 0xe0, 0xb7, 0x44, 0x6a, 0x80, 0xae, 0xd7, 0x20, 0x5b, 0x18, 0x88, 0x9c, + 0x22, 0x8a, 0xae, 0xaf, 0x68, 0x9c, 0x32, 0xca, 0xaf, 0x2a, 0x1b, 0x45, 0xaf, 0xb0, 0xb3, 0x5c, + 0xff, 0xb1, 0x5f, 0x67, 0x1a, 0x73, 0x63, 0x2a, 0xe6, 0x24, 0xf0, 0x18, 0xcf, 0x7d, 0xa5, 0x3b, + 0x9c, 0x37, 0xe4, 0xe1, 0xb4, 0x0e, 0x3a, 0x3a, 0x9a, 0xe4, 0x09, 0xf0, 0x86, 0x27, 0xed, 0xfb, + 0xfe, 0x9a, 0x1a, 0x09, 0x91, 0x34, 0x51, 0x76, 0x1f, 0x40, 0xa4, 0x09, 0x19, 0x81, 0x8f, 0x25, + 0x92, 0x9f, 0xf4, 0x0b, 0x5a, 0x35, 0xf4, 0x0b, 0xb3, 0xba, 0x19, 0xc8, 0x5d, 0x03, 0xec, 0x1f, + 0xee, 0xa9, 0x35, 0x4d, 0xda, 0xbd, 0x33, 0x99, 0x94, 0x43, 0x9e, 0xf5, 0x42, 0x19, 0x86, 0xf9, + 0xe8, 0x4f, 0x86, 0x3c, 0xa9, 0x70, 0x8d, 0xee, 0xc0, 0xde, 0x3c, 0x6e, 0xdd, 0x11, 0xd8, 0xe4, + 0x62, 0x57, 0xb6, 0x24, 0x59, 0xb0, 0x1a, 0xba, 0x59, 0xda, 0x54, 0xb7, 0xee, 0xe6, 0x31, 0xb7, + 0x6a, 0x74, 0x15, 0xe2, 0x36, 0x76, 0x5a, 0x11, 0x94, 0x4d, 0x12, 0x7a, 0xf6, 0xb2, 0xb1, 0xf3, + 0x4f, 0xdb, 0x6c, 0x97, 0x71, 0xd9, 0x96, 0xec, 0x3d, 0x12, 0x9b, 0x80, 0x5c, 0xcb, 0xf7, 0x4f, + 0xcc, 0x73, 0xf5, 0x69, 0xef, 0x29, 0x81, 0x2d, 0x4c, 0xb6, 0x67, 0x0f, 0xc5, 0xed, 0x89, 0x2e, + 0x70, 0x27, 0x6d, 0x52, 0x51, 0xba, 0x7b, 0x39, 0x84, 0xe9, 0x46, 0x41, 0x46, 0xc4, 0x5f, 0x9a, + 0x1b, 0x3c, 0x1a, 0x18, 0x1f, 0x22, 0x71, 0x04, 0x13, 0x78, 0xb8, 0x04, 0x1a, 0xec, 0x63, 0xdd, + 0x46, 0x1a, 0xed, 0x50, 0x07, 0xe5, 0x48, 0xc7, 0xad, 0x96, 0x2f, 0xd4, 0x1a, 0x3e, 0xf5, 0x8d, + 0x81, 0xac, 0x9a, 0x54, 0x47, 0x97, 0x67, 0xbe, 0x63, 0xa6, 0x2d, 0x81, 0x66, 0x11, 0x7d, 0x72, + 0x60, 0x5f, 0x77, 0x95, 0x29, 0xc3, 0x41, 0xfc, 0xa1, 0x34, 0xb6, 0x0d, 0xad, 0xc1, 0x0e, 0x3d, + 0xa0, 0x4f, 0x5d, 0xdf, 0xe5, 0x37, 0x35, 0x6e, 0xfc, 0x28, 0xd6, 0x98, 0x1a, 0x1f, 0xe2, 0x9f, + 0x31, 0xe7, 0x39, 0xb2, 0x91, 0xb2, 0xb3, 0x9d, 0xa7, 0x8b, 0x56, 0x4c, 0xd7, 0x67, 0xb9, 0x27, + 0xf7, 0x4c, 0xc3, 0x16, 0x05, 0x4e, 0x28, 0x02, 0xdd, 0xdc, 0x6a, 0xb7, 0xd4, 0x97, 0xd0, 0xbe, + 0xee, 0x95, 0x47, 0x62, 0x54, 0xb2, 0xdc, 0xfe, 0xb9, 0x49, 0xa6, 0x72, 0x9d, 0x63, 0xfd, 0x76, + 0x19, 0x74, 0x5a, 0xe9, 0xb9, 0xf7, 0x9d, 0xd9, 0x76, 0xd1, 0x1c, 0x30, 0xdd, 0xc6, 0x56, 0x0e, + 0x69, 0xcd, 0xb1, 0xad, 0x0d, 0x23, 0xb6, 0xf2, 0xa5, 0x8e, 0x10, 0x8f, 0x79, 0xf0, 0x9a, 0x9d, + 0xee, 0x63, 0xc5, 0x2c, 0x3d, 0x3f, 0xf2, 0xda, 0xf2, 0x69, 0x2a, 0x48, 0x65, 0xb2, 0xe2, 0x41, + 0x2a, 0x1f, 0x5b, 0x12, 0xc0, 0xcf, 0x8a, 0x1c, 0xd0, 0xb1, 0x16, 0xf8, 0x1f, 0xde, 0xc9, 0x64, + 0xdd, 0xb2, 0x42, 0xed, 0xe1, 0x9c, 0x88, 0xc6, 0x49, 0xbc, 0x11, 0xd0, 0xf0, 0x20, 0x3b, 0x5b, + 0x79, 0xd9, 0xda, 0xca, 0x9d, 0x16, 0xea, 0x6f, 0x37, 0xa1, 0xdf, 0x33, 0x6d, 0x00, 0xf4, 0x51, + 0x2a, 0x5c, 0x40, 0x6b, 0xf0, 0x6b, 0xb5, 0xf6, 0xac, 0x30, 0xae, 0x6e, 0x6d, 0xad, 0xda, 0xcb, + 0x03, 0xfe, 0x92, 0xdc, 0x31, 0xf3, 0x9b, 0x96, 0xba, 0x76, 0x5e, 0x8a, 0xde, 0xc5, 0x3e, 0xb2, + 0x92, 0x21, 0x0e, 0x61, 0x6e, 0xdb, 0x73, 0x6d, 0x37, 0xe0, 0x8d, 0x4c, 0x75, 0xc6, 0x18, 0xad, + 0x6e, 0x69, 0xdd, 0x99, 0x4a, 0xb2, 0xd1, 0x5c, 0xbf, 0x18, 0xed, 0xac, 0x43, 0x3f, 0x39, 0x48, + 0x9b, 0x7a, 0xf9, 0xdb, 0xce, 0xbe, 0xa1, 0x35, 0xcb, 0x25, 0xb5, 0xdd, 0x25, 0xec, 0xe3, 0xae, + 0x50, 0xad, 0x60, 0x90, 0x65, 0x08, 0x18, 0x5e, 0x96, 0x31, 0xc3, 0x42, 0x3b, 0xc5, 0x05, 0xf1, + 0x23, 0x07, 0x52, 0xd0, 0xa9, 0x63, 0xbc, 0xd8, 0xf7, 0x08, 0x44, 0x68, 0x18, 0x67, 0x66, 0x70, + 0x60, 0x26, 0xc8, 0x86, 0x38, 0x2a, 0x49, 0x3e, 0x46, 0x5c, 0x18, 0x9c, 0x62, 0x76, 0x25, 0xec, + 0x31, 0xd6, 0x10, 0x7c, 0x94, 0x66, 0xb0, 0x87, 0xcf, 0x32, 0xa7, 0xfa, 0x0d, 0x1c, 0x0f, 0x7a, + 0x89, 0x71, 0x2f, 0xc4, 0x7d, 0x34, 0x78, 0xe5, 0x06, 0x99, 0x82, 0x86, 0xf1, 0xda, 0x0a, 0xf5, + 0x14, 0x52, 0x96, 0x47, 0x0c, 0xf6, 0x80, 0xb8, 0x16, 0xe1, 0xf3, 0xa4, 0x27, 0x51, 0x7f, 0x5e, + 0x11, 0x3a, 0x25, 0x8e, 0xeb, 0x08, 0x83, 0xc6, 0x56, 0xb0, 0x48, 0x2c, 0x87, 0x9a, 0x42, 0xf5, + 0x76, 0x27, 0xe2, 0xf7, 0x32, 0xd2, 0x9c, 0x43, 0xb9, 0xdc, 0x8b, 0xbd, 0x16, 0xd5, 0x4b, 0x19, + 0x69, 0xce, 0x45, 0xf6, 0x94, 0xdb, 0xcb, 0xd9, 0x53, 0x5d, 0x6e, 0xec, 0xe5, 0x38, 0x16, 0x22, + 0x26, 0x7b, 0x9b, 0xf1, 0x79, 0x7e, 0xb2, 0x29, 0x11, 0x70, 0x89, 0x1c, 0x69, 0x0d, 0xd7, 0x4a, + 0x57, 0x7c, 0x10, 0x6b, 0x2d, 0x92, 0x9f, 0xfa, 0x73, 0x4e, 0xd1, 0x6a, 0x62, 0x57, 0xab, 0x73, + 0x5d, 0x49, 0x6b, 0x77, 0xb5, 0x2d, 0xc7, 0x8e, 0x85, 0x76, 0xb7, 0xa5, 0x3c, 0xce, 0xb9, 0x3d, + 0x58, 0x98, 0x42, 0x6d, 0xca, 0x2e, 0x3b, 0xf3, 0x67, 0xa9, 0xbd, 0x1f, 0x66, 0x65, 0x0e, 0xf4, + 0x65, 0x3a, 0x96, 0x5a, 0x10, 0x63, 0xc8, 0xc2, 0x73, 0xf5, 0x79, 0xcb, 0xe8, 0xe4, 0xb9, 0xa0, + 0xfb, 0x90, 0x76, 0x0d, 0xad, 0x7b, 0xc8, 0x58, 0x39, 0x88, 0x46, 0x8a, 0x40, 0xb2, 0x4a, 0xf7, + 0x00, 0x4f, 0xe7, 0xea, 0xac, 0xbc, 0x96, 0x6a, 0xa2, 0x9f, 0x71, 0xb5, 0xb5, 0xc2, 0x4b, 0x74, + 0xed, 0xcc, 0x5a, 0x78, 0x00, 0x1f, 0x06, 0xfe, 0x5f, 0xdb, 0x36, 0xfc, 0x4a, 0x53, 0x66, 0xac, + 0xa6, 0xd6, 0x95, 0xe7, 0xbc, 0xa2, 0xd5, 0x61, 0xcd, 0xd1, 0x53, 0x6f, 0xc5, 0x49, 0x3d, 0xbb, + 0xd0, 0x87, 0x35, 0xf8, 0x8a, 0xd6, 0x68, 0xf0, 0xca, 0xb6, 0x3b, 0xb7, 0x7a, 0x54, 0xbf, 0x81, + 0xf6, 0x99, 0x5b, 0x17, 0xe8, 0xdb, 0x54, 0x90, 0x45, 0x35, 0x83, 0xbc, 0x90, 0xb2, 0x41, 0x3a, + 0x41, 0x5c, 0xdc, 0xaf, 0x1c, 0x62, 0x77, 0x56, 0x80, 0x38, 0x48, 0xdc, 0x09, 0x5c, 0xe8, 0x97, + 0x73, 0x8d, 0x40, 0x87, 0x21, 0x26, 0xd6, 0x4e, 0xe2, 0x1c, 0x39, 0xb0, 0x01, 0xa6, 0x56, 0xab, + 0xa1, 0xcc, 0x06, 0xbe, 0xbb, 0x5f, 0xa1, 0x39, 0x46, 0x7d, 0x81, 0xf1, 0x94, 0xe8, 0xb7, 0x94, + 0x46, 0xb9, 0xbe, 0x6b, 0xb4, 0xd9, 0x3e, 0xfd, 0x24, 0xcd, 0x97, 0xcc, 0x64, 0x68, 0x35, 0xcc, + 0xa1, 0xd5, 0x86, 0xb6, 0x38, 0x7b, 0xdc, 0x76, 0xb2, 0x9d, 0x79, 0x87, 0x19, 0xcf, 0x9f, 0x21, + 0x70, 0x13, 0x67, 0xf8, 0xcc, 0xa7, 0xfd, 0x5e, 0x17, 0xf2, 0x01, 0x53, 0x9c, 0xc1, 0xb3, 0x19, + 0xc8, 0x34, 0xe4, 0x27, 0x79, 0x02, 0xf9, 0xc9, 0xae, 0x0e, 0xfe, 0xae, 0xbe, 0x7f, 0x7c, 0x78, + 0x30, 0x9f, 0x75, 0xb1, 0x57, 0x99, 0x34, 0x7a, 0xfe, 0x76, 0x32, 0x6f, 0xf0, 0x93, 0x5e, 0xa3, + 0xfa, 0x2c, 0x8c, 0x6b, 0x10, 0x70, 0xd6, 0x00, 0x66, 0x55, 0x1c, 0x14, 0x78, 0x69, 0xc9, 0xec, + 0xda, 0x7c, 0x38, 0x4e, 0x12, 0x9a, 0x11, 0x3c, 0x80, 0x43, 0xfd, 0xc1, 0x4b, 0x26, 0xe3, 0x10, + 0x46, 0xe4, 0x0d, 0x1f, 0x85, 0x8e, 0x01, 0xbb, 0x87, 0xf9, 0x95, 0x14, 0xe4, 0x00, 0xd1, 0x3e, + 0x3a, 0x07, 0x9f, 0x5c, 0xdf, 0x4b, 0xa1, 0x7d, 0x13, 0xd9, 0x4a, 0xef, 0x42, 0x9c, 0xb2, 0xef, + 0x3b, 0x2d, 0x53, 0x5b, 0xb4, 0xf6, 0x28, 0x53, 0x6a, 0x43, 0x1f, 0x2c, 0x98, 0x56, 0x59, 0x29, + 0x34, 0x77, 0xeb, 0xde, 0x30, 0xdb, 0xf2, 0x15, 0x86, 0x6d, 0x69, 0x3b, 0x61, 0xaa, 0x43, 0xcc, + 0x22, 0xcf, 0xb4, 0x5c, 0x7b, 0x6e, 0x84, 0x63, 0x87, 0xd9, 0x86, 0x5f, 0xbf, 0x6f, 0xf5, 0xba, + 0x0c, 0xcc, 0x69, 0x68, 0xd5, 0xd6, 0x6c, 0x0e, 0x79, 0x83, 0x3e, 0xa9, 0x4f, 0xeb, 0x83, 0x56, + 0xab, 0xa7, 0x68, 0xb7, 0xad, 0xfd, 0xb8, 0x5b, 0xe5, 0xc6, 0x05, 0x6a, 0x6f, 0xa4, 0x32, 0xf0, + 0x51, 0x86, 0xfc, 0xae, 0xe1, 0x04, 0x75, 0x1c, 0xc8, 0xed, 0x40, 0xcf, 0xd0, 0xf7, 0x0a, 0x3d, + 0xf8, 0x94, 0x44, 0x27, 0xe3, 0x73, 0x7d, 0xcc, 0x8f, 0x49, 0x65, 0x88, 0x35, 0x37, 0x25, 0xfe, + 0x8e, 0x7a, 0x47, 0x5f, 0x43, 0x88, 0x3f, 0x60, 0xff, 0x79, 0xc2, 0x5b, 0x12, 0xea, 0x9b, 0x80, + 0xfa, 0x36, 0xc5, 0x38, 0x04, 0xfd, 0x64, 0x6b, 0x8f, 0xf9, 0x9b, 0x08, 0xf9, 0x1b, 0xec, 0xaf, + 0x27, 0xb2, 0x24, 0xf8, 0x54, 0x38, 0x7c, 0x2e, 0x69, 0xb4, 0xaf, 0x05, 0xb1, 0x2d, 0xf8, 0xf9, + 0x29, 0xd0, 0x88, 0xc5, 0x4f, 0x01, 0xd6, 0xaf, 0x74, 0x2b, 0x8a, 0x51, 0xe7, 0xfa, 0x90, 0x13, + 0x39, 0x4d, 0xf6, 0xb9, 0x6f, 0x08, 0x5b, 0x11, 0x45, 0x89, 0x35, 0x1a, 0x4a, 0x46, 0x75, 0x79, + 0x65, 0x92, 0x75, 0x88, 0x35, 0x78, 0x78, 0xc9, 0xba, 0x2f, 0x2f, 0xa6, 0xdd, 0x6f, 0x4e, 0x87, + 0x1c, 0xf8, 0xe9, 0x97, 0x17, 0x9b, 0xbc, 0x34, 0x2c, 0x1b, 0xff, 0x01, 0x9e, 0xcf, 0x90, 0x1b, + 0xae, 0xfa, 0x0a, 0xd8, 0x21, 0xc5, 0x1a, 0x06, 0xf2, 0x0b, 0xfe, 0x09, 0xec, 0x83, 0x83, 0xc6, + 0xe1, 0x09, 0x91, 0xad, 0x80, 0x19, 0x22, 0x17, 0xf3, 0xba, 0xd8, 0x7f, 0x83, 0x0c, 0x06, 0xfe, + 0x7b, 0x06, 0xf9, 0xce, 0x2c, 0x88, 0x1b, 0xe1, 0x59, 0xc4, 0x43, 0x33, 0x1c, 0x1f, 0xdb, 0x5b, + 0x21, 0x92, 0xdb, 0x88, 0xff, 0xdd, 0xe3, 0x36, 0xf6, 0x37, 0x76, 0x98, 0x47, 0x88, 0xe0, 0xdb, + 0xa7, 0x4f, 0xbd, 0xa5, 0x04, 0x3a, 0x53, 0x9f, 0x8e, 0x21, 0x6e, 0xea, 0x57, 0xac, 0x56, 0xa2, + 0xdd, 0xea, 0xcb, 0x1a, 0xe4, 0x81, 0x0c, 0xe4, 0x80, 0xa1, 0x9d, 0x65, 0x8e, 0xdb, 0x39, 0xce, + 0x5e, 0x34, 0xe0, 0x3b, 0x38, 0xb2, 0xdb, 0xf5, 0xd6, 0xb5, 0x1a, 0x1d, 0x57, 0x6d, 0x98, 0xcf, + 0xf7, 0xdd, 0x9c, 0xac, 0x92, 0x91, 0xa4, 0x8e, 0x65, 0x88, 0x0b, 0x77, 0x11, 0xec, 0xd3, 0xb5, + 0xc2, 0xf6, 0x86, 0x21, 0xd5, 0xa9, 0x37, 0x06, 0x3f, 0x50, 0xeb, 0xec, 0xf3, 0xb7, 0x03, 0x80, + 0x71, 0xda, 0x06, 0x36, 0x5b, 0xe0, 0x23, 0xc2, 0xb5, 0xe4, 0x51, 0xd5, 0x1c, 0x2e, 0xaa, 0x53, + 0xd7, 0xca, 0xac, 0x57, 0xb2, 0x04, 0xd1, 0x52, 0x20, 0x4f, 0x60, 0xc3, 0x0b, 0x28, 0x4f, 0x18, + 0xdf, 0xd5, 0xaf, 0xc5, 0xa1, 0x87, 0x78, 0x68, 0x16, 0xfb, 0x7e, 0x1a, 0x1b, 0x80, 0x1d, 0x1b, + 0x42, 0xfc, 0xc8, 0x00, 0xbd, 0xcc, 0xfa, 0xa0, 0xf3, 0xd4, 0xb3, 0x0c, 0x53, 0xe2, 0x0a, 0x60, + 0x63, 0xc7, 0x6d, 0x88, 0xab, 0x06, 0x95, 0x79, 0x29, 0xd7, 0x62, 0x04, 0x5d, 0xe2, 0xeb, 0xe7, + 0x7b, 0x32, 0xec, 0x66, 0x85, 0x37, 0x96, 0xea, 0xbc, 0xc2, 0x75, 0x85, 0x29, 0x27, 0xf5, 0xed, + 0x65, 0x93, 0x93, 0x9a, 0x3c, 0xf5, 0x29, 0xe0, 0x83, 0xb8, 0x5c, 0x66, 0x20, 0xb5, 0x67, 0x64, + 0x27, 0x92, 0x32, 0xc4, 0xa1, 0x68, 0xb7, 0x00, 0xbf, 0x01, 0xb7, 0x85, 0xf8, 0x72, 0xa7, 0xcd, + 0x5a, 0x5d, 0x2d, 0x07, 0x72, 0x99, 0xab, 0xec, 0x45, 0xee, 0x5d, 0x3c, 0xbe, 0x60, 0xa3, 0x66, + 0xf6, 0x7d, 0x1d, 0x52, 0x89, 0x7a, 0xf4, 0x99, 0x79, 0x71, 0x23, 0x5f, 0x28, 0x57, 0x84, 0xe1, + 0xfa, 0x11, 0xe2, 0xa5, 0xe3, 0xb6, 0x12, 0xd9, 0x99, 0x79, 0xc7, 0xaf, 0xb5, 0x92, 0x73, 0xe1, + 0xf3, 0xe1, 0x25, 0xf2, 0xd3, 0x3d, 0x79, 0xf3, 0x38, 0x1f, 0xca, 0x38, 0xef, 0xa8, 0x4d, 0xaa, + 0xce, 0xc1, 0x56, 0x49, 0x20, 0xdf, 0x3c, 0xc1, 0x7a, 0x8d, 0x41, 0xb0, 0x5e, 0x61, 0x90, 0x16, + 0x2d, 0x93, 0xfb, 0xd7, 0xe4, 0xdb, 0x21, 0x5d, 0x5a, 0x83, 0x08, 0x7c, 0x56, 0xb0, 0x97, 0xd3, + 0x1c, 0xa1, 0x2c, 0xce, 0xe2, 0xba, 0x05, 0xec, 0x7d, 0x98, 0x3b, 0x69, 0xef, 0x4f, 0xda, 0x83, + 0x93, 0x36, 0xc6, 0xae, 0x41, 0x4e, 0x34, 0x15, 0x3a, 0x4f, 0x5d, 0x88, 0x1f, 0x05, 0x5f, 0x6d, + 0x18, 0xf3, 0x1a, 0x4f, 0xe6, 0x56, 0x95, 0x8d, 0xfa, 0x82, 0xfc, 0x69, 0x11, 0xcb, 0xaf, 0xaa, + 0x56, 0x77, 0x72, 0x20, 0x6f, 0x1b, 0x02, 0xed, 0x21, 0x6d, 0x2f, 0x0e, 0xf2, 0xc7, 0xfb, 0x9c, + 0x3b, 0x1a, 0x94, 0xf3, 0x99, 0x4e, 0x94, 0x57, 0x81, 0x4c, 0x96, 0xb9, 0x61, 0x9d, 0xef, 0x0c, + 0x45, 0x18, 0x7b, 0x52, 0x43, 0xb8, 0xbf, 0x35, 0x78, 0x90, 0x59, 0x0a, 0xd3, 0xb5, 0x5e, 0x76, + 0x07, 0xf9, 0x0d, 0xd6, 0x43, 0xf8, 0x7d, 0x07, 0xbe, 0x07, 0xb2, 0xbd, 0x93, 0xc3, 0x7a, 0x40, + 0x40, 0xcf, 0x31, 0x69, 0x32, 0x58, 0x8f, 0x2d, 0xa3, 0x3d, 0xf3, 0xb1, 0x6e, 0x04, 0x76, 0x4c, + 0xd2, 0x96, 0x40, 0x9f, 0x5d, 0xcd, 0x17, 0xfa, 0x15, 0x08, 0x6d, 0xb2, 0xcd, 0xf2, 0x6d, 0xb3, + 0x49, 0xf8, 0x07, 0xa1, 0x68, 0xf4, 0x0c, 0x7f, 0x56, 0xee, 0x4b, 0xe2, 0x90, 0xd4, 0x86, 0x76, + 0x3b, 0x6f, 0xdb, 0xa4, 0xca, 0xf4, 0x5e, 0xb8, 0xa7, 0x32, 0xd9, 0xce, 0xcb, 0x5d, 0x31, 0x08, + 0x95, 0xbb, 0x9b, 0x8c, 0x25, 0x3d, 0x2a, 0x64, 0xed, 0xd2, 0xd2, 0x2a, 0xe9, 0x0a, 0x65, 0x11, + 0xe2, 0x9b, 0xfa, 0x56, 0xe0, 0x9a, 0x7e, 0xf5, 0xe5, 0xe5, 0xc5, 0xb9, 0x65, 0x6d, 0xc2, 0x17, + 0x33, 0xc5, 0x17, 0x88, 0x73, 0x20, 0x74, 0xaa, 0xf5, 0x03, 0xa4, 0xe6, 0xc4, 0x68, 0x3f, 0xa0, + 0xbd, 0x2d, 0x57, 0x68, 0x7d, 0x51, 0xc3, 0x73, 0x8f, 0x11, 0xe1, 0x4a, 0xa4, 0xee, 0x93, 0x25, + 0xe1, 0x5d, 0x5a, 0xb9, 0xe5, 0x7a, 0x60, 0x5f, 0x3b, 0x60, 0x77, 0xb7, 0xb2, 0x05, 0xfe, 0xf7, + 0x9e, 0x40, 0x1e, 0x25, 0x60, 0x3e, 0x15, 0xf8, 0x22, 0x0b, 0x73, 0x0c, 0x88, 0xc1, 0x3a, 0x22, + 0xac, 0x87, 0xf6, 0x98, 0x1c, 0xc6, 0x97, 0xa1, 0x0d, 0xb1, 0x66, 0x13, 0x62, 0xb3, 0x67, 0x25, + 0x23, 0x91, 0x5d, 0xbd, 0x88, 0x71, 0xa2, 0x3b, 0x13, 0x8d, 0xa6, 0x53, 0xdf, 0x83, 0xfd, 0x7d, + 0x81, 0xdc, 0x0a, 0x6d, 0xa9, 0x0f, 0xb1, 0x98, 0x05, 0x11, 0x5c, 0xaf, 0x01, 0x63, 0x65, 0xe0, + 0xb5, 0xa2, 0xbc, 0xec, 0xc4, 0x1d, 0xd8, 0xe6, 0x17, 0xa5, 0x07, 0xfe, 0xd6, 0x7a, 0x56, 0x44, + 0xb3, 0xfd, 0x40, 0xc8, 0xd3, 0x4b, 0x06, 0x7d, 0x06, 0xf4, 0x63, 0x4d, 0x4d, 0x99, 0x14, 0x5f, + 0x14, 0x6b, 0x74, 0xfb, 0xc2, 0xca, 0x33, 0xd1, 0x08, 0x8b, 0x90, 0xf5, 0x32, 0xd0, 0xe3, 0x89, + 0x90, 0xad, 0x8c, 0xb1, 0x5f, 0x8d, 0xf0, 0x5a, 0x50, 0xce, 0xa6, 0x7e, 0x41, 0xa4, 0x78, 0x06, + 0xf1, 0xc1, 0xf5, 0x7c, 0x16, 0xf6, 0x34, 0xa0, 0xb1, 0x1a, 0xe4, 0x03, 0xef, 0xc8, 0xb3, 0xf6, + 0xc4, 0x86, 0xb8, 0xb3, 0xa2, 0xc0, 0x5e, 0x84, 0xe5, 0x23, 0xe6, 0xf0, 0x10, 0x5b, 0x81, 0x92, + 0x55, 0x3b, 0x0b, 0x23, 0x96, 0x49, 0x59, 0xe8, 0x14, 0x21, 0x96, 0xe8, 0xd4, 0x8c, 0xfb, 0x5b, + 0x6b, 0x1f, 0xe6, 0xec, 0x5c, 0x98, 0xd3, 0xcf, 0x4e, 0xda, 0x86, 0x08, 0xc4, 0x18, 0x3c, 0xb0, + 0xe0, 0x6f, 0xd0, 0x4f, 0x56, 0x67, 0x8d, 0x62, 0x47, 0x78, 0x08, 0xe0, 0x6d, 0x4b, 0x14, 0x7e, + 0x8f, 0x0d, 0xe1, 0x9b, 0xbe, 0xdd, 0x26, 0x8c, 0x2e, 0x00, 0xad, 0x2a, 0xdb, 0x69, 0x07, 0x94, + 0xff, 0xb6, 0x3d, 0xd3, 0xb2, 0x72, 0xc7, 0x18, 0x04, 0x6d, 0xb0, 0xf3, 0xb3, 0x21, 0x6d, 0x13, + 0x0c, 0xa0, 0xf9, 0x4d, 0xc6, 0x30, 0xda, 0x0a, 0xd9, 0xcd, 0x03, 0xfa, 0x80, 0xbf, 0x06, 0x79, + 0xec, 0x11, 0x4e, 0x23, 0xa2, 0x4f, 0x72, 0xa4, 0x4c, 0xfd, 0x37, 0xe6, 0xd1, 0x65, 0xf4, 0xa9, + 0xc8, 0xef, 0x96, 0x24, 0xd3, 0x76, 0x6b, 0xab, 0xd5, 0x20, 0xe6, 0x46, 0x7e, 0xbf, 0xa7, 0x2e, + 0xd0, 0x43, 0x79, 0x68, 0xf4, 0xb4, 0x01, 0xe7, 0x0b, 0x46, 0x5b, 0x60, 0x1e, 0x9a, 0x43, 0x08, + 0xad, 0x81, 0x7f, 0x96, 0xc0, 0x94, 0x7a, 0x82, 0x7f, 0xdf, 0xeb, 0xf9, 0x2b, 0xa3, 0x5e, 0xbe, + 0x7d, 0xd9, 0x5f, 0xb1, 0x4b, 0x61, 0x9b, 0x07, 0x1e, 0x8f, 0x70, 0x0e, 0x69, 0x6c, 0x01, 0x4e, + 0x29, 0xe3, 0x36, 0x14, 0x45, 0xaa, 0xae, 0x26, 0xcb, 0xe2, 0xb2, 0xd7, 0xdb, 0xb6, 0x32, 0x03, + 0xb7, 0xd4, 0x2b, 0x33, 0x9c, 0x55, 0x91, 0xb9, 0x26, 0xe4, 0x15, 0x9d, 0x6e, 0x09, 0x61, 0xac, + 0x1f, 0x19, 0x19, 0x6c, 0x87, 0xa4, 0x40, 0x7b, 0x4d, 0x61, 0x32, 0xc0, 0xb3, 0x36, 0xe3, 0x45, + 0xf3, 0x68, 0xa8, 0x0f, 0xf2, 0xb2, 0x41, 0x79, 0x41, 0xfd, 0x91, 0x08, 0x9e, 0xf5, 0x79, 0x60, + 0x97, 0x1b, 0x60, 0xb7, 0x2b, 0xbc, 0x54, 0xaf, 0x41, 0x2e, 0xc8, 0x3d, 0xcd, 0x47, 0xb7, 0x46, + 0xbb, 0x08, 0xf1, 0xa9, 0x70, 0x9f, 0xb1, 0x51, 0x87, 0xaa, 0xa4, 0x63, 0x2e, 0x21, 0x47, 0xbb, + 0x57, 0x48, 0xd7, 0x65, 0x4d, 0x22, 0x80, 0x0d, 0xdc, 0xdc, 0xb2, 0xbd, 0x61, 0xa0, 0x5a, 0x3e, + 0xd6, 0x7b, 0x19, 0x88, 0x0f, 0x40, 0x1f, 0x40, 0x8b, 0xf8, 0x20, 0x34, 0xb0, 0x80, 0x86, 0x83, + 0x86, 0xaf, 0x71, 0x2d, 0x3c, 0x77, 0x01, 0xbd, 0x07, 0xba, 0xe4, 0xb8, 0x5e, 0xf0, 0xd9, 0xf0, + 0x5b, 0xad, 0x76, 0x4f, 0x7c, 0xe8, 0x2c, 0x46, 0xb7, 0x6e, 0xcd, 0xe7, 0x8c, 0x36, 0x23, 0x92, + 0x6d, 0x29, 0x67, 0x8f, 0xdb, 0xb7, 0x86, 0x30, 0xe4, 0x9e, 0x56, 0xda, 0x43, 0x1f, 0x62, 0x73, + 0x73, 0xd4, 0x23, 0xed, 0xae, 0xf1, 0x60, 0x5b, 0x10, 0x71, 0x55, 0x6b, 0xb7, 0x2c, 0x84, 0xe0, + 0x99, 0x27, 0x21, 0x6b, 0xab, 0x12, 0xd7, 0xdc, 0x0f, 0x98, 0x71, 0x8f, 0xad, 0x92, 0xae, 0xe7, + 0x78, 0x51, 0x1d, 0xbe, 0x32, 0x40, 0x7d, 0x70, 0x70, 0x7f, 0xc0, 0x6c, 0xfb, 0xa8, 0x2e, 0xd6, + 0x91, 0x02, 0x59, 0x06, 0xbf, 0x74, 0x56, 0x77, 0xde, 0x8a, 0xcb, 0x16, 0xd6, 0x53, 0x7c, 0xe0, + 0xdf, 0x56, 0xcb, 0x55, 0x2e, 0xd5, 0x75, 0x4e, 0xda, 0xec, 0xf3, 0xe2, 0xb9, 0xdd, 0x38, 0xfc, + 0x83, 0x35, 0x43, 0xff, 0x3b, 0x3d, 0xf1, 0xc7, 0x51, 0xfb, 0xf1, 0x61, 0xd3, 0x38, 0x99, 0x43, + 0xfd, 0x3f, 0xdf, 0xc1, 0x78, 0xd2, 0x80, 0x2c, 0x8f, 0x9e, 0x5f, 0xf1, 0x32, 0xea, 0xe2, 0xb2, + 0xe5, 0x57, 0xc1, 0x4c, 0x49, 0xa5, 0x8c, 0x51, 0xde, 0xb4, 0x87, 0x79, 0xce, 0xdf, 0x07, 0xf5, + 0xf6, 0xf0, 0xfc, 0x01, 0x9c, 0x14, 0xbf, 0xc1, 0xb3, 0xa5, 0xa2, 0x8f, 0xd1, 0x18, 0x09, 0x68, + 0xbc, 0xd3, 0x78, 0x34, 0x0b, 0x6d, 0xb1, 0x27, 0xb4, 0x49, 0x0d, 0xe2, 0x50, 0x52, 0xf2, 0x4b, + 0x62, 0x29, 0x1c, 0xaf, 0xe0, 0x78, 0x46, 0xa2, 0xe3, 0x61, 0x8d, 0x39, 0x07, 0x32, 0xce, 0x6f, + 0xcb, 0xfb, 0x0c, 0xc6, 0xa5, 0x6d, 0x51, 0xe2, 0x98, 0xde, 0x3e, 0x13, 0xcc, 0x0f, 0xed, 0x6d, + 0x82, 0x9e, 0x8f, 0x81, 0x5d, 0x99, 0x55, 0x7c, 0x6d, 0x59, 0x0f, 0x6a, 0x88, 0x10, 0x93, 0x53, + 0x5d, 0x61, 0xeb, 0xf0, 0x0c, 0xe2, 0x51, 0x56, 0xdc, 0x69, 0x18, 0x0b, 0xb0, 0xc8, 0x7b, 0xd4, + 0x07, 0xd4, 0xa1, 0x0a, 0xc6, 0x07, 0xbe, 0xb6, 0x27, 0xc5, 0xf5, 0xce, 0x9c, 0xed, 0x6b, 0x8a, + 0x36, 0x2c, 0x99, 0x96, 0xda, 0x6c, 0x8b, 0xcf, 0xca, 0x76, 0xbf, 0x6b, 0x42, 0xa4, 0x0a, 0xdf, + 0xc7, 0xca, 0x76, 0xb6, 0x6b, 0x2a, 0xb6, 0x5d, 0xda, 0x5a, 0x83, 0x5a, 0xbb, 0xfe, 0xb2, 0x83, + 0x3c, 0xb7, 0x0f, 0xe3, 0xab, 0x8a, 0xa6, 0x95, 0x4c, 0xa7, 0xf9, 0xe6, 0x5c, 0xc0, 0xae, 0x72, + 0xc2, 0xff, 0x3c, 0x11, 0x24, 0xa0, 0x28, 0x37, 0x78, 0xbf, 0x1c, 0xbc, 0xcb, 0x06, 0xf6, 0xc2, + 0x1a, 0x4a, 0x54, 0x37, 0x9d, 0x9e, 0xb4, 0x07, 0x68, 0x53, 0xeb, 0xbd, 0x3c, 0x07, 0x76, 0xfb, + 0x54, 0x16, 0x9e, 0x7b, 0x72, 0xa2, 0xad, 0x58, 0x51, 0x1d, 0x21, 0xac, 0x1b, 0x8c, 0x8f, 0xdb, + 0x9e, 0x1f, 0xfb, 0xf1, 0x8c, 0xe3, 0xc6, 0x31, 0xa4, 0xce, 0x78, 0x6c, 0x75, 0x53, 0x10, 0xab, + 0x4b, 0xf9, 0x3f, 0x1a, 0xa7, 0x1a, 0x95, 0x0e, 0x2f, 0x59, 0x12, 0xad, 0x43, 0xbc, 0x64, 0x6e, + 0x15, 0xc2, 0xca, 0x65, 0xf0, 0x97, 0x0b, 0x52, 0xc6, 0xda, 0xbf, 0xf0, 0xae, 0x33, 0x0c, 0x6e, + 0x2b, 0xf5, 0x21, 0x86, 0xc7, 0xb8, 0x70, 0x21, 0x4a, 0xc7, 0x67, 0x18, 0x48, 0xd7, 0xa0, 0xe6, + 0x32, 0xe4, 0xa5, 0x72, 0x69, 0x2f, 0x32, 0xf3, 0x5e, 0x85, 0x3b, 0x89, 0xd9, 0x8d, 0x79, 0xa3, + 0xc1, 0xd9, 0xcf, 0x75, 0x48, 0x4c, 0x20, 0x66, 0x96, 0xea, 0x82, 0xff, 0xd2, 0xe8, 0x0e, 0x73, + 0x20, 0xd1, 0x62, 0xb9, 0xcb, 0xb9, 0x4f, 0xbd, 0x29, 0x91, 0x25, 0xcc, 0x2d, 0xf3, 0x99, 0xb9, + 0x52, 0xe9, 0x28, 0xf3, 0x70, 0xde, 0xd6, 0x0d, 0x6b, 0x2c, 0xc3, 0x7d, 0xab, 0x4a, 0xdc, 0x47, + 0x7e, 0xd8, 0x96, 0xac, 0x82, 0x2e, 0xcd, 0xbb, 0xf5, 0x4c, 0xbb, 0x2e, 0x09, 0x3d, 0x0d, 0x72, + 0x5d, 0xdb, 0x53, 0x4c, 0xdb, 0x6d, 0xf9, 0xfe, 0x63, 0x67, 0x26, 0xe5, 0x7a, 0x7e, 0x78, 0x7e, + 0x05, 0xf1, 0x0b, 0xcd, 0x77, 0xf0, 0xfc, 0x0e, 0x9f, 0x49, 0x5a, 0xaf, 0x21, 0xc9, 0xbd, 0x06, + 0xc4, 0x40, 0x44, 0x12, 0x07, 0x20, 0xdf, 0x1b, 0x3c, 0xdf, 0x00, 0xb9, 0x2e, 0xbf, 0xdc, 0x5a, + 0xd5, 0xcc, 0x66, 0x76, 0x7b, 0x2b, 0x8c, 0x56, 0xa4, 0xd7, 0xca, 0x83, 0x93, 0x9a, 0x36, 0xf3, + 0xc5, 0xfb, 0xae, 0xbc, 0x28, 0xce, 0xba, 0x36, 0xe7, 0xb9, 0x10, 0x93, 0x34, 0x6e, 0x27, 0xa4, + 0xbb, 0x6f, 0x56, 0x0d, 0x61, 0x94, 0x59, 0x0f, 0x6e, 0x73, 0xd9, 0x6a, 0x56, 0xdf, 0xf2, 0x9e, + 0xc3, 0x71, 0xf7, 0x9e, 0x1f, 0xb8, 0xf2, 0xa0, 0x14, 0xc8, 0x35, 0x9e, 0x0b, 0xf9, 0xed, 0xc0, + 0x2f, 0x95, 0x1e, 0x20, 0x2f, 0x8c, 0x0e, 0x20, 0xb3, 0x06, 0xbf, 0xc9, 0xd2, 0x33, 0xc9, 0xb2, + 0x4a, 0x9a, 0x19, 0xb0, 0x1b, 0xe5, 0x30, 0x2e, 0xa7, 0x67, 0x30, 0xf5, 0xc4, 0x29, 0x74, 0x70, + 0x9e, 0xb9, 0x6f, 0x67, 0x5a, 0x24, 0x71, 0x80, 0x79, 0x2b, 0x5e, 0xbe, 0x67, 0xc0, 0xdb, 0x17, + 0x0f, 0x5a, 0x71, 0x1e, 0x8b, 0x07, 0x77, 0x2d, 0x19, 0xfa, 0xf9, 0x0e, 0xb6, 0x15, 0x6c, 0xd7, + 0xe9, 0xc9, 0x35, 0x83, 0xed, 0xa6, 0x0f, 0xed, 0x0a, 0xf6, 0x13, 0x27, 0x6e, 0xf3, 0x2e, 0x8e, + 0x77, 0x82, 0x62, 0x14, 0xbd, 0xdb, 0x80, 0xe3, 0x07, 0xf1, 0xfc, 0x26, 0xf6, 0x97, 0x95, 0xb8, + 0x4d, 0xe7, 0x0b, 0x74, 0xbd, 0x5a, 0x0c, 0x9f, 0xa7, 0x84, 0xa0, 0xf0, 0x0e, 0x6d, 0x72, 0x68, + 0x73, 0x87, 0xf9, 0x0d, 0x21, 0x9a, 0x1f, 0xac, 0x47, 0xe1, 0x05, 0xfd, 0x2f, 0x01, 0x7e, 0xe1, + 0x8e, 0x6c, 0x34, 0x7a, 0x3a, 0xce, 0x56, 0x0d, 0x0e, 0xec, 0x68, 0x9d, 0x7b, 0x22, 0x10, 0x4e, + 0xcf, 0x7c, 0x7e, 0x42, 0x1e, 0xab, 0x64, 0x0f, 0xfc, 0x26, 0xed, 0x2c, 0x47, 0x6c, 0xa1, 0x4e, + 0xba, 0x73, 0x4e, 0xf2, 0x2b, 0xb2, 0xa1, 0xb8, 0x9c, 0xea, 0x57, 0x45, 0xf2, 0xfc, 0xc2, 0x81, + 0x39, 0x69, 0x1b, 0x63, 0x83, 0xcb, 0x0d, 0x6b, 0x5b, 0xc3, 0xd8, 0xf1, 0x0d, 0xa3, 0xbe, 0x26, + 0x33, 0x97, 0xef, 0xa1, 0xd1, 0xb6, 0xfa, 0x7c, 0xdf, 0x6e, 0x38, 0xc4, 0x5e, 0xf3, 0xf6, 0xb0, + 0xe9, 0x1a, 0x31, 0x3f, 0x5f, 0x48, 0xc5, 0xa5, 0x05, 0x39, 0xfa, 0x32, 0x2e, 0x51, 0x9a, 0xbe, + 0x9e, 0x48, 0x33, 0x7f, 0xe0, 0x8f, 0x14, 0x5c, 0xd5, 0x20, 0x87, 0x79, 0x35, 0x52, 0x4e, 0xf0, + 0xcf, 0x87, 0x7e, 0x88, 0xf3, 0xa2, 0x36, 0x1a, 0x76, 0x7a, 0xc8, 0x1c, 0xb5, 0xb1, 0x9e, 0x00, + 0x0a, 0x1d, 0xb7, 0xb1, 0xde, 0xc7, 0x33, 0x71, 0x1b, 0x52, 0x1c, 0x7a, 0x4e, 0x87, 0xbe, 0x80, + 0xc3, 0xab, 0x1c, 0x94, 0x47, 0xf5, 0x43, 0xdb, 0x00, 0x7c, 0xca, 0xf6, 0xa1, 0xed, 0x43, 0x3f, + 0x3f, 0x8f, 0xdb, 0xc1, 0x25, 0xa2, 0x43, 0x3f, 0xac, 0xd7, 0xc7, 0x92, 0x40, 0xdc, 0x36, 0x70, + 0x7c, 0x29, 0x6e, 0xc3, 0x7a, 0x68, 0x80, 0x58, 0x70, 0xd9, 0x2c, 0xa9, 0x5a, 0xfd, 0x67, 0xd0, + 0x1e, 0xb5, 0xff, 0xb0, 0xae, 0x97, 0x85, 0xb5, 0x48, 0xb8, 0x3e, 0xa9, 0xca, 0x44, 0x33, 0xb8, + 0x3d, 0xa9, 0xce, 0xc9, 0xc8, 0xe7, 0xd6, 0xb8, 0x7b, 0x51, 0x22, 0x6b, 0x52, 0xe6, 0xa2, 0x39, + 0xd1, 0x67, 0xf7, 0xb9, 0x3f, 0x66, 0x47, 0xd5, 0xca, 0x8e, 0x40, 0xf2, 0xf0, 0x2c, 0x71, 0x4b, + 0x52, 0x93, 0x31, 0x88, 0x9f, 0x92, 0x5a, 0x23, 0x1a, 0x53, 0x1d, 0x65, 0xc1, 0xbe, 0x56, 0xc7, + 0xd6, 0x68, 0xa1, 0xec, 0x86, 0x83, 0x8e, 0xf5, 0xcc, 0x73, 0xa6, 0xde, 0xe5, 0x1a, 0xc3, 0xec, + 0x43, 0x6b, 0x94, 0x7d, 0x58, 0xd3, 0xfa, 0x7a, 0xb5, 0x44, 0x46, 0x06, 0xc7, 0xe0, 0x5a, 0xcf, + 0x3e, 0x67, 0x91, 0x6a, 0x1e, 0xe1, 0xed, 0x48, 0x55, 0x20, 0x63, 0x82, 0x6d, 0x09, 0x2b, 0xaf, + 0x26, 0xa9, 0xcd, 0xf1, 0xb3, 0x41, 0x40, 0x0a, 0x00, 0xb7, 0x16, 0x9d, 0x47, 0x71, 0xc4, 0x2b, + 0x2f, 0x98, 0x47, 0xbc, 0xef, 0xf5, 0x39, 0x35, 0xb1, 0x9d, 0x85, 0xea, 0x7d, 0xfa, 0x88, 0x77, + 0x84, 0x3e, 0x7e, 0xfe, 0xf6, 0xe7, 0x1f, 0x7f, 0xff, 0xf9, 0xc7, 0x9f, 0x7f, 0x7c, 0x75, 0x6c, + 0xdb, 0xc3, 0x3b, 0x47, 0xe9, 0xb4, 0x96, 0x1e, 0x19, 0x5f, 0x53, 0x1f, 0x58, 0x96, 0xfd, 0x16, + 0x34, 0xbd, 0x2d, 0x34, 0x27, 0x93, 0x49, 0xd8, 0xcc, 0xa6, 0xa0, 0x99, 0xcd, 0x66, 0xc3, 0x66, + 0x0e, 0x9b, 0xb9, 0x5c, 0x2e, 0x6c, 0xe6, 0xb1, 0x99, 0xcf, 0xe7, 0xc3, 0x66, 0x01, 0x9b, 0x85, + 0x42, 0x21, 0x6c, 0x16, 0xb1, 0x59, 0x2c, 0x16, 0xc3, 0x66, 0x09, 0x9b, 0xa5, 0x52, 0x29, 0x6c, + 0x8e, 0xb0, 0x39, 0x1a, 0x8d, 0xc2, 0xa6, 0x86, 0x4d, 0x4d, 0xd3, 0xc2, 0xa6, 0x8e, 0x4d, 0x5d, + 0xd7, 0xc3, 0xe6, 0x18, 0x9b, 0xe3, 0xf1, 0x38, 0x6c, 0x3a, 0xfa, 0xf8, 0xeb, 0x87, 0x52, 0x8e, + 0x8d, 0x36, 0x84, 0x57, 0xf0, 0x70, 0x3f, 0x9e, 0xbd, 0xd6, 0xa6, 0x69, 0x95, 0x5e, 0xbf, 0xfa, + 0x9a, 0x5a, 0xa8, 0x4b, 0x73, 0xb5, 0xb6, 0xe8, 0x65, 0xa9, 0x68, 0xe4, 0xc8, 0x1e, 0xef, 0x70, + 0xe4, 0x42, 0x75, 0x0c, 0x13, 0xc6, 0x30, 0xd0, 0x81, 0x77, 0xb4, 0x0c, 0xc7, 0x5e, 0x2f, 0xc7, + 0xc1, 0xdd, 0xb9, 0xaf, 0xa9, 0x8d, 0xea, 0x7c, 0x0a, 0x68, 0x83, 0x34, 0x3b, 0xba, 0x99, 0x55, + 0xd3, 0xad, 0x8d, 0xee, 0x99, 0x9a, 0xfa, 0x25, 0xa5, 0xe8, 0xce, 0x58, 0x5d, 0xc2, 0x17, 0x57, + 0x5d, 0xba, 0x69, 0x57, 0x77, 0xcc, 0x49, 0x34, 0xda, 0x35, 0xf7, 0xfa, 0xd7, 0x14, 0x7b, 0xbf, + 0xda, 0xc2, 0x93, 0x13, 0xa0, 0xde, 0x16, 0x81, 0x7a, 0xfa, 0xd6, 0x4b, 0xab, 0x96, 0x69, 0x00, + 0x12, 0x9a, 0xbe, 0xf4, 0x74, 0x07, 0xf7, 0xe6, 0xeb, 0xa3, 0xb9, 0xe9, 0xa5, 0x83, 0x7d, 0x68, + 0xaa, 0x65, 0xd9, 0x6b, 0xef, 0x6b, 0x6a, 0x69, 0x2f, 0xf5, 0x44, 0xef, 0x1a, 0x96, 0x82, 0xe5, + 0x2c, 0x5d, 0x4b, 0xf4, 0x2d, 0xec, 0xfd, 0x95, 0x0e, 0xf7, 0xe2, 0xf3, 0x8b, 0x63, 0xa3, 0xe5, + 0xd5, 0x55, 0x7a, 0x6a, 0x1a, 0x53, 0xc0, 0x6e, 0xea, 0x45, 0x34, 0xf1, 0x1c, 0xd8, 0xe5, 0x4a, + 0x75, 0x00, 0xd7, 0x24, 0xd9, 0xbf, 0x1c, 0x68, 0x3a, 0xd5, 0x71, 0x3c, 0x6c, 0x9b, 0x61, 0xfe, + 0x17, 0x0c, 0xa1, 0x97, 0x1b, 0xe3, 0xd6, 0xca, 0x76, 0xcd, 0x80, 0x2d, 0x13, 0x73, 0xab, 0x23, + 0x23, 0xed, 0x8d, 0xee, 0xb8, 0x9a, 0x63, 0x5b, 0x56, 0x7a, 0xa4, 0x4f, 0xd5, 0x8d, 0x89, 0xab, + 0x84, 0x98, 0x50, 0xf0, 0xab, 0x24, 0xa3, 0x58, 0x66, 0xb5, 0x4d, 0x31, 0xa9, 0x2c, 0xbe, 0x9f, + 0xd3, 0x74, 0x1c, 0xcb, 0xf6, 0x68, 0xed, 0x79, 0xf6, 0x12, 0x67, 0x02, 0xe9, 0x2c, 0x73, 0xa9, + 0xc7, 0x30, 0xb5, 0xb5, 0xe3, 0xe2, 0x9c, 0x95, 0x6d, 0x86, 0xe4, 0xa6, 0x13, 0xee, 0x2c, 0x75, + 0xa4, 0x5b, 0xee, 0xa9, 0x50, 0xac, 0xd4, 0xf1, 0xd8, 0x5c, 0x82, 0x6e, 0x94, 0x8e, 0xd6, 0xa5, + 0x53, 0x3e, 0xe0, 0x9d, 0x49, 0x3a, 0x0d, 0x67, 0x9d, 0xef, 0x6c, 0x64, 0x03, 0x0e, 0x8b, 0xaf, + 0xa9, 0xfb, 0x2c, 0xe5, 0xbf, 0x13, 0x90, 0x25, 0x7f, 0x49, 0x18, 0x8a, 0x88, 0xb8, 0xef, 0x00, + 0x80, 0xa5, 0x01, 0x3c, 0x1c, 0x03, 0xba, 0x40, 0x16, 0x94, 0x2f, 0x2b, 0xed, 0x58, 0x31, 0x8e, + 0x23, 0xc7, 0xa4, 0x4b, 0x45, 0x48, 0x05, 0xb0, 0x82, 0x3e, 0xdf, 0x51, 0x57, 0x2b, 0xdd, 0xb9, + 0x8c, 0x8a, 0x67, 0xaf, 0x82, 0xfd, 0x58, 0xfa, 0xc4, 0x0b, 0xbe, 0x85, 0xe8, 0x1c, 0x4b, 0xfe, + 0x01, 0xa3, 0x2c, 0x62, 0xb4, 0x4f, 0x9b, 0xcb, 0xb1, 0x0e, 0xa6, 0x20, 0x56, 0xb1, 0x3b, 0xbc, + 0xd4, 0xe9, 0x9e, 0x5d, 0x54, 0xfc, 0x18, 0x5c, 0x54, 0xfc, 0x18, 0x0b, 0x3e, 0xde, 0x6d, 0x44, + 0x92, 0x83, 0xdd, 0xb1, 0x8e, 0xb5, 0x21, 0x1b, 0x20, 0x8d, 0x3c, 0x49, 0xc7, 0xa2, 0x02, 0x0f, + 0xc6, 0xa6, 0xbb, 0xb2, 0x54, 0x80, 0x65, 0x2e, 0x69, 0xdf, 0xc8, 0xb2, 0xb5, 0xf9, 0xb7, 0x03, + 0x37, 0xd2, 0x94, 0xf6, 0xb8, 0xe5, 0x03, 0x07, 0xee, 0xa6, 0x6b, 0xe3, 0x70, 0x6b, 0x32, 0x80, + 0x9f, 0xcf, 0x26, 0x88, 0x62, 0x2e, 0x27, 0x81, 0x89, 0xf3, 0xf0, 0x06, 0x6b, 0x1a, 0xe0, 0x53, + 0x4d, 0x8a, 0xc8, 0x72, 0x2c, 0x9b, 0xc1, 0x14, 0x57, 0x37, 0xde, 0x9e, 0x71, 0x5f, 0x3c, 0x9e, + 0x30, 0xa6, 0x33, 0x2e, 0xe9, 0x32, 0x7d, 0x48, 0x95, 0x06, 0x8d, 0xf0, 0xd7, 0xd4, 0x1a, 0x99, + 0xa4, 0xa9, 0xae, 0x7e, 0x62, 0x23, 0x92, 0xac, 0x9c, 0xeb, 0xbb, 0x73, 0x88, 0xc8, 0xb9, 0x83, + 0x40, 0xa6, 0x23, 0xe1, 0x2a, 0x25, 0xe6, 0x6d, 0x54, 0xeb, 0x7c, 0x1e, 0xe5, 0xf3, 0x1b, 0x13, + 0x5d, 0xcb, 0x1c, 0x83, 0x1d, 0x40, 0xde, 0xfe, 0xf9, 0x07, 0xce, 0x3f, 0xe0, 0x4b, 0xbf, 0x82, + 0xf1, 0xd4, 0x87, 0x9f, 0x72, 0x2b, 0x6a, 0xb2, 0xae, 0xea, 0x1c, 0x50, 0xc2, 0xa2, 0x30, 0x92, + 0x4a, 0x94, 0x66, 0x81, 0x61, 0xc8, 0xba, 0x42, 0xc8, 0xb8, 0x58, 0xae, 0x43, 0xfc, 0x16, 0xe6, + 0x78, 0x6c, 0xe9, 0xaf, 0xc2, 0x9d, 0x58, 0x54, 0xac, 0x27, 0x96, 0xad, 0x7a, 0x87, 0x0d, 0x9d, + 0x2b, 0x72, 0x52, 0x71, 0x2f, 0x5b, 0xdb, 0xc3, 0xbe, 0x1c, 0xdb, 0x83, 0x4d, 0x7d, 0x62, 0xc6, + 0xba, 0x11, 0xf7, 0x84, 0x4a, 0x13, 0x8f, 0x4a, 0x31, 0x77, 0x39, 0x37, 0xc6, 0x42, 0xdf, 0x52, + 0x4b, 0x74, 0x0e, 0x83, 0x2d, 0x45, 0x50, 0x42, 0xa1, 0xa3, 0xf6, 0xe0, 0x9a, 0x3c, 0x5f, 0xdd, + 0x7f, 0x60, 0x53, 0x2c, 0x73, 0xa3, 0xe3, 0x7d, 0xf1, 0xa4, 0x25, 0x0d, 0x64, 0x23, 0x06, 0x18, + 0x1a, 0xb2, 0x63, 0xe1, 0x1d, 0xd9, 0x0e, 0xb0, 0x10, 0xf6, 0x9e, 0x60, 0x2b, 0x88, 0x30, 0x82, + 0xb9, 0xee, 0xd8, 0xb2, 0xd7, 0xf8, 0x39, 0x31, 0x2d, 0x0f, 0xa1, 0x8d, 0x1d, 0x7b, 0x95, 0x76, + 0xa7, 0xea, 0xd8, 0xf6, 0x3f, 0x51, 0xcb, 0x1b, 0xfe, 0xc3, 0x48, 0xe1, 0xb0, 0xe1, 0x51, 0xa0, + 0x63, 0xd7, 0x2d, 0xe0, 0xb1, 0xe5, 0xb9, 0xa4, 0x75, 0x88, 0xea, 0xc1, 0x66, 0x9f, 0x63, 0x6c, + 0x2e, 0xa7, 0xe0, 0x58, 0x91, 0xed, 0xa1, 0x14, 0x84, 0xea, 0x10, 0x6d, 0x3b, 0xa4, 0x49, 0x92, + 0x8d, 0x21, 0xf3, 0xde, 0x74, 0xc4, 0xda, 0x61, 0x23, 0x60, 0x26, 0x13, 0x58, 0xc4, 0x66, 0x16, + 0x95, 0x33, 0x7c, 0x63, 0xc2, 0x6f, 0x38, 0x25, 0x75, 0xf9, 0x15, 0x93, 0xe4, 0x12, 0xa4, 0xc0, + 0x7d, 0x95, 0x42, 0x5d, 0x08, 0x28, 0x91, 0x2d, 0x5c, 0xa2, 0xc3, 0xd7, 0x29, 0x7a, 0xc6, 0xd7, + 0xf9, 0x97, 0xbb, 0xc0, 0x3f, 0xfd, 0xf3, 0x05, 0x60, 0x77, 0x18, 0x0c, 0x6d, 0xf4, 0xd7, 0xa1, + 0x15, 0x2f, 0x40, 0x0b, 0xf4, 0x26, 0x00, 0xf7, 0x3e, 0x18, 0xa9, 0x7f, 0x99, 0x0b, 0xfc, 0x63, + 0x07, 0x95, 0x06, 0x08, 0xaf, 0x80, 0xc3, 0xbf, 0x3f, 0x50, 0x41, 0x33, 0x9c, 0x20, 0x04, 0x5d, + 0x06, 0x6e, 0xe0, 0x58, 0x38, 0xc2, 0x16, 0xa8, 0x8b, 0xf6, 0x29, 0x80, 0xb1, 0xfc, 0xfc, 0x5f, + 0xd8, 0x87, 0x60, 0x22, 0xf5, 0xa0, 0xbd, 0xf8, 0x30, 0x95, 0x0e, 0x17, 0xf2, 0x56, 0x5f, 0x52, + 0x45, 0x20, 0xf5, 0xe7, 0xf8, 0xc9, 0xc8, 0x0b, 0x9f, 0x7c, 0x8e, 0xed, 0x44, 0x9a, 0x3a, 0xc5, + 0x93, 0x09, 0xdf, 0x2e, 0x1b, 0xbf, 0x4f, 0x09, 0x0c, 0xbc, 0xed, 0x97, 0x14, 0x85, 0x7d, 0x1b, + 0x4e, 0x36, 0xa1, 0xfd, 0x39, 0x13, 0xa3, 0x97, 0xa6, 0xf8, 0x7d, 0x7e, 0x4f, 0x68, 0x83, 0x1c, + 0x0a, 0xff, 0x0c, 0x23, 0x61, 0xe0, 0x22, 0x4b, 0x1f, 0xab, 0x93, 0xa3, 0x63, 0xf4, 0xba, 0x39, + 0x57, 0xfa, 0x24, 0x79, 0xf0, 0x51, 0x8c, 0xc4, 0xe7, 0x64, 0xe8, 0xc2, 0xb2, 0xa1, 0xb8, 0x8d, + 0xec, 0x2d, 0x6a, 0x02, 0x7d, 0x18, 0x28, 0x0e, 0x78, 0x83, 0xed, 0x99, 0xf1, 0x40, 0xb4, 0x01, + 0x15, 0xff, 0x6b, 0x4a, 0x5d, 0x7b, 0xf6, 0xb7, 0xb3, 0x88, 0xee, 0xcd, 0x6d, 0x7d, 0x10, 0x26, + 0x13, 0x08, 0x28, 0xdd, 0x84, 0xe8, 0xa7, 0xe3, 0x08, 0x24, 0x5c, 0x98, 0xb6, 0x29, 0x66, 0xae, + 0x0d, 0xde, 0xe7, 0x24, 0xd6, 0x0e, 0xfd, 0xc9, 0x02, 0x12, 0x94, 0x69, 0xea, 0xaf, 0xd4, 0x65, + 0xeb, 0x9c, 0x14, 0x8b, 0xc9, 0x97, 0x14, 0xfb, 0xf9, 0xbf, 0xee, 0x0a, 0xee, 0xe7, 0x94, 0x0e, + 0xce, 0x35, 0x0d, 0x4e, 0x3b, 0x15, 0x93, 0x38, 0x1d, 0x07, 0x69, 0xb1, 0x87, 0x80, 0xff, 0xd2, + 0x91, 0x47, 0x3a, 0xf5, 0x8c, 0x49, 0x57, 0x8c, 0x7b, 0x05, 0xa3, 0x7b, 0xd9, 0xbc, 0xbd, 0x1a, + 0xe9, 0x5e, 0x08, 0xb9, 0xde, 0x50, 0xe4, 0xf3, 0x20, 0x29, 0x36, 0xf9, 0x13, 0x4b, 0xc7, 0x36, + 0x75, 0x19, 0x69, 0xd3, 0xd3, 0x17, 0x6e, 0x22, 0xc4, 0x98, 0xad, 0x5d, 0xcf, 0x9c, 0xec, 0xd2, + 0xa1, 0x24, 0x25, 0x7a, 0x0e, 0xf1, 0x1b, 0xaa, 0x96, 0xbd, 0x52, 0x35, 0xd3, 0xdb, 0xa1, 0x65, + 0x7c, 0x28, 0x9c, 0x19, 0xcb, 0x7b, 0x97, 0xca, 0x1c, 0xf5, 0xa5, 0x69, 0x7d, 0x03, 0x20, 0xdc, + 0x13, 0x61, 0x75, 0x3d, 0x75, 0x87, 0x16, 0x32, 0xe9, 0xdc, 0x22, 0xaf, 0x76, 0x20, 0x4e, 0x94, + 0x3d, 0x00, 0x4e, 0xda, 0x7c, 0x77, 0xd4, 0x15, 0x3f, 0xba, 0x14, 0x70, 0x06, 0x8c, 0x0f, 0xa8, + 0x46, 0x37, 0x7f, 0x14, 0x7c, 0x26, 0x55, 0x96, 0x3d, 0xf0, 0xe7, 0x43, 0x88, 0x13, 0x1b, 0xa4, + 0x7d, 0xd0, 0x99, 0x7d, 0x38, 0xef, 0xcd, 0xc6, 0xbd, 0x85, 0x44, 0xd4, 0xf3, 0xc1, 0xb3, 0x55, + 0x97, 0xea, 0xdd, 0x81, 0x30, 0xaf, 0x32, 0xa9, 0x10, 0xd8, 0x8e, 0x6d, 0x3a, 0x64, 0xf4, 0x03, + 0xe5, 0xf3, 0xfb, 0xd3, 0xba, 0x50, 0xf2, 0x1d, 0x75, 0x6c, 0xae, 0x81, 0xb6, 0x05, 0x8a, 0xca, + 0x41, 0x4b, 0x8b, 0x41, 0xfb, 0x4c, 0xca, 0x62, 0x3a, 0x14, 0x62, 0x61, 0x2a, 0x04, 0x12, 0x76, + 0xc1, 0x50, 0x0d, 0x3e, 0xa5, 0x0b, 0x81, 0x75, 0x8c, 0xa4, 0x19, 0xc4, 0x91, 0x02, 0x3e, 0xf7, + 0x83, 0xaf, 0x31, 0x3b, 0x20, 0xce, 0x9d, 0x3b, 0xb5, 0xfd, 0x23, 0x0a, 0x21, 0x2f, 0x20, 0x9f, + 0x5e, 0xa8, 0x21, 0x8e, 0xea, 0x58, 0x37, 0x97, 0x20, 0x3d, 0x05, 0xf7, 0x4b, 0xb2, 0x91, 0xca, + 0xe2, 0x9b, 0xa3, 0xa3, 0xa5, 0x38, 0x85, 0xa9, 0x3b, 0x8e, 0xed, 0x9c, 0x01, 0x3d, 0x27, 0xfb, + 0x87, 0x51, 0xf6, 0xfa, 0x6a, 0xb1, 0x50, 0x42, 0xb2, 0xa4, 0x1e, 0xe7, 0x5f, 0x11, 0xdd, 0x42, + 0xbd, 0x5b, 0x6d, 0x93, 0x81, 0x48, 0x32, 0x13, 0x0b, 0xbb, 0xce, 0x17, 0xce, 0x66, 0xb3, 0xfa, + 0x15, 0xfa, 0x0e, 0x3f, 0x45, 0xde, 0xe7, 0x5a, 0xc4, 0x98, 0x77, 0xbf, 0x1d, 0xa7, 0x8d, 0x27, + 0x9a, 0x7d, 0xc5, 0xc6, 0x06, 0x14, 0xc2, 0x7c, 0x05, 0x37, 0x13, 0xf3, 0x3c, 0x17, 0x77, 0x39, + 0x51, 0x38, 0x10, 0xf7, 0x65, 0x8f, 0xfb, 0x40, 0xd8, 0x5f, 0xcb, 0xfe, 0xee, 0x03, 0x79, 0x0b, + 0xa8, 0xc2, 0x5e, 0x8c, 0x28, 0xaf, 0xa4, 0xc6, 0x1f, 0xcc, 0x85, 0x41, 0xa5, 0x20, 0x94, 0xfb, + 0x6c, 0x28, 0x51, 0x91, 0xf9, 0x2b, 0x14, 0x8e, 0xa1, 0x9d, 0x04, 0xbc, 0x01, 0x8c, 0xf9, 0x26, + 0xb0, 0xbf, 0xb1, 0xf6, 0xe4, 0x1f, 0x98, 0x77, 0x4c, 0xb3, 0x4e, 0xa7, 0x15, 0x99, 0xf7, 0x4c, + 0x9b, 0xea, 0xaa, 0xe3, 0xc5, 0xd1, 0x7a, 0x48, 0x0e, 0xca, 0x5e, 0x34, 0x7e, 0xa7, 0x61, 0x61, + 0x31, 0x19, 0x16, 0x7e, 0x98, 0x30, 0x71, 0x7e, 0x09, 0x1b, 0x3f, 0x59, 0x3e, 0x34, 0xee, 0xf8, + 0xe4, 0xc4, 0xfa, 0xd3, 0x09, 0xff, 0x86, 0xd4, 0x6d, 0xe2, 0xa8, 0x0b, 0xdd, 0x8d, 0x84, 0x15, + 0xdd, 0xba, 0x63, 0x2f, 0x52, 0x7f, 0x1d, 0x62, 0xe1, 0x54, 0xc2, 0xde, 0xfc, 0x8d, 0xdc, 0x39, + 0x74, 0x06, 0xca, 0x9a, 0x4a, 0x68, 0xc6, 0xdf, 0xc7, 0x39, 0x5a, 0xb8, 0x6d, 0x04, 0x1b, 0x99, + 0xfb, 0x8f, 0x1f, 0x8f, 0xcc, 0x86, 0x3a, 0x02, 0x87, 0xba, 0xf6, 0xf4, 0x88, 0xef, 0x6c, 0x0e, + 0x21, 0xc6, 0x0b, 0xe4, 0x92, 0x52, 0x40, 0x17, 0x73, 0xa2, 0x6d, 0x9c, 0xa8, 0xc3, 0xc1, 0xa6, + 0xe5, 0x3f, 0x9f, 0x5b, 0xaf, 0xd7, 0x6d, 0x48, 0x2c, 0xa3, 0xe9, 0xb8, 0x72, 0x60, 0x2e, 0x57, + 0x6b, 0xef, 0xff, 0x78, 0xbb, 0x95, 0xfe, 0x03, 0x78, 0x62, 0xe8, 0xff, 0x4d, 0xc3, 0xbe, 0xd0, + 0x59, 0x60, 0xe9, 0x42, 0x85, 0xc7, 0x9a, 0x7e, 0x9a, 0xde, 0x64, 0x43, 0x85, 0x89, 0x35, 0x2a, + 0x68, 0xc6, 0x8e, 0x3c, 0x0a, 0xca, 0xa3, 0x2f, 0x17, 0x35, 0xfa, 0xb8, 0x68, 0x75, 0x51, 0xcc, + 0xcf, 0xd0, 0xfb, 0x3a, 0xb1, 0xb5, 0xb5, 0x7b, 0xa9, 0x82, 0x74, 0x71, 0xf4, 0xd7, 0xd8, 0xef, + 0x05, 0xb9, 0xb4, 0xb3, 0x5e, 0x2e, 0x69, 0x05, 0x01, 0xd6, 0xd6, 0xe6, 0x09, 0xed, 0x09, 0xc5, + 0x25, 0x92, 0x9e, 0x5c, 0x80, 0xf3, 0x39, 0x4e, 0x49, 0x46, 0x38, 0xc6, 0x48, 0xfd, 0xc4, 0x40, + 0x98, 0x19, 0xfc, 0xff, 0xf9, 0xbd, 0x48, 0x78, 0xd3, 0xf5, 0x62, 0x74, 0x54, 0x93, 0x0b, 0x44, + 0x3d, 0x42, 0xa5, 0xb8, 0xda, 0x5e, 0xe5, 0xec, 0x25, 0x41, 0x08, 0x9c, 0xdb, 0x39, 0xae, 0xaf, + 0xb0, 0x31, 0xe9, 0xb8, 0xef, 0x23, 0xe7, 0x7b, 0x09, 0x73, 0xac, 0x5c, 0xd2, 0xc6, 0x3b, 0x29, + 0x76, 0xce, 0xe5, 0xf7, 0x53, 0x29, 0xb1, 0x56, 0x44, 0xa1, 0x44, 0x08, 0x1c, 0x46, 0xa4, 0x17, + 0xc0, 0xfd, 0x8f, 0x92, 0xf1, 0xb2, 0x7b, 0xb9, 0x5f, 0x6d, 0x5f, 0x43, 0xdc, 0xfd, 0x65, 0xea, + 0x9c, 0x4a, 0x7f, 0x88, 0xe6, 0x65, 0xcd, 0xb8, 0x52, 0xe3, 0xbd, 0x82, 0xca, 0xc4, 0x84, 0x14, + 0x00, 0x9c, 0xd8, 0x69, 0x9a, 0xfa, 0x8b, 0x10, 0xd6, 0x51, 0xdd, 0xf2, 0x9f, 0x40, 0xf8, 0x67, + 0x22, 0x5e, 0x7c, 0x83, 0x37, 0x49, 0xa9, 0x4d, 0xb3, 0x89, 0x8a, 0xe2, 0x07, 0x1f, 0xeb, 0xac, + 0x47, 0x21, 0xf0, 0x71, 0x8c, 0x4c, 0x15, 0x2f, 0x1a, 0x73, 0xc2, 0x94, 0xc8, 0xa4, 0xe5, 0x99, + 0x93, 0x50, 0x2f, 0x91, 0xe0, 0x85, 0x60, 0x7c, 0x37, 0xe9, 0x70, 0x93, 0x18, 0xdc, 0xb9, 0x66, + 0xb2, 0x8f, 0x7d, 0xc0, 0xe2, 0xda, 0x51, 0xce, 0x1d, 0x20, 0x3a, 0x72, 0xcc, 0x08, 0x8d, 0x93, + 0xc2, 0x59, 0xd0, 0xbf, 0x82, 0x58, 0x3c, 0x20, 0xfb, 0x51, 0x6d, 0x3d, 0x0c, 0x47, 0xa2, 0x95, + 0x8b, 0x61, 0xf0, 0xf8, 0x4a, 0x3d, 0x08, 0x73, 0xb8, 0x0f, 0x0c, 0xc3, 0x24, 0xea, 0x41, 0xde, + 0x71, 0xd5, 0xa3, 0x74, 0x64, 0xb2, 0xd9, 0x63, 0x62, 0xe4, 0xce, 0xc3, 0xd3, 0x87, 0x2b, 0x0a, + 0xfe, 0x5a, 0xd9, 0x23, 0xe0, 0xdb, 0xb9, 0x16, 0xfb, 0x53, 0x93, 0xfa, 0xc2, 0x13, 0x09, 0xc8, + 0x16, 0x7e, 0x69, 0x5f, 0x87, 0x30, 0x22, 0x3d, 0x5e, 0x3b, 0x6a, 0x94, 0x33, 0xd1, 0x38, 0x34, + 0x32, 0x7e, 0x88, 0x2f, 0xfe, 0x15, 0x7f, 0x7a, 0x63, 0xba, 0xe6, 0xc8, 0xb4, 0xa8, 0x03, 0x9f, + 0x9a, 0xe3, 0xb1, 0xbe, 0x4c, 0x8c, 0x3a, 0x68, 0x7d, 0xac, 0xf4, 0xb9, 0x31, 0x98, 0x19, 0xf8, + 0xef, 0x88, 0x80, 0xe9, 0x64, 0xa5, 0xff, 0x24, 0x35, 0x8d, 0x48, 0x77, 0x7f, 0x2a, 0xc6, 0x17, + 0xeb, 0x7b, 0x7f, 0x47, 0x00, 0x4f, 0x2a, 0xb3, 0xb8, 0x47, 0x2c, 0x44, 0xe5, 0xdf, 0x2a, 0xcc, + 0x06, 0x38, 0xbd, 0x68, 0x6e, 0xda, 0x3f, 0xcc, 0x0f, 0x53, 0xb1, 0xb8, 0xdc, 0x88, 0xfd, 0x67, + 0x45, 0xb3, 0x04, 0xd7, 0xb3, 0x17, 0xf5, 0xf0, 0x24, 0xcd, 0x3d, 0x8f, 0xe5, 0x10, 0xec, 0xe8, + 0x18, 0x6e, 0x2e, 0x01, 0x89, 0x46, 0xb2, 0x27, 0x15, 0x84, 0xa3, 0x1a, 0x93, 0x95, 0x50, 0x95, + 0xe4, 0xc9, 0x40, 0x70, 0xe4, 0xf5, 0x46, 0x08, 0x42, 0xfd, 0xc4, 0x85, 0xe7, 0x17, 0x1e, 0x25, + 0x4d, 0x09, 0xfe, 0x4a, 0x43, 0xf2, 0x97, 0x30, 0xdc, 0x8d, 0x71, 0xbb, 0x5d, 0x58, 0xdf, 0xd6, + 0xde, 0xa4, 0xf4, 0xe5, 0x3b, 0xb4, 0x52, 0xd0, 0x5a, 0xba, 0x3f, 0x3e, 0x4e, 0x3d, 0x6f, 0xf5, + 0x35, 0x93, 0xf1, 0x7d, 0xff, 0xce, 0xcf, 0xdd, 0xd9, 0x8e, 0x91, 0x81, 0xd0, 0x9a, 0xc1, 0xf1, + 0x1f, 0x53, 0xc1, 0x0f, 0x84, 0x7c, 0x04, 0xeb, 0xfe, 0x31, 0x15, 0x98, 0x91, 0xb0, 0x81, 0x26, + 0xf3, 0xc7, 0x47, 0x2a, 0xd6, 0x1f, 0x7f, 0x7e, 0x5f, 0xd9, 0xd6, 0xce, 0x00, 0xbe, 0x52, 0x5f, + 0x0c, 0x20, 0x41, 0x8c, 0xd0, 0x23, 0xc0, 0x7b, 0x81, 0xf9, 0x52, 0x60, 0x3e, 0x66, 0x7e, 0x7e, + 0x47, 0x78, 0x3f, 0x6f, 0x3e, 0x03, 0xa6, 0x69, 0x47, 0x07, 0xc4, 0xbd, 0x63, 0x91, 0x09, 0x75, + 0x2e, 0x7b, 0x2a, 0x4a, 0x07, 0xeb, 0x94, 0x65, 0x8a, 0xa8, 0x0e, 0xc5, 0x64, 0x1c, 0x96, 0x0e, + 0x23, 0xc8, 0x33, 0xe3, 0x93, 0x80, 0x10, 0xac, 0xf6, 0xf5, 0x68, 0xe1, 0x0b, 0xb1, 0x54, 0x78, + 0xfa, 0x48, 0x89, 0x4d, 0x63, 0x2e, 0x07, 0xe0, 0x1f, 0xc7, 0xee, 0x49, 0xa5, 0x73, 0xaf, 0xf9, + 0x29, 0x9a, 0x73, 0x07, 0x3a, 0x1c, 0x14, 0x78, 0x98, 0xe8, 0x04, 0xfb, 0x6f, 0xcc, 0x35, 0xe9, + 0x6f, 0x71, 0xfc, 0xf5, 0xcf, 0xcc, 0xca, 0x69, 0x00, 0xbb, 0x04, 0x9f, 0xa3, 0x3b, 0xff, 0x7d, + 0xea, 0xb3, 0xfe, 0x07, 0xed, 0xd3, 0x49, 0x71, 0xe0, 0xd8, 0x82, 0x22, 0x3b, 0xa2, 0x7f, 0xcc, + 0x45, 0xdb, 0x99, 0x4c, 0x7b, 0x0e, 0x18, 0x82, 0xc5, 0xca, 0xba, 0x17, 0x98, 0x10, 0xea, 0x47, + 0x21, 0x50, 0xe6, 0x4b, 0x0a, 0x81, 0xb4, 0x9d, 0x98, 0xba, 0x35, 0xbe, 0xa4, 0x15, 0xc9, 0xce, + 0x6b, 0xcf, 0xaf, 0x50, 0xf0, 0x10, 0x64, 0x5f, 0xa2, 0x63, 0xf1, 0x15, 0xda, 0x1f, 0x62, 0x5d, + 0x73, 0xb9, 0xc4, 0x33, 0xec, 0x15, 0xd8, 0xa4, 0xa0, 0xd8, 0xfd, 0x25, 0xf5, 0xfa, 0x04, 0xd8, + 0xfe, 0xf1, 0x84, 0xd4, 0x5f, 0xa9, 0x57, 0xed, 0x40, 0x7c, 0xce, 0x77, 0x64, 0x3f, 0x73, 0xb4, + 0x94, 0x4f, 0x79, 0x70, 0xc1, 0xff, 0xd2, 0xe1, 0x90, 0x08, 0x1e, 0x67, 0xe4, 0x67, 0xc9, 0x19, + 0x93, 0x48, 0xc7, 0xde, 0x53, 0xd5, 0xa1, 0xe2, 0x02, 0xb8, 0xab, 0x01, 0x7a, 0xe8, 0xe1, 0x2f, + 0x46, 0xe4, 0x01, 0x0e, 0x4b, 0xdd, 0x07, 0x34, 0x68, 0xb2, 0x18, 0x8e, 0x18, 0xeb, 0x13, 0x75, + 0x6d, 0x1d, 0xb0, 0x34, 0xb5, 0x23, 0xe3, 0x1a, 0xec, 0x86, 0x49, 0x9c, 0xb0, 0x6e, 0xb7, 0xc9, + 0x68, 0x23, 0xcf, 0x9c, 0x0a, 0x62, 0x3c, 0xd0, 0x09, 0xed, 0xe9, 0x45, 0x41, 0x0e, 0x86, 0xac, + 0x5c, 0xcf, 0x7d, 0x5d, 0x05, 0x2f, 0x1d, 0x48, 0x95, 0x92, 0x39, 0xc7, 0x11, 0xfe, 0x77, 0xae, + 0x67, 0x3b, 0xfa, 0xf8, 0x9f, 0x6a, 0xf5, 0x45, 0xaa, 0xdd, 0xb9, 0xea, 0x26, 0xb4, 0x3f, 0xff, + 0x83, 0x30, 0x29, 0x9e, 0xef, 0x02, 0x0d, 0xe3, 0xde, 0x38, 0x86, 0xd1, 0x96, 0x93, 0xd7, 0x85, + 0xaa, 0x58, 0x4c, 0x56, 0xb9, 0xb2, 0xa5, 0xeb, 0xb7, 0x4f, 0x5e, 0xcf, 0x3a, 0x8f, 0x76, 0x7b, + 0xb8, 0x73, 0x90, 0x0b, 0x2c, 0xcf, 0x35, 0x9b, 0x15, 0xb2, 0xda, 0x77, 0x82, 0x1a, 0xc5, 0xe9, + 0x09, 0x53, 0xea, 0xca, 0x01, 0x0b, 0x38, 0x92, 0x2f, 0xa9, 0xe8, 0x84, 0xf9, 0x8a, 0x38, 0xab, + 0x81, 0x84, 0xbd, 0x42, 0x9b, 0xa9, 0x6a, 0x4d, 0xce, 0x04, 0x3a, 0x40, 0x36, 0x20, 0x4d, 0xb2, + 0xb6, 0x3f, 0x3e, 0xbd, 0xb8, 0x91, 0x20, 0xe4, 0xf1, 0x29, 0x79, 0x48, 0xca, 0x5f, 0xa2, 0x64, + 0xc8, 0xac, 0xa9, 0x1e, 0x64, 0x6b, 0xd7, 0x62, 0x9c, 0x8b, 0x49, 0xc0, 0x69, 0xd8, 0x97, 0xcb, + 0x26, 0xd4, 0x2e, 0x7e, 0x1a, 0x46, 0x4f, 0xe7, 0x4b, 0x5f, 0xac, 0x3e, 0x87, 0x56, 0x49, 0x9b, + 0xce, 0xad, 0x23, 0x0a, 0xa1, 0x07, 0xcf, 0x66, 0xc3, 0x98, 0x37, 0x57, 0xb8, 0xb4, 0x10, 0x73, + 0xa4, 0xe6, 0x9b, 0x8b, 0x20, 0x98, 0x77, 0x40, 0x48, 0x46, 0x8e, 0xc9, 0xeb, 0x07, 0x01, 0x91, + 0xa8, 0xc9, 0xbe, 0xca, 0x90, 0xa3, 0x1a, 0xfd, 0xf9, 0x96, 0xa3, 0x4c, 0x2b, 0x71, 0xbe, 0xcc, + 0x1c, 0xc3, 0x87, 0xc5, 0xe7, 0x6f, 0xb2, 0xfb, 0xf8, 0xbc, 0x26, 0x02, 0x1a, 0x26, 0x0b, 0x51, + 0xd8, 0x5d, 0x78, 0x4f, 0x7a, 0xf2, 0x8a, 0x6e, 0x20, 0x0f, 0xe2, 0x13, 0x89, 0x03, 0x96, 0x2b, + 0x97, 0xd6, 0x3a, 0x83, 0xe5, 0xc3, 0xdf, 0x82, 0x4b, 0xa0, 0x76, 0x78, 0x12, 0xcf, 0x4b, 0x5c, + 0xe1, 0x89, 0x41, 0x9c, 0x73, 0x06, 0x39, 0x12, 0xd7, 0xc8, 0xbe, 0x5d, 0x8c, 0xdf, 0xaf, 0xf3, + 0x3b, 0xa2, 0x5e, 0x78, 0x1a, 0x1d, 0xf0, 0xe8, 0xff, 0xa6, 0x8e, 0x49, 0x7a, 0x9d, 0x14, 0xf9, + 0xcf, 0x97, 0x98, 0xfc, 0x95, 0x7e, 0x07, 0xc3, 0xfd, 0x7e, 0x40, 0xc5, 0xcf, 0xe7, 0xdc, 0xfc, + 0xaa, 0x4e, 0x3c, 0xdd, 0x49, 0x96, 0x42, 0x53, 0x37, 0x37, 0xdf, 0xae, 0x70, 0xf8, 0x72, 0xba, + 0xfe, 0x16, 0x52, 0x87, 0x25, 0xce, 0x4e, 0xbc, 0x92, 0x00, 0x2e, 0x4d, 0x08, 0xf8, 0xf8, 0x70, + 0xb0, 0x3d, 0x47, 0x42, 0x54, 0x38, 0xaa, 0xa0, 0x47, 0x85, 0xcb, 0x30, 0x3a, 0xbc, 0x94, 0xcf, + 0x84, 0xf2, 0x14, 0xc9, 0x36, 0x8d, 0x3e, 0x72, 0x61, 0xfc, 0x77, 0x9e, 0x5b, 0x46, 0x57, 0x53, + 0xf2, 0x85, 0xf0, 0x66, 0x4a, 0x58, 0x39, 0xba, 0xd6, 0xfd, 0x4a, 0x57, 0x68, 0x58, 0x4f, 0x6e, + 0x59, 0x85, 0x59, 0xd8, 0x45, 0x4b, 0x73, 0x7a, 0x7b, 0x32, 0x91, 0xd7, 0x26, 0xee, 0xf2, 0xc5, + 0xd2, 0x76, 0xa4, 0x1a, 0x41, 0xb4, 0x72, 0xd1, 0x28, 0x5e, 0xb5, 0xa0, 0xef, 0x2a, 0x33, 0x14, + 0x7f, 0xbd, 0xcc, 0x70, 0x29, 0x18, 0xf9, 0x47, 0x61, 0xfc, 0xbb, 0xab, 0x0c, 0xe7, 0xd7, 0xbd, + 0x62, 0xb2, 0x98, 0x67, 0x25, 0x95, 0x38, 0x79, 0x2f, 0x5d, 0x3c, 0xcc, 0x89, 0x2f, 0x2d, 0xa9, + 0xcb, 0x71, 0x10, 0x23, 0x5d, 0x16, 0xe1, 0x7f, 0x2f, 0xf4, 0xb1, 0xa9, 0xa6, 0x54, 0xcb, 0x4a, + 0xc1, 0xc8, 0xd4, 0xa7, 0xc4, 0x61, 0x47, 0xa1, 0x40, 0xef, 0x39, 0x04, 0x8f, 0x81, 0x63, 0xe1, + 0xe3, 0xdc, 0x7d, 0x1e, 0x1f, 0xff, 0x15, 0xde, 0xaf, 0x0b, 0xab, 0x3d, 0x51, 0x3d, 0xaa, 0x10, + 0xf3, 0xf3, 0x2d, 0xf0, 0xc5, 0x52, 0x21, 0x82, 0x73, 0x7c, 0xf1, 0x26, 0xae, 0xdd, 0xdd, 0xd1, + 0x6b, 0x76, 0x27, 0x77, 0x30, 0x13, 0x37, 0x00, 0xef, 0xa6, 0xc7, 0x1b, 0x3b, 0x6c, 0xfd, 0x42, + 0xf9, 0xeb, 0xd0, 0xf9, 0x16, 0x62, 0x6c, 0x36, 0xff, 0x10, 0x62, 0xf6, 0x21, 0xc0, 0xaa, 0xad, + 0x2d, 0xae, 0x2c, 0x04, 0xff, 0x43, 0x86, 0x1d, 0xfe, 0x94, 0xe3, 0xf7, 0x4c, 0xf4, 0xeb, 0x9f, + 0xf4, 0x32, 0xac, 0xbd, 0x84, 0x95, 0xc7, 0x3f, 0x6e, 0xec, 0xe5, 0x23, 0x7c, 0x7e, 0xfa, 0x8c, + 0xbf, 0xa0, 0x09, 0x7d, 0x63, 0x73, 0x93, 0x32, 0xe1, 0xb1, 0xb6, 0xb9, 0x49, 0x69, 0x96, 0xea, + 0xba, 0x30, 0x22, 0xb8, 0x66, 0x70, 0xf3, 0x13, 0x07, 0x62, 0x8c, 0x88, 0xbf, 0x29, 0x99, 0x92, + 0xeb, 0x77, 0x77, 0x77, 0xdf, 0x33, 0x30, 0x1e, 0x41, 0x2e, 0xed, 0xf0, 0xb7, 0x23, 0x29, 0x80, + 0x93, 0x89, 0x29, 0x8a, 0x02, 0xb4, 0x43, 0x37, 0xc9, 0x7e, 0xbb, 0xf9, 0xd9, 0xb5, 0x1d, 0x67, + 0xf7, 0x25, 0x02, 0x95, 0x5a, 0xea, 0xfa, 0xd8, 0x4d, 0x35, 0xd4, 0x8d, 0xda, 0xa5, 0x70, 0xfe, + 0x15, 0x40, 0xfe, 0x9e, 0x89, 0x01, 0xc7, 0xd8, 0x85, 0xc0, 0xc3, 0x2b, 0xa5, 0x37, 0x14, 0x5b, + 0x60, 0x11, 0xfd, 0x05, 0xd0, 0x44, 0x3f, 0xde, 0x2f, 0xba, 0xf0, 0x18, 0x04, 0x02, 0x67, 0xd2, + 0xc7, 0x21, 0x53, 0x11, 0x40, 0x48, 0x49, 0x2c, 0x17, 0xdf, 0x00, 0x69, 0x34, 0xcb, 0xd4, 0xe6, + 0x08, 0xd6, 0x30, 0x2c, 0x9d, 0x3e, 0x05, 0x02, 0xc5, 0x90, 0x0d, 0xeb, 0xe6, 0xe7, 0x77, 0x33, + 0x6a, 0xd2, 0x4b, 0xa7, 0x37, 0x3f, 0xff, 0xf7, 0x87, 0xad, 0xce, 0x94, 0x26, 0xdf, 0xbe, 0x67, + 0xcc, 0x9f, 0xdf, 0x57, 0x09, 0x2c, 0x82, 0x0b, 0x1e, 0x37, 0x3f, 0x29, 0x98, 0xef, 0x99, 0x15, + 0x6c, 0x2a, 0x58, 0xed, 0x22, 0x0a, 0x2d, 0xeb, 0x6c, 0xfd, 0x96, 0x85, 0xdc, 0xb9, 0xb8, 0x60, + 0x56, 0xcd, 0x5e, 0x5f, 0xb0, 0x67, 0x2e, 0xde, 0xb1, 0x60, 0x77, 0xb7, 0xd4, 0xce, 0x96, 0xc4, + 0x87, 0x57, 0x17, 0x65, 0xd9, 0xe2, 0xf5, 0x45, 0x71, 0xe6, 0xdb, 0x6b, 0x9e, 0x13, 0xf9, 0x31, + 0xbc, 0x5a, 0x78, 0x75, 0xd5, 0x3c, 0xcb, 0xbc, 0x42, 0x5b, 0x5d, 0x9f, 0xbf, 0xb9, 0x6a, 0xfd, + 0x6c, 0xd1, 0x3a, 0x58, 0x88, 0xab, 0x0b, 0xe6, 0xf2, 0xa3, 0xeb, 0x0b, 0xe2, 0xcc, 0x2b, 0x0b, + 0xc6, 0x6b, 0xf8, 0xe6, 0x12, 0x8c, 0xe9, 0x1d, 0xd8, 0x33, 0x5a, 0x1e, 0xba, 0xc3, 0x5f, 0xa1, + 0x4d, 0xfd, 0x48, 0x7d, 0xcc, 0xb8, 0xba, 0x87, 0x77, 0xa9, 0xdd, 0x8f, 0xdf, 0xae, 0xc9, 0xd1, + 0x6b, 0x6c, 0xe5, 0xed, 0xe5, 0xc4, 0x34, 0xde, 0xdc, 0x2d, 0x58, 0x85, 0x73, 0x49, 0xd6, 0x44, + 0x7b, 0xac, 0x7f, 0xf2, 0x9c, 0xb5, 0x7e, 0x55, 0xa2, 0x72, 0xe3, 0x57, 0xc8, 0xcc, 0xa7, 0x10, + 0xc0, 0xe9, 0xda, 0x91, 0x11, 0x88, 0x6c, 0x47, 0x68, 0xde, 0xa8, 0x8e, 0xc5, 0x60, 0xa6, 0xe3, + 0x9b, 0x9f, 0x1c, 0x0d, 0x0a, 0x97, 0xba, 0xeb, 0x22, 0x88, 0x63, 0xc5, 0x34, 0x2d, 0x3a, 0xfe, + 0x18, 0xa7, 0x54, 0xe2, 0xf2, 0x6f, 0x24, 0xf1, 0x81, 0xf0, 0x1d, 0x4f, 0x4e, 0x9c, 0x6c, 0x44, + 0x70, 0x68, 0x30, 0x88, 0xd8, 0x04, 0x7d, 0xb0, 0x34, 0x25, 0xc7, 0x14, 0x8f, 0x67, 0xe0, 0xa1, + 0xee, 0xc1, 0x13, 0x54, 0x6a, 0x7b, 0x49, 0x87, 0xfe, 0xb8, 0x59, 0xaf, 0xc6, 0x10, 0x5b, 0xf4, + 0x1c, 0xd5, 0xb4, 0x3e, 0x79, 0x53, 0xd3, 0x85, 0x3e, 0x30, 0xbb, 0x3f, 0x6e, 0xb2, 0x85, 0xc2, + 0x0d, 0xfe, 0xda, 0xf1, 0x8f, 0x1b, 0xf6, 0x26, 0x45, 0x8b, 0x36, 0x37, 0xf4, 0x8c, 0xe7, 0x06, + 0xfc, 0xae, 0xb5, 0x86, 0x16, 0x9b, 0x2d, 0xdd, 0xa4, 0x32, 0x17, 0x31, 0x0a, 0x6d, 0x32, 0xd0, + 0x3a, 0xa2, 0xd1, 0xb5, 0x4f, 0x93, 0x9e, 0xcc, 0x53, 0x84, 0xa3, 0x5b, 0xb6, 0x60, 0x37, 0x1d, + 0xed, 0xc7, 0x8d, 0x3a, 0xc2, 0x4b, 0xde, 0x23, 0x4b, 0x5d, 0xce, 0x11, 0x4e, 0x30, 0xf0, 0x02, + 0x88, 0xe4, 0xfa, 0x29, 0x30, 0xe0, 0xd1, 0x0d, 0xc6, 0x9b, 0x24, 0x6b, 0x78, 0x8c, 0x18, 0xdc, + 0x9b, 0x04, 0x6f, 0xc3, 0xf0, 0xf4, 0x68, 0x54, 0x70, 0xfc, 0x12, 0x8f, 0x02, 0x1b, 0x8c, 0xbb, + 0x49, 0xec, 0x22, 0x1a, 0xe8, 0x9f, 0xf3, 0x39, 0xf8, 0x53, 0x85, 0x9b, 0x9f, 0x7d, 0x0c, 0x3a, + 0xf0, 0xc7, 0xa0, 0x97, 0x4b, 0xdd, 0x3a, 0x67, 0xf7, 0xdb, 0x1c, 0xeb, 0x9f, 0xad, 0x7f, 0xcc, + 0x3f, 0xba, 0x95, 0x4f, 0x13, 0xd5, 0x72, 0xf5, 0x5f, 0x63, 0x23, 0xf3, 0x1f, 0x60, 0x63, 0x62, + 0x0a, 0x3d, 0x8b, 0x38, 0x75, 0x3b, 0xf0, 0x30, 0xa1, 0x8d, 0x2b, 0xfe, 0xd3, 0xc7, 0x0f, 0x93, + 0x09, 0x44, 0x56, 0xcc, 0xc7, 0xcf, 0xdf, 0x62, 0xff, 0x78, 0x16, 0xed, 0x85, 0x63, 0xbe, 0x9d, + 0x50, 0xfe, 0x35, 0x98, 0xea, 0x3b, 0x60, 0xaa, 0xbf, 0x08, 0x53, 0x2b, 0xbd, 0x0d, 0x13, 0xc7, + 0xfc, 0x0a, 0x4c, 0xb0, 0x71, 0x6f, 0xc2, 0xc4, 0x31, 0xbf, 0x02, 0x13, 0x5f, 0x6f, 0xc1, 0xc4, + 0xd7, 0x75, 0x98, 0x29, 0x3c, 0xd1, 0x39, 0x05, 0xcc, 0x30, 0x6f, 0x33, 0x2a, 0x18, 0x13, 0x03, + 0xfe, 0x3e, 0x72, 0xde, 0x27, 0x00, 0x6f, 0x23, 0x8c, 0x63, 0xde, 0x4f, 0x04, 0xc4, 0xe2, 0x2d, + 0x98, 0xc1, 0x98, 0x5f, 0x81, 0x89, 0xec, 0x7d, 0x0b, 0x26, 0x8e, 0xf9, 0x05, 0x98, 0x25, 0xdc, + 0xd9, 0x1b, 0x30, 0xe9, 0x98, 0x77, 0xc3, 0x74, 0x96, 0xe3, 0xd7, 0xe1, 0xe1, 0xdf, 0x04, 0xa6, + 0x92, 0x7f, 0x9e, 0x44, 0x93, 0x93, 0xd4, 0xe5, 0xab, 0x0e, 0x69, 0x96, 0xde, 0xb8, 0xbe, 0xf9, + 0xd9, 0xb9, 0xa8, 0xeb, 0x34, 0x44, 0x76, 0xad, 0x64, 0x18, 0x19, 0x22, 0x86, 0x35, 0x69, 0xcd, + 0x4a, 0x41, 0x9c, 0x99, 0xc0, 0x2f, 0x38, 0x46, 0xea, 0x5a, 0xb6, 0xf7, 0x89, 0x41, 0xa0, 0xec, + 0x05, 0xd7, 0xfd, 0xce, 0xf9, 0x2c, 0xce, 0xcf, 0xfe, 0xf3, 0xf9, 0x59, 0x9c, 0x9f, 0xbb, 0xe4, + 0xbe, 0xcf, 0x4c, 0x38, 0xb5, 0xb0, 0x40, 0x31, 0x0b, 0xe2, 0x15, 0xea, 0xf4, 0x53, 0xef, 0x72, + 0xd9, 0xe1, 0x1f, 0xda, 0x84, 0xfe, 0x7a, 0x94, 0x8b, 0xfc, 0x75, 0x78, 0xac, 0x79, 0x08, 0xc4, + 0x71, 0x68, 0x10, 0xbf, 0x07, 0x5d, 0xed, 0x60, 0xa5, 0x13, 0x3b, 0x1f, 0x3e, 0x0d, 0x32, 0x94, + 0xef, 0xc1, 0x59, 0xd9, 0xcf, 0x72, 0x50, 0x6a, 0xff, 0x9e, 0x09, 0xdb, 0x87, 0x1e, 0x01, 0x6f, + 0x70, 0xfe, 0x2b, 0xd9, 0x91, 0x09, 0xa0, 0x5f, 0x77, 0x99, 0x88, 0x41, 0x78, 0x2b, 0xfc, 0x9a, + 0x67, 0x3c, 0xa3, 0x4d, 0x30, 0x3e, 0xe5, 0xae, 0x20, 0x71, 0xb9, 0xe0, 0xdd, 0x82, 0xbb, 0xbd, + 0xef, 0x8a, 0x68, 0x72, 0xd9, 0xc2, 0x3f, 0x8a, 0x68, 0xba, 0xb8, 0xf4, 0x1b, 0x3e, 0x92, 0x8e, + 0xf9, 0xc5, 0x28, 0xe7, 0x3f, 0xe1, 0x1e, 0xaf, 0x91, 0x0f, 0x2b, 0xa4, 0x78, 0x16, 0xb8, 0xbb, + 0x4e, 0xc2, 0x60, 0xc7, 0xe1, 0x4d, 0xea, 0x77, 0x11, 0x34, 0xcf, 0x3c, 0xfc, 0x23, 0x82, 0xd6, + 0x23, 0x64, 0xde, 0x20, 0x6a, 0x3c, 0xee, 0xff, 0x63, 0xc2, 0x2e, 0xc2, 0x30, 0xfd, 0x6d, 0x9a, + 0x66, 0x2f, 0xd8, 0x30, 0x6a, 0x3c, 0x70, 0xcc, 0x64, 0x3b, 0x62, 0x8e, 0xcc, 0x88, 0x37, 0x08, + 0x0c, 0x58, 0x17, 0x0b, 0x4b, 0xaf, 0xe5, 0x00, 0x93, 0xad, 0x65, 0xba, 0x54, 0x77, 0xc2, 0xaa, + 0xc1, 0xdd, 0xdd, 0x5d, 0x62, 0x58, 0xe0, 0x1f, 0xcf, 0xd5, 0xb0, 0xab, 0x1b, 0x0b, 0xbc, 0xac, + 0xf9, 0x56, 0x84, 0xea, 0xea, 0x06, 0x3e, 0xbe, 0x0a, 0x3f, 0x31, 0x6e, 0xed, 0x05, 0xfc, 0x7e, + 0x55, 0xfd, 0x2b, 0xea, 0xc6, 0x76, 0x20, 0x60, 0x7d, 0xc5, 0x00, 0xd0, 0xc0, 0xd8, 0x7d, 0xa4, + 0x99, 0xd0, 0x29, 0xd5, 0x11, 0x87, 0x14, 0xbd, 0x4a, 0xeb, 0x82, 0x8d, 0x0d, 0x09, 0x7f, 0x6e, + 0x97, 0xd1, 0xe6, 0xe1, 0x39, 0xe3, 0x31, 0x49, 0xdb, 0x8e, 0x0e, 0xef, 0x81, 0x61, 0x7f, 0xc3, + 0x31, 0xbc, 0x0a, 0x20, 0xfb, 0x0e, 0xcf, 0xf0, 0x2a, 0x80, 0xdc, 0x99, 0x6b, 0xf8, 0x45, 0x00, + 0x79, 0x04, 0x90, 0x8f, 0x01, 0x84, 0x5c, 0xfe, 0x45, 0x20, 0x05, 0x04, 0x52, 0xf8, 0x0d, 0x2c, + 0x8a, 0x08, 0xa0, 0xf8, 0x1b, 0x00, 0xee, 0x11, 0xc0, 0xfd, 0x6f, 0x00, 0x28, 0x21, 0x80, 0xd2, + 0x6f, 0xd2, 0xe1, 0x01, 0x81, 0x3c, 0xfc, 0x06, 0x16, 0x6c, 0x10, 0x6a, 0x30, 0xbf, 0x03, 0x22, + 0x10, 0xca, 0xdf, 0x91, 0x4a, 0x96, 0x8a, 0x25, 0x9b, 0xfd, 0x4d, 0x6a, 0xb0, 0x54, 0x38, 0xd9, + 0xdf, 0x91, 0x4e, 0x96, 0x8a, 0x27, 0x9b, 0xff, 0x1d, 0x10, 0x54, 0x38, 0xd9, 0xdf, 0x91, 0x4e, + 0x96, 0x8a, 0x27, 0x5b, 0x3c, 0xa5, 0x47, 0xf0, 0x67, 0x60, 0x21, 0x94, 0xe0, 0xe4, 0x06, 0x4f, + 0xcc, 0xd0, 0xf8, 0x74, 0x83, 0xa3, 0x79, 0xb4, 0xe9, 0xb1, 0xdb, 0x0a, 0x3c, 0x09, 0x1d, 0x37, + 0xb2, 0xb7, 0x37, 0xa1, 0x75, 0xea, 0xd1, 0x32, 0x4f, 0xd2, 0x5f, 0x85, 0x85, 0x9f, 0x6e, 0x18, + 0x3e, 0xb9, 0x2b, 0x75, 0x79, 0xb4, 0x08, 0x3d, 0xdd, 0x82, 0x85, 0xd0, 0xc7, 0x60, 0x27, 0x35, + 0x8f, 0x14, 0x97, 0x08, 0xb1, 0xe4, 0x94, 0x29, 0x58, 0x7e, 0x30, 0x70, 0x29, 0xb6, 0x98, 0xd2, + 0xe0, 0xa9, 0xab, 0x6e, 0x74, 0x5a, 0xa4, 0x76, 0x43, 0xb3, 0x7d, 0x17, 0x02, 0xc1, 0xa9, 0x6f, + 0xef, 0x2b, 0xa0, 0x48, 0x4a, 0xdb, 0x69, 0xd6, 0xeb, 0x1b, 0xd3, 0x76, 0xd7, 0x36, 0xc6, 0x0f, + 0xff, 0xf1, 0xc6, 0x2a, 0xa6, 0xe3, 0x7a, 0xa9, 0x15, 0xc5, 0xe1, 0x6b, 0x2a, 0x11, 0x0d, 0x00, + 0x3e, 0xee, 0x79, 0x08, 0x10, 0xe0, 0x15, 0xdc, 0xd7, 0x39, 0xd4, 0x83, 0xa8, 0x8b, 0x67, 0xf3, + 0x07, 0x67, 0x7e, 0x13, 0x42, 0x7f, 0x54, 0xaf, 0x02, 0xd7, 0xdf, 0x05, 0x3c, 0x1b, 0x01, 0x2f, + 0xc4, 0xc0, 0x73, 0x11, 0x70, 0xac, 0xec, 0xa6, 0xf0, 0x5e, 0xf2, 0xe5, 0x05, 0xbc, 0x77, 0x2d, + 0xc0, 0xdc, 0x45, 0x4b, 0x14, 0x0b, 0x77, 0x05, 0xcc, 0x9b, 0xf4, 0x15, 0x3e, 0x65, 0x0f, 0x9b, + 0x81, 0x11, 0x3f, 0xdd, 0x70, 0xc9, 0xc4, 0xa5, 0xad, 0x93, 0xd5, 0xde, 0xb9, 0xdc, 0xff, 0xa3, + 0xed, 0x48, 0x7b, 0xdb, 0xc6, 0x95, 0xdf, 0x1f, 0xf0, 0xfe, 0x83, 0x2d, 0xec, 0x33, 0xa4, 0x9a, + 0x91, 0xed, 0xa4, 0xa7, 0x5d, 0xc2, 0x70, 0x9c, 0x34, 0xcd, 0x6e, 0x8e, 0x36, 0x49, 0xdb, 0xed, + 0x06, 0xd9, 0x40, 0x96, 0x28, 0x5b, 0x89, 0x2c, 0x79, 0x25, 0xf9, 0x4a, 0xec, 0xff, 0xfe, 0x66, + 0x86, 0x3a, 0xe8, 0xab, 0xbb, 0x28, 0xde, 0x2b, 0xd0, 0x48, 0xe2, 0x31, 0x24, 0xe7, 0x9e, 0xa1, + 0x44, 0xff, 0xcd, 0x60, 0x75, 0xf3, 0x0d, 0x0c, 0xf6, 0xe3, 0xb4, 0x96, 0xcc, 0xea, 0xf7, 0xc2, + 0x44, 0xb2, 0x05, 0xde, 0x6c, 0x4a, 0x20, 0x9e, 0x8d, 0xe0, 0x05, 0x8f, 0xaa, 0xf4, 0x85, 0x23, + 0x11, 0xdc, 0x58, 0x3d, 0x70, 0x5d, 0x76, 0x65, 0x3d, 0xd3, 0x28, 0x65, 0x47, 0xc2, 0x15, 0x73, + 0x66, 0x3b, 0x12, 0xae, 0x7f, 0x3f, 0x68, 0xe3, 0xa7, 0x52, 0xad, 0x69, 0x3c, 0xf2, 0xd3, 0xa3, + 0xee, 0xff, 0x54, 0x5a, 0x3b, 0x73, 0xbf, 0x7e, 0x7a, 0xd8, 0x83, 0x5d, 0xc3, 0xd6, 0x5f, 0xda, + 0xbb, 0x87, 0xcd, 0xbd, 0xaf, 0x1d, 0x99, 0x65, 0xc5, 0x51, 0xa3, 0xcf, 0xf4, 0xb6, 0x64, 0x22, + 0xf3, 0xe3, 0x4e, 0xb6, 0xd4, 0xe1, 0x46, 0x60, 0xce, 0xa3, 0xf4, 0x4d, 0xde, 0x8a, 0x2f, 0x89, + 0x5f, 0x90, 0xc9, 0x80, 0x60, 0xd8, 0x07, 0x6d, 0x06, 0xbe, 0x7c, 0x9a, 0x79, 0x55, 0x5e, 0x93, + 0x1d, 0x05, 0xfd, 0xec, 0x17, 0xcb, 0xbc, 0xaf, 0x87, 0x97, 0x57, 0xd3, 0xfa, 0x6f, 0x27, 0x7d, + 0x3c, 0x44, 0xb1, 0x73, 0x71, 0xfd, 0x65, 0x70, 0xfc, 0x05, 0x4f, 0xb0, 0xea, 0xd3, 0x2f, 0x7c, + 0x9d, 0x77, 0x3b, 0x74, 0xfa, 0xe3, 0x1f, 0x9f, 0xfd, 0x13, 0x79, 0x82, 0xd8, 0xef, 0x17, 0xd7, + 0x57, 0xf5, 0xd3, 0x4e, 0x14, 0xbf, 0xb4, 0x5f, 0xd3, 0x49, 0x53, 0x57, 0xc1, 0xe7, 0x2f, 0x0d, + 0x3c, 0x9c, 0x6a, 0xf6, 0x30, 0x9d, 0xbc, 0xfd, 0xfe, 0x99, 0x4e, 0xe2, 0xfa, 0xd5, 0x3e, 0x1e, + 0xfc, 0x61, 0x4f, 0x3b, 0x9d, 0xa3, 0x18, 0x4f, 0x18, 0x7c, 0x73, 0xd4, 0xb1, 0x9d, 0xc9, 0x5f, + 0xf8, 0xc3, 0x5d, 0x9d, 0xdf, 0xce, 0xae, 0xbf, 0x5c, 0x1d, 0x7e, 0xfd, 0x38, 0x10, 0x6f, 0x9c, + 0xfe, 0xec, 0x21, 0x99, 0x4e, 0x8f, 0x3b, 0x47, 0x87, 0x23, 0xb7, 0x56, 0x7b, 0xf5, 0xf4, 0xe5, + 0x68, 0xfa, 0xe8, 0x07, 0xa3, 0xa7, 0x0f, 0x9d, 0xe0, 0xb7, 0xf0, 0xfa, 0xc6, 0xeb, 0x5f, 0x7c, + 0xb8, 0xb9, 0xa9, 0xff, 0xf8, 0x97, 0xd3, 0x76, 0xfc, 0x3b, 0x39, 0xb2, 0x2f, 0x3d, 0xf1, 0x7b, + 0xf5, 0xe4, 0x55, 0x30, 0xb9, 0x38, 0xb3, 0x9e, 0x02, 0xcf, 0x7f, 0xed, 0x36, 0x2e, 0x26, 0xd5, + 0x5a, 0xf2, 0x74, 0x60, 0xbf, 0xa9, 0x1e, 0x24, 0xc0, 0x1b, 0xb5, 0x9b, 0xd1, 0xb8, 0xf6, 0xd0, + 0x13, 0x6f, 0xdf, 0xbc, 0xb1, 0xdf, 0xbe, 0xc2, 0x93, 0xf2, 0x8f, 0x3f, 0xf7, 0x61, 0xb8, 0xfe, + 0x31, 0x9e, 0xb5, 0xd5, 0xc9, 0x6e, 0x4f, 0xf1, 0xe0, 0x2c, 0x3c, 0x6f, 0xf5, 0x90, 0xce, 0x6d, + 0xc6, 0xdb, 0xfe, 0x21, 0x9d, 0x51, 0x86, 0xc7, 0xf1, 0x2b, 0xb7, 0x1e, 0xe2, 0xe1, 0x18, 0xa7, + 0xfb, 0xd9, 0xeb, 0xc8, 0xdb, 0xd3, 0xce, 0x67, 0x3c, 0xd7, 0xac, 0x0b, 0xa0, 0x4e, 0x2f, 0xbe, + 0xbf, 0xaa, 0x5a, 0x1f, 0x27, 0x4e, 0xfc, 0xfd, 0xca, 0x7a, 0x9a, 0x3c, 0xfc, 0xf6, 0xee, 0xc1, + 0x3d, 0x7f, 0xe3, 0x4e, 0x9e, 0x6a, 0xf5, 0xea, 0xf7, 0x83, 0x6a, 0x6d, 0xbf, 0x7a, 0x70, 0xf0, + 0x7a, 0xfa, 0x36, 0x6f, 0xde, 0x07, 0x40, 0x03, 0xc4, 0xfa, 0xf1, 0x29, 0x12, 0x63, 0xb0, 0x3a, + 0xa9, 0x9f, 0x9d, 0xdf, 0xd1, 0xf1, 0xe5, 0xd8, 0x89, 0xdc, 0x33, 0xfb, 0xe9, 0xf7, 0xa1, 0x9f, + 0xfc, 0x71, 0x30, 0xff, 0xf0, 0xda, 0x1d, 0x4f, 0x27, 0xfb, 0x62, 0xf8, 0xae, 0xea, 0x54, 0x83, + 0x57, 0x81, 0x38, 0x78, 0xba, 0x39, 0xb0, 0xff, 0x70, 0x47, 0xd5, 0x5a, 0xe7, 0xe3, 0xff, 0x6f, + 0x1e, 0x12, 0x4f, 0xdf, 0x47, 0x07, 0x4f, 0x17, 0xbd, 0x37, 0xbd, 0x93, 0x2f, 0x22, 0x7e, 0xf3, + 0xfd, 0xe9, 0xed, 0xf4, 0xf2, 0xe0, 0xe0, 0xa5, 0x3b, 0x14, 0x63, 0xf7, 0xe0, 0x55, 0x6f, 0xe8, + 0xd4, 0x9e, 0xde, 0xcd, 0xab, 0x93, 0x77, 0x63, 0xf7, 0x69, 0xf6, 0xf6, 0xff, 0x43, 0x93, 0xfc, + 0xb6, 0x7b, 0xea, 0xd8, 0x2f, 0x67, 0x07, 0xd5, 0xfd, 0xf3, 0xaf, 0x8d, 0xa8, 0x77, 0xe2, 0x0e, + 0x3f, 0x8c, 0xa2, 0x6a, 0xed, 0xb5, 0xa8, 0xf9, 0xef, 0xc6, 0xe2, 0xcd, 0x81, 0x7b, 0x53, 0x1d, + 0x25, 0x8d, 0xea, 0xc7, 0xfd, 0x5a, 0x2f, 0xa8, 0xd6, 0xfc, 0x93, 0xdf, 0xdf, 0xee, 0x80, 0xf3, + 0x3f, 0xc3, 0xd7, 0x4f, 0xfd, 0xeb, 0x7f, 0xaa, 0x8d, 0xdf, 0xd6, 0x1e, 0xcf, 0xbe, 0x77, 0xff, + 0xea, 0xcc, 0x4e, 0x2f, 0x6e, 0xe6, 0x7f, 0xc8, 0x5f, 0x6f, 0xba, 0xfe, 0xf2, 0xf5, 0xf2, 0xea, + 0xb7, 0x57, 0xdd, 0xef, 0xa7, 0xa7, 0x5c, 0xcb, 0x95, 0x91, 0x92, 0xd9, 0x45, 0xdd, 0xf1, 0x38, + 0xc9, 0xb7, 0xc5, 0xf3, 0xed, 0xf0, 0xad, 0x0e, 0x2e, 0xfa, 0x84, 0xe9, 0x0b, 0x09, 0x8a, 0xda, + 0x8c, 0xc4, 0x5f, 0x63, 0x11, 0x27, 0xbf, 0xc6, 0x61, 0xa0, 0x07, 0x63, 0xdf, 0x07, 0xed, 0x79, + 0x25, 0x5c, 0x30, 0xea, 0x83, 0xdd, 0xda, 0x77, 0x3b, 0xa4, 0xd5, 0x0d, 0xcd, 0xae, 0x1f, 0xc6, + 0xa2, 0x24, 0x37, 0x29, 0x7f, 0xe4, 0x76, 0x6f, 0x87, 0x85, 0xca, 0xfc, 0xe4, 0x23, 0xc2, 0xa1, + 0xed, 0xf9, 0x6f, 0xde, 0xa3, 0xf7, 0x0f, 0xa7, 0x83, 0x28, 0x21, 0x97, 0x64, 0x15, 0xa0, 0x1d, + 0xb8, 0x57, 0xe4, 0xfc, 0xd2, 0xfa, 0x7a, 0x78, 0xb2, 0x9b, 0xfc, 0x5d, 0xca, 0xd5, 0xb9, 0xad, + 0x79, 0x9a, 0xe7, 0x96, 0x23, 0x4a, 0x53, 0x2f, 0x19, 0x94, 0x64, 0x0d, 0x02, 0xa7, 0x6f, 0x67, + 0xc9, 0xa2, 0xec, 0xbf, 0x79, 0xfd, 0xb2, 0x95, 0xba, 0x76, 0xa5, 0xde, 0xbc, 0xd4, 0xf1, 0x22, + 0x3b, 0x0c, 0xc3, 0x47, 0x4f, 0xd0, 0x2b, 0x13, 0xc9, 0x40, 0xc8, 0x97, 0x0b, 0xec, 0x70, 0x38, + 0x1c, 0x07, 0x94, 0x62, 0xca, 0xdd, 0xc0, 0x0d, 0xab, 0x42, 0xdf, 0x28, 0x6f, 0x31, 0x11, 0x6b, + 0xa9, 0x26, 0x3c, 0xd1, 0x69, 0x6d, 0x37, 0x7a, 0x95, 0x1d, 0x7c, 0x60, 0x87, 0x76, 0xc1, 0x05, + 0xa9, 0xeb, 0x14, 0x96, 0xc6, 0x40, 0x8d, 0xde, 0xd8, 0xf3, 0xf1, 0x85, 0xf0, 0x92, 0x90, 0xa6, + 0x9d, 0x51, 0x29, 0xac, 0x0b, 0xc7, 0x8e, 0xc0, 0x6d, 0xca, 0x5e, 0x32, 0x01, 0x23, 0x16, 0x4e, + 0x4d, 0xd9, 0xf7, 0x7b, 0x38, 0x26, 0x4f, 0x3b, 0x12, 0xc9, 0x38, 0x0a, 0x4a, 0x49, 0x08, 0x77, + 0x60, 0xa2, 0xd0, 0xff, 0xc3, 0x70, 0x00, 0x17, 0x8e, 0x3e, 0x60, 0x8c, 0xf1, 0x01, 0x2e, 0x99, + 0xbe, 0xb3, 0x86, 0x31, 0xf0, 0x1e, 0xdf, 0x5b, 0xc1, 0x37, 0x75, 0x00, 0x05, 0x51, 0x20, 0x22, + 0x73, 0x17, 0x07, 0xac, 0x86, 0x29, 0x67, 0x61, 0x44, 0x2e, 0xcb, 0x65, 0x36, 0x2b, 0xa8, 0x14, + 0x3f, 0x24, 0xff, 0x66, 0xff, 0x7d, 0xb5, 0xff, 0x38, 0x48, 0x3c, 0x1f, 0xa6, 0x8d, 0x64, 0xff, + 0x1b, 0x8a, 0x7f, 0x08, 0x23, 0x58, 0x3d, 0x3a, 0xce, 0x22, 0xa2, 0x63, 0x01, 0x61, 0x68, 0x56, + 0xf2, 0xc0, 0xd5, 0xc4, 0xef, 0xf5, 0x91, 0x92, 0x82, 0xde, 0x17, 0x02, 0x34, 0x10, 0x3a, 0x42, + 0xd7, 0x4d, 0x57, 0x0d, 0x58, 0x19, 0x22, 0x0e, 0xe2, 0x70, 0x1c, 0xd9, 0xc0, 0x35, 0x03, 0x11, + 0x94, 0x82, 0x10, 0x13, 0x8c, 0x88, 0x65, 0x73, 0x83, 0xf6, 0x40, 0xd9, 0x9c, 0xee, 0x88, 0x33, + 0x6d, 0x0b, 0xa1, 0x37, 0x96, 0x85, 0xee, 0xe3, 0x16, 0xe2, 0xe7, 0x2f, 0xa8, 0xd4, 0x5e, 0x94, + 0xff, 0xfd, 0xaf, 0x17, 0x25, 0x2f, 0x0a, 0xcd, 0x87, 0xb8, 0x34, 0x79, 0x69, 0xbe, 0x34, 0xeb, + 0x58, 0xb0, 0x5f, 0x6f, 0xbc, 0xde, 0x83, 0x3f, 0xef, 0x4a, 0xbf, 0xd2, 0xd7, 0xd7, 0x47, 0x56, + 0xe0, 0x09, 0x1f, 0x6b, 0xce, 0x3c, 0x5b, 0x04, 0x31, 0xac, 0x68, 0x0c, 0xeb, 0x8a, 0x4a, 0xe7, + 0x9f, 0xce, 0x4a, 0xfb, 0xb2, 0x4f, 0x1f, 0xf8, 0x7e, 0xdc, 0x33, 0x61, 0xcd, 0xb5, 0x07, 0x0b, + 0x7b, 0xd5, 0x24, 0x58, 0xa8, 0xab, 0xfd, 0xfb, 0x5f, 0xe5, 0xec, 0x07, 0x5c, 0xf5, 0x84, 0x09, + 0xe3, 0x59, 0x0b, 0x7b, 0x0f, 0xc0, 0x52, 0x1a, 0xe7, 0xe8, 0x78, 0x87, 0x6e, 0x49, 0xcc, 0xf0, + 0x8d, 0xff, 0xb8, 0x52, 0xd1, 0x10, 0xb0, 0xeb, 0x05, 0xc2, 0xd1, 0xca, 0x59, 0x25, 0x30, 0xce, + 0xd8, 0x17, 0x6d, 0x79, 0x31, 0xd3, 0xa6, 0x5c, 0xe8, 0x46, 0x53, 0xcb, 0xc0, 0x16, 0x90, 0x64, + 0xef, 0x4a, 0x45, 0x5e, 0x4d, 0x6b, 0xe8, 0xb4, 0xe5, 0xad, 0x2e, 0x8c, 0x66, 0x62, 0xc2, 0xa4, + 0xb0, 0xe7, 0x92, 0x52, 0x9e, 0x2c, 0x9f, 0x15, 0x4c, 0x09, 0x99, 0x1b, 0xe8, 0xe2, 0xc1, 0xb4, + 0x5a, 0x13, 0x60, 0x4a, 0x9b, 0x2b, 0xb5, 0x4b, 0xe6, 0x71, 0xf8, 0x33, 0xe0, 0xb7, 0x77, 0x6c, + 0x0c, 0x7f, 0x5a, 0xf9, 0x0f, 0xd2, 0x8e, 0xe4, 0x8a, 0xb0, 0x47, 0xc8, 0x02, 0x16, 0x31, 0x8f, + 0xc5, 0xdc, 0x8a, 0xfa, 0x63, 0xf2, 0x4b, 0x99, 0xc5, 0xc7, 0x2d, 0xe0, 0x0c, 0xdd, 0x2b, 0xca, + 0x4c, 0x5f, 0x04, 0xfd, 0x64, 0xd0, 0xda, 0x7f, 0xef, 0xed, 0xed, 0xb5, 0x8c, 0x81, 0x39, 0x1a, + 0xc7, 0x03, 0x3d, 0xbe, 0xf5, 0xee, 0x0c, 0x6a, 0x0a, 0x93, 0x47, 0xd5, 0x5a, 0xe6, 0xc2, 0xb4, + 0x07, 0x9e, 0xef, 0x44, 0x22, 0xa8, 0x54, 0xf4, 0x41, 0xda, 0x6d, 0xb1, 0x48, 0x3b, 0x14, 0xb5, + 0x06, 0x73, 0x84, 0x2f, 0x12, 0x51, 0x52, 0x8a, 0x5a, 0x59, 0xfb, 0x96, 0xe1, 0xb9, 0xba, 0x1e, + 0x70, 0xe8, 0x15, 0x8e, 0x74, 0xc3, 0xa8, 0x54, 0x26, 0xa1, 0xe7, 0x94, 0xea, 0x65, 0xce, 0x03, + 0x2c, 0x32, 0xe4, 0xec, 0x82, 0xac, 0xb9, 0x3a, 0xa7, 0x80, 0xe6, 0x24, 0xfc, 0x58, 0x40, 0xe8, + 0x12, 0xfa, 0xc2, 0x52, 0xf0, 0x8c, 0x73, 0x0a, 0x38, 0xd9, 0x00, 0xa6, 0x47, 0xbc, 0xa0, 0x44, + 0x4e, 0xb6, 0xc4, 0xc0, 0x26, 0xd0, 0x00, 0x46, 0x6a, 0x43, 0x40, 0xa5, 0x35, 0xb3, 0x00, 0xab, + 0x00, 0x02, 0xe5, 0xd7, 0x09, 0x7e, 0xa2, 0xa4, 0x07, 0x40, 0xcd, 0x98, 0x6e, 0x0b, 0x08, 0x38, + 0x46, 0xc4, 0xcb, 0x0d, 0xc3, 0x60, 0x51, 0xa5, 0x12, 0xb6, 0xad, 0x5b, 0x2b, 0x9d, 0xe6, 0x5e, + 0xe3, 0xae, 0xca, 0x83, 0xa6, 0xc5, 0x39, 0x1f, 0xb7, 0x2d, 0x7e, 0x1b, 0xdc, 0x35, 0xad, 0x74, + 0xce, 0x06, 0x0b, 0x79, 0x44, 0x14, 0xf4, 0x79, 0x20, 0xa6, 0x25, 0xbb, 0x95, 0xea, 0x22, 0xdf, + 0x0c, 0x40, 0x03, 0x5d, 0xe0, 0x4f, 0x33, 0x27, 0xcc, 0xcf, 0x51, 0xc5, 0x2d, 0x78, 0xb0, 0x12, + 0x18, 0x1a, 0x44, 0x5d, 0xc4, 0x5c, 0xce, 0x58, 0xb4, 0x25, 0x9a, 0x9a, 0x02, 0x6a, 0x1f, 0xc5, + 0x7c, 0xa3, 0x18, 0x0b, 0x99, 0xbf, 0xcc, 0xf9, 0xe0, 0x5c, 0xf2, 0x01, 0x62, 0x93, 0x78, 0x01, + 0x25, 0x59, 0x18, 0xc9, 0x6d, 0x78, 0xc7, 0x05, 0xfc, 0xc9, 0x26, 0x91, 0x14, 0x3d, 0x7c, 0xd9, + 0x43, 0xd2, 0x3a, 0x81, 0xa5, 0x6e, 0xe1, 0xe6, 0xa4, 0x9d, 0x48, 0xbe, 0xb5, 0xc7, 0x11, 0x7e, + 0x99, 0xc5, 0x85, 0xb1, 0x44, 0xf0, 0x82, 0x6f, 0x69, 0xfc, 0x29, 0x0a, 0x87, 0x5e, 0x2c, 0xda, + 0xe9, 0xd5, 0x04, 0x3d, 0x1b, 0xfa, 0x13, 0xe0, 0x76, 0x13, 0x74, 0x4e, 0x60, 0xf6, 0xbc, 0xc0, + 0xd1, 0x37, 0xea, 0x8c, 0x26, 0x28, 0x0b, 0x8c, 0xcf, 0xc3, 0x71, 0xc2, 0x5c, 0x5e, 0xc3, 0x37, + 0xde, 0x16, 0x62, 0xa6, 0xb7, 0x9b, 0xf1, 0xa2, 0xbf, 0x08, 0x16, 0xa3, 0xc5, 0x2f, 0xc6, 0x22, + 0x1a, 0x0d, 0x16, 0xe1, 0x34, 0x5e, 0x0c, 0x03, 0x7b, 0x11, 0x24, 0xd3, 0x05, 0x88, 0xd3, 0xad, + 0x3d, 0xb8, 0x5b, 0x3c, 0x85, 0xe1, 0xe2, 0xcf, 0x30, 0x72, 0x6a, 0x1e, 0x20, 0x5d, 0x95, 0x8a, + 0x58, 0x4f, 0x8c, 0xe7, 0x72, 0x62, 0xde, 0x3b, 0x5e, 0x94, 0xcc, 0x61, 0x6d, 0xd9, 0x2d, 0x2f, + 0xd7, 0x81, 0x2d, 0x1a, 0x9c, 0x87, 0x92, 0x5c, 0xc8, 0x24, 0x02, 0x88, 0x56, 0xa0, 0x05, 0xc5, + 0x2d, 0xc3, 0x62, 0xd2, 0x4a, 0xb0, 0x21, 0x32, 0x6e, 0xcb, 0x28, 0xa0, 0x9d, 0x42, 0xb7, 0xa2, + 0xc3, 0xb5, 0xc4, 0x63, 0x86, 0x60, 0x53, 0x9e, 0x93, 0xe8, 0x3d, 0x09, 0xe7, 0x22, 0xa3, 0x37, + 0x10, 0x6e, 0xb1, 0x48, 0x72, 0xfa, 0x9b, 0x49, 0x78, 0x86, 0x2f, 0xb7, 0x75, 0x21, 0x40, 0xd2, + 0x0d, 0xac, 0x5d, 0x2d, 0x29, 0x60, 0x1f, 0xe3, 0x3a, 0x24, 0xc2, 0xcf, 0x75, 0x50, 0x00, 0x89, + 0xc2, 0x29, 0x20, 0x19, 0x05, 0x13, 0x25, 0xf9, 0x2d, 0xb1, 0x5e, 0xc8, 0x95, 0xd1, 0xd2, 0xcf, + 0x6c, 0x00, 0xf5, 0xa3, 0xb8, 0x05, 0xd2, 0x98, 0x0b, 0x60, 0x68, 0x64, 0x0b, 0x45, 0x97, 0xa4, + 0x14, 0x1a, 0xb2, 0x06, 0x27, 0x04, 0x1c, 0x0d, 0x58, 0xc3, 0x0b, 0x0f, 0xe1, 0x8f, 0x91, 0xf1, + 0x8f, 0x28, 0xe6, 0x76, 0x51, 0xcc, 0x2d, 0x31, 0xe5, 0x87, 0x7b, 0xb8, 0xe0, 0x16, 0xe8, 0x0f, + 0xa4, 0xef, 0x10, 0x4c, 0x45, 0x17, 0xe7, 0xb4, 0x82, 0xac, 0x09, 0x22, 0x8b, 0x91, 0xa6, 0x32, + 0x9e, 0x61, 0x2e, 0x1a, 0x99, 0x11, 0x9c, 0xa6, 0x86, 0xc3, 0xe2, 0x98, 0x5c, 0x96, 0x69, 0x06, + 0xd3, 0x80, 0xc7, 0xa9, 0x58, 0x2a, 0x81, 0x12, 0xb6, 0x8f, 0x84, 0x2b, 0x8b, 0x7c, 0x1d, 0xa0, + 0x90, 0xf8, 0xfb, 0x7a, 0xc0, 0x12, 0xa5, 0x89, 0xec, 0x5e, 0x26, 0xa4, 0x47, 0xa8, 0x7e, 0x34, + 0xda, 0xe2, 0x96, 0xdd, 0x70, 0x50, 0x90, 0xeb, 0x6d, 0xb2, 0xbe, 0x51, 0x16, 0x2e, 0x16, 0xc0, + 0x38, 0xd4, 0xd9, 0xb4, 0xe3, 0xf8, 0x46, 0xcc, 0x12, 0x1e, 0x2c, 0x16, 0x1a, 0x4c, 0x0d, 0x9b, + 0xaf, 0x1b, 0x91, 0x40, 0xae, 0x68, 0x03, 0x4a, 0x8e, 0x65, 0x4f, 0x62, 0x99, 0x2e, 0x41, 0x01, + 0x1b, 0xb4, 0x1c, 0x68, 0x27, 0xa9, 0x7c, 0xf3, 0x66, 0x81, 0xa1, 0xd6, 0x6e, 0x28, 0x2e, 0x28, + 0xad, 0x54, 0xca, 0xc0, 0xc7, 0xdc, 0x35, 0x81, 0x17, 0x12, 0xdd, 0x33, 0xda, 0x58, 0x58, 0xd5, + 0x46, 0x33, 0xad, 0x89, 0x77, 0xcb, 0x65, 0x8e, 0x10, 0x07, 0x33, 0x80, 0x51, 0x38, 0x8e, 0xfd, + 0xf9, 0x35, 0x6e, 0xc7, 0x81, 0x73, 0xf3, 0xf1, 0xe6, 0xfc, 0x4c, 0x22, 0x24, 0x20, 0xe9, 0xf0, + 0xb2, 0x42, 0xd0, 0xc4, 0xf7, 0xf7, 0x78, 0x08, 0x2c, 0xad, 0xb3, 0x40, 0x6a, 0xa8, 0x21, 0x57, + 0xd4, 0x61, 0x54, 0x2d, 0xa0, 0xdb, 0xc6, 0x9d, 0xa4, 0x3e, 0x58, 0x42, 0x40, 0x35, 0x90, 0x0d, + 0x89, 0x3e, 0xf2, 0x2d, 0x5b, 0xe8, 0xb5, 0xae, 0x35, 0x02, 0x6e, 0x11, 0xbf, 0xd4, 0x18, 0xc0, + 0x00, 0x20, 0xeb, 0x0c, 0x6e, 0xc6, 0xe3, 0x9e, 0x44, 0x13, 0xb8, 0x3e, 0x2c, 0x68, 0x87, 0x28, + 0x1d, 0x96, 0xe3, 0x1c, 0xe3, 0xc1, 0x23, 0x67, 0x5e, 0x9c, 0x08, 0x98, 0x8d, 0x2e, 0x98, 0xc3, + 0x62, 0x54, 0x3e, 0x92, 0x99, 0xb6, 0x55, 0x32, 0x14, 0x6c, 0x3f, 0x2d, 0x8b, 0x09, 0xa5, 0xc5, + 0x23, 0x58, 0x4c, 0xc3, 0xb8, 0x15, 0x77, 0x3c, 0x28, 0x50, 0x41, 0x9b, 0x6c, 0x65, 0xe2, 0x34, + 0x0d, 0x71, 0x99, 0xde, 0x97, 0x41, 0xbf, 0x0b, 0xf2, 0x03, 0x8d, 0xe7, 0x24, 0x9a, 0x3f, 0x27, + 0xd4, 0x2d, 0xb5, 0x1d, 0x60, 0x39, 0x82, 0xa5, 0x6d, 0x25, 0x36, 0xaa, 0x8b, 0xe7, 0xa5, 0x54, + 0x98, 0x01, 0xa2, 0x1f, 0x8d, 0x18, 0xe0, 0x29, 0x1e, 0x09, 0xdf, 0xa7, 0x24, 0xaa, 0x96, 0x4a, + 0xba, 0x9c, 0x71, 0x27, 0x93, 0x55, 0xd0, 0xa1, 0x34, 0x05, 0x42, 0x98, 0xc5, 0x71, 0xb0, 0x0d, + 0x9c, 0xfd, 0x39, 0xc3, 0x1c, 0x51, 0xb3, 0x9d, 0xe2, 0x2c, 0x1d, 0x7c, 0xb1, 0x20, 0x22, 0x07, + 0x6d, 0xab, 0xbd, 0x01, 0xf5, 0xe2, 0x5a, 0xd7, 0x36, 0xbf, 0x3a, 0x6e, 0xbc, 0x7b, 0xf7, 0xae, + 0x46, 0xb0, 0x34, 0xb6, 0x86, 0xf6, 0x02, 0x97, 0xea, 0xcc, 0x9a, 0x5b, 0x6c, 0x27, 0x32, 0x05, + 0x8e, 0x08, 0xba, 0xf9, 0xe7, 0x87, 0x63, 0x01, 0x0e, 0xa8, 0x82, 0x00, 0xaa, 0x05, 0x86, 0x44, + 0x05, 0x28, 0xca, 0x5c, 0xf4, 0xa5, 0x50, 0x15, 0x4a, 0x02, 0x55, 0x46, 0xae, 0x4f, 0xc1, 0x4f, + 0x52, 0x68, 0x7a, 0x9b, 0x98, 0x38, 0xc5, 0x3b, 0x54, 0x2a, 0x88, 0xcc, 0x8f, 0xe8, 0x11, 0xdd, + 0xf0, 0x3a, 0xeb, 0x83, 0x9d, 0x66, 0xf7, 0xf0, 0xa7, 0x30, 0x02, 0x9f, 0xd6, 0x34, 0xf9, 0x47, + 0x33, 0x1e, 0x78, 0x6e, 0x22, 0x75, 0x39, 0x38, 0x8a, 0xa3, 0x30, 0x00, 0x8e, 0x3a, 0xf2, 0x9c, + 0xf3, 0x10, 0x7c, 0xee, 0x4a, 0x65, 0x4b, 0xa1, 0xaa, 0x8b, 0x3b, 0x85, 0xea, 0x62, 0x9e, 0xf1, + 0x7c, 0x53, 0xad, 0x02, 0xbf, 0xf5, 0xb9, 0x64, 0x87, 0x48, 0xf1, 0x6b, 0x22, 0x33, 0x9c, 0xc2, + 0x5c, 0xaf, 0xbf, 0x9e, 0x1c, 0xfb, 0x02, 0x5d, 0x2e, 0x98, 0x57, 0x6e, 0x65, 0xcb, 0xba, 0x76, + 0x7f, 0x0f, 0x21, 0x88, 0x65, 0x27, 0xa8, 0xca, 0xef, 0x35, 0x62, 0x3a, 0xa3, 0x25, 0x45, 0xe9, + 0x4b, 0x3e, 0x86, 0x97, 0xab, 0x5c, 0x00, 0x1d, 0x2b, 0xfa, 0x15, 0x07, 0xa8, 0x54, 0x22, 0x13, + 0xdf, 0xe6, 0x0e, 0x1c, 0xa9, 0x61, 0x41, 0x10, 0xf6, 0xf6, 0x6e, 0x60, 0x3a, 0x88, 0x00, 0xe6, + 0x2d, 0x16, 0xb0, 0x74, 0x83, 0xc5, 0xc5, 0xdc, 0xbf, 0xa8, 0x6a, 0x97, 0x74, 0x0c, 0xf8, 0x20, + 0x31, 0xef, 0xa3, 0x39, 0x48, 0x9d, 0x3d, 0x10, 0x88, 0xcc, 0xc9, 0xca, 0xd9, 0x00, 0x78, 0x19, + 0xf5, 0x31, 0xaa, 0xe2, 0x54, 0xab, 0x71, 0xa5, 0x6a, 0x43, 0x2b, 0x09, 0x23, 0x23, 0x9a, 0x82, + 0x0d, 0xe0, 0x80, 0x91, 0xef, 0x25, 0xa8, 0x3c, 0x11, 0xc5, 0xc5, 0x42, 0x80, 0xc5, 0xd0, 0x42, + 0xe7, 0x38, 0x47, 0x65, 0xdd, 0x96, 0x66, 0xeb, 0x2b, 0xa6, 0xb8, 0x69, 0x4e, 0xba, 0x52, 0x00, + 0xca, 0xaa, 0x09, 0xae, 0xa2, 0x13, 0xda, 0xe4, 0xc8, 0x9a, 0x36, 0x60, 0x31, 0x11, 0x08, 0x18, + 0xc1, 0x01, 0x27, 0xb3, 0x84, 0x3a, 0xa8, 0x43, 0xa8, 0x4f, 0x99, 0xac, 0x49, 0x9c, 0x79, 0x60, + 0x33, 0xd8, 0x25, 0xe0, 0x05, 0x3c, 0x02, 0x40, 0x96, 0x67, 0xae, 0x90, 0x05, 0xfc, 0x04, 0xe6, + 0x11, 0x51, 0xc0, 0x3d, 0x63, 0x36, 0x08, 0x6a, 0x66, 0x4e, 0x11, 0x65, 0x5b, 0x9c, 0x1f, 0x3b, + 0x5b, 0xbb, 0x1a, 0x69, 0x20, 0xc6, 0x25, 0xbe, 0x23, 0x4e, 0xab, 0x2f, 0x56, 0x0b, 0x0e, 0x7d, + 0x04, 0x14, 0x48, 0x18, 0xa9, 0x03, 0xb5, 0xa6, 0x0b, 0x01, 0x55, 0x12, 0x8d, 0xed, 0x24, 0x8c, + 0xc8, 0x35, 0xc8, 0x06, 0x66, 0x3e, 0xb8, 0x8a, 0x36, 0x3f, 0x86, 0x85, 0x92, 0xa9, 0x68, 0x41, + 0xbf, 0xb2, 0x4f, 0x2e, 0x6a, 0x64, 0xde, 0xcb, 0x65, 0x76, 0x33, 0x20, 0xc0, 0xe3, 0x3e, 0x14, + 0xdb, 0x3b, 0x60, 0x61, 0x5f, 0xec, 0x5a, 0x06, 0xc9, 0x8b, 0x94, 0xb1, 0x8d, 0xb6, 0xfe, 0xa0, + 0x47, 0xcc, 0x66, 0x07, 0x34, 0x75, 0x96, 0x00, 0x0c, 0x4c, 0xe3, 0x22, 0xe2, 0x61, 0x34, 0x0b, + 0xba, 0x9c, 0x81, 0xa9, 0x81, 0xf2, 0x38, 0xf5, 0xbd, 0x23, 0x7e, 0xa5, 0x2b, 0x73, 0xb4, 0x59, + 0x48, 0x64, 0x28, 0x47, 0x66, 0x00, 0x84, 0x39, 0x84, 0xbe, 0x38, 0xc3, 0xfc, 0x81, 0xd8, 0x4e, + 0xf6, 0x94, 0x03, 0x35, 0x56, 0x07, 0x62, 0x10, 0x83, 0x25, 0xc0, 0x35, 0x70, 0xd1, 0x63, 0x65, + 0x62, 0xd4, 0x07, 0xc8, 0x15, 0x33, 0x74, 0xc7, 0x8d, 0xc2, 0x9d, 0xcd, 0xd1, 0x8c, 0x74, 0xe9, + 0x43, 0xe8, 0x39, 0x41, 0x26, 0xe5, 0x36, 0xb0, 0x27, 0x20, 0x49, 0x78, 0xfd, 0xe0, 0x52, 0x9a, + 0x69, 0x00, 0x6a, 0x57, 0x2a, 0x7d, 0xc0, 0x60, 0xea, 0xf1, 0xdb, 0x60, 0x3d, 0xca, 0xc0, 0x75, + 0x65, 0x74, 0xe0, 0x6c, 0x8c, 0x4c, 0x74, 0x8b, 0xdb, 0x4c, 0xf7, 0x79, 0xbf, 0xbd, 0xc6, 0x63, + 0xa9, 0x1c, 0x6f, 0xd7, 0x80, 0xd9, 0x31, 0x0f, 0x1a, 0xb3, 0x8c, 0xe6, 0xf6, 0x8e, 0xba, 0x65, + 0x18, 0xdb, 0xfc, 0x42, 0x0b, 0xb8, 0xc0, 0x07, 0x3e, 0x94, 0x7a, 0xaa, 0x95, 0x98, 0x2e, 0xee, + 0xb1, 0x11, 0x7f, 0x42, 0xdc, 0xb4, 0x22, 0xe2, 0x6a, 0x9d, 0xd1, 0xfa, 0x19, 0x26, 0x27, 0x7d, + 0x39, 0xe0, 0x9e, 0x02, 0x08, 0x62, 0xc9, 0x35, 0xbe, 0x67, 0x23, 0x25, 0xec, 0xcb, 0xb4, 0x03, + 0x04, 0x39, 0xc6, 0xf3, 0x46, 0x53, 0x30, 0xaf, 0xb9, 0xcb, 0xe2, 0x42, 0x65, 0xe1, 0x99, 0x32, + 0x07, 0xbc, 0x92, 0x34, 0x9e, 0x73, 0x30, 0x9e, 0x1b, 0xdf, 0xba, 0xb7, 0xce, 0x9d, 0x89, 0x7b, + 0x0e, 0x77, 0x9c, 0x6e, 0x69, 0x13, 0x6b, 0x29, 0xa9, 0x58, 0xbe, 0xaf, 0x54, 0x46, 0xe4, 0x94, + 0xf3, 0x51, 0xda, 0xad, 0x70, 0xc6, 0x72, 0x01, 0x1b, 0x91, 0xf3, 0x21, 0x95, 0xd5, 0x40, 0xd1, + 0x2f, 0x03, 0x55, 0xbf, 0xc8, 0xd9, 0x0e, 0x88, 0xdd, 0xae, 0x3d, 0xdc, 0x75, 0xe9, 0xb7, 0x07, + 0xaa, 0x4a, 0x91, 0x50, 0x74, 0xa5, 0x8c, 0x8a, 0x80, 0xbf, 0x61, 0x06, 0xa3, 0x3c, 0xc6, 0x4d, + 0x87, 0x01, 0x9e, 0x58, 0x17, 0xe7, 0x5c, 0x81, 0x32, 0x08, 0xae, 0x51, 0x35, 0x40, 0x50, 0x9e, + 0x3a, 0xdf, 0x88, 0xfe, 0x98, 0xc2, 0x73, 0xc0, 0x22, 0x38, 0xeb, 0x2e, 0x98, 0x25, 0x07, 0xfe, + 0x4f, 0x78, 0x16, 0x0c, 0x83, 0x95, 0xaa, 0x83, 0x31, 0x10, 0x6d, 0x91, 0x16, 0x34, 0xeb, 0x88, + 0x63, 0x5c, 0xc6, 0x24, 0xf7, 0x12, 0x87, 0xbc, 0xde, 0x1a, 0xbe, 0x9f, 0xb4, 0x86, 0xd5, 0xaa, + 0x1c, 0x6a, 0xce, 0x07, 0xb7, 0xc3, 0x3b, 0xd6, 0xe3, 0xf3, 0x35, 0x5a, 0x4d, 0x39, 0x60, 0xae, + 0xd7, 0x9e, 0x2b, 0x72, 0xb2, 0xf2, 0x00, 0xcd, 0xc1, 0x83, 0x6e, 0xf6, 0x30, 0x56, 0x6c, 0xe2, + 0x92, 0x5a, 0x72, 0x5d, 0xd3, 0xb6, 0xee, 0x56, 0xab, 0x6c, 0x74, 0x3b, 0xbd, 0xe3, 0x73, 0x58, + 0x7a, 0x0f, 0xd4, 0x7c, 0x8e, 0xcf, 0x79, 0x81, 0xcf, 0x76, 0x39, 0x5a, 0x2c, 0xe6, 0x05, 0xaa, + 0x4c, 0x20, 0xc9, 0x50, 0x37, 0x9a, 0x11, 0x09, 0xcb, 0xf8, 0xb6, 0x5f, 0xad, 0x22, 0x80, 0x65, + 0xba, 0x84, 0xfb, 0xb5, 0x25, 0xdc, 0xcb, 0x25, 0xf8, 0xe0, 0x2c, 0xc2, 0xf4, 0x6d, 0x12, 0x61, + 0x52, 0xa9, 0x53, 0x4e, 0x31, 0x6d, 0x61, 0x7c, 0xa6, 0x86, 0xab, 0x50, 0x14, 0xe7, 0x05, 0xf0, + 0x6d, 0xba, 0x91, 0xb3, 0x94, 0x75, 0xcc, 0xdd, 0xdb, 0x2b, 0x5c, 0x52, 0xe7, 0x7d, 0x3f, 0x4d, + 0x1e, 0x38, 0x2d, 0xef, 0x3d, 0x98, 0x32, 0x18, 0x4c, 0x8d, 0x6e, 0xc6, 0xe4, 0x23, 0xeb, 0x33, + 0x50, 0x55, 0x78, 0xcb, 0xba, 0xa0, 0x70, 0xd7, 0xb9, 0x4a, 0x7f, 0xe4, 0xbe, 0xb1, 0xc5, 0x92, + 0x3d, 0xb6, 0x73, 0x30, 0xb3, 0x02, 0x1f, 0xcd, 0x0d, 0xa6, 0x7c, 0xcc, 0x35, 0x5f, 0xbb, 0x3c, + 0xdb, 0xae, 0xc3, 0x2b, 0x95, 0x6b, 0x7d, 0xc6, 0x8a, 0x86, 0x46, 0xb3, 0xbb, 0x58, 0xec, 0x68, + 0x0b, 0x12, 0xa0, 0x34, 0x34, 0x9e, 0x6d, 0x0e, 0xfc, 0x84, 0x01, 0x40, 0xba, 0x7e, 0x0f, 0x1a, + 0xf4, 0xf7, 0x1a, 0xa0, 0xc6, 0xf6, 0xf6, 0xe8, 0xc1, 0xa9, 0x54, 0x9c, 0x6a, 0xb5, 0xd5, 0x03, + 0xa6, 0x78, 0x5c, 0xda, 0xe0, 0x3e, 0xd8, 0xc0, 0x92, 0xa4, 0x50, 0x2d, 0xc9, 0x34, 0xa0, 0xf2, + 0x6c, 0x34, 0xc2, 0xf2, 0x62, 0xe5, 0x19, 0x11, 0x74, 0xee, 0x54, 0xf5, 0x62, 0x1b, 0x4d, 0x1b, + 0xe0, 0x59, 0x2b, 0x92, 0x73, 0x01, 0x7a, 0x0b, 0x73, 0x56, 0x41, 0x2c, 0xa2, 0xe4, 0x50, 0xa0, + 0x3e, 0x85, 0x01, 0x40, 0x97, 0x91, 0x2a, 0x81, 0x45, 0xb1, 0x2e, 0xd2, 0xd0, 0x2d, 0xe8, 0x8e, + 0x2e, 0xf4, 0xc8, 0x50, 0x28, 0x39, 0x04, 0x12, 0x5c, 0xea, 0x78, 0x45, 0xc5, 0x2d, 0xed, 0x96, + 0xf3, 0x1e, 0x1c, 0x8f, 0xa2, 0x11, 0x10, 0x1a, 0x58, 0x69, 0x6f, 0xef, 0xce, 0xc0, 0xa6, 0x36, + 0xb6, 0x5b, 0x82, 0xe2, 0x1a, 0x91, 0xb4, 0xdd, 0x67, 0xb2, 0x38, 0x36, 0x77, 0x44, 0x31, 0x06, + 0x5b, 0x15, 0x51, 0x29, 0x33, 0x01, 0x0d, 0x95, 0x86, 0xb5, 0x45, 0x46, 0x0b, 0x42, 0x59, 0x09, + 0x90, 0x53, 0x58, 0xbb, 0x58, 0x60, 0x3c, 0x1a, 0x30, 0xbc, 0xa7, 0x3f, 0x19, 0xa2, 0xfb, 0x46, + 0xd1, 0x5f, 0x18, 0x5a, 0xa6, 0x10, 0xd1, 0xb2, 0xa0, 0xaf, 0xea, 0xa9, 0x21, 0x14, 0x14, 0xc8, + 0x71, 0xc0, 0xab, 0x47, 0x10, 0xb0, 0x22, 0x8d, 0xd4, 0x5b, 0xd6, 0x3a, 0xfd, 0x16, 0x99, 0x1e, + 0xdb, 0x09, 0xe6, 0x8a, 0x28, 0xa4, 0xde, 0x1c, 0x1c, 0xbb, 0xc3, 0xd0, 0xb8, 0x7a, 0xa1, 0xaa, + 0xd3, 0xb1, 0x01, 0x8a, 0x23, 0x66, 0x5e, 0xe1, 0xcf, 0x5d, 0x2a, 0x59, 0x3f, 0xae, 0x3a, 0x0f, + 0xad, 0xb0, 0x7d, 0xa6, 0x87, 0x20, 0xd3, 0xa9, 0xc3, 0xb9, 0xaa, 0x31, 0xc0, 0xe8, 0xeb, 0x6b, + 0x45, 0x60, 0x2f, 0xdc, 0x34, 0x8e, 0xa6, 0x78, 0x26, 0xc7, 0xd5, 0x5a, 0xbb, 0xc5, 0x02, 0xe3, + 0x7d, 0x16, 0xc1, 0x1f, 0xc5, 0x27, 0xc6, 0x47, 0xb2, 0x5d, 0x09, 0xb4, 0x07, 0x77, 0x3e, 0xb5, + 0x5d, 0x49, 0x4b, 0xc9, 0x0c, 0x44, 0x62, 0xe2, 0x01, 0xd5, 0x52, 0xa6, 0x6a, 0xa5, 0xd6, 0x08, + 0x2c, 0xbe, 0x58, 0x2e, 0x65, 0x3c, 0xa4, 0x66, 0x6e, 0xae, 0x56, 0xa8, 0x08, 0xee, 0x45, 0x96, + 0x72, 0x23, 0x82, 0x20, 0xb8, 0x30, 0x09, 0x51, 0xfa, 0xc8, 0xec, 0x65, 0x0f, 0xb0, 0x0a, 0x4c, + 0x08, 0xb7, 0x31, 0x25, 0x28, 0xa6, 0xa5, 0x44, 0x47, 0x10, 0x6c, 0x6e, 0xe2, 0xcf, 0xad, 0xe8, + 0x01, 0x01, 0x04, 0x9c, 0xa4, 0xb5, 0x73, 0xaa, 0x35, 0x56, 0x9c, 0x23, 0x20, 0x44, 0x0a, 0x83, + 0x0f, 0xc1, 0xbb, 0x40, 0xa3, 0x05, 0x9c, 0x6d, 0xdd, 0x46, 0x77, 0x6b, 0x3e, 0x54, 0x92, 0xf9, + 0x79, 0x41, 0xe1, 0xd3, 0x50, 0xb3, 0xec, 0x89, 0x59, 0xa4, 0x30, 0x20, 0xa4, 0x8b, 0x58, 0x03, + 0x62, 0xa0, 0xcc, 0x55, 0x09, 0x0a, 0xac, 0x0d, 0xb3, 0x35, 0xaa, 0x31, 0x8e, 0x32, 0x0c, 0x54, + 0x87, 0x0a, 0x92, 0x1f, 0x54, 0xdb, 0x43, 0x59, 0xa8, 0x18, 0x0f, 0xa3, 0x94, 0xd1, 0x6e, 0xfa, + 0x80, 0xfe, 0x2a, 0x52, 0x0c, 0xa8, 0x49, 0x41, 0xa5, 0xcb, 0x52, 0xed, 0xcf, 0x65, 0xa6, 0x30, + 0xcf, 0xd0, 0x62, 0x55, 0xfe, 0x80, 0x35, 0x79, 0xce, 0x27, 0x51, 0xa7, 0x60, 0xf6, 0x45, 0x72, + 0x24, 0x22, 0x6f, 0x22, 0x9c, 0x6b, 0xfc, 0x84, 0xfc, 0x43, 0x14, 0x0e, 0x29, 0x81, 0x24, 0xbd, + 0x76, 0x74, 0xd5, 0xc0, 0x73, 0x6c, 0x2b, 0x21, 0xd3, 0x37, 0xcf, 0xf7, 0x37, 0x03, 0xa9, 0xbc, + 0x54, 0xa7, 0x2c, 0xa2, 0x5a, 0x7c, 0x25, 0x6c, 0x01, 0xf0, 0x53, 0xa8, 0x3f, 0xa8, 0x94, 0x51, + 0x23, 0xa6, 0x5c, 0x82, 0x72, 0x3a, 0xcd, 0x84, 0xac, 0xbd, 0x2e, 0xb9, 0xab, 0x2b, 0x9f, 0x09, + 0x1f, 0xca, 0x73, 0xd1, 0x12, 0x98, 0x2d, 0xbb, 0xe5, 0xe8, 0x6b, 0x52, 0x2b, 0x02, 0x9d, 0xf7, + 0xa1, 0x27, 0xe2, 0x56, 0xb8, 0xca, 0x26, 0x58, 0x20, 0x98, 0x8a, 0xe2, 0x06, 0xa3, 0xac, 0x19, + 0x0c, 0xdc, 0x90, 0x57, 0x8a, 0xcd, 0x3d, 0x33, 0x9e, 0x07, 0x76, 0xee, 0x79, 0x7f, 0xa1, 0xf7, + 0x9a, 0x69, 0x45, 0x88, 0xa5, 0x36, 0xa6, 0x22, 0x9b, 0xa7, 0x40, 0xc2, 0x06, 0x90, 0x0f, 0x93, + 0x55, 0x29, 0x99, 0xd8, 0x8a, 0x20, 0x9d, 0x16, 0xe1, 0x02, 0xf0, 0x5d, 0xb9, 0x18, 0x35, 0x0d, + 0x1f, 0x18, 0xf9, 0x1b, 0xd9, 0x04, 0x21, 0x14, 0xc0, 0xec, 0x10, 0x8c, 0x03, 0x66, 0x35, 0x5f, + 0x1b, 0x79, 0x22, 0xca, 0xd2, 0x2c, 0xf0, 0x45, 0x64, 0x01, 0x91, 0x70, 0xb1, 0xf0, 0xc1, 0x2f, + 0x59, 0x43, 0x99, 0x0d, 0x5e, 0x8a, 0x9c, 0x28, 0xb8, 0x2a, 0x49, 0xc1, 0xc4, 0x13, 0xee, 0x2e, + 0x16, 0x0e, 0xa8, 0x9d, 0x95, 0x98, 0x85, 0xc2, 0xcb, 0x21, 0x1f, 0xa1, 0xd6, 0xff, 0xc7, 0xec, + 0xe2, 0xf3, 0x73, 0x9d, 0x92, 0x97, 0x7e, 0x4a, 0x87, 0xbf, 0xed, 0xa4, 0x83, 0x63, 0x65, 0x60, + 0x63, 0x5a, 0x22, 0x58, 0x68, 0xe6, 0xa6, 0xc4, 0x46, 0x9a, 0x0c, 0xf2, 0x8a, 0xb1, 0x42, 0xd7, + 0x11, 0xdb, 0x97, 0xda, 0x8b, 0xce, 0xb9, 0x1e, 0xfb, 0xce, 0x1a, 0x41, 0x52, 0x62, 0xed, 0xa8, + 0xd5, 0xc9, 0x95, 0x33, 0xda, 0x18, 0xf7, 0xad, 0xf3, 0x69, 0xd6, 0x7f, 0x6b, 0x71, 0xda, 0x31, + 0x67, 0x18, 0xab, 0x98, 0xb5, 0x32, 0x39, 0x7b, 0x85, 0xe9, 0x54, 0xa2, 0xf0, 0x75, 0x96, 0xcd, + 0x95, 0x0a, 0x05, 0x3c, 0x45, 0xda, 0xba, 0xc1, 0xca, 0xf7, 0xa0, 0x30, 0x78, 0x92, 0xaa, 0xa9, + 0x62, 0x60, 0xc0, 0x22, 0x69, 0xdd, 0x6e, 0x2e, 0x16, 0x76, 0x86, 0xf1, 0x6d, 0xf5, 0x3a, 0x46, + 0xbb, 0x2e, 0x2e, 0x07, 0x2a, 0xae, 0x03, 0x6b, 0x04, 0x08, 0x49, 0x8d, 0x7b, 0xb6, 0x52, 0x7d, + 0xc8, 0x77, 0xd6, 0xea, 0x03, 0x30, 0x47, 0x32, 0x5d, 0x31, 0x67, 0x3d, 0x70, 0x41, 0x29, 0x19, + 0xf1, 0x37, 0xc1, 0xf1, 0x54, 0x72, 0xf1, 0x0c, 0x82, 0xd7, 0xc8, 0x68, 0x81, 0xc7, 0xd6, 0x07, + 0x5b, 0xef, 0xad, 0x69, 0xd6, 0x69, 0xa5, 0x32, 0xa3, 0xad, 0x0e, 0x0a, 0x34, 0xe0, 0xa6, 0xfd, + 0x00, 0x86, 0x70, 0x06, 0x72, 0x43, 0x3e, 0x41, 0x53, 0x9f, 0x73, 0x8f, 0xa9, 0xec, 0xc8, 0x3d, + 0x88, 0x3d, 0xa7, 0xd0, 0xc2, 0xc6, 0xf0, 0x3d, 0x47, 0x5c, 0x71, 0x8b, 0x1c, 0xec, 0x6d, 0x84, + 0xc6, 0xa0, 0xeb, 0x25, 0xe0, 0xba, 0x04, 0xcc, 0x4e, 0xe1, 0x09, 0xc3, 0x50, 0x4c, 0x04, 0x80, + 0x97, 0xed, 0x91, 0x38, 0xc8, 0x24, 0x55, 0xcc, 0x27, 0x0c, 0xc6, 0xc5, 0xe9, 0xea, 0xf1, 0x8a, + 0x2c, 0x64, 0x5b, 0x4f, 0x93, 0xc5, 0xa2, 0x41, 0x79, 0x54, 0x6c, 0xb1, 0x2d, 0x68, 0x45, 0x90, + 0x1d, 0x88, 0x5b, 0x31, 0xd8, 0x0d, 0x21, 0xda, 0x74, 0xd9, 0x04, 0x7c, 0x5d, 0x25, 0x62, 0xa3, + 0x71, 0x29, 0x2f, 0x0f, 0xce, 0x3c, 0x46, 0x02, 0x80, 0x1a, 0xb8, 0xf4, 0x25, 0xce, 0x1e, 0xb9, + 0xda, 0xb6, 0xf5, 0x28, 0xdb, 0xc0, 0x45, 0x7f, 0x5c, 0x0d, 0xf5, 0x7a, 0x6c, 0x02, 0x16, 0x0f, + 0x3d, 0xf9, 0x2d, 0x61, 0xf3, 0x44, 0x86, 0xcd, 0xe8, 0xa9, 0xcf, 0x2b, 0x95, 0x33, 0x7d, 0x4e, + 0x99, 0x53, 0x5c, 0x27, 0xef, 0xc1, 0xcc, 0xcb, 0x41, 0x91, 0x29, 0xeb, 0x02, 0x7e, 0xae, 0x79, + 0xd2, 0xba, 0xe6, 0xd7, 0x1b, 0xa8, 0x6b, 0x19, 0x7a, 0x97, 0x5f, 0x1b, 0x69, 0xc7, 0x56, 0x4f, + 0x1d, 0xa9, 0xcb, 0x7a, 0x3b, 0x9c, 0xda, 0xae, 0x4a, 0xe8, 0xe5, 0x12, 0x07, 0x2a, 0x83, 0x76, + 0x09, 0xdb, 0x1f, 0xb3, 0x3d, 0x98, 0xe6, 0x3d, 0x26, 0x4d, 0xd5, 0xec, 0xdb, 0x16, 0xa1, 0xcb, + 0x4b, 0x91, 0x05, 0xd9, 0x10, 0x83, 0xe0, 0x7b, 0x29, 0x0b, 0x5d, 0xb0, 0xf2, 0xf8, 0xf9, 0x5a, + 0xbe, 0xb5, 0x69, 0x6c, 0xa9, 0xa2, 0x5d, 0x1c, 0xe9, 0x10, 0x24, 0x46, 0xeb, 0x06, 0x9c, 0x36, + 0x4a, 0x93, 0x2d, 0x0b, 0x1d, 0x7c, 0xa6, 0x6e, 0x68, 0xe0, 0x12, 0x5b, 0xeb, 0xf6, 0x75, 0x55, + 0x01, 0x04, 0xc3, 0xad, 0xe6, 0x2e, 0x2d, 0xd7, 0x51, 0xf6, 0x7a, 0x99, 0x24, 0xb7, 0x76, 0xbb, + 0x6a, 0x22, 0x75, 0xca, 0x71, 0xc3, 0x75, 0xc3, 0x5b, 0x13, 0x3b, 0xbd, 0xb5, 0x0b, 0x5d, 0x51, + 0x16, 0x02, 0x1c, 0xfe, 0x0c, 0x99, 0xe0, 0xa3, 0x89, 0x15, 0x43, 0x43, 0xed, 0x8b, 0x65, 0xce, + 0xa5, 0xef, 0x28, 0x13, 0xab, 0xd9, 0xa6, 0x18, 0xcb, 0x7c, 0x10, 0x52, 0x43, 0x42, 0x3e, 0x4a, + 0x95, 0x96, 0xc8, 0x07, 0xa9, 0xd5, 0x8a, 0xdb, 0xc5, 0x02, 0xf7, 0xa3, 0x08, 0xc8, 0x1a, 0xaa, + 0xc1, 0x9f, 0x2b, 0x46, 0xeb, 0x29, 0x79, 0xb0, 0xcc, 0xd3, 0x90, 0x7b, 0xb7, 0xcf, 0xcb, 0x62, + 0xcb, 0x23, 0x82, 0x80, 0x31, 0x7a, 0x9f, 0x45, 0xc5, 0xad, 0x08, 0x42, 0xb9, 0x6d, 0x1b, 0x02, + 0xe0, 0x67, 0x11, 0xa8, 0x02, 0xfc, 0xf4, 0xe7, 0xc1, 0x6f, 0xdd, 0x55, 0xc8, 0x47, 0x38, 0xd7, + 0xe7, 0x85, 0x7b, 0xc9, 0x9e, 0xf1, 0xdb, 0x30, 0x5c, 0x75, 0x73, 0xf5, 0x45, 0x82, 0x14, 0x4d, + 0xb9, 0x85, 0xd5, 0x57, 0x0b, 0x14, 0x74, 0x19, 0x2a, 0x16, 0x53, 0xf5, 0xac, 0xd6, 0xee, 0xd8, + 0x7c, 0x2d, 0x9a, 0x28, 0x24, 0x01, 0x57, 0xca, 0x60, 0x28, 0x1c, 0xdb, 0xb0, 0x9f, 0xee, 0xce, + 0x1b, 0x2c, 0x96, 0x9f, 0x55, 0x2d, 0x19, 0x60, 0xc1, 0x4e, 0xb5, 0xb7, 0x32, 0x7d, 0x98, 0xfc, + 0x0f, 0x21, 0x24, 0xa8, 0x18, 0xe9, 0x2d, 0x85, 0x7d, 0x80, 0x21, 0x9b, 0x14, 0xdd, 0x8d, 0xe7, + 0xe5, 0x52, 0x5a, 0x81, 0x19, 0xbe, 0xff, 0x33, 0x8e, 0x85, 0x13, 0x4e, 0x03, 0x8d, 0x3d, 0xa6, + 0x4f, 0x88, 0x5a, 0x0d, 0x42, 0x6e, 0xf9, 0x34, 0x1e, 0x69, 0xec, 0x08, 0xdf, 0xb9, 0x1a, 0xdb, + 0x03, 0x7c, 0x7b, 0x24, 0xd1, 0xd8, 0xb7, 0xf4, 0x51, 0x36, 0x3c, 0x4c, 0x9f, 0x60, 0x14, 0x0d, + 0x22, 0x83, 0x7c, 0x18, 0xdc, 0xd1, 0xce, 0x48, 0x9d, 0xe0, 0x9c, 0x45, 0x2a, 0xc1, 0x38, 0xaf, + 0x24, 0xc5, 0xe9, 0xd8, 0x73, 0xb8, 0x7e, 0x6e, 0x25, 0x03, 0x33, 0xb2, 0x02, 0x27, 0x1c, 0xea, + 0x46, 0xb5, 0x61, 0x98, 0x49, 0x98, 0xe6, 0xf9, 0x0e, 0x5e, 0xab, 0xfb, 0x4d, 0xaf, 0x8c, 0x65, + 0xb6, 0x95, 0x29, 0xb7, 0x85, 0xef, 0x89, 0xca, 0xf7, 0xf7, 0x28, 0x43, 0xba, 0x1a, 0x60, 0x70, + 0x99, 0x38, 0x4c, 0x33, 0x79, 0x3a, 0x6d, 0x6b, 0xe6, 0x95, 0xeb, 0xe1, 0x83, 0xa1, 0xc4, 0x22, + 0x1b, 0xbb, 0x08, 0xea, 0x9b, 0x1c, 0x3d, 0x49, 0x52, 0xf2, 0xb8, 0x6e, 0x67, 0xec, 0xe8, 0x8e, + 0xd6, 0xc0, 0x9e, 0x47, 0x56, 0x1c, 0x83, 0x27, 0xd4, 0x2c, 0x37, 0x96, 0xc6, 0x92, 0x25, 0xdb, + 0xc0, 0x29, 0xca, 0x45, 0x85, 0x38, 0xdd, 0x0a, 0x71, 0x0d, 0xc8, 0x00, 0x30, 0xe3, 0x4b, 0x66, + 0xe7, 0x2b, 0x3c, 0x40, 0xcc, 0x8a, 0x73, 0x95, 0x9b, 0xc4, 0xba, 0x24, 0x2a, 0x6a, 0x40, 0x49, + 0x90, 0x18, 0x7d, 0x7c, 0xfa, 0x84, 0xc0, 0xb9, 0x91, 0x05, 0xb7, 0xf5, 0xbb, 0x26, 0x04, 0x28, + 0x98, 0x27, 0xf4, 0x3d, 0xe8, 0xf9, 0x3b, 0x0b, 0xf2, 0xfb, 0xef, 0x10, 0xb0, 0xe5, 0xb3, 0x41, + 0x17, 0xe2, 0x10, 0x3f, 0x28, 0x06, 0xbc, 0x77, 0xa9, 0x1a, 0xbc, 0x7a, 0x1c, 0x21, 0x9e, 0x7a, + 0xb4, 0x99, 0x46, 0x5b, 0x39, 0xc6, 0x33, 0xfe, 0x80, 0x5e, 0x69, 0xd6, 0xa4, 0xcb, 0x51, 0xb3, + 0xa7, 0x67, 0x39, 0x54, 0x76, 0xfb, 0xc8, 0xbe, 0xb1, 0x2e, 0x3b, 0xdc, 0x86, 0x23, 0x49, 0x7a, + 0xb9, 0xac, 0x53, 0x7c, 0xbd, 0x5e, 0x97, 0x3b, 0x33, 0xda, 0xf5, 0x4d, 0xe7, 0xea, 0x46, 0x33, + 0x64, 0x4e, 0xa4, 0x45, 0x40, 0x1f, 0x25, 0xec, 0x6f, 0xcd, 0x5d, 0x7d, 0xce, 0x2f, 0xbf, 0x1e, + 0xaf, 0x76, 0xe9, 0xca, 0x2e, 0x87, 0x3b, 0xbb, 0x1c, 0x5f, 0x1c, 0x69, 0x06, 0x9b, 0xfe, 0xb3, + 0xc9, 0x2e, 0x81, 0x18, 0x4b, 0x30, 0xba, 0x45, 0x98, 0xfb, 0xb5, 0xb0, 0x35, 0xe9, 0xb1, 0x27, + 0x81, 0x35, 0xf1, 0xfa, 0x16, 0xba, 0xc5, 0xf8, 0x33, 0x9e, 0x9d, 0x3e, 0xc2, 0x0c, 0x79, 0xed, + 0x4f, 0x5d, 0x6f, 0x97, 0xed, 0x01, 0xb8, 0xc6, 0x62, 0x01, 0xb3, 0x88, 0x40, 0xc9, 0x19, 0xa6, + 0xf1, 0x22, 0xb6, 0x5c, 0x2b, 0xf2, 0x6a, 0x9e, 0xdc, 0xfc, 0x05, 0xd6, 0x0d, 0x78, 0xcd, 0xfb, + 0x34, 0x00, 0x3e, 0x59, 0x78, 0x9f, 0x42, 0x07, 0xfe, 0x58, 0x8e, 0x52, 0x1b, 0xf1, 0xb5, 0xc3, + 0x55, 0xb2, 0xa8, 0x14, 0x3c, 0x92, 0xa0, 0x1d, 0x49, 0x46, 0xb1, 0x43, 0xbf, 0xaa, 0xd5, 0x6a, + 0x5a, 0x35, 0x32, 0x07, 0x61, 0x9c, 0xc0, 0x65, 0x04, 0x42, 0x85, 0x49, 0x5b, 0xb8, 0x8d, 0x85, + 0x15, 0xd9, 0x83, 0x6a, 0xd2, 0x54, 0xde, 0x20, 0xf9, 0xb0, 0xb9, 0xab, 0x14, 0xed, 0x05, 0xef, + 0x79, 0xe3, 0x6d, 0xbd, 0x5d, 0x6f, 0x36, 0xf2, 0xc8, 0xf7, 0x05, 0x27, 0xe9, 0xfc, 0x74, 0x5a, + 0x83, 0x1a, 0x16, 0xad, 0x3e, 0x6a, 0xe7, 0x25, 0xad, 0xaa, 0x27, 0xd5, 0xf0, 0x05, 0x95, 0xda, + 0x61, 0x0c, 0x3e, 0xa2, 0x51, 0xd5, 0xb0, 0x54, 0x64, 0xa5, 0xb1, 0x17, 0xa4, 0xa5, 0x1d, 0x28, + 0x0f, 0xa9, 0x16, 0xff, 0xd6, 0xe1, 0xea, 0xa5, 0xd7, 0x55, 0x18, 0xc1, 0x56, 0x18, 0x81, 0x1a, + 0x73, 0xfd, 0xa2, 0xda, 0xfb, 0x88, 0xa1, 0x75, 0x1e, 0x47, 0x7e, 0x36, 0xeb, 0x91, 0x4e, 0x7b, + 0x09, 0xec, 0x99, 0xb6, 0x29, 0x9b, 0x9a, 0x17, 0x81, 0x92, 0x90, 0x8c, 0xa0, 0xb1, 0x19, 0x04, + 0x09, 0x33, 0x36, 0x87, 0xbf, 0x73, 0x26, 0x7f, 0x1e, 0xf3, 0x39, 0xff, 0x11, 0x18, 0x8d, 0x8e, + 0x0c, 0x87, 0x56, 0x40, 0x75, 0x88, 0x11, 0x01, 0x0e, 0x10, 0x54, 0x63, 0xa9, 0x36, 0x41, 0xae, + 0xe8, 0x07, 0xa8, 0xfd, 0x9f, 0x69, 0xd7, 0xf4, 0x23, 0x58, 0xe8, 0xe6, 0x57, 0xf0, 0x03, 0x50, + 0x5e, 0xc3, 0xc8, 0xeb, 0x7b, 0x18, 0xeb, 0x96, 0x65, 0x47, 0xdb, 0x8b, 0x6c, 0x1c, 0x6e, 0xcb, + 0x1c, 0xee, 0xef, 0x29, 0x09, 0xa5, 0xb1, 0xa8, 0x29, 0x18, 0x1e, 0x23, 0xdd, 0xd4, 0xf0, 0x1c, + 0x2b, 0x8d, 0x52, 0x9c, 0xe1, 0xa3, 0x90, 0xc7, 0x5f, 0x69, 0xcd, 0x7d, 0x26, 0x9f, 0x9b, 0x1a, + 0x9e, 0x63, 0xa0, 0x2d, 0xff, 0x19, 0x6c, 0x3a, 0x55, 0x97, 0x60, 0xef, 0xed, 0xff, 0x43, 0xe8, + 0xae, 0xeb, 0x02, 0x74, 0x63, 0xf9, 0xcb, 0xca, 0xfb, 0x26, 0xfc, 0x79, 0xd6, 0xac, 0x03, 0xa2, + 0x80, 0xec, 0xcd, 0xb7, 0x0c, 0xd0, 0x4b, 0x79, 0x68, 0x26, 0x17, 0xda, 0xcc, 0x2a, 0x97, 0x4b, + 0xd2, 0x3a, 0x27, 0xbc, 0x13, 0x45, 0xd6, 0x1c, 0x13, 0x93, 0xfe, 0x9c, 0x7c, 0x22, 0xf6, 0x9c, + 0xe6, 0xc9, 0x0f, 0x5e, 0xd7, 0x97, 0x86, 0x39, 0xb4, 0x46, 0xfa, 0xaa, 0x01, 0xce, 0x5f, 0x4b, + 0x31, 0xd8, 0xd3, 0x8a, 0x62, 0xcb, 0xa9, 0x2c, 0x74, 0xd4, 0x72, 0x12, 0x24, 0x49, 0x66, 0xfe, + 0x22, 0x5c, 0x6e, 0x09, 0x30, 0x66, 0x12, 0x8a, 0x25, 0x48, 0xd0, 0x12, 0x88, 0x9d, 0x96, 0x20, + 0x59, 0x49, 0x3d, 0xad, 0x59, 0x02, 0xa1, 0x5a, 0x82, 0xfb, 0xfc, 0xac, 0x84, 0x4e, 0xd0, 0x07, + 0x27, 0x72, 0x75, 0xee, 0xa9, 0x4b, 0x98, 0x9b, 0x75, 0x73, 0x3a, 0x10, 0xc2, 0xa7, 0x96, 0x29, + 0x13, 0x82, 0x3d, 0xc2, 0xb7, 0x61, 0x42, 0xfb, 0x71, 0xea, 0xc5, 0x94, 0x4f, 0x5c, 0x6f, 0x7d, + 0xe4, 0xe1, 0x51, 0xbd, 0x00, 0xb2, 0xbd, 0x07, 0x28, 0xaa, 0x26, 0x7b, 0xba, 0x68, 0xef, 0x85, + 0x4d, 0x70, 0x2b, 0xc3, 0xbd, 0xc4, 0xf8, 0x0f, 0x96, 0xc1, 0x7f, 0xba, 0x59, 0x32, 0x65, 0x49, + 0x59, 0xb2, 0x4b, 0x45, 0x59, 0x2a, 0x0a, 0x88, 0x23, 0x94, 0x05, 0x22, 0x31, 0xc3, 0x57, 0x8b, + 0xe4, 0x39, 0x78, 0xdf, 0xe8, 0x19, 0x23, 0x50, 0xc9, 0x25, 0x57, 0x74, 0x2c, 0x1e, 0xf3, 0x28, + 0x01, 0xe1, 0x83, 0xde, 0x1a, 0xc4, 0x13, 0x16, 0xf3, 0xb0, 0xb6, 0xbf, 0x17, 0x60, 0xaa, 0x82, + 0x5c, 0x8b, 0x55, 0x04, 0xe8, 0x9e, 0x39, 0xc0, 0x70, 0xe7, 0x85, 0xae, 0x68, 0x00, 0x70, 0x55, + 0x31, 0x87, 0x52, 0x6b, 0xd4, 0xeb, 0x2f, 0xf4, 0x78, 0x0f, 0x37, 0xb3, 0xe4, 0x81, 0xa9, 0xa0, + 0x4b, 0x0c, 0x66, 0xf3, 0xb8, 0x1a, 0xb0, 0x01, 0xfe, 0xfd, 0xa1, 0x64, 0x12, 0x36, 0x34, 0x26, + 0x0f, 0x7d, 0x0b, 0x59, 0x7a, 0x18, 0x63, 0xb8, 0x5b, 0x3a, 0x59, 0x76, 0xfe, 0x9b, 0x46, 0x27, + 0xe8, 0xa1, 0xb4, 0x02, 0x60, 0xe0, 0xdd, 0x58, 0x23, 0x8f, 0x19, 0x9f, 0xf0, 0xe4, 0x3f, 0xcb, + 0x3f, 0xc1, 0x0b, 0x7e, 0xd7, 0xcc, 0x9e, 0x3d, 0xa7, 0x99, 0xb9, 0x1c, 0xd4, 0x3c, 0xc6, 0xaf, + 0xc3, 0xd9, 0x73, 0xe8, 0xba, 0xf8, 0x59, 0x99, 0x56, 0xff, 0x0f, 0x49, 0x48, 0x38, 0x92, 0x47, + 0x68, 0x68, 0xb9, 0x58, 0x6c, 0x69, 0x8b, 0x3f, 0xf5, 0xb1, 0xb5, 0x75, 0x5a, 0x96, 0x1e, 0xfe, + 0x06, 0xa5, 0x28, 0xb5, 0x06, 0x81, 0xd8, 0xba, 0x68, 0x90, 0xda, 0xf1, 0xa6, 0x64, 0xc6, 0xaa, + 0xd8, 0x2e, 0xd9, 0xc9, 0x9a, 0xec, 0xe4, 0x92, 0x03, 0x50, 0x51, 0xcb, 0x03, 0x60, 0xdc, 0x24, + 0x4a, 0x98, 0xd3, 0xfc, 0xa0, 0xdb, 0xec, 0xbf, 0xcc, 0x3d, 0x6d, 0x73, 0xdb, 0x36, 0xd2, 0xdf, + 0x3b, 0x93, 0xff, 0x40, 0xb3, 0x49, 0x4c, 0x4a, 0x14, 0xf5, 0xe2, 0xda, 0xd7, 0x52, 0x66, 0x34, + 0x89, 0xdb, 0x4c, 0x72, 0xbd, 0x34, 0xb9, 0x3a, 0xe9, 0xf5, 0xce, 0xd6, 0x93, 0xd2, 0x12, 0x2c, + 0x71, 0x22, 0x93, 0x2e, 0x09, 0xc9, 0xf6, 0xc9, 0xfa, 0xef, 0xb7, 0x2f, 0x00, 0x09, 0x52, 0x94, + 0x93, 0xdc, 0xdc, 0x87, 0x67, 0x9a, 0xca, 0xc4, 0x3b, 0xb0, 0x58, 0x2c, 0x76, 0x17, 0x8b, 0xc5, + 0xdc, 0xcb, 0xbb, 0x03, 0x0f, 0x38, 0xff, 0x76, 0xdf, 0x3f, 0x74, 0x8b, 0x45, 0x3e, 0xcf, 0x17, + 0x8e, 0xdd, 0xde, 0xc2, 0x6b, 0xa8, 0xae, 0x6d, 0x7b, 0xf4, 0x78, 0x89, 0x87, 0x8e, 0xaf, 0x5d, + 0xe8, 0xf0, 0x86, 0x7b, 0xdc, 0x48, 0x65, 0x54, 0xb7, 0xf3, 0x48, 0x2a, 0x4f, 0xf0, 0xb6, 0x37, + 0x81, 0xfd, 0xdf, 0x9b, 0xdc, 0x05, 0x80, 0x60, 0x45, 0xd7, 0xc9, 0xf5, 0x7e, 0xfb, 0x37, 0xc7, + 0xfe, 0xd6, 0x6e, 0x6b, 0xa8, 0x43, 0x43, 0x58, 0x3b, 0xd0, 0x4a, 0xaa, 0xe4, 0x6f, 0xda, 0x3f, + 0xd6, 0x6e, 0x92, 0xa6, 0x1a, 0x5b, 0xe8, 0x9c, 0xcd, 0x6d, 0x11, 0x71, 0xf4, 0x0a, 0x87, 0x7b, + 0x9d, 0xd8, 0x5f, 0x21, 0x42, 0x6e, 0x3e, 0x3b, 0x08, 0x5e, 0x1b, 0xcd, 0x95, 0x32, 0xc9, 0x54, + 0xc0, 0xd3, 0xcb, 0x88, 0x6e, 0xc7, 0xd5, 0x67, 0x2b, 0xa1, 0x86, 0x1e, 0x7b, 0xeb, 0x2c, 0xc8, + 0x88, 0x4a, 0xea, 0x45, 0x76, 0xba, 0x9a, 0x69, 0x62, 0xa9, 0xa3, 0xde, 0x52, 0x10, 0xb6, 0xa0, + 0x49, 0x7b, 0x51, 0xee, 0x77, 0x11, 0x08, 0xff, 0xc1, 0x5c, 0xc7, 0xe0, 0x5e, 0x17, 0xe1, 0x1c, + 0x54, 0x17, 0xbd, 0xc1, 0xc7, 0x84, 0xbb, 0xec, 0x14, 0x52, 0x1f, 0x6d, 0xe0, 0x61, 0x59, 0xa7, + 0xe8, 0xc8, 0x11, 0x4d, 0x14, 0x0a, 0x92, 0x03, 0xab, 0x3a, 0x67, 0xb2, 0x00, 0xc8, 0xb1, 0x08, + 0xa3, 0x4e, 0x5e, 0xac, 0xd5, 0xbc, 0x42, 0x14, 0x20, 0x68, 0xd0, 0x8c, 0xa1, 0x84, 0xac, 0x8e, + 0xec, 0x64, 0x20, 0xb4, 0xe0, 0x97, 0xe8, 0xc4, 0xae, 0x32, 0x71, 0xa6, 0xce, 0x46, 0x32, 0x4a, + 0x06, 0x8e, 0x40, 0x7e, 0x7e, 0xde, 0x4c, 0x36, 0x98, 0xb9, 0x47, 0x56, 0xd2, 0x99, 0xb4, 0xf0, + 0x89, 0xde, 0xae, 0xa2, 0x1f, 0xb0, 0xc9, 0x13, 0x05, 0x59, 0x72, 0x4d, 0x57, 0x30, 0x6c, 0x1e, + 0xff, 0x9f, 0x19, 0x88, 0x0b, 0x2d, 0xd9, 0x16, 0x2d, 0xe0, 0x7e, 0x16, 0xc0, 0x72, 0xfa, 0x69, + 0xc2, 0xfc, 0x5b, 0xe2, 0xad, 0xe7, 0x30, 0x4b, 0x79, 0x60, 0x54, 0x0a, 0x33, 0xdd, 0x5d, 0xb4, + 0x96, 0x2e, 0xb2, 0xde, 0x62, 0x83, 0xfa, 0x81, 0x62, 0xfb, 0xf8, 0xd3, 0xa4, 0xd5, 0x9d, 0xfe, + 0x31, 0x1e, 0x87, 0x4d, 0xc5, 0xed, 0xdb, 0x4b, 0xc7, 0x7e, 0x82, 0x76, 0x80, 0xe1, 0x75, 0x94, + 0xe5, 0xe2, 0x25, 0x7a, 0xa5, 0xc4, 0x72, 0x9a, 0xad, 0x1a, 0x09, 0xa2, 0x67, 0x49, 0x60, 0xa8, + 0xfd, 0x7f, 0x37, 0x97, 0x1d, 0x96, 0x7a, 0x9d, 0x48, 0xd4, 0x0b, 0x1f, 0x19, 0x3c, 0xc9, 0x3f, + 0x4d, 0xd3, 0xa7, 0x52, 0x86, 0x81, 0x3c, 0x08, 0xea, 0x53, 0x94, 0x9d, 0x9c, 0x81, 0x07, 0x24, + 0x81, 0xcf, 0xe0, 0xfe, 0x1a, 0xda, 0xce, 0x28, 0x38, 0xeb, 0x9c, 0x9f, 0xb7, 0xc7, 0xa3, 0xf3, + 0xf3, 0x69, 0xeb, 0xfc, 0xdc, 0x87, 0x3f, 0xed, 0x27, 0x23, 0xf7, 0xbe, 0x92, 0x80, 0x31, 0xb6, + 0xf7, 0x73, 0x68, 0x9f, 0x9d, 0x9f, 0xe7, 0xf7, 0xe7, 0xe7, 0xce, 0xb8, 0x0d, 0x6b, 0xeb, 0xaf, + 0xb0, 0x9a, 0xce, 0x3c, 0x08, 0xe6, 0xbb, 0x82, 0xf0, 0x0d, 0x75, 0xba, 0x23, 0xdb, 0xfb, 0xfb, + 0x57, 0x97, 0xdd, 0x59, 0xd5, 0xbf, 0xe8, 0x18, 0xe6, 0x57, 0x31, 0xfb, 0xe9, 0x16, 0x89, 0xec, + 0xec, 0xc2, 0x6e, 0xff, 0x0c, 0x4b, 0x5a, 0xd6, 0xa3, 0x23, 0xbb, 0xfd, 0x77, 0xc0, 0x99, 0x6a, + 0x3c, 0xd0, 0x20, 0xca, 0x9e, 0x6e, 0x45, 0x73, 0x76, 0x10, 0x70, 0xec, 0xff, 0x83, 0xb1, 0x7f, + 0x3b, 0xba, 0xef, 0xdd, 0xe2, 0xa0, 0x33, 0x88, 0x70, 0xce, 0x7a, 0x9d, 0x1f, 0xa2, 0xce, 0xe5, + 0xf3, 0xce, 0xcb, 0xf1, 0x1a, 0x18, 0x72, 0xdb, 0x8b, 0xeb, 0xb1, 0x03, 0x8c, 0xcd, 0xab, 0x95, + 0xda, 0xed, 0x04, 0xd8, 0x60, 0xfd, 0xcf, 0x7e, 0x0c, 0x13, 0x1e, 0x3d, 0x94, 0x43, 0x67, 0x5a, + 0x34, 0x64, 0x8a, 0xf5, 0x3f, 0xca, 0x31, 0x79, 0x28, 0x87, 0xce, 0x34, 0xaf, 0xc9, 0x6a, 0xb4, + 0x34, 0xd2, 0xe4, 0x84, 0x6f, 0x74, 0xef, 0xf5, 0x95, 0xfa, 0x85, 0x2f, 0x04, 0x03, 0x56, 0xf7, + 0x00, 0xab, 0x7b, 0xde, 0x0a, 0xfe, 0x8f, 0x82, 0xfe, 0xc6, 0xd3, 0xf2, 0x3d, 0x5e, 0x24, 0x92, + 0x80, 0xd9, 0xb0, 0xe8, 0xd7, 0xb0, 0x47, 0x07, 0xeb, 0x09, 0x79, 0x44, 0x04, 0xda, 0x0b, 0xfb, + 0x60, 0xb0, 0x07, 0x8c, 0x01, 0xc0, 0xba, 0x21, 0x16, 0x40, 0xda, 0x9c, 0x97, 0x91, 0xb2, 0xa9, + 0x84, 0xb8, 0xdd, 0x9d, 0x96, 0x2f, 0x76, 0xa5, 0x6d, 0x86, 0x73, 0x53, 0x56, 0x85, 0xfe, 0x36, + 0xf0, 0x25, 0x5b, 0x67, 0xef, 0x28, 0x1e, 0x6d, 0xd9, 0xe0, 0x4a, 0x54, 0xa4, 0x82, 0xa8, 0xde, + 0x35, 0x50, 0xc0, 0x9c, 0xe5, 0x03, 0xef, 0xfb, 0xcd, 0xe3, 0x2e, 0xcb, 0x45, 0xd2, 0x75, 0x59, + 0xba, 0xd3, 0xbd, 0x0e, 0x65, 0x61, 0x5c, 0x40, 0x55, 0x20, 0x0a, 0x8e, 0x6a, 0x99, 0x8b, 0xe1, + 0xd7, 0x33, 0x23, 0x02, 0xd6, 0x33, 0x17, 0x63, 0x36, 0x32, 0x03, 0xf7, 0x8d, 0xd7, 0x6c, 0x72, + 0x89, 0x97, 0x75, 0xa0, 0xc7, 0x73, 0xa9, 0xf3, 0xae, 0x90, 0xb5, 0xca, 0x57, 0x66, 0x4e, 0x3b, + 0x23, 0xfb, 0x40, 0xf8, 0x98, 0xe9, 0x8f, 0x0b, 0xb6, 0x18, 0xd4, 0x9d, 0xa9, 0xd6, 0x6c, 0xcf, + 0x75, 0xb6, 0x5c, 0x7f, 0xac, 0x8c, 0xfc, 0xd4, 0x06, 0xe5, 0xa7, 0x53, 0xa6, 0x1d, 0x25, 0x16, + 0xca, 0x26, 0x51, 0x82, 0xd4, 0x79, 0x63, 0x21, 0x9a, 0x92, 0x8f, 0x28, 0x07, 0xa2, 0x01, 0xd5, + 0xe2, 0xa9, 0x7a, 0x7b, 0x91, 0xcf, 0xb8, 0xdd, 0xa1, 0x1e, 0x69, 0x28, 0x81, 0x85, 0xaa, 0x4f, + 0xe4, 0x09, 0xfb, 0x33, 0xac, 0xed, 0x36, 0xfa, 0x8c, 0x1e, 0x8b, 0x9e, 0xc9, 0x71, 0xb8, 0x25, + 0x1b, 0xa9, 0x04, 0xcf, 0x61, 0x45, 0x1e, 0x5a, 0xe3, 0xa6, 0x64, 0x3a, 0x5a, 0x6d, 0x00, 0x58, + 0xe3, 0x44, 0x98, 0xba, 0x10, 0x2d, 0x71, 0x42, 0x9f, 0xe7, 0x52, 0xeb, 0xbf, 0xe6, 0x04, 0xd6, + 0xf7, 0xe9, 0xaf, 0x00, 0xad, 0x06, 0x7e, 0xd7, 0x9f, 0x77, 0x8f, 0x7a, 0xc4, 0xf1, 0x12, 0x0f, + 0x4a, 0x1c, 0x2f, 0x6d, 0xfe, 0xc0, 0xeb, 0xd2, 0x1e, 0x01, 0x7c, 0x23, 0x5e, 0x8b, 0x71, 0x61, + 0x4f, 0x14, 0x1d, 0x34, 0xda, 0x4b, 0x60, 0x0f, 0xea, 0xa4, 0x68, 0x63, 0x41, 0x5f, 0x71, 0x2b, + 0x45, 0x1e, 0x96, 0xbe, 0x31, 0xe8, 0x62, 0x78, 0x12, 0x66, 0x4f, 0x8e, 0xd4, 0x76, 0x00, 0xbb, + 0xfa, 0xe0, 0xf0, 0xb0, 0x75, 0x06, 0x6c, 0xb1, 0x97, 0xc3, 0x7f, 0x0b, 0x2f, 0x19, 0x9f, 0x4d, + 0xc6, 0xde, 0x8c, 0xa3, 0x21, 0xe8, 0xa9, 0x24, 0x8a, 0xbe, 0xe0, 0x68, 0x95, 0x13, 0x93, 0x30, + 0x9a, 0x81, 0x0b, 0x33, 0xfe, 0x3e, 0x7d, 0x05, 0xd3, 0xb8, 0x35, 0x10, 0x1a, 0x41, 0xd6, 0x85, + 0xa2, 0x34, 0x82, 0x19, 0x7d, 0x21, 0xb7, 0x7e, 0x41, 0x5f, 0xb1, 0xda, 0x21, 0xa3, 0x5b, 0xd6, + 0x60, 0x00, 0x53, 0x57, 0xee, 0x99, 0x2a, 0x26, 0x0a, 0xe3, 0x0e, 0x9e, 0x2d, 0xc6, 0xd0, 0x7b, + 0x54, 0xa4, 0xc6, 0x20, 0xc5, 0x47, 0xdd, 0x58, 0xeb, 0x6b, 0x62, 0xa5, 0xaa, 0xc9, 0x03, 0x11, + 0xf6, 0x4c, 0x65, 0x49, 0x0a, 0x11, 0x4e, 0x02, 0xfb, 0x7b, 0x37, 0x6a, 0x3b, 0xc9, 0x71, 0x36, + 0x3a, 0x0a, 0x7a, 0x15, 0x6d, 0x4a, 0x82, 0x19, 0x32, 0x00, 0x19, 0x64, 0x18, 0x98, 0x09, 0x19, + 0x26, 0xa4, 0xc0, 0xe7, 0x43, 0xc2, 0x77, 0x4a, 0x1c, 0x03, 0x42, 0x76, 0xd4, 0x6b, 0x09, 0xa0, + 0x65, 0xb8, 0x83, 0x4e, 0x80, 0x9e, 0xe1, 0xdf, 0xc5, 0xa6, 0x9c, 0xc8, 0x57, 0xf9, 0xa2, 0x71, + 0x22, 0x79, 0xfe, 0xd2, 0x62, 0xfe, 0x92, 0xd0, 0x19, 0x74, 0x04, 0x4c, 0x07, 0xc0, 0x01, 0xd5, + 0x12, 0xa3, 0x24, 0x40, 0xd9, 0x24, 0x0e, 0xb3, 0xe3, 0xbe, 0xe8, 0xfc, 0x00, 0xa3, 0x13, 0xad, + 0xb4, 0x9b, 0x0d, 0x8b, 0x76, 0xa1, 0x7e, 0xd5, 0x6c, 0xec, 0x2d, 0x82, 0x43, 0xd8, 0xbf, 0x75, + 0xab, 0x8b, 0x1d, 0x50, 0x0f, 0x07, 0x2d, 0xe9, 0x2f, 0x18, 0x7b, 0x5a, 0x8e, 0x80, 0x46, 0x7a, + 0xbd, 0x91, 0x08, 0x06, 0xbd, 0x1e, 0x34, 0xac, 0x3a, 0x21, 0xda, 0xa9, 0x6e, 0x6f, 0x00, 0xed, + 0xa1, 0x46, 0xc2, 0x6d, 0x6a, 0x33, 0x81, 0xa1, 0x52, 0x62, 0x77, 0xb0, 0x41, 0x6a, 0x8d, 0x83, + 0x45, 0x1d, 0x9a, 0x89, 0xe0, 0x64, 0xcb, 0x1c, 0x1a, 0x74, 0xbf, 0x5e, 0x11, 0xf4, 0x03, 0xaa, + 0x01, 0x08, 0x94, 0x55, 0x34, 0xd3, 0x53, 0xb3, 0x0e, 0x3c, 0xce, 0xdd, 0x5e, 0x84, 0xa2, 0xd0, + 0xb0, 0x16, 0x9b, 0x8e, 0x66, 0x84, 0x0c, 0xd3, 0x3f, 0x65, 0x23, 0x43, 0x06, 0x2c, 0x68, 0xdc, + 0xc2, 0x56, 0x36, 0x43, 0x73, 0x6b, 0x92, 0x9e, 0x93, 0xfa, 0xf3, 0xfb, 0xfb, 0xd4, 0xcf, 0xf1, + 0x67, 0x85, 0x3f, 0x91, 0xab, 0xb5, 0xcf, 0xba, 0x6e, 0x96, 0xce, 0x53, 0x6d, 0x1e, 0x6e, 0x96, + 0xa7, 0xa1, 0x00, 0xea, 0x37, 0x43, 0xc3, 0x58, 0xdf, 0x8e, 0x51, 0x0c, 0xb9, 0x4d, 0xad, 0xd7, + 0x99, 0xb1, 0x1c, 0x5b, 0xae, 0x47, 0x83, 0xf9, 0x83, 0x8c, 0x33, 0x33, 0x0c, 0x8b, 0xf7, 0xc2, + 0x0c, 0x27, 0xee, 0xa6, 0x68, 0xbf, 0x0e, 0xca, 0x82, 0xaa, 0x6e, 0x01, 0xcf, 0x58, 0xab, 0xa8, + 0x4a, 0x5f, 0x47, 0x81, 0x61, 0x68, 0x11, 0x8d, 0xfa, 0x30, 0x45, 0xd1, 0xc6, 0x55, 0x73, 0xb4, + 0x78, 0x78, 0x60, 0x80, 0xef, 0xdb, 0x03, 0x9b, 0x33, 0xd2, 0xd1, 0xc0, 0x16, 0x25, 0x16, 0x54, + 0x07, 0x96, 0xd7, 0x06, 0xb6, 0x68, 0x1a, 0x18, 0xb6, 0xff, 0x55, 0x03, 0xd3, 0xcb, 0xe1, 0x73, + 0x03, 0x2b, 0xf6, 0xca, 0x07, 0xb0, 0x18, 0xf2, 0xa8, 0xce, 0x23, 0xc7, 0x07, 0xac, 0x22, 0x14, + 0x43, 0x61, 0x12, 0x3f, 0x66, 0xfa, 0xe3, 0x82, 0xa4, 0xbe, 0x6a, 0x95, 0x8d, 0x58, 0xad, 0xcd, + 0xf3, 0xc3, 0x3e, 0xe2, 0xb4, 0x23, 0xc2, 0x7f, 0xf9, 0xe2, 0x56, 0x4c, 0x70, 0x43, 0x1e, 0x39, + 0x69, 0xf8, 0xa7, 0x83, 0xf7, 0x56, 0x3c, 0xa0, 0x87, 0xc8, 0xb9, 0x63, 0x68, 0xa0, 0x42, 0x19, + 0x85, 0x0e, 0x38, 0xe4, 0xc2, 0x32, 0x0c, 0xa5, 0x2c, 0x8a, 0x3e, 0x7d, 0xfa, 0xe5, 0x65, 0xa1, + 0x6d, 0x0c, 0x7d, 0x37, 0xf6, 0xf0, 0xda, 0xe0, 0x9e, 0xd8, 0xbd, 0x8b, 0xc2, 0x50, 0x2c, 0xc5, + 0xd3, 0xa8, 0x4d, 0x14, 0xb7, 0x73, 0xc0, 0xcd, 0x14, 0xf0, 0x31, 0x01, 0x1c, 0xcc, 0x80, 0x8d, + 0x8b, 0xd5, 0x14, 0x69, 0x16, 0xe5, 0xcb, 0x20, 0x09, 0x02, 0x33, 0x08, 0x12, 0x7e, 0xe6, 0xd2, + 0x9f, 0x19, 0xff, 0xb9, 0x70, 0x6b, 0x55, 0x3d, 0x0c, 0x41, 0x18, 0x8c, 0x82, 0x61, 0x2e, 0x2b, + 0x40, 0xec, 0xff, 0xa5, 0xf5, 0x3b, 0xc1, 0x02, 0xe1, 0xa0, 0x02, 0x83, 0x31, 0x82, 0x41, 0x05, + 0x0e, 0xc6, 0x0c, 0xc1, 0xe8, 0xeb, 0xcb, 0xe1, 0xcc, 0x71, 0xe0, 0x3b, 0x55, 0xc9, 0xa2, 0x5a, + 0x49, 0x59, 0x43, 0x59, 0xdc, 0x6c, 0x73, 0x52, 0x9b, 0xb5, 0x07, 0xf2, 0x43, 0x5b, 0xba, 0xa1, + 0x07, 0xe7, 0x09, 0x00, 0xf6, 0x05, 0xf3, 0x84, 0x9b, 0x6c, 0xb1, 0x9c, 0x3e, 0x3b, 0x57, 0x90, + 0x47, 0xcf, 0x15, 0xeb, 0x54, 0xa0, 0x98, 0x46, 0xf6, 0xbc, 0x6d, 0x3f, 0xe1, 0xaf, 0x05, 0x7c, + 0x29, 0xbc, 0x2f, 0x2b, 0xfd, 0x32, 0xbc, 0x17, 0xb2, 0x09, 0xf1, 0x51, 0x15, 0x58, 0x22, 0x2f, + 0xec, 0x39, 0x06, 0xf2, 0x62, 0x88, 0x40, 0x98, 0x36, 0x23, 0xfe, 0xe7, 0xca, 0x7e, 0x39, 0xe2, + 0xc3, 0x58, 0x6a, 0x00, 0x45, 0xee, 0x71, 0x8d, 0x6a, 0xbb, 0x1c, 0x00, 0xba, 0x28, 0x10, 0x5f, + 0xd1, 0x1e, 0xbe, 0x3f, 0x8d, 0xea, 0x64, 0x7c, 0xd4, 0x52, 0xe4, 0x8e, 0xc9, 0x03, 0x02, 0x70, + 0x58, 0x99, 0x70, 0x2d, 0xff, 0xff, 0xe9, 0x7f, 0x59, 0xc9, 0xaa, 0xf5, 0x87, 0x8d, 0x3c, 0x4b, + 0xa9, 0x3a, 0xa5, 0x1b, 0xac, 0xc5, 0xd1, 0x18, 0x3b, 0xb4, 0x7c, 0x5f, 0x1c, 0x90, 0xd9, 0xa8, + 0xe4, 0x0b, 0x20, 0x4f, 0xa9, 0x6c, 0xb4, 0x3d, 0x76, 0xd4, 0x6b, 0xe3, 0x2b, 0xe7, 0x80, 0x26, + 0xa5, 0x6a, 0xf1, 0xc8, 0x3f, 0x3a, 0x3a, 0x32, 0x92, 0x2f, 0x2b, 0xc9, 0x07, 0x07, 0xfe, 0xc1, + 0xc1, 0x41, 0x99, 0xdc, 0xab, 0x26, 0x1f, 0xf6, 0xcc, 0xa4, 0x4b, 0x33, 0xe9, 0xa8, 0x56, 0x71, + 0xaf, 0x57, 0x49, 0xfe, 0xbe, 0x56, 0xf1, 0x65, 0x35, 0xb9, 0xdf, 0xab, 0x77, 0x79, 0x6c, 0xf0, + 0x82, 0xb6, 0xa1, 0x0e, 0x0c, 0x88, 0xb1, 0xa8, 0xec, 0x7f, 0x80, 0x1e, 0x82, 0x18, 0x1c, 0x14, + 0x70, 0x05, 0xb0, 0x37, 0x88, 0x7e, 0x8d, 0x19, 0x90, 0xe9, 0x52, 0x59, 0x86, 0xcd, 0xf0, 0xe2, + 0x25, 0x97, 0xe8, 0x25, 0x97, 0x14, 0x4b, 0x2e, 0x29, 0x96, 0x5c, 0x63, 0xa7, 0xb9, 0x5c, 0xa6, + 0xcb, 0x65, 0x45, 0xb9, 0x4c, 0x97, 0xab, 0x0c, 0x88, 0x05, 0xa4, 0x40, 0x1d, 0x87, 0x04, 0x7c, + 0x40, 0xd6, 0xd8, 0x65, 0x41, 0x4c, 0x1b, 0xe9, 0x1b, 0x77, 0x74, 0x99, 0x0f, 0x6f, 0x1e, 0xea, + 0x56, 0xac, 0xbb, 0x15, 0x17, 0xdd, 0x8a, 0x8b, 0x6e, 0x6d, 0x4a, 0x6d, 0x2f, 0x3e, 0xb7, 0x13, + 0x65, 0xbb, 0x74, 0xda, 0xe9, 0x03, 0x7a, 0xe2, 0xaa, 0x02, 0x5b, 0xfa, 0xfc, 0x01, 0x2d, 0xd4, + 0xd4, 0xd8, 0x0a, 0xa9, 0x37, 0xdb, 0xfa, 0xc7, 0xdd, 0x87, 0x0e, 0xea, 0xb4, 0x81, 0x58, 0x1a, + 0xc2, 0xfc, 0x57, 0xa4, 0xc0, 0xff, 0xec, 0xf1, 0x03, 0x80, 0x2b, 0xbd, 0xbf, 0x47, 0x26, 0x5c, + 0x69, 0x22, 0xdb, 0x83, 0x56, 0x06, 0xff, 0x27, 0xcc, 0xb8, 0xf2, 0xc3, 0xab, 0x62, 0xa8, 0x6e, + 0x6c, 0x84, 0x8e, 0x12, 0xf8, 0xe9, 0x09, 0x56, 0x64, 0xb4, 0x41, 0xe6, 0x11, 0x9d, 0x41, 0x8b, + 0x2d, 0x2a, 0x8b, 0xb5, 0xf8, 0xb9, 0x65, 0x18, 0x87, 0x0b, 0x90, 0x1a, 0xc3, 0x03, 0xff, 0x68, + 0x17, 0x02, 0x63, 0x8e, 0xfc, 0x01, 0x64, 0xc0, 0xf4, 0xd5, 0xe6, 0xa1, 0x03, 0x0d, 0x6e, 0x59, + 0x9f, 0x68, 0x88, 0xad, 0x13, 0x0d, 0x7e, 0x1a, 0xe9, 0x7d, 0x7a, 0x1d, 0xe8, 0x5e, 0xbe, 0xa1, + 0x18, 0xef, 0xbf, 0x38, 0xea, 0xe0, 0x5d, 0xad, 0x42, 0xac, 0x90, 0xfc, 0xd3, 0x11, 0x08, 0xaa, + 0x57, 0x9a, 0x7a, 0xf6, 0x91, 0x99, 0x51, 0xdb, 0xcb, 0x6e, 0x83, 0xdc, 0xcb, 0xee, 0xe0, 0xe7, + 0x36, 0x48, 0x00, 0xa2, 0x77, 0xf4, 0xab, 0xba, 0x0d, 0xe2, 0x96, 0xee, 0x38, 0x7c, 0xd6, 0xb5, + 0xde, 0xcd, 0xba, 0xf1, 0xcf, 0x6b, 0xff, 0xbf, 0x5a, 0x55, 0x9e, 0xb7, 0x63, 0xd2, 0xc7, 0x46, + 0xd0, 0xbb, 0x14, 0xc4, 0xab, 0x3a, 0x62, 0xc2, 0x4e, 0x4d, 0x37, 0x5c, 0xc8, 0x04, 0x15, 0xdf, + 0xa1, 0x6b, 0x56, 0x58, 0x68, 0xe5, 0xb8, 0x32, 0x72, 0xa0, 0x61, 0x74, 0x0c, 0x94, 0x1a, 0xca, + 0x4e, 0x98, 0xb4, 0x8d, 0x88, 0xee, 0x80, 0x51, 0xaf, 0x14, 0xbe, 0x0b, 0x99, 0x5b, 0xa2, 0xc4, + 0xdd, 0x2b, 0x34, 0xc6, 0x35, 0x6d, 0x74, 0xd6, 0x8a, 0xbf, 0x5e, 0x77, 0x4f, 0xbe, 0x3f, 0xa8, + 0xf5, 0xad, 0xf1, 0xa8, 0x61, 0x14, 0x88, 0x5d, 0x1e, 0x23, 0xee, 0xc2, 0x70, 0x7b, 0x6e, 0x7b, + 0x79, 0xeb, 0x61, 0x1c, 0xb7, 0x73, 0xfb, 0x41, 0x1c, 0xb7, 0x57, 0xf6, 0xc6, 0x68, 0xaa, 0x54, + 0xc1, 0x3b, 0x4e, 0x46, 0x7a, 0x9d, 0x78, 0x1c, 0xe6, 0x68, 0x16, 0xad, 0xd5, 0xee, 0x74, 0x97, + 0x6c, 0x87, 0xfd, 0x4f, 0xbc, 0xcb, 0xfe, 0x47, 0x5c, 0xc5, 0xf2, 0x55, 0x9a, 0x7e, 0x42, 0x0e, + 0x23, 0x96, 0xc1, 0x05, 0x59, 0xab, 0xda, 0x5a, 0x74, 0x25, 0xeb, 0x16, 0xbc, 0x0b, 0xae, 0xc2, + 0xd0, 0x3b, 0x91, 0x65, 0x82, 0x4d, 0xcb, 0x8c, 0x78, 0x5a, 0xfc, 0x6c, 0x25, 0xf5, 0x7c, 0x82, + 0xaf, 0x94, 0x95, 0x0a, 0x56, 0x23, 0xe9, 0x34, 0x9b, 0x84, 0xe5, 0x92, 0xa1, 0x84, 0x50, 0x6b, + 0x9b, 0x38, 0xa8, 0xda, 0x2d, 0x9a, 0x81, 0xce, 0x39, 0x36, 0x53, 0x6a, 0xec, 0x9e, 0x6d, 0x94, + 0xc4, 0x93, 0x08, 0x68, 0x24, 0xc7, 0x9f, 0x15, 0xfe, 0x44, 0x86, 0x69, 0x0b, 0x13, 0xa3, 0x52, + 0xdd, 0xcb, 0x6b, 0x80, 0x3a, 0x41, 0xcb, 0x84, 0xfd, 0x69, 0x90, 0x8a, 0xcb, 0x34, 0x2d, 0xdb, + 0x56, 0xa5, 0xc1, 0xe2, 0xa5, 0xd6, 0xcb, 0x5a, 0x37, 0xcd, 0x80, 0xa3, 0x0a, 0x10, 0x6e, 0x3e, + 0xd0, 0x8a, 0x74, 0x29, 0x47, 0x94, 0x89, 0xbf, 0x43, 0x1d, 0x19, 0x98, 0x91, 0x67, 0xeb, 0xc2, + 0x38, 0x29, 0xf8, 0xb7, 0xc7, 0x1e, 0xe4, 0xf3, 0x60, 0x0d, 0xf4, 0xc5, 0x48, 0xb8, 0x96, 0x66, + 0xca, 0xb8, 0xb1, 0x69, 0x7a, 0x68, 0xcf, 0xae, 0x98, 0x66, 0xc5, 0x75, 0xd3, 0xac, 0xf8, 0xbf, + 0x33, 0xcd, 0x8a, 0x4d, 0x86, 0x2c, 0x4d, 0x76, 0x9e, 0xc1, 0xe3, 0x56, 0x63, 0x20, 0xcc, 0xd0, + 0x61, 0x5b, 0x84, 0x38, 0xa7, 0xbf, 0x80, 0x7b, 0x23, 0x19, 0x9c, 0xc9, 0xb1, 0xeb, 0x03, 0x76, + 0xfd, 0x14, 0xc1, 0x1a, 0x32, 0x77, 0xb1, 0xd4, 0x18, 0x10, 0x95, 0x0f, 0xf0, 0x50, 0x13, 0x5b, + 0xf0, 0x9c, 0x04, 0x4a, 0xdd, 0xdf, 0xd3, 0x1f, 0xe0, 0xf0, 0xa0, 0x77, 0xda, 0x40, 0x2f, 0xad, + 0x23, 0x23, 0xe4, 0x40, 0x8e, 0xbb, 0x21, 0xba, 0xb1, 0x51, 0x61, 0x1a, 0x4a, 0x48, 0xd8, 0x6d, + 0x1b, 0x6b, 0xc4, 0x36, 0x51, 0x1e, 0x8f, 0x4d, 0x30, 0x5c, 0x5e, 0x9a, 0x70, 0x28, 0xc8, 0x1b, + 0x02, 0xe0, 0xeb, 0x06, 0xce, 0xdb, 0x77, 0xa2, 0xa1, 0x06, 0xf9, 0x86, 0xc9, 0x36, 0x2c, 0xf0, + 0x54, 0x1b, 0x9b, 0xf1, 0x68, 0xa6, 0xd4, 0xf5, 0x18, 0x51, 0x9c, 0xa4, 0x41, 0x42, 0x7f, 0xab, + 0x8f, 0x58, 0x49, 0x95, 0xa3, 0x57, 0x0a, 0x27, 0x41, 0x9c, 0x32, 0x4c, 0x57, 0xdd, 0xa3, 0x51, + 0xa7, 0x3f, 0xec, 0x1d, 0x27, 0x78, 0x75, 0x87, 0x94, 0x51, 0x45, 0xf2, 0x59, 0xd2, 0xee, 0x8f, + 0x87, 0x0e, 0x2f, 0x21, 0xb7, 0xe8, 0x9d, 0x82, 0x9e, 0xf0, 0x10, 0xbe, 0x80, 0x31, 0x93, 0x48, + 0x42, 0x4f, 0x4c, 0xa3, 0x51, 0x13, 0x1f, 0x68, 0x12, 0xa1, 0xd9, 0x38, 0xec, 0x0d, 0xe3, 0xe3, + 0xac, 0x70, 0x57, 0xd4, 0x6e, 0xbb, 0x19, 0x90, 0x31, 0x73, 0x2a, 0xd2, 0xda, 0x48, 0x4c, 0x52, + 0xf0, 0xbf, 0x1c, 0x91, 0xd9, 0xc9, 0xea, 0xb4, 0x57, 0x07, 0xbb, 0x63, 0xa0, 0x9e, 0x93, 0x31, + 0x66, 0x66, 0x55, 0xcc, 0xac, 0x77, 0x3f, 0x13, 0xf8, 0xc4, 0xe2, 0xb6, 0x76, 0x48, 0x9b, 0xc4, + 0x3a, 0x6b, 0xde, 0xeb, 0x65, 0x7d, 0x06, 0xc9, 0xb1, 0x9d, 0x29, 0x00, 0x1b, 0x74, 0x8d, 0xce, + 0xa4, 0xca, 0x9d, 0x81, 0x29, 0x27, 0x16, 0x07, 0x2e, 0x0e, 0x27, 0xa7, 0x71, 0x99, 0x42, 0xe5, + 0x8b, 0x25, 0x6c, 0xe8, 0x98, 0x01, 0xc6, 0x98, 0x72, 0xf7, 0xd3, 0xfa, 0xc2, 0xda, 0xc6, 0xa3, + 0x5a, 0x8d, 0x06, 0xe4, 0x11, 0xee, 0x69, 0x33, 0xdc, 0x53, 0x84, 0x3b, 0xfa, 0x4e, 0x32, 0xe0, + 0x9e, 0x22, 0xdc, 0x0b, 0xcd, 0x67, 0xb5, 0x43, 0x1a, 0x43, 0xd8, 0xd8, 0x38, 0x31, 0x8d, 0x8d, + 0x13, 0xbc, 0x20, 0x66, 0x88, 0xa0, 0xf5, 0x3e, 0xa6, 0x49, 0xcd, 0x4e, 0x54, 0xc3, 0x58, 0x2c, + 0xb4, 0xf9, 0x75, 0x75, 0x3f, 0x21, 0x23, 0x50, 0x5b, 0x1b, 0x7a, 0x9a, 0x55, 0x19, 0x3b, 0x44, + 0x0d, 0x86, 0x35, 0xba, 0xcb, 0x9b, 0xc2, 0x85, 0x71, 0xb5, 0x43, 0x11, 0xac, 0xda, 0xe4, 0xaa, + 0xcd, 0x63, 0x7b, 0xcf, 0xe0, 0x04, 0xa2, 0xdc, 0xdb, 0xe5, 0xb7, 0xb7, 0x53, 0x6d, 0x1c, 0xdd, + 0xb4, 0xd1, 0xf6, 0x3c, 0x9b, 0x5c, 0x24, 0xdb, 0xca, 0xc0, 0xa9, 0xb6, 0xe3, 0x2a, 0x4d, 0xb1, + 0xa0, 0xa1, 0xeb, 0xf7, 0x5d, 0xe9, 0x4d, 0x08, 0xa3, 0x45, 0x61, 0x6c, 0xb4, 0xdb, 0xa9, 0x8d, + 0xdb, 0x7b, 0x0d, 0x74, 0xbb, 0x38, 0x2c, 0x77, 0xad, 0x8c, 0x4a, 0x43, 0xba, 0x48, 0xbb, 0xd5, + 0x17, 0x65, 0xd1, 0x5c, 0x62, 0xb7, 0xab, 0x2c, 0x4a, 0x77, 0xe4, 0x67, 0x93, 0x67, 0x33, 0x7b, + 0x23, 0x9b, 0xa1, 0x40, 0x62, 0x72, 0x03, 0xa8, 0x90, 0x15, 0x6c, 0x7b, 0xba, 0xa3, 0x6e, 0x36, + 0xa0, 0xfe, 0x5c, 0xd5, 0x48, 0xa6, 0xea, 0x6b, 0xb5, 0x26, 0x99, 0x19, 0x8e, 0x2b, 0x70, 0x53, + 0x28, 0x25, 0x95, 0x69, 0xbc, 0xaa, 0xc9, 0x03, 0x54, 0xf9, 0x3b, 0x7e, 0x02, 0x4d, 0x4b, 0x27, + 0x5a, 0xe2, 0x48, 0x7c, 0xf5, 0xa5, 0x04, 0x82, 0x84, 0x99, 0xe6, 0x8d, 0xe2, 0xba, 0x98, 0x8f, + 0xd8, 0x92, 0x39, 0x4b, 0xe5, 0x88, 0xbe, 0x79, 0x86, 0x82, 0xa1, 0xe2, 0x22, 0xca, 0xbe, 0x88, + 0x6d, 0xa3, 0x4a, 0x10, 0x7f, 0x40, 0x42, 0x65, 0x3e, 0xb3, 0x66, 0xab, 0xaf, 0xdd, 0xa9, 0x54, + 0xac, 0x79, 0x25, 0xad, 0x45, 0xbe, 0xe6, 0x12, 0x64, 0x28, 0x17, 0x20, 0x33, 0x1a, 0xb3, 0xb1, + 0xae, 0x34, 0x97, 0x37, 0xdd, 0xe8, 0x97, 0x35, 0xe3, 0x46, 0x1e, 0xd4, 0x41, 0xaf, 0xa7, 0xa5, + 0x1c, 0xfa, 0x34, 0xe4, 0xd3, 0xe0, 0x7b, 0xaf, 0x90, 0x4e, 0xd8, 0xf4, 0xd1, 0x94, 0x4c, 0x4a, + 0x03, 0x48, 0x43, 0x57, 0x03, 0x7b, 0xa5, 0x21, 0x0d, 0x55, 0xa3, 0x48, 0x08, 0x86, 0x22, 0x35, + 0x81, 0xce, 0xab, 0x1a, 0x43, 0x05, 0xb0, 0xa0, 0x4a, 0x5b, 0xc2, 0x40, 0x05, 0x0a, 0x53, 0xc1, + 0xc0, 0x8e, 0x12, 0x19, 0x97, 0x66, 0x85, 0x9e, 0x29, 0x71, 0x73, 0x27, 0x4d, 0x81, 0x32, 0xe8, + 0x0f, 0x3c, 0xfd, 0x0a, 0xd4, 0x91, 0xa7, 0xb8, 0x40, 0xc2, 0x20, 0xda, 0x81, 0xa6, 0xd2, 0x5b, + 0x49, 0x6f, 0x26, 0xbd, 0x8f, 0xd2, 0xbb, 0x92, 0xa1, 0xe3, 0xac, 0x4c, 0xfe, 0xdd, 0x93, 0x15, + 0xdf, 0x84, 0xcc, 0x3b, 0xe7, 0x75, 0x1f, 0x2e, 0xda, 0x4d, 0x06, 0x21, 0x57, 0x69, 0x44, 0x13, + 0x5e, 0x3b, 0x50, 0xfb, 0xb6, 0xe1, 0x2c, 0x9a, 0xcc, 0x36, 0xa8, 0x28, 0x62, 0x3a, 0x81, 0x46, + 0xb9, 0xf5, 0xb9, 0x43, 0x78, 0xb0, 0xf1, 0x90, 0xbb, 0xa6, 0x3b, 0x5e, 0xd9, 0xb6, 0x22, 0x56, + 0x98, 0xa7, 0xf0, 0xaa, 0x07, 0x23, 0x51, 0x7a, 0xf0, 0xf8, 0x73, 0x29, 0xb2, 0xbb, 0x53, 0x7a, + 0x0a, 0x89, 0x8e, 0x7f, 0x87, 0xd5, 0x1b, 0xf3, 0x7c, 0x4d, 0x0c, 0x6f, 0x9e, 0x29, 0xea, 0x4d, + 0x36, 0x16, 0xf6, 0x82, 0x9d, 0xdb, 0xa2, 0xbb, 0x91, 0xa2, 0x26, 0x18, 0xe3, 0xf4, 0x8e, 0xc8, + 0xe9, 0x28, 0x73, 0xdc, 0x8a, 0x85, 0xbb, 0xfd, 0xe3, 0xdb, 0x37, 0x27, 0xfc, 0x6c, 0x0a, 0xba, + 0xc5, 0x15, 0x53, 0x7b, 0x8c, 0x72, 0x61, 0xbc, 0x31, 0xb8, 0xd6, 0x10, 0xa0, 0x10, 0x5e, 0x9a, + 0x57, 0x0c, 0x6a, 0x30, 0x01, 0xf8, 0x4f, 0x41, 0x18, 0x5a, 0xe1, 0x6d, 0x86, 0xf2, 0x42, 0x16, + 0x4d, 0x4c, 0x01, 0xcc, 0x8f, 0x12, 0xb7, 0x3a, 0x67, 0x26, 0xc3, 0x35, 0xe3, 0xd5, 0x5c, 0x7a, + 0x27, 0xe5, 0xc2, 0x0d, 0xae, 0xa4, 0xb7, 0x8c, 0x03, 0x10, 0x48, 0xae, 0xbd, 0xe2, 0xba, 0x57, + 0x20, 0xbd, 0x57, 0x84, 0xad, 0xc1, 0x63, 0xef, 0x94, 0x30, 0x02, 0x99, 0xf9, 0x7f, 0x20, 0x32, + 0x05, 0xff, 0x46, 0xb5, 0x74, 0xbc, 0x08, 0xd6, 0xca, 0x93, 0xdf, 0x07, 0x90, 0xc4, 0x7f, 0xf3, + 0x78, 0x3a, 0x9f, 0x67, 0x93, 0x77, 0x20, 0xce, 0x06, 0x2f, 0x3d, 0x32, 0x73, 0xfa, 0x80, 0x1c, + 0xfe, 0x9f, 0xfc, 0xfd, 0x4a, 0xdc, 0xbe, 0x86, 0x8a, 0x7f, 0xf7, 0x40, 0x26, 0x7d, 0x9f, 0x42, + 0x28, 0xf8, 0xe7, 0xc6, 0x43, 0x9f, 0xa2, 0x84, 0x97, 0xe4, 0x01, 0x14, 0x04, 0x7c, 0x34, 0x81, + 0xaf, 0x73, 0x00, 0x85, 0x6b, 0x3a, 0xf2, 0x11, 0x07, 0xc2, 0xa3, 0xd7, 0xe9, 0x1f, 0x7f, 0x2c, + 0xcd, 0xb1, 0xa4, 0x8b, 0x3b, 0x0c, 0x0c, 0x10, 0x69, 0x3e, 0xc4, 0xab, 0x4b, 0x2c, 0x30, 0x27, + 0x33, 0x72, 0x61, 0x20, 0x41, 0x6e, 0x14, 0xd3, 0x77, 0xb4, 0xa0, 0xf3, 0xf0, 0x23, 0xa2, 0xec, + 0x06, 0xdf, 0x69, 0x56, 0x4e, 0x48, 0x7f, 0xc5, 0x1d, 0x83, 0x6e, 0x38, 0x58, 0x2b, 0xe5, 0x52, + 0x14, 0x5d, 0xbd, 0xe4, 0x41, 0xb7, 0x6b, 0xb8, 0x16, 0xcd, 0x23, 0x00, 0x8d, 0x94, 0x79, 0x97, + 0x9e, 0x24, 0xa2, 0x1b, 0x12, 0x75, 0x07, 0xa3, 0x84, 0xf2, 0xff, 0x0b, 0x07, 0xa3, 0xf2, 0x6b, + 0x1d, 0x8c, 0xda, 0xe5, 0x18, 0x60, 0x0f, 0x70, 0x03, 0xe1, 0x97, 0x11, 0x58, 0xdb, 0x67, 0x9c, + 0x8e, 0x1a, 0x1a, 0x73, 0x1a, 0x43, 0xc9, 0xe6, 0xf4, 0x86, 0xc9, 0xb1, 0xd4, 0xfc, 0x4c, 0xa2, + 0xdd, 0x92, 0x64, 0x74, 0xdc, 0x3b, 0xcc, 0x7c, 0x91, 0x00, 0x32, 0x93, 0x31, 0x4f, 0x68, 0x06, + 0xd0, 0x75, 0x99, 0x47, 0x2e, 0x88, 0x0a, 0x63, 0x1f, 0xda, 0xe9, 0x59, 0x4b, 0x10, 0x93, 0x63, + 0x2b, 0x27, 0xf3, 0x6f, 0xb2, 0x58, 0xaa, 0x34, 0xb7, 0x51, 0xe3, 0x8f, 0x9c, 0x6b, 0x46, 0x57, + 0xd5, 0x81, 0x43, 0xdc, 0xf0, 0xda, 0x5d, 0x03, 0x3d, 0x3a, 0x39, 0x3d, 0x0d, 0xe8, 0xe2, 0xda, + 0xf2, 0xea, 0x82, 0xe9, 0x62, 0xff, 0xd0, 0xbb, 0x41, 0x37, 0x6d, 0x68, 0x53, 0x34, 0xe4, 0xae, + 0x9b, 0x9a, 0x04, 0x6d, 0x1c, 0xc2, 0x77, 0xed, 0x46, 0xc2, 0x14, 0x13, 0x99, 0xa0, 0x99, 0x64, + 0x82, 0x60, 0xa0, 0x1c, 0xd4, 0xec, 0xa1, 0x88, 0x29, 0xd9, 0x45, 0x5c, 0x41, 0x32, 0xc8, 0xa4, + 0x6a, 0x57, 0x03, 0x80, 0xa7, 0xe8, 0xb3, 0xb5, 0x29, 0x15, 0xbe, 0x01, 0x8d, 0x79, 0xa4, 0x1b, + 0xd8, 0xd8, 0x76, 0xe7, 0xe1, 0x13, 0x9f, 0x8d, 0x17, 0x35, 0xe5, 0xa9, 0x4a, 0x69, 0xb8, 0x8b, + 0x4d, 0x9a, 0xb2, 0xa1, 0xa7, 0x3c, 0xbc, 0x39, 0x8a, 0x57, 0xdc, 0x20, 0xcf, 0x22, 0x24, 0x87, + 0x9f, 0x6f, 0xb3, 0x0f, 0x1a, 0x0d, 0x83, 0xa5, 0xc7, 0xc8, 0x1a, 0xc4, 0x1e, 0xbb, 0x41, 0x09, + 0x76, 0xf7, 0xe8, 0x17, 0xca, 0xf0, 0xf4, 0xe9, 0x1e, 0x7f, 0x40, 0xf3, 0xbf, 0x44, 0xbf, 0x50, + 0xe3, 0x7c, 0xa0, 0x13, 0xa4, 0x9e, 0x72, 0x22, 0xf6, 0x40, 0x25, 0x2f, 0x38, 0xc7, 0xa6, 0xc0, + 0xc4, 0x07, 0xf2, 0xbe, 0x54, 0x29, 0x00, 0x04, 0x1c, 0x67, 0x10, 0x79, 0x89, 0x1a, 0x4c, 0x30, + 0xf1, 0x04, 0x13, 0xed, 0xa6, 0xe2, 0x38, 0x6c, 0x45, 0xd3, 0x51, 0xb9, 0xb4, 0x7a, 0x28, 0xdb, + 0x4a, 0x65, 0xba, 0xba, 0x96, 0x77, 0x4d, 0x99, 0x96, 0xf0, 0x8d, 0x72, 0x06, 0xfd, 0x89, 0xe8, + 0x77, 0x82, 0x57, 0x2c, 0x01, 0x0c, 0xa2, 0xf0, 0x18, 0x14, 0x3b, 0x78, 0x05, 0x78, 0x4f, 0x21, + 0x30, 0x60, 0x6b, 0x0e, 0x11, 0x2a, 0x75, 0xb3, 0x31, 0x3d, 0x93, 0x12, 0x62, 0xc5, 0x97, 0x4e, + 0xff, 0x99, 0xd4, 0x72, 0xb7, 0xd9, 0x28, 0x23, 0xb8, 0x6d, 0x6b, 0x49, 0x4d, 0xe0, 0xb5, 0x07, + 0xd4, 0xd9, 0x75, 0x9d, 0x51, 0x70, 0xee, 0x3b, 0xe7, 0xd3, 0x36, 0x9e, 0xe9, 0x8d, 0x82, 0x33, + 0xf1, 0xd3, 0xd8, 0x39, 0x6b, 0x77, 0xc6, 0x23, 0x8e, 0x7a, 0xdc, 0x2d, 0xdd, 0x62, 0x8d, 0x0a, + 0x7d, 0x63, 0xcf, 0x73, 0xe4, 0x59, 0x7f, 0x3c, 0xc2, 0x9f, 0xc2, 0xe9, 0x90, 0xdb, 0x81, 0xc8, + 0xc1, 0x78, 0xd4, 0xc6, 0xdf, 0x00, 0xcf, 0xfd, 0x7a, 0x1b, 0xc3, 0x7a, 0xd5, 0x30, 0x69, 0x45, + 0x97, 0x7e, 0x2f, 0xe3, 0x5b, 0x31, 0xa5, 0xab, 0x33, 0xdb, 0xba, 0x4a, 0xd1, 0x95, 0x6e, 0x4b, + 0xea, 0x04, 0x83, 0xb4, 0x18, 0xfe, 0x54, 0x05, 0x5e, 0x0f, 0x72, 0xaa, 0x0b, 0x8b, 0xcc, 0xcf, + 0x6a, 0xcb, 0xc9, 0x38, 0x31, 0x44, 0x75, 0xa4, 0x3a, 0x35, 0x3c, 0x89, 0x12, 0x74, 0x4c, 0x3d, + 0xa1, 0xb7, 0xdd, 0xd5, 0x6b, 0xbd, 0x11, 0xfc, 0x2b, 0x1a, 0xb3, 0x81, 0x67, 0x63, 0xca, 0x96, + 0xb8, 0xde, 0xc2, 0x57, 0x48, 0x01, 0x70, 0x1b, 0x29, 0x11, 0x8a, 0xc2, 0xa1, 0x08, 0x16, 0xbe, + 0xba, 0x03, 0x48, 0x97, 0xb5, 0x2b, 0x89, 0x3b, 0x37, 0x7d, 0xb3, 0x46, 0xb3, 0x04, 0xd4, 0x00, + 0x09, 0x88, 0x31, 0x95, 0x68, 0x3f, 0x2b, 0x28, 0x6e, 0xd1, 0x06, 0x13, 0xc0, 0x26, 0xc5, 0x9c, + 0x66, 0xcf, 0x51, 0x05, 0xe6, 0x94, 0xe0, 0xcd, 0x42, 0xb4, 0x51, 0x3a, 0x23, 0x83, 0x7c, 0x74, + 0xa5, 0x8d, 0xb7, 0x27, 0x89, 0x68, 0x06, 0x75, 0x3c, 0xc9, 0xc2, 0xfe, 0x71, 0x5d, 0x76, 0x35, + 0x1c, 0x29, 0x95, 0x72, 0x2b, 0x20, 0x80, 0x19, 0x08, 0xd6, 0x48, 0xba, 0xe8, 0x5e, 0x32, 0x4c, + 0x84, 0x1e, 0x08, 0x22, 0xb6, 0x01, 0xa3, 0xd1, 0x52, 0x5d, 0xc7, 0xc1, 0x77, 0xda, 0x9c, 0x66, + 0x08, 0x3d, 0x5f, 0x2c, 0x1c, 0xb3, 0x88, 0x08, 0xf6, 0x49, 0x0e, 0x39, 0x33, 0x1f, 0xee, 0x1b, + 0xef, 0x03, 0x82, 0x55, 0x26, 0x66, 0x19, 0x9e, 0x89, 0x71, 0xc0, 0x0e, 0x91, 0x71, 0x2d, 0x6f, + 0xb5, 0x26, 0xb0, 0x40, 0xa4, 0x28, 0x1b, 0xfa, 0x9a, 0x0a, 0x85, 0x7f, 0x19, 0x2f, 0x40, 0xd4, + 0x74, 0x8a, 0x8a, 0x78, 0x6e, 0xa8, 0xe7, 0x4b, 0xd7, 0x35, 0x68, 0xaf, 0x52, 0xb9, 0x37, 0x02, + 0x7c, 0x58, 0x41, 0x82, 0xd8, 0xa7, 0xfd, 0xe2, 0xe9, 0x53, 0xc4, 0xb9, 0x37, 0x4b, 0x49, 0x8a, + 0xed, 0xb7, 0x17, 0xb9, 0xc8, 0x80, 0x25, 0xa9, 0x48, 0x24, 0x46, 0xdf, 0x64, 0xb3, 0x26, 0xcc, + 0xcc, 0x81, 0x5a, 0x0c, 0x76, 0xf3, 0x96, 0x37, 0x67, 0x36, 0x90, 0xca, 0xf4, 0x31, 0x66, 0xec, + 0x39, 0xe6, 0x5a, 0xaa, 0x50, 0xfc, 0xcf, 0xcc, 0x06, 0x80, 0x05, 0xf0, 0x69, 0xb2, 0x58, 0x42, + 0xdb, 0xca, 0x00, 0x92, 0x55, 0xe6, 0x58, 0x37, 0x79, 0xcb, 0x73, 0x79, 0xb8, 0xc8, 0x57, 0xc5, + 0xa8, 0x75, 0x83, 0xff, 0xfc, 0x94, 0xc7, 0x5c, 0xd6, 0x7b, 0x91, 0x4e, 0xef, 0x40, 0xca, 0x43, + 0x4e, 0x97, 0x88, 0x2d, 0x6c, 0xb4, 0xf9, 0xf2, 0x42, 0x66, 0x82, 0x0c, 0x76, 0x0b, 0x4a, 0xb1, + 0xac, 0x8a, 0x6e, 0xa2, 0x62, 0x81, 0xc9, 0x2b, 0x9f, 0x6e, 0x3f, 0x32, 0x2e, 0x8b, 0x04, 0x37, + 0x7a, 0x10, 0x50, 0x81, 0x75, 0x0a, 0xb6, 0xc6, 0x67, 0x03, 0x1b, 0x5c, 0x5e, 0x10, 0x06, 0xfe, + 0xa0, 0xe8, 0x8c, 0xfe, 0x50, 0x04, 0x1d, 0x95, 0xc8, 0x80, 0x11, 0x6a, 0x81, 0xb0, 0x52, 0xbd, + 0xb6, 0x3e, 0xdc, 0x75, 0xe2, 0xab, 0xd6, 0xaa, 0xcb, 0xd0, 0x67, 0xc6, 0xa1, 0xb6, 0xfe, 0x95, + 0x8f, 0x5f, 0xbc, 0x78, 0xc9, 0xb0, 0x0c, 0xd5, 0xdd, 0x8d, 0x86, 0x4c, 0x37, 0xe2, 0xe2, 0xe7, + 0x58, 0x7e, 0xf8, 0x92, 0xac, 0x34, 0x9c, 0xe7, 0xd4, 0xa3, 0xd0, 0xbe, 0x8a, 0x92, 0xf8, 0x7a, + 0xb9, 0xe0, 0xb3, 0x13, 0xb5, 0xf0, 0x0b, 0xb7, 0xa6, 0x0e, 0x79, 0x44, 0x6a, 0x26, 0x24, 0xac, + 0xc9, 0x2b, 0x80, 0x08, 0xf3, 0x2a, 0xb3, 0xf4, 0xee, 0x4b, 0x86, 0x6c, 0x54, 0xdf, 0xdf, 0x5d, + 0x3d, 0xbb, 0x07, 0xd0, 0xd5, 0x17, 0x65, 0x76, 0xd1, 0x1c, 0xa9, 0xb5, 0xe5, 0x62, 0x64, 0xd7, + 0x6f, 0xe8, 0xdb, 0x81, 0xdd, 0x70, 0xab, 0xde, 0x1e, 0x9e, 0x55, 0xae, 0x7e, 0x9b, 0x17, 0xbf, + 0xcb, 0x6b, 0xdf, 0x0d, 0x3a, 0x6e, 0x54, 0x5a, 0xe9, 0x1e, 0x03, 0xab, 0x09, 0xe8, 0xd4, 0x80, + 0x69, 0xe4, 0x61, 0x96, 0x58, 0x90, 0xbd, 0xbe, 0x89, 0x6c, 0x80, 0x63, 0x4d, 0x43, 0xc0, 0x8d, + 0xa7, 0x00, 0x14, 0xb0, 0xa8, 0xb0, 0x12, 0x57, 0x4c, 0x95, 0xb6, 0x48, 0x08, 0x9e, 0xf3, 0xc1, + 0x24, 0x02, 0xe1, 0x14, 0x20, 0x1c, 0x91, 0x5f, 0xc4, 0xda, 0x3d, 0x68, 0x20, 0xd3, 0xc6, 0x5e, + 0x49, 0x0e, 0x6d, 0x4a, 0x5f, 0xb7, 0xf6, 0x55, 0x0c, 0x13, 0x0d, 0x34, 0x15, 0x4d, 0x52, 0x1f, + 0xca, 0x16, 0xdd, 0x52, 0x36, 0xb4, 0x5b, 0x88, 0x1e, 0xca, 0x88, 0x6f, 0x80, 0x71, 0x4e, 0xb4, + 0x2e, 0xde, 0x75, 0xbb, 0xda, 0xbb, 0x44, 0x1b, 0xd4, 0xee, 0x84, 0x15, 0x2d, 0xad, 0x0a, 0xf2, + 0x97, 0xbc, 0x72, 0x77, 0x40, 0xd6, 0xa9, 0x7a, 0x1d, 0xf7, 0x9e, 0x39, 0xb2, 0x5a, 0x6c, 0xa9, + 0x6f, 0x77, 0x77, 0x26, 0x74, 0xe6, 0x09, 0x0c, 0x86, 0x0c, 0x7b, 0x68, 0xa3, 0x70, 0x4c, 0x9e, + 0x97, 0x42, 0xb2, 0xf9, 0x39, 0xec, 0x3d, 0x93, 0x23, 0xd9, 0x09, 0xf1, 0xcc, 0xb2, 0x33, 0x68, + 0x01, 0x2f, 0x70, 0x19, 0x1c, 0xaa, 0x1c, 0xed, 0x70, 0x00, 0xad, 0x77, 0x0e, 0x7b, 0x10, 0x09, + 0x12, 0x6d, 0x1b, 0xc8, 0x11, 0xdf, 0xf1, 0x4b, 0x3b, 0xb1, 0xeb, 0x45, 0xe5, 0x4c, 0xe5, 0xcd, + 0x33, 0x65, 0xa0, 0x73, 0x39, 0x49, 0xc4, 0x73, 0xf1, 0x94, 0xf8, 0xca, 0x35, 0xc7, 0x94, 0xac, + 0x77, 0xea, 0xd7, 0xd8, 0xbd, 0x22, 0x9b, 0xb2, 0x21, 0x55, 0xc7, 0xa2, 0x78, 0xf0, 0xb2, 0xc5, + 0x8a, 0x20, 0x77, 0xaf, 0x79, 0x31, 0x32, 0x58, 0x5a, 0x31, 0x69, 0x1e, 0x0a, 0x52, 0x5f, 0xe1, + 0x1e, 0xc1, 0x51, 0x68, 0x32, 0xe9, 0x14, 0x38, 0x51, 0x22, 0x2f, 0xfb, 0x70, 0x87, 0x3d, 0x6f, + 0x64, 0x2b, 0xdd, 0x63, 0xa0, 0xd4, 0x77, 0xb0, 0xad, 0x6f, 0xc6, 0xe4, 0x64, 0x3e, 0x33, 0x8d, + 0x96, 0x00, 0x20, 0x14, 0x07, 0x24, 0xd8, 0x63, 0x97, 0xed, 0x99, 0xb7, 0x44, 0xbd, 0x93, 0xcb, + 0x42, 0x69, 0xf7, 0x3a, 0x9a, 0x09, 0x0b, 0x9f, 0xaf, 0xa0, 0x97, 0x04, 0xd2, 0x89, 0x15, 0x5a, + 0x97, 0xd1, 0x22, 0x17, 0x1e, 0x06, 0xe2, 0xeb, 0x21, 0x27, 0x5c, 0xe7, 0x65, 0x7c, 0x92, 0xfe, + 0x22, 0x6e, 0x4e, 0xc5, 0xac, 0x88, 0x52, 0x79, 0xe2, 0xfc, 0x6d, 0x62, 0xe4, 0x5a, 0x3c, 0x2f, + 0x03, 0x71, 0xfe, 0xb7, 0x95, 0x19, 0xc2, 0x07, 0x70, 0xca, 0x30, 0xba, 0xb5, 0x3a, 0x85, 0xd1, + 0x55, 0x63, 0xde, 0xcf, 0xd0, 0x39, 0x17, 0x16, 0x03, 0xd1, 0x89, 0x4a, 0xfd, 0x3a, 0xbb, 0xb8, + 0xa9, 0xb5, 0x79, 0x33, 0xc7, 0xd7, 0xc9, 0x20, 0xf2, 0xac, 0xe7, 0xc1, 0x7f, 0x63, 0x15, 0x0d, + 0xa2, 0x6d, 0x44, 0x0f, 0x92, 0x40, 0x02, 0x65, 0xd7, 0x09, 0xd7, 0xe8, 0x35, 0x9a, 0xe3, 0xb1, + 0x56, 0x1d, 0x9d, 0x2c, 0x7e, 0x5c, 0x66, 0x10, 0x79, 0xd4, 0x53, 0x11, 0xfc, 0x32, 0xb5, 0x98, + 0xbe, 0xbc, 0x85, 0x58, 0x1d, 0x39, 0x81, 0x58, 0x23, 0x88, 0x8f, 0x2c, 0x4e, 0xf9, 0xa9, 0xc4, + 0xdc, 0xcc, 0xc5, 0x2f, 0x18, 0xa8, 0x37, 0x14, 0x43, 0xab, 0xd3, 0x57, 0x09, 0xe8, 0xb6, 0x8e, + 0x55, 0xa3, 0x66, 0x25, 0x62, 0x76, 0x82, 0x4a, 0x1d, 0x8c, 0x02, 0x90, 0x8b, 0xa9, 0x19, 0x82, + 0xce, 0x42, 0x91, 0x04, 0x9d, 0x5e, 0x70, 0x0c, 0x2c, 0x61, 0x00, 0xbc, 0x4a, 0x55, 0x5f, 0x7a, + 0x64, 0x93, 0x37, 0xf8, 0xee, 0x4c, 0x01, 0x42, 0x0e, 0x1b, 0x73, 0x80, 0xcd, 0xdf, 0x18, 0x05, + 0xb0, 0x4a, 0xbd, 0xe1, 0x41, 0x14, 0xc9, 0xa8, 0x16, 0x91, 0x6b, 0x1c, 0x4d, 0x29, 0xd1, 0xfb, + 0xc4, 0x19, 0x3a, 0x8d, 0xfc, 0x96, 0x67, 0xad, 0x09, 0x8d, 0xf4, 0xf0, 0x62, 0x9e, 0xd7, 0xf5, + 0x66, 0x88, 0xaf, 0xf8, 0x10, 0x34, 0xae, 0xe3, 0xc9, 0x27, 0x88, 0x42, 0x6c, 0xc7, 0x87, 0x52, + 0x0c, 0x55, 0x90, 0x63, 0x7f, 0x7b, 0xad, 0x94, 0xb9, 0xd6, 0xfa, 0xd1, 0x37, 0xac, 0xe2, 0xb4, + 0x06, 0x47, 0x3d, 0x0f, 0x02, 0x55, 0x3d, 0x23, 0x8f, 0xe1, 0xd1, 0x37, 0xd4, 0xd8, 0xa3, 0x6f, + 0x0a, 0x9e, 0x9f, 0x75, 0x9c, 0xbf, 0xa1, 0xf9, 0x49, 0xbc, 0x88, 0xe5, 0x9d, 0x32, 0xf0, 0x76, + 0xb1, 0xbe, 0xf8, 0xd2, 0x72, 0xf6, 0x8a, 0xad, 0x7d, 0x1e, 0x03, 0xa7, 0x94, 0x58, 0x4f, 0x9f, + 0x52, 0x4f, 0x7e, 0xc4, 0x49, 0x80, 0x6c, 0x1d, 0x73, 0x52, 0x9e, 0x59, 0x07, 0x3d, 0xa0, 0x35, + 0x58, 0x76, 0xeb, 0xf9, 0x27, 0x68, 0x76, 0x43, 0xff, 0x8c, 0xc6, 0xd3, 0x04, 0x35, 0x69, 0xdc, + 0x18, 0x9e, 0x5c, 0x39, 0x98, 0x0b, 0x5b, 0xad, 0xb9, 0x40, 0x28, 0x9c, 0x1e, 0x58, 0x61, 0x68, + 0xd9, 0xc0, 0x5d, 0x8a, 0xc0, 0xa6, 0x42, 0xbc, 0xda, 0x10, 0x0f, 0x87, 0x14, 0x88, 0xaf, 0x21, + 0x88, 0xa5, 0x16, 0xa7, 0xc0, 0x64, 0xc1, 0xba, 0x44, 0x3a, 0xf2, 0x5a, 0x8a, 0x2b, 0x67, 0x1f, + 0x62, 0x5f, 0x5f, 0xef, 0xeb, 0x06, 0xf6, 0x28, 0xb3, 0xfb, 0xe8, 0x9b, 0x75, 0x59, 0x0e, 0x1a, + 0x01, 0x16, 0xd5, 0xb1, 0x5f, 0x42, 0xfd, 0x16, 0x4e, 0xbd, 0x6f, 0xbd, 0x03, 0xe9, 0x37, 0x17, + 0x16, 0x0c, 0x5f, 0x64, 0xfc, 0xe6, 0xd2, 0xeb, 0x77, 0x7b, 0xb6, 0xcb, 0x8d, 0x95, 0x8d, 0xe4, + 0xd5, 0x46, 0xd4, 0xc2, 0x37, 0x87, 0x4c, 0x13, 0x49, 0xf8, 0x82, 0x3d, 0x52, 0xdc, 0xd1, 0x8b, + 0xbb, 0xd7, 0x53, 0x67, 0x7f, 0x92, 0x2f, 0xf6, 0xdd, 0xd2, 0x91, 0x2f, 0x80, 0x27, 0xcd, 0x2c, + 0x27, 0x26, 0x3c, 0xb3, 0x62, 0xeb, 0x18, 0xca, 0x69, 0x85, 0x8e, 0x85, 0x67, 0x98, 0x38, 0xee, + 0xc9, 0x14, 0x0f, 0x32, 0x99, 0x75, 0x41, 0x47, 0x30, 0x33, 0x12, 0xf1, 0xf8, 0x51, 0x7b, 0x80, + 0x10, 0x9a, 0x67, 0x03, 0x7e, 0xe3, 0x3f, 0xd7, 0xe6, 0x5e, 0xf0, 0x72, 0xc4, 0x17, 0x4e, 0xf1, + 0x95, 0xeb, 0x47, 0xdf, 0xa8, 0x37, 0xbd, 0xd5, 0x73, 0x87, 0x1c, 0x47, 0xeb, 0xed, 0x83, 0x8c, + 0x17, 0x34, 0x0f, 0x84, 0x77, 0x3e, 0x4c, 0x9f, 0x79, 0x5e, 0x61, 0xf0, 0xba, 0x34, 0x69, 0x42, + 0x52, 0xa3, 0x0e, 0x4e, 0x01, 0x8d, 0x17, 0x7f, 0xca, 0x67, 0x42, 0x9c, 0x0a, 0xeb, 0x58, 0xc5, + 0x08, 0x8f, 0x51, 0x12, 0xb8, 0x01, 0x6b, 0x70, 0x88, 0xc5, 0xa6, 0xdb, 0x6e, 0x84, 0xd8, 0x2e, + 0x8a, 0x10, 0x53, 0x1f, 0x14, 0xed, 0xc0, 0x58, 0x5d, 0x1b, 0x61, 0xf7, 0x16, 0x90, 0xed, 0xc9, + 0xca, 0x76, 0x15, 0xbc, 0xd4, 0xcd, 0xe1, 0xb0, 0xa7, 0x50, 0xa1, 0x19, 0x5d, 0xae, 0x27, 0x57, + 0xfb, 0x2e, 0xa1, 0x1b, 0x0e, 0x0d, 0xb0, 0x4d, 0xbd, 0x36, 0x4b, 0x34, 0xa1, 0x1c, 0x6e, 0x05, + 0x9d, 0x6b, 0x30, 0x95, 0xd1, 0xc5, 0x6b, 0xc6, 0x30, 0xfd, 0xaa, 0x64, 0x6d, 0xfe, 0xf3, 0x17, + 0x77, 0x27, 0xda, 0xb1, 0xbe, 0x53, 0x3e, 0x3d, 0xe9, 0x36, 0xe0, 0x80, 0x4e, 0xdc, 0xc2, 0x04, + 0x9d, 0x80, 0xf8, 0x50, 0x78, 0xe9, 0xc7, 0x35, 0xd1, 0x14, 0x5f, 0x3c, 0x61, 0x60, 0x5b, 0x11, + 0x9d, 0xac, 0xa1, 0x15, 0xa2, 0xad, 0x06, 0x82, 0xb0, 0x60, 0x92, 0xe7, 0xaa, 0x37, 0xb9, 0x86, + 0x46, 0xf5, 0x38, 0x18, 0xb3, 0x85, 0x36, 0x40, 0x46, 0x57, 0xb2, 0x05, 0x08, 0xfd, 0x64, 0x26, + 0x16, 0x82, 0x89, 0x41, 0xa7, 0x46, 0x9a, 0x8a, 0x16, 0x84, 0x45, 0x51, 0x5b, 0x20, 0x27, 0x7b, + 0x94, 0xc1, 0x68, 0x94, 0x4d, 0x00, 0xad, 0xf2, 0x99, 0x72, 0xaf, 0x18, 0x0e, 0xce, 0x19, 0xe9, + 0xb7, 0x79, 0x88, 0xaf, 0x21, 0xfc, 0xf1, 0x84, 0xbb, 0x85, 0x48, 0xe3, 0xf3, 0x2c, 0x39, 0xfb, + 0xf9, 0x55, 0x9a, 0xca, 0xf9, 0xbe, 0x81, 0x15, 0x90, 0x8d, 0xe7, 0x9f, 0xde, 0x2b, 0x56, 0xea, + 0xca, 0xfd, 0x4e, 0x27, 0x86, 0x4c, 0x5c, 0x65, 0xc3, 0xb2, 0xa0, 0x29, 0x1c, 0x1a, 0x6b, 0x58, + 0x32, 0x5e, 0x0f, 0x8d, 0xc1, 0xe6, 0xf3, 0xf4, 0xe6, 0x3d, 0x3e, 0xdd, 0xe9, 0x90, 0x67, 0x47, + 0x4b, 0xa0, 0x32, 0xa4, 0x32, 0x5c, 0xf2, 0xbd, 0xd4, 0xb4, 0xf6, 0xd5, 0x93, 0x9f, 0xd8, 0xc2, + 0x6d, 0xf9, 0xae, 0x07, 0x0e, 0x0d, 0x6a, 0xa2, 0x48, 0x73, 0x4a, 0xb9, 0xe2, 0x91, 0x65, 0xd3, + 0x07, 0xb0, 0x2d, 0xd8, 0x32, 0x02, 0x7f, 0x02, 0x54, 0x2a, 0xd3, 0x2b, 0x4e, 0xf5, 0x90, 0xeb, + 0xe4, 0x11, 0x83, 0x38, 0x73, 0x45, 0x74, 0x14, 0x2a, 0xd9, 0x47, 0x11, 0x68, 0x9f, 0x12, 0xd9, + 0x28, 0x94, 0xcf, 0x92, 0x76, 0xe4, 0x26, 0x06, 0xdb, 0x02, 0x34, 0xe0, 0x4a, 0x21, 0xa6, 0x79, + 0x6d, 0x5b, 0xd5, 0x9e, 0xde, 0x36, 0xa1, 0x1c, 0xf5, 0x96, 0xf1, 0xcd, 0xc2, 0x35, 0xff, 0x43, + 0xaf, 0xb7, 0xbd, 0x84, 0x30, 0x13, 0x69, 0x93, 0x18, 0xa2, 0x4c, 0x64, 0x0a, 0x00, 0xef, 0x9f, + 0xa4, 0x00, 0x24, 0xe5, 0x63, 0x2a, 0xb5, 0xc8, 0x51, 0x00, 0xc0, 0x19, 0xe8, 0xf5, 0xb4, 0xa0, + 0xd5, 0x19, 0x3f, 0x32, 0x48, 0x8f, 0xa7, 0x21, 0x67, 0xe6, 0x5b, 0xaf, 0xf9, 0x25, 0xb5, 0x38, + 0xcf, 0x97, 0xf4, 0xb4, 0x70, 0x0e, 0x88, 0x92, 0x7b, 0xea, 0xd9, 0x36, 0xeb, 0x2e, 0x05, 0xbe, + 0xe5, 0xa7, 0xd3, 0x77, 0x3e, 0xe0, 0x81, 0xb1, 0xac, 0x8b, 0x1e, 0x11, 0x70, 0xeb, 0x5d, 0xda, + 0x39, 0x93, 0x15, 0x30, 0x7c, 0x41, 0xae, 0x12, 0x3c, 0x3c, 0xa9, 0xc6, 0x7a, 0x34, 0xfa, 0x00, + 0xd5, 0xfc, 0x8a, 0x6f, 0xcd, 0x5d, 0x89, 0x53, 0x99, 0x39, 0x99, 0x64, 0xaa, 0x42, 0xf8, 0x88, + 0xfb, 0x96, 0xbe, 0xa0, 0x9e, 0x49, 0xcd, 0x49, 0x4c, 0xa3, 0x3b, 0x24, 0x36, 0xc6, 0x9d, 0x48, + 0xd9, 0xfd, 0xfe, 0xe8, 0x3b, 0x86, 0x38, 0x39, 0x97, 0xcf, 0x6a, 0xe9, 0x8e, 0x84, 0xad, 0x1c, + 0x8b, 0xb5, 0x38, 0x5f, 0xf7, 0xe0, 0xa8, 0xcc, 0x0d, 0xe2, 0xd1, 0xc3, 0xd9, 0x21, 0x00, 0x35, + 0xb6, 0xa8, 0x4c, 0xf7, 0xa8, 0x28, 0x07, 0xe2, 0x2f, 0x82, 0x01, 0x3b, 0x33, 0xb2, 0x1c, 0xfa, + 0xdb, 0x06, 0xb2, 0x61, 0xc3, 0x2f, 0x87, 0x80, 0xbe, 0xf6, 0x11, 0xa3, 0x21, 0x60, 0x5b, 0x01, + 0xfd, 0x05, 0xfa, 0x87, 0x99, 0x00, 0x10, 0x2e, 0xc6, 0x20, 0x7e, 0x63, 0x35, 0x40, 0x6f, 0x1c, + 0xec, 0xf4, 0xfd, 0x3d, 0xd5, 0xe7, 0x62, 0x85, 0x18, 0x2e, 0xea, 0xa3, 0x11, 0xa9, 0xea, 0xe6, + 0x30, 0xa7, 0x54, 0x1f, 0x7e, 0x40, 0x85, 0x45, 0x4d, 0xcc, 0xd1, 0x60, 0xcb, 0x40, 0x77, 0xa0, + 0x84, 0x6b, 0xa9, 0xba, 0xb1, 0x3d, 0x95, 0x2e, 0x81, 0x8d, 0x39, 0xfc, 0x81, 0x08, 0x13, 0xb7, + 0xa4, 0xb2, 0x10, 0x10, 0xb0, 0x39, 0x14, 0x16, 0x8b, 0xbc, 0xc7, 0x16, 0x0e, 0x1a, 0x73, 0x73, + 0xb9, 0xe6, 0x1a, 0x39, 0x57, 0x91, 0x46, 0xd0, 0xc3, 0xfa, 0x5a, 0x00, 0x2b, 0xaa, 0x33, 0x17, + 0x13, 0x1b, 0x17, 0x9a, 0x12, 0xf2, 0x20, 0xdf, 0x16, 0x12, 0x20, 0x67, 0x98, 0xa5, 0x37, 0x0e, + 0x1e, 0xaf, 0xe0, 0x8d, 0x5e, 0xcf, 0xc2, 0xb7, 0x1f, 0x71, 0xbb, 0xb7, 0x19, 0x1f, 0x54, 0xd9, + 0x3f, 0x8e, 0x65, 0xf6, 0xec, 0x58, 0x4e, 0xf5, 0xb3, 0x7f, 0x90, 0x5f, 0x4e, 0xed, 0x67, 0x8f, + 0x51, 0x82, 0xdb, 0x1c, 0x77, 0xe5, 0xd4, 0x4c, 0x84, 0x7a, 0x38, 0x11, 0x3e, 0x36, 0x8f, 0xd7, + 0x58, 0xa3, 0xca, 0xd3, 0x85, 0x5a, 0xfe, 0xd8, 0xea, 0xc4, 0x75, 0x4a, 0x8a, 0x11, 0x7e, 0x8d, + 0x33, 0x2e, 0xf1, 0x70, 0x82, 0xaf, 0xb6, 0x69, 0xdc, 0x12, 0x11, 0xb2, 0x53, 0xb1, 0x0f, 0x0b, + 0x51, 0x60, 0x00, 0x65, 0x49, 0xdc, 0x6d, 0x55, 0x02, 0xfe, 0x29, 0x74, 0xd5, 0x7d, 0x8d, 0x2b, + 0xd7, 0x37, 0x19, 0x15, 0x82, 0xb5, 0x9c, 0xfb, 0x10, 0x28, 0xa3, 0x97, 0x38, 0xc6, 0x5f, 0x58, + 0xb1, 0x3c, 0xa1, 0xd6, 0xa7, 0x1a, 0xb2, 0x58, 0xe8, 0x19, 0x7a, 0x33, 0x41, 0xa6, 0x13, 0x03, + 0xdd, 0x90, 0x42, 0x43, 0x55, 0x1d, 0xfc, 0x16, 0x2d, 0x15, 0x99, 0x11, 0x77, 0x7a, 0x80, 0x11, + 0xd0, 0xb4, 0xae, 0x1e, 0x93, 0x70, 0x1a, 0x9e, 0xdb, 0x43, 0x18, 0xaf, 0xba, 0xa5, 0xad, 0xab, + 0xd7, 0x75, 0x87, 0xd6, 0x61, 0xcf, 0x6a, 0x99, 0x2a, 0x75, 0x88, 0xed, 0x82, 0xd0, 0xbc, 0x55, + 0xcd, 0x15, 0xd7, 0x83, 0xfd, 0x5f, 0xc2, 0x94, 0xe5, 0x0c, 0x1b, 0xda, 0xd3, 0xc9, 0x51, 0x28, + 0xde, 0xc3, 0x8c, 0xfd, 0x65, 0x09, 0x3e, 0x80, 0x3e, 0x0d, 0x7e, 0x79, 0xf6, 0x69, 0xac, 0x86, + 0x06, 0x51, 0x78, 0x1d, 0x0a, 0xa9, 0x0d, 0xd5, 0x81, 0x78, 0x53, 0xa0, 0x00, 0xca, 0xe0, 0xa8, + 0xd4, 0x50, 0x99, 0x70, 0x9a, 0x2c, 0xea, 0xf5, 0xce, 0xdc, 0x25, 0x33, 0x4a, 0xed, 0x4d, 0x90, + 0xba, 0xdb, 0x3f, 0x2f, 0x97, 0xf3, 0xe8, 0xd3, 0x52, 0x43, 0x33, 0xf6, 0x57, 0x22, 0xf3, 0x49, + 0xf5, 0x93, 0xff, 0x23, 0x96, 0x73, 0x07, 0x5f, 0x31, 0xef, 0xf9, 0xb8, 0x7e, 0x54, 0x01, 0x20, + 0x59, 0xf1, 0x2c, 0x8a, 0xcb, 0x02, 0x93, 0x44, 0xa7, 0xe1, 0x37, 0x31, 0x5f, 0x10, 0x82, 0xc6, + 0xff, 0x58, 0x3d, 0x5e, 0x53, 0x7d, 0x1b, 0xcb, 0x06, 0xec, 0x9a, 0x24, 0x1b, 0x5b, 0x3f, 0x1b, + 0x7a, 0x4c, 0x87, 0x88, 0xc5, 0xab, 0x94, 0xd0, 0x4b, 0x7a, 0xeb, 0x1c, 0xb0, 0x0f, 0x7b, 0xbe, + 0xc1, 0x2f, 0xdd, 0x75, 0xfb, 0xc5, 0x12, 0xd8, 0x62, 0xdb, 0x83, 0x9a, 0xe2, 0xa9, 0x5b, 0x4d, + 0x3a, 0x8d, 0x67, 0x49, 0x44, 0xd7, 0x93, 0x88, 0x25, 0xc2, 0x4c, 0x37, 0xf1, 0x65, 0xec, 0xe7, + 0x1c, 0xdf, 0xb6, 0x9f, 0x58, 0x8e, 0xdd, 0xb6, 0x54, 0x6c, 0x96, 0xe7, 0xc0, 0x52, 0xd8, 0xd6, + 0xf4, 0xc5, 0x95, 0x6b, 0xd7, 0x6a, 0xfa, 0x70, 0x8d, 0xa4, 0x95, 0x74, 0x9d, 0x06, 0x99, 0x85, + 0xd9, 0xa0, 0x78, 0xb7, 0x96, 0xfb, 0x25, 0x60, 0x35, 0xe1, 0xb0, 0xed, 0xe1, 0xaf, 0x67, 0x5b, + 0x9f, 0x5e, 0xd4, 0x6b, 0xfc, 0x09, 0x04, 0xb9, 0x2b, 0x44, 0x54, 0x2d, 0xcb, 0xda, 0x1e, 0xa2, + 0x48, 0x2d, 0xd7, 0x9b, 0xe7, 0x27, 0x16, 0xb0, 0xbc, 0x19, 0xb9, 0xba, 0x89, 0xfd, 0xab, 0x68, + 0x52, 0xaf, 0x26, 0x59, 0x81, 0xc4, 0x97, 0x5c, 0x51, 0x05, 0xb1, 0x8f, 0x6e, 0xdd, 0x0a, 0x82, + 0x87, 0x3e, 0x79, 0x33, 0x41, 0x41, 0x87, 0xc3, 0x8b, 0x1b, 0x10, 0x63, 0x20, 0xcc, 0xe3, 0x83, + 0x05, 0x8c, 0x60, 0xa6, 0x35, 0xbc, 0x2d, 0x74, 0x7c, 0x5a, 0xed, 0xbb, 0x15, 0x8e, 0x83, 0x26, + 0xaf, 0x79, 0xad, 0xeb, 0x97, 0xd3, 0x9d, 0xdc, 0x5c, 0xef, 0x44, 0x78, 0x88, 0xd9, 0x9f, 0x3d, + 0x20, 0x70, 0x0f, 0x4d, 0x21, 0x5b, 0x2d, 0x81, 0x3b, 0x44, 0x7f, 0xb4, 0x5b, 0x9b, 0x71, 0x7d, + 0xba, 0x86, 0x76, 0xbb, 0x90, 0x79, 0xf1, 0xb0, 0x29, 0xa4, 0x2c, 0x67, 0xff, 0xa9, 0xee, 0xda, + 0x9f, 0x1b, 0x37, 0x8e, 0xf4, 0xcf, 0x97, 0xaa, 0xfc, 0x0f, 0x20, 0x62, 0x1f, 0x08, 0x8b, 0x4f, + 0xad, 0x94, 0x5b, 0x93, 0xa2, 0x5c, 0x8e, 0xe3, 0xcb, 0x6d, 0x6a, 0xb3, 0x71, 0x79, 0xd7, 0x95, + 0xb8, 0xb6, 0xb6, 0x2c, 0x3e, 0x40, 0x11, 0x59, 0x88, 0x40, 0x11, 0xd4, 0x8a, 0x2a, 0x85, 0xff, + 0xfb, 0xf5, 0xd7, 0x3d, 0x03, 0xcc, 0x00, 0x03, 0x92, 0x72, 0xec, 0x5c, 0x5d, 0xd5, 0xd6, 0x8a, + 0x98, 0x67, 0x4f, 0xcf, 0xab, 0xa7, 0xfb, 0x9b, 0x9e, 0x47, 0xad, 0x61, 0x88, 0xcd, 0xad, 0x0e, + 0x09, 0x7a, 0x34, 0x24, 0x28, 0x4e, 0x29, 0x24, 0x48, 0xd0, 0xc5, 0x28, 0x44, 0x78, 0xba, 0xd6, + 0xe3, 0x13, 0x3b, 0x82, 0x49, 0x52, 0x58, 0x25, 0x30, 0x3e, 0x1b, 0x16, 0x69, 0xaf, 0x99, 0xd6, + 0x50, 0x53, 0x1c, 0x9b, 0xa3, 0x99, 0x9f, 0xc1, 0x55, 0x23, 0x96, 0xa8, 0xe2, 0x17, 0x74, 0xf9, + 0x4d, 0x76, 0x1d, 0xc8, 0x2f, 0x07, 0x78, 0xf9, 0x7c, 0xf5, 0x91, 0x9f, 0xd7, 0xfd, 0xcf, 0xf5, + 0x2c, 0x87, 0xe6, 0xe7, 0x8a, 0xcf, 0x4e, 0x9e, 0x9c, 0xf9, 0x39, 0xcd, 0x2c, 0xdd, 0xc9, 0x63, + 0xc2, 0x54, 0x0c, 0x75, 0xf5, 0x9e, 0x0e, 0x66, 0xfc, 0x1c, 0xab, 0x40, 0xc7, 0x29, 0x14, 0xd5, + 0xb7, 0x11, 0x13, 0xfa, 0x1e, 0xc6, 0x42, 0x0e, 0xb5, 0x69, 0x82, 0x6d, 0x4d, 0xbf, 0x4e, 0x30, + 0xf2, 0xfd, 0x7d, 0xf5, 0x89, 0x59, 0x8e, 0xbb, 0x9b, 0x6e, 0x84, 0x06, 0xbc, 0x14, 0x5f, 0x3c, + 0x0b, 0xcb, 0x74, 0xea, 0xa7, 0x7c, 0xcb, 0x36, 0xc0, 0x5b, 0xa0, 0xf5, 0x10, 0x2c, 0x2a, 0xfe, + 0x76, 0xa7, 0xaa, 0xa6, 0xf4, 0xaa, 0xdf, 0x41, 0xc4, 0xde, 0x7a, 0x5e, 0xd6, 0x7a, 0x4f, 0x56, + 0xf0, 0x47, 0x5d, 0x7c, 0x78, 0xcb, 0x64, 0x43, 0xa9, 0xb5, 0xea, 0x08, 0x3d, 0x02, 0x69, 0x75, + 0x97, 0x31, 0xc5, 0x45, 0xab, 0x23, 0x14, 0x68, 0xd4, 0x2c, 0xe9, 0x75, 0xbd, 0x78, 0x85, 0xf6, + 0xc5, 0x97, 0x97, 0xfc, 0x0a, 0x6d, 0x8d, 0x66, 0x1a, 0x38, 0xae, 0xf2, 0xf9, 0xd3, 0xae, 0x84, + 0xeb, 0x40, 0x01, 0xd6, 0x62, 0x43, 0x11, 0x5b, 0x09, 0xe5, 0xe7, 0x6d, 0xcb, 0x7d, 0x10, 0x11, + 0xb4, 0x0f, 0xb2, 0xd7, 0x1e, 0x8f, 0xdf, 0x6f, 0xa6, 0x3d, 0xd0, 0x9d, 0x22, 0xcd, 0xcc, 0x04, + 0x7d, 0x55, 0x92, 0xbb, 0x3c, 0xd5, 0xfd, 0x2a, 0x70, 0x9d, 0x32, 0xb3, 0xa0, 0xb1, 0x5a, 0xdb, + 0x63, 0xc0, 0x57, 0x23, 0x44, 0x3d, 0x6e, 0x02, 0xd9, 0x60, 0xe2, 0x0f, 0x7c, 0x68, 0xab, 0x26, + 0xb4, 0x7c, 0x6a, 0xa5, 0x56, 0x77, 0x48, 0x0d, 0x14, 0x25, 0xa9, 0xaf, 0x87, 0x06, 0x28, 0x66, + 0x6e, 0x72, 0x55, 0x13, 0x5f, 0x4e, 0x30, 0xaf, 0xa3, 0xb5, 0x66, 0x68, 0x63, 0x53, 0x4e, 0x24, + 0x2e, 0x3a, 0x91, 0x38, 0x07, 0x69, 0x69, 0x76, 0x12, 0x65, 0x8a, 0x87, 0x6a, 0xc1, 0x7a, 0x6e, + 0x9f, 0xfd, 0x89, 0xf6, 0xe2, 0x2c, 0x5e, 0xdf, 0x36, 0x77, 0x19, 0x0e, 0xfc, 0x65, 0xfc, 0x2f, + 0xd2, 0x63, 0xb7, 0x9b, 0xcc, 0xc9, 0x96, 0xa1, 0x62, 0xcb, 0xf9, 0xe5, 0x65, 0x95, 0x1d, 0x94, + 0xe5, 0x57, 0xed, 0xa7, 0x3c, 0x9b, 0x1f, 0xec, 0x29, 0x07, 0x49, 0x94, 0xe5, 0xe7, 0x75, 0x90, + 0x31, 0x2b, 0x57, 0xde, 0x2c, 0xb3, 0xe8, 0x48, 0xa2, 0x35, 0x72, 0x1e, 0x5f, 0x2d, 0x20, 0x2d, + 0x7d, 0xf6, 0x64, 0x2c, 0xdf, 0x34, 0x99, 0xa7, 0xf3, 0x6d, 0x7d, 0x1e, 0x53, 0x42, 0xfb, 0xc5, + 0x6a, 0x5a, 0x99, 0xbe, 0x7b, 0xd8, 0x98, 0x2b, 0xc6, 0xe0, 0xe5, 0xd2, 0xb5, 0x62, 0x70, 0x6d, + 0x0f, 0x1b, 0x12, 0x3b, 0x63, 0x92, 0x14, 0x1e, 0x72, 0x79, 0xf9, 0x9c, 0xd9, 0x69, 0x94, 0x3f, + 0xdb, 0xc4, 0x7e, 0x8d, 0xbd, 0x71, 0x6e, 0x2f, 0xcb, 0xa8, 0xf4, 0x0f, 0x9b, 0x58, 0xaf, 0xcc, + 0x15, 0xa6, 0xbd, 0xdb, 0xd0, 0x29, 0x54, 0x8c, 0xb8, 0x26, 0xbb, 0xf5, 0x98, 0x30, 0x75, 0xbe, + 0x95, 0x3e, 0xa0, 0xca, 0xa9, 0xb5, 0x7d, 0x27, 0xe5, 0x0a, 0x3b, 0x6a, 0xb0, 0xf3, 0x04, 0xb6, + 0xce, 0xd7, 0xcb, 0x82, 0x7b, 0xf3, 0xca, 0x52, 0x2b, 0xcd, 0xb0, 0x97, 0xda, 0x81, 0x66, 0xdc, + 0x81, 0x32, 0x17, 0xd8, 0xa4, 0x54, 0x99, 0x8b, 0x4a, 0x99, 0x0b, 0x73, 0xc7, 0x92, 0xce, 0x78, + 0xf1, 0x5f, 0xba, 0x4c, 0xc7, 0x1e, 0xb9, 0x89, 0x3e, 0xe9, 0x5d, 0xf2, 0xfb, 0x08, 0x78, 0xc2, + 0xc8, 0x5b, 0x68, 0xbc, 0xeb, 0x29, 0x1b, 0x26, 0xe5, 0xaf, 0xf4, 0x0c, 0x15, 0x53, 0xd9, 0x30, + 0x29, 0xcd, 0x2f, 0xb1, 0x61, 0x5a, 0x5c, 0x87, 0xe8, 0x5a, 0x1c, 0x88, 0xea, 0x12, 0x15, 0xb8, + 0x9d, 0xae, 0xb7, 0x2e, 0xb1, 0x4a, 0xb4, 0x8c, 0x86, 0xdc, 0x71, 0x3d, 0x51, 0x76, 0x08, 0xb7, + 0x32, 0x01, 0x65, 0x01, 0xb1, 0x59, 0x29, 0x2b, 0xa8, 0xbe, 0x29, 0xff, 0x97, 0xe9, 0x2e, 0xbe, + 0xbb, 0xbf, 0xf3, 0x64, 0xba, 0x7b, 0xe9, 0x12, 0x8b, 0x02, 0x8b, 0x6a, 0x1e, 0xfc, 0xd0, 0xaf, + 0xa2, 0x85, 0x7e, 0x1d, 0x1e, 0x0a, 0x1f, 0xd3, 0xe8, 0xa4, 0x34, 0xe6, 0xea, 0xd0, 0x00, 0xfa, + 0x8a, 0x58, 0xa5, 0xbd, 0x37, 0x35, 0xc1, 0x2e, 0x73, 0xd5, 0xbe, 0xae, 0xa3, 0xd4, 0x72, 0x5c, + 0xa9, 0x9c, 0x2c, 0x17, 0x94, 0xd8, 0x50, 0xae, 0xf1, 0x54, 0xa9, 0x35, 0xfa, 0xa6, 0x9c, 0x8c, + 0x37, 0xa1, 0xd3, 0x5a, 0x60, 0x66, 0x8f, 0x44, 0x74, 0x04, 0xe5, 0xd1, 0x44, 0xec, 0xe2, 0xb6, + 0xfe, 0x30, 0xdb, 0xa4, 0xb7, 0x10, 0xac, 0xa1, 0x37, 0x13, 0xbb, 0xa2, 0xf7, 0x05, 0x9d, 0x0c, + 0x3d, 0x38, 0x7f, 0x80, 0xd0, 0x58, 0x46, 0x17, 0x32, 0xa5, 0x0e, 0xd3, 0x27, 0x52, 0x39, 0x94, + 0xdd, 0xc8, 0x2d, 0xec, 0xee, 0xad, 0xbe, 0x6d, 0xfb, 0xe5, 0x60, 0x11, 0xdd, 0x76, 0xc4, 0x6e, + 0x86, 0xf5, 0x4b, 0xe5, 0xda, 0x7f, 0xde, 0xf1, 0x7e, 0x77, 0x71, 0x71, 0x61, 0x05, 0x85, 0x18, + 0x30, 0x91, 0xf9, 0xe6, 0x5f, 0x83, 0xf6, 0x37, 0xb0, 0x26, 0x7c, 0x10, 0xd2, 0xe1, 0xae, 0xa6, + 0xde, 0x27, 0x62, 0x88, 0xa4, 0x06, 0xad, 0x33, 0x98, 0x9c, 0x97, 0x4c, 0x69, 0x35, 0xf0, 0x37, + 0xdf, 0xe7, 0xc4, 0x5d, 0x9b, 0x55, 0x2c, 0x42, 0x98, 0x8c, 0x38, 0x94, 0x57, 0x78, 0x59, 0x2a, + 0x78, 0x48, 0x1a, 0x3a, 0x29, 0x6b, 0x54, 0xcd, 0x4a, 0xdb, 0x04, 0xd4, 0x89, 0x28, 0xa0, 0x2b, + 0x24, 0xa8, 0x08, 0xd1, 0x33, 0xfa, 0x6d, 0x79, 0xfa, 0x28, 0xf4, 0xd5, 0xfc, 0xa1, 0xe4, 0x74, + 0x78, 0xe7, 0x61, 0x25, 0x29, 0x6e, 0x20, 0x7a, 0xac, 0xf7, 0x10, 0xc6, 0xf2, 0x1b, 0x7b, 0x30, + 0x73, 0xd9, 0x13, 0x2b, 0xb5, 0x3f, 0x44, 0x42, 0x5f, 0x31, 0x0f, 0x89, 0x1a, 0x49, 0xa5, 0x8d, + 0xfa, 0x26, 0xf4, 0x5a, 0xa2, 0xfd, 0x2c, 0x8f, 0x3c, 0x14, 0x7c, 0x52, 0x4b, 0x39, 0x7b, 0x85, + 0x4d, 0xd9, 0xfc, 0x34, 0xfe, 0x66, 0x73, 0x33, 0x2b, 0xa8, 0xe4, 0x5a, 0x27, 0xd0, 0x41, 0x48, + 0xfd, 0xda, 0x14, 0x4a, 0x07, 0xc3, 0xad, 0x56, 0xc9, 0xcd, 0x23, 0x9a, 0x11, 0xd4, 0xe6, 0x3e, + 0xa7, 0x3e, 0x43, 0x75, 0x61, 0x61, 0xe8, 0x12, 0xdc, 0x27, 0x92, 0x87, 0xd0, 0x52, 0x71, 0x12, + 0x62, 0x24, 0x14, 0x69, 0x20, 0x0b, 0xea, 0x8d, 0x90, 0x79, 0x8e, 0x63, 0x8e, 0x47, 0xeb, 0x28, + 0x92, 0xee, 0xb9, 0xfc, 0xfb, 0x69, 0x12, 0x36, 0xaf, 0x78, 0x9a, 0x68, 0xaa, 0xf8, 0xc6, 0x5e, + 0xa8, 0x44, 0x41, 0xee, 0x1a, 0xa5, 0x3f, 0xbc, 0x6a, 0x0b, 0x43, 0xeb, 0x6b, 0xde, 0xec, 0x7e, + 0xbb, 0x4d, 0xd7, 0xdf, 0x41, 0x1a, 0x08, 0x6c, 0x35, 0x6a, 0x1b, 0x66, 0xf1, 0x50, 0x49, 0x07, + 0xb0, 0x37, 0x8c, 0xf8, 0xe0, 0xd9, 0x54, 0xc4, 0x9b, 0xa4, 0x9a, 0x7f, 0x9d, 0x7c, 0x7d, 0x7a, + 0xf6, 0xb7, 0x8f, 0xeb, 0x79, 0xb5, 0x00, 0x6d, 0x5e, 0xaf, 0x97, 0xe2, 0x2a, 0x67, 0xb9, 0x9b, + 0x05, 0xe8, 0x85, 0xc2, 0x00, 0x1e, 0x36, 0x5b, 0xea, 0x7e, 0x07, 0x27, 0x1d, 0xc7, 0x96, 0x46, + 0xb5, 0x38, 0x90, 0xf4, 0x11, 0x84, 0x47, 0xd7, 0x51, 0x95, 0xf8, 0x6d, 0x16, 0x45, 0x8b, 0xd3, + 0x93, 0xbf, 0x82, 0x9d, 0x25, 0x8f, 0xb7, 0x8f, 0xa7, 0x67, 0xf9, 0x5b, 0x50, 0x0c, 0x32, 0x01, + 0x16, 0x84, 0x0e, 0xe3, 0xe6, 0x03, 0x84, 0xaf, 0x40, 0x33, 0x40, 0x2d, 0x6f, 0x68, 0xb8, 0xdc, + 0x86, 0x29, 0x0e, 0xfc, 0xb3, 0x2d, 0x6b, 0x98, 0x0b, 0x63, 0x73, 0x93, 0x91, 0x2c, 0xcb, 0xb7, + 0x6e, 0x03, 0x19, 0x0a, 0xa8, 0x19, 0xc7, 0x10, 0x58, 0x35, 0x8c, 0xd5, 0xc2, 0x9a, 0x8d, 0x62, + 0x68, 0x5a, 0xdb, 0xc2, 0x28, 0x5c, 0x5f, 0x7b, 0x31, 0x4d, 0x23, 0x6f, 0xb0, 0x1b, 0xd0, 0xe2, + 0x52, 0x2f, 0x9e, 0xad, 0x62, 0xb4, 0xa6, 0x6d, 0x44, 0x45, 0xa9, 0xac, 0x6a, 0x36, 0x9e, 0x81, + 0x66, 0x1c, 0x26, 0xa2, 0x1d, 0x78, 0x35, 0x31, 0x5b, 0xa0, 0x8a, 0xb6, 0x93, 0x74, 0x87, 0x07, + 0xec, 0x6f, 0xbf, 0xfd, 0x0d, 0xed, 0xf3, 0x89, 0xd3, 0xe6, 0x20, 0xe3, 0xf0, 0xbb, 0x29, 0xad, + 0xa6, 0xb8, 0x33, 0x3e, 0x96, 0xa4, 0x8d, 0x43, 0xb2, 0x2d, 0xb1, 0x6a, 0xf0, 0xbe, 0xc2, 0x95, + 0x0d, 0xd1, 0x81, 0xd2, 0xd0, 0xa7, 0x9e, 0x6a, 0x77, 0xbb, 0xf3, 0xee, 0xef, 0x43, 0x1a, 0xfe, + 0xfa, 0xe3, 0x45, 0x58, 0x37, 0x00, 0xaa, 0x8e, 0xfe, 0x1e, 0x0e, 0x2e, 0xda, 0x71, 0x27, 0x6f, + 0x9a, 0xf4, 0x1b, 0x24, 0x28, 0x86, 0x47, 0xe1, 0x4a, 0x98, 0x27, 0x7d, 0x2f, 0xa1, 0xb6, 0x81, + 0x53, 0xc4, 0x15, 0x50, 0x36, 0x51, 0x44, 0x70, 0x2a, 0xe8, 0xa5, 0x7e, 0x6c, 0x0f, 0xb2, 0x1d, + 0x28, 0x31, 0x42, 0xe0, 0xd8, 0x3a, 0xd4, 0x8a, 0xe8, 0x3c, 0xbd, 0x57, 0x3a, 0xe5, 0x38, 0xa3, + 0x9c, 0xfc, 0x17, 0xd3, 0x96, 0xf7, 0x08, 0x44, 0x2a, 0x76, 0x53, 0xfb, 0xce, 0x43, 0x9d, 0xda, + 0xf7, 0x00, 0xdb, 0x64, 0x15, 0x1b, 0x42, 0x9c, 0x2b, 0x45, 0x52, 0xd5, 0x9e, 0xdd, 0x30, 0x36, + 0x20, 0x86, 0xdc, 0x85, 0xc7, 0xf0, 0xe8, 0xb4, 0xe9, 0x31, 0xf5, 0xd0, 0x81, 0x26, 0x77, 0x7b, + 0x8f, 0x66, 0xd3, 0x94, 0xd6, 0x4a, 0x2a, 0x6f, 0xef, 0xd6, 0xc7, 0x31, 0x23, 0xb0, 0x0b, 0x3a, + 0xe6, 0x4a, 0x95, 0x15, 0xcc, 0x05, 0x99, 0x3f, 0xca, 0x71, 0x75, 0x8d, 0xff, 0xb8, 0x5a, 0x44, + 0x32, 0x47, 0x7b, 0xda, 0xf1, 0x66, 0x85, 0xc5, 0x75, 0xca, 0xaf, 0xfa, 0x62, 0xae, 0xf0, 0x8f, + 0xb0, 0x34, 0x19, 0x30, 0xc0, 0x66, 0x5f, 0x7c, 0xaa, 0x2f, 0xb0, 0xf0, 0x1f, 0x79, 0xba, 0x7e, + 0x57, 0xb7, 0x79, 0x9a, 0xb6, 0x7c, 0xaa, 0xeb, 0x6e, 0xba, 0x5e, 0x74, 0xbc, 0x8d, 0xc2, 0xae, + 0x08, 0xd8, 0x88, 0xda, 0x33, 0x4b, 0xf3, 0x48, 0x7d, 0x0b, 0x5a, 0xc3, 0x84, 0xef, 0x68, 0x10, + 0x49, 0x81, 0xf9, 0x68, 0x19, 0x75, 0x85, 0x66, 0xc5, 0xb6, 0xd5, 0xd1, 0xb6, 0x10, 0x76, 0x04, + 0x71, 0xa2, 0x3a, 0x9c, 0xc8, 0xd2, 0x46, 0x4b, 0x12, 0xbb, 0x86, 0x4e, 0xb8, 0xc5, 0x72, 0x07, + 0xdc, 0x24, 0x03, 0x41, 0xa2, 0x73, 0x67, 0x0a, 0x6b, 0xc2, 0x04, 0x82, 0x28, 0xb8, 0xdf, 0x60, + 0x72, 0x49, 0x0b, 0xbf, 0xf2, 0x82, 0x3e, 0xc8, 0xeb, 0xe7, 0x71, 0x30, 0xf2, 0x74, 0xfb, 0x8d, + 0x60, 0x5c, 0x1f, 0x0b, 0x46, 0xf2, 0x55, 0x20, 0x4e, 0xa8, 0xbf, 0x94, 0x32, 0x9f, 0xa5, 0x4a, + 0xf5, 0x38, 0x35, 0xc9, 0x30, 0x80, 0x8a, 0xc0, 0xf4, 0xb2, 0x49, 0xf6, 0xc5, 0x66, 0x8b, 0xe3, + 0x0f, 0x4e, 0x0f, 0x65, 0xd1, 0x59, 0x4a, 0x44, 0x8f, 0x02, 0xa2, 0x35, 0x50, 0x05, 0xaa, 0x48, + 0x99, 0x5a, 0xea, 0xa3, 0x07, 0xb0, 0x97, 0xe2, 0xfc, 0x98, 0x41, 0x38, 0xf4, 0xfd, 0xe7, 0xb7, + 0x7f, 0x7d, 0xa3, 0xa0, 0xd4, 0xf1, 0xf2, 0xb1, 0xc8, 0xa7, 0x84, 0xf8, 0x68, 0x8b, 0x8b, 0x51, + 0x6d, 0xaa, 0x9e, 0x31, 0x44, 0x77, 0xd1, 0x76, 0x95, 0x2e, 0x46, 0x7c, 0x00, 0xeb, 0xb0, 0xc9, + 0x86, 0x96, 0xfa, 0x7c, 0x84, 0x28, 0x5f, 0xdd, 0x7e, 0xeb, 0x22, 0xce, 0x1f, 0xd1, 0x4e, 0x98, + 0xc1, 0x3d, 0x00, 0xdb, 0x8a, 0xb9, 0xad, 0x63, 0x8f, 0x0e, 0x65, 0x1b, 0xdc, 0x24, 0xff, 0xe1, + 0xdd, 0x7f, 0x77, 0x5f, 0x42, 0xd8, 0xa2, 0x22, 0x80, 0x4f, 0x1e, 0xa1, 0x6b, 0x80, 0x0e, 0xf9, + 0xed, 0x6f, 0x7a, 0xdb, 0x15, 0x89, 0xaa, 0x1b, 0x40, 0xa4, 0xae, 0x0b, 0x90, 0x11, 0x7d, 0xf6, + 0xd2, 0x8f, 0x85, 0xb5, 0xd7, 0x34, 0xb7, 0x5a, 0x23, 0x13, 0xe9, 0x50, 0x93, 0x04, 0x17, 0xa5, + 0x21, 0x48, 0x15, 0x67, 0xd9, 0xc2, 0xcd, 0x11, 0x45, 0x19, 0xec, 0x31, 0xa5, 0x86, 0x49, 0xcd, + 0xbe, 0x6b, 0x0e, 0xc7, 0xd0, 0xb0, 0xee, 0x07, 0xdf, 0x02, 0xc0, 0x0e, 0x12, 0x32, 0x3a, 0x1e, + 0x47, 0x86, 0xb9, 0x18, 0xc9, 0x91, 0xba, 0x97, 0xdf, 0xcf, 0xe7, 0x38, 0x40, 0x54, 0xe4, 0x6b, + 0xaa, 0x8c, 0xd9, 0xa3, 0x0a, 0xd6, 0xbd, 0x4a, 0x12, 0x18, 0x0f, 0xa8, 0x12, 0x6b, 0x55, 0x7e, + 0xca, 0x73, 0x4d, 0x41, 0xd0, 0x79, 0x9c, 0x04, 0x57, 0x72, 0x9b, 0x56, 0xeb, 0x0d, 0x06, 0xfe, + 0xb5, 0x82, 0x4e, 0x5e, 0xf5, 0x25, 0x86, 0x8f, 0x77, 0x4c, 0x40, 0xb4, 0x5c, 0xd2, 0xd0, 0xcd, + 0x7b, 0xf9, 0x2a, 0x5e, 0xa2, 0x29, 0x5e, 0xbf, 0x2f, 0x28, 0x5f, 0x5a, 0xcb, 0x68, 0xd3, 0x2e, + 0xb6, 0xcd, 0x78, 0xed, 0x99, 0xe9, 0x43, 0xeb, 0x4b, 0x34, 0xe9, 0x4f, 0x7e, 0x4c, 0x07, 0x67, + 0x43, 0xe3, 0x1e, 0x9e, 0x0d, 0x69, 0x63, 0x64, 0xad, 0xf1, 0xa8, 0x92, 0x7c, 0x5f, 0xab, 0x3f, + 0xdd, 0x6c, 0xdb, 0x6a, 0x11, 0x32, 0x76, 0xeb, 0x5a, 0xb5, 0xd4, 0xd2, 0x1d, 0xb6, 0xb2, 0xe0, + 0x4a, 0x84, 0x2f, 0x7d, 0xb8, 0xa5, 0xed, 0x4f, 0xce, 0xfc, 0x90, 0xa5, 0xce, 0xaa, 0xd4, 0xf5, + 0xe2, 0x85, 0x77, 0x16, 0xd8, 0x6a, 0x8d, 0xbf, 0xb7, 0x9b, 0xd2, 0x85, 0x63, 0xff, 0xda, 0x11, + 0xc7, 0x6b, 0xe1, 0x59, 0x70, 0xd5, 0x97, 0x9a, 0xf9, 0x78, 0x1f, 0xe8, 0xf9, 0xc7, 0x89, 0x33, + 0x59, 0x01, 0x5c, 0xdc, 0x54, 0x57, 0x8b, 0x6b, 0x0d, 0xd3, 0x59, 0x42, 0xfb, 0xf3, 0x54, 0x8e, + 0x1a, 0xe9, 0x0b, 0x96, 0x96, 0x54, 0x1c, 0xe6, 0x69, 0x59, 0x35, 0x31, 0xf5, 0x51, 0x98, 0x6a, + 0x0f, 0x9c, 0xe0, 0xac, 0x5a, 0x09, 0x31, 0x88, 0xf8, 0x78, 0xed, 0x88, 0xe0, 0xa7, 0x84, 0x02, + 0x6b, 0x80, 0xc1, 0x30, 0x3a, 0x2c, 0x77, 0xbd, 0xc9, 0x6e, 0xec, 0x45, 0xe7, 0xc6, 0xf7, 0xa3, + 0x66, 0x9e, 0x18, 0x70, 0x78, 0x2b, 0xe0, 0x72, 0xf1, 0x5b, 0x4d, 0x85, 0xb5, 0xc8, 0x60, 0x08, + 0xe1, 0x2a, 0x9c, 0x7b, 0x21, 0x22, 0x58, 0x05, 0x53, 0xd9, 0x64, 0x55, 0x06, 0xd6, 0x56, 0x70, + 0x39, 0x40, 0x67, 0xfd, 0x91, 0x53, 0xcc, 0xb0, 0x0b, 0x42, 0xfe, 0xac, 0xdc, 0x3f, 0x70, 0x08, + 0x16, 0xfe, 0x26, 0x65, 0x6f, 0x09, 0xc3, 0x97, 0x38, 0xc7, 0x87, 0x85, 0x29, 0x13, 0x24, 0x61, + 0x9b, 0x65, 0xfe, 0x29, 0x3a, 0xfd, 0xf6, 0x6b, 0x0e, 0x81, 0x30, 0xa0, 0x6a, 0xdf, 0x83, 0xe2, + 0x6d, 0xbc, 0x4d, 0x22, 0x83, 0x22, 0x8d, 0xab, 0x95, 0x42, 0x60, 0xc0, 0x7e, 0xf8, 0x44, 0xe1, + 0x06, 0x16, 0xb5, 0x8c, 0x99, 0xb3, 0x8a, 0x84, 0xd6, 0x39, 0x0b, 0xa0, 0xcb, 0xf1, 0x62, 0xf5, + 0x2f, 0x10, 0xaa, 0x65, 0x1e, 0x0a, 0xa2, 0xc3, 0xd6, 0x58, 0x76, 0x50, 0xc5, 0x5a, 0xc5, 0x55, + 0x11, 0xbf, 0x5f, 0xf1, 0xba, 0x61, 0x1b, 0xe7, 0x11, 0x84, 0x7a, 0x74, 0x37, 0xf0, 0xb6, 0x04, + 0x86, 0x5b, 0xb2, 0x19, 0xa5, 0xea, 0x78, 0xb9, 0x86, 0x80, 0x09, 0xfe, 0x38, 0x17, 0x0b, 0xda, + 0xc1, 0x73, 0x88, 0xc2, 0x6a, 0x53, 0xda, 0xd9, 0x06, 0x96, 0x32, 0x01, 0x2b, 0xe7, 0xbd, 0x75, + 0x22, 0x99, 0x35, 0x1e, 0x98, 0x43, 0x16, 0x2c, 0x47, 0x19, 0x20, 0xe5, 0xbc, 0x77, 0xbf, 0xc8, + 0x88, 0x24, 0xfa, 0x42, 0x84, 0x0d, 0x03, 0xce, 0x7b, 0x59, 0x0e, 0xa0, 0x57, 0x15, 0x06, 0x8c, + 0x70, 0x27, 0x59, 0xf3, 0xc7, 0x77, 0x0c, 0xfb, 0x62, 0x18, 0x25, 0x6b, 0xfc, 0x58, 0x8e, 0xed, + 0x65, 0x09, 0x09, 0x3b, 0x2c, 0x34, 0xb2, 0xd6, 0xca, 0x1b, 0x69, 0xbd, 0x97, 0xab, 0x88, 0x79, + 0xae, 0x1b, 0xc5, 0x55, 0xcd, 0xe7, 0xeb, 0x25, 0x9c, 0x7f, 0x35, 0xa5, 0x8e, 0x1c, 0xa9, 0xa7, + 0xbb, 0xa6, 0xd4, 0xdb, 0x7a, 0x6a, 0x98, 0x96, 0xbd, 0xfe, 0x70, 0xd0, 0x98, 0xc5, 0xce, 0xc3, + 0x43, 0x38, 0xe6, 0xe9, 0x2c, 0x99, 0x0a, 0x94, 0xf5, 0x7c, 0x42, 0x47, 0x20, 0x99, 0x73, 0x0b, + 0x06, 0x35, 0x3a, 0xec, 0xb6, 0xd6, 0x72, 0x61, 0x98, 0x5e, 0xe3, 0x65, 0x5b, 0xac, 0xac, 0x40, + 0x93, 0x46, 0x09, 0x8d, 0x7d, 0x14, 0xc8, 0xa3, 0x6b, 0x31, 0xf6, 0xc4, 0x5f, 0xd8, 0x1e, 0x1f, + 0x6c, 0x9b, 0x55, 0x32, 0x61, 0xac, 0x2c, 0xb3, 0x48, 0xaa, 0xd1, 0x0a, 0xad, 0xb8, 0x0a, 0xd5, + 0x7a, 0x93, 0x7a, 0x9a, 0x80, 0x96, 0xb1, 0x57, 0x96, 0x7a, 0x80, 0xb1, 0xde, 0xd5, 0xcb, 0x92, + 0x9f, 0x85, 0x90, 0x05, 0x5f, 0xce, 0x69, 0x0d, 0x82, 0x36, 0x95, 0x38, 0x10, 0x75, 0xbb, 0x4a, + 0x14, 0x5a, 0xbc, 0x8f, 0x8e, 0x60, 0x63, 0xb5, 0xfd, 0x3c, 0xa1, 0x94, 0xef, 0x07, 0x1f, 0x18, + 0x6f, 0x64, 0x85, 0x0d, 0x1d, 0x61, 0xe7, 0x1f, 0xc4, 0xb8, 0x5e, 0x39, 0xf3, 0x0a, 0x7e, 0x9e, + 0x12, 0x08, 0x06, 0x42, 0xd2, 0xbe, 0x00, 0x5f, 0x0c, 0xc8, 0x2d, 0x70, 0xef, 0xa1, 0x5e, 0x3d, + 0x0e, 0x1e, 0xd8, 0x8b, 0x2e, 0x57, 0xe5, 0x22, 0xe7, 0x87, 0x06, 0x45, 0x83, 0x3b, 0x63, 0xdc, + 0xcb, 0xdd, 0xe3, 0xb0, 0x76, 0xd2, 0x37, 0xb2, 0xc4, 0xbb, 0x5f, 0x42, 0x99, 0x01, 0x97, 0xa2, + 0x45, 0xc3, 0x15, 0xf4, 0x3f, 0xee, 0x2d, 0x77, 0x2c, 0x6b, 0x1b, 0xb5, 0x65, 0xac, 0xc6, 0x34, + 0x85, 0x21, 0x97, 0xee, 0xe0, 0x5b, 0xd9, 0xac, 0x71, 0x22, 0x9a, 0x6f, 0xd2, 0x24, 0x79, 0x97, + 0x66, 0x0d, 0x12, 0x7d, 0x8d, 0x44, 0x81, 0x36, 0xbe, 0x63, 0xdd, 0xe2, 0xa1, 0x82, 0xe5, 0xe2, + 0x8c, 0x40, 0x20, 0xfb, 0xc3, 0xde, 0xcb, 0xb1, 0x56, 0x0e, 0xe6, 0x3d, 0xc6, 0xe3, 0x59, 0xf2, + 0x1f, 0x9f, 0xf1, 0x04, 0x84, 0xc9, 0xf5, 0x49, 0x92, 0x86, 0xa1, 0xcd, 0xc2, 0xe9, 0x9c, 0x6f, + 0x03, 0x17, 0xa7, 0xa6, 0xb6, 0x2a, 0xd3, 0x9a, 0x28, 0x95, 0x42, 0x60, 0x7a, 0x49, 0x89, 0xbd, + 0x49, 0x7a, 0xab, 0x92, 0xab, 0xc2, 0xec, 0x03, 0x9e, 0x42, 0x23, 0x43, 0x5b, 0xa6, 0xb0, 0xfa, + 0xb2, 0x74, 0xb7, 0xf0, 0x57, 0x6d, 0xb6, 0xe9, 0xec, 0x1f, 0x2c, 0x75, 0xc0, 0x01, 0x20, 0x5f, + 0x2d, 0x81, 0x4c, 0x41, 0x81, 0xe6, 0x5a, 0x72, 0x48, 0x2b, 0x69, 0xaf, 0x42, 0x5f, 0x0c, 0x15, + 0x46, 0xbc, 0x3c, 0xf9, 0x51, 0x59, 0x75, 0xac, 0xa2, 0x50, 0xf6, 0x26, 0x11, 0xb2, 0x64, 0x5b, + 0x68, 0xd1, 0x1f, 0xbd, 0x73, 0x27, 0x5f, 0x2b, 0xd4, 0x87, 0xb1, 0x54, 0x80, 0xfd, 0x02, 0xe6, + 0x14, 0x8d, 0x46, 0xcf, 0xfb, 0x11, 0x87, 0x71, 0x09, 0x7a, 0x88, 0x93, 0xc4, 0x13, 0x2f, 0x23, + 0xcb, 0xa5, 0xc7, 0x4e, 0x8c, 0x98, 0xff, 0xb2, 0xc3, 0x9c, 0xd1, 0x6f, 0x5a, 0xa6, 0xef, 0x21, + 0x21, 0x05, 0x36, 0x10, 0xca, 0x5d, 0xc3, 0x22, 0xe2, 0x3a, 0x00, 0xce, 0x51, 0x19, 0x6c, 0x6e, + 0xad, 0x13, 0xe2, 0x96, 0x62, 0x1a, 0x11, 0xbb, 0xdf, 0x9f, 0xde, 0x68, 0xa8, 0x0e, 0x15, 0x64, + 0xb5, 0xdc, 0xea, 0x5a, 0xfa, 0xb7, 0x62, 0x40, 0xa1, 0x4b, 0xac, 0x72, 0xe1, 0xaf, 0x74, 0x94, + 0x51, 0x6d, 0xce, 0xb1, 0x4c, 0x03, 0xb3, 0xba, 0x8e, 0xb6, 0x0f, 0xe9, 0xe6, 0xa3, 0xf0, 0x60, + 0x9d, 0x3e, 0xf0, 0xb5, 0x1e, 0x40, 0x5f, 0x61, 0x69, 0x24, 0xf9, 0x37, 0x3a, 0xd0, 0xe6, 0x77, + 0x48, 0xa2, 0xb8, 0x4a, 0x94, 0xa4, 0xc7, 0x8b, 0xf7, 0x92, 0x74, 0x7d, 0x4b, 0x89, 0x50, 0x89, + 0x93, 0x37, 0xd8, 0xb4, 0x99, 0x3b, 0xd8, 0xb8, 0xe9, 0x87, 0x6e, 0x0b, 0x33, 0x49, 0x37, 0x4e, + 0x09, 0x35, 0x21, 0x72, 0xc9, 0x36, 0xbf, 0x11, 0x19, 0xc7, 0x60, 0xc4, 0x89, 0x0c, 0x85, 0xf4, + 0xf5, 0x29, 0x8e, 0x1e, 0xf4, 0x10, 0xe7, 0x2b, 0x50, 0x2d, 0xfc, 0x75, 0xab, 0x65, 0x54, 0x72, + 0xa7, 0x0e, 0x85, 0x32, 0x39, 0x15, 0x27, 0x02, 0xd2, 0xc3, 0x99, 0x1c, 0x97, 0x49, 0xbe, 0xaa, + 0x9d, 0xcc, 0xfb, 0xba, 0xd4, 0x9b, 0x91, 0x5f, 0xfc, 0x76, 0x2b, 0x90, 0xcd, 0xfa, 0x37, 0x73, + 0xb3, 0x56, 0x38, 0x3f, 0xf5, 0xa7, 0x33, 0xb8, 0xe3, 0x99, 0x25, 0xd3, 0xf5, 0xc7, 0x83, 0x0a, + 0x68, 0x87, 0xfe, 0x5b, 0xd1, 0x6e, 0xa9, 0x9e, 0x8b, 0x0b, 0x33, 0x2e, 0xce, 0xb1, 0x08, 0xa8, + 0xb8, 0xa6, 0xae, 0x8a, 0xb5, 0xe4, 0xd7, 0x21, 0x99, 0x51, 0x8b, 0x97, 0xa1, 0x93, 0x3c, 0xc4, + 0x34, 0xe8, 0xea, 0x54, 0x61, 0x27, 0x6b, 0xe7, 0x9a, 0xda, 0xfe, 0xaa, 0xde, 0xf4, 0xa2, 0x64, + 0xab, 0xf1, 0x76, 0x9b, 0xef, 0xa6, 0x1f, 0x21, 0xed, 0xb4, 0x8b, 0xa3, 0xf3, 0x5a, 0x5f, 0x27, + 0xab, 0x9b, 0x5e, 0xbd, 0x41, 0x91, 0x2a, 0x93, 0x19, 0xda, 0x60, 0xd9, 0xb0, 0xb2, 0x75, 0x87, + 0xa5, 0x05, 0x4b, 0x15, 0xcb, 0xb9, 0xaf, 0x8a, 0x0b, 0x67, 0xa1, 0x54, 0x9a, 0xc9, 0x00, 0xdf, + 0x1b, 0x30, 0x39, 0x27, 0x78, 0xac, 0x8e, 0xc5, 0x82, 0x46, 0x4c, 0xc5, 0xbe, 0x89, 0x1e, 0xb4, + 0x29, 0xd7, 0xb3, 0x09, 0x31, 0x81, 0x58, 0xb3, 0x8d, 0x13, 0x20, 0x55, 0xe0, 0xa1, 0xfe, 0x7f, + 0xa0, 0x9f, 0xac, 0xd6, 0xfd, 0x3c, 0x20, 0xd4, 0x3a, 0x6f, 0x42, 0xb1, 0x58, 0x85, 0xff, 0xcb, + 0x18, 0x1b, 0xab, 0xb4, 0x9f, 0x03, 0x8b, 0x32, 0xc2, 0x9e, 0x45, 0xee, 0x41, 0xfc, 0x4d, 0x13, + 0x81, 0x8c, 0xc3, 0x29, 0xeb, 0x24, 0x49, 0x88, 0xf8, 0xc4, 0xd6, 0xd2, 0x13, 0x51, 0x24, 0xde, + 0x6a, 0x9a, 0x58, 0x50, 0x12, 0xab, 0x78, 0x17, 0xaa, 0xc4, 0xa6, 0x7f, 0xec, 0x99, 0x30, 0x82, + 0x1a, 0xdc, 0xc4, 0x02, 0x57, 0xb8, 0xb5, 0xe2, 0x6e, 0x1c, 0x84, 0x03, 0xaa, 0x6a, 0x54, 0xa4, + 0x27, 0xb7, 0x9a, 0x7a, 0x35, 0xbd, 0x12, 0x4c, 0x2b, 0xdd, 0xd8, 0x63, 0x67, 0xd9, 0x65, 0x13, + 0x8a, 0x15, 0x04, 0x43, 0xc1, 0xe6, 0x0a, 0xa7, 0xa7, 0x5f, 0xd2, 0x80, 0xe1, 0xcb, 0x29, 0x37, + 0xe0, 0xeb, 0xc5, 0x42, 0x4f, 0x51, 0x4b, 0x85, 0xf4, 0x2f, 0x36, 0xa4, 0x40, 0x61, 0x1a, 0x58, + 0x5b, 0xbd, 0xfb, 0x62, 0x71, 0x18, 0xbd, 0x67, 0xcd, 0x10, 0x1c, 0x3e, 0xc1, 0xbd, 0xa9, 0x17, + 0x5f, 0x4d, 0x90, 0x41, 0x4c, 0x5e, 0x4f, 0x22, 0xde, 0x51, 0x3a, 0x71, 0xa9, 0x85, 0x2c, 0x24, + 0xcd, 0x50, 0xca, 0x49, 0x1e, 0x7e, 0x05, 0x09, 0x73, 0xc4, 0x07, 0xe1, 0x7d, 0xa1, 0x54, 0x3d, + 0xb2, 0x0b, 0x2b, 0x30, 0x6a, 0x1e, 0x3e, 0x15, 0xa7, 0xcd, 0xe6, 0xf5, 0x32, 0x07, 0x94, 0xf5, + 0xa6, 0x38, 0x82, 0x8f, 0x1d, 0xc4, 0x6b, 0x15, 0x58, 0xde, 0xf1, 0x84, 0x34, 0x94, 0xe8, 0x92, + 0xb0, 0x8c, 0x7b, 0x5b, 0x55, 0x8a, 0xb6, 0x36, 0x45, 0xff, 0x76, 0xec, 0x02, 0x8b, 0x39, 0xc8, + 0x7a, 0x35, 0x91, 0xda, 0x69, 0xc4, 0x2d, 0x34, 0x9f, 0xc6, 0x5a, 0xf3, 0xbb, 0x3f, 0xda, 0x7c, + 0x76, 0xb0, 0x30, 0x92, 0x22, 0xf8, 0x3b, 0xcd, 0xf8, 0x33, 0xcd, 0x0a, 0x69, 0xea, 0x30, 0xc4, + 0xe0, 0xff, 0x12, 0x99, 0xa0, 0x87, 0x99, 0xd4, 0x4c, 0xff, 0x1b, 0x61, 0x52, 0x24, 0xfd, 0x7f, + 0xe2, 0x20, 0x5b, 0x18, 0x83, 0x8c, 0x99, 0xab, 0x01, 0xe5, 0x57, 0xb0, 0xca, 0x59, 0x32, 0xad, + 0x4f, 0xc7, 0x02, 0xda, 0x26, 0x69, 0x3f, 0x26, 0x11, 0x78, 0x35, 0xfd, 0x14, 0x79, 0x77, 0xf7, + 0xc9, 0x36, 0xce, 0x92, 0xa8, 0x44, 0x3e, 0x51, 0x8c, 0x20, 0x47, 0x20, 0x1e, 0xcb, 0x5d, 0x5d, + 0x53, 0xcd, 0x50, 0x80, 0x87, 0xf3, 0x0f, 0x06, 0x9a, 0x49, 0xd7, 0xd9, 0xed, 0x1e, 0xef, 0x37, + 0xee, 0xa7, 0xc1, 0x73, 0x47, 0x2d, 0x30, 0x6a, 0xc5, 0xa8, 0x05, 0x3c, 0xed, 0xc0, 0x3c, 0xa2, + 0xe8, 0xd3, 0xe7, 0x11, 0xe0, 0x70, 0x30, 0xaf, 0x7c, 0xfa, 0x19, 0xf3, 0x08, 0x20, 0xca, 0x82, + 0xa8, 0xc6, 0x1a, 0xf8, 0x28, 0xd4, 0xd2, 0x38, 0xcd, 0xfc, 0xc3, 0x69, 0x47, 0xa2, 0x12, 0x31, + 0x79, 0xbc, 0x06, 0x00, 0x30, 0x47, 0x27, 0x8c, 0x42, 0xc6, 0x86, 0xa9, 0x51, 0x78, 0x32, 0x15, + 0x7f, 0x6f, 0xc7, 0xd0, 0x2f, 0x34, 0xd0, 0xb0, 0xdc, 0x59, 0x2a, 0x79, 0x4a, 0x79, 0x72, 0xc1, + 0xca, 0x42, 0xd8, 0x6e, 0x58, 0xa9, 0xe9, 0x6f, 0x36, 0x4d, 0x0e, 0xb6, 0xab, 0x6a, 0x6a, 0x7c, + 0x6e, 0xd3, 0xc0, 0xdd, 0x5a, 0xcb, 0x8e, 0x31, 0xb3, 0xae, 0xc5, 0x0d, 0xff, 0x2d, 0x8a, 0x01, + 0x0c, 0x08, 0xa8, 0xaa, 0xea, 0x14, 0x6b, 0x76, 0xe5, 0xbb, 0x53, 0x08, 0xb7, 0xf4, 0x5d, 0x4e, + 0x5e, 0x1d, 0x1a, 0xf5, 0x85, 0xfa, 0xab, 0x99, 0x8c, 0xf8, 0x24, 0x32, 0x6a, 0x7a, 0xb4, 0x67, + 0x93, 0xf2, 0x1a, 0x9b, 0x78, 0x8d, 0x0a, 0x7e, 0x97, 0xc5, 0x8b, 0x9f, 0xa1, 0x76, 0xf8, 0xe6, + 0xc7, 0x7a, 0x5b, 0xb2, 0x04, 0xf7, 0x1f, 0x49, 0x4c, 0x6e, 0xda, 0x4a, 0x1c, 0x4a, 0x73, 0x19, + 0xc7, 0x46, 0x09, 0x23, 0xdc, 0xe8, 0xf1, 0xa1, 0xad, 0x66, 0xbe, 0xe0, 0xde, 0xe3, 0x41, 0xc6, + 0x98, 0x4a, 0xf4, 0x90, 0x72, 0xc2, 0x5d, 0xce, 0xb1, 0x0c, 0x91, 0x99, 0x81, 0xaf, 0x61, 0x1d, + 0xcb, 0x61, 0x0d, 0xbc, 0xfd, 0x2f, 0x31, 0x74, 0x99, 0xa9, 0x27, 0x32, 0xfb, 0xbb, 0xb7, 0xc2, + 0x6c, 0x76, 0xe7, 0xd2, 0x62, 0x83, 0xc4, 0xaf, 0x89, 0x60, 0xe2, 0x83, 0x66, 0xde, 0x00, 0x66, + 0x12, 0xb4, 0xd1, 0x14, 0x70, 0x13, 0xdf, 0xd2, 0x02, 0x3d, 0x17, 0xf7, 0xa4, 0xca, 0x30, 0x2e, + 0x1f, 0xbb, 0x21, 0x7f, 0x44, 0xfc, 0x6b, 0x18, 0xe6, 0x7c, 0x5b, 0x8e, 0x65, 0x0a, 0xe9, 0x84, + 0xfe, 0x16, 0x3b, 0x32, 0xed, 0xbf, 0x79, 0x92, 0x02, 0xc5, 0x0f, 0xdf, 0x1e, 0x02, 0xa6, 0xe1, + 0x00, 0xe7, 0x12, 0xca, 0x82, 0xbb, 0x63, 0x16, 0x64, 0x39, 0x4f, 0x82, 0x06, 0x0c, 0x56, 0x3b, + 0xee, 0x0e, 0xc3, 0x12, 0x87, 0x65, 0xcb, 0x08, 0xaf, 0xc5, 0xad, 0xaf, 0x27, 0x8e, 0x94, 0x4a, + 0x02, 0xe4, 0xd6, 0x9c, 0x77, 0xe6, 0xf7, 0xfc, 0x26, 0x9d, 0x99, 0xff, 0xd6, 0x4c, 0x07, 0x3c, + 0x0f, 0x3b, 0xad, 0x6b, 0x79, 0x3f, 0xc0, 0xf9, 0x2a, 0x33, 0x09, 0x1e, 0x60, 0xa5, 0x91, 0xdc, + 0xd8, 0x55, 0xa4, 0x81, 0x5c, 0xba, 0x3e, 0x8a, 0x8a, 0xb7, 0x3d, 0xcb, 0xa9, 0x82, 0xf4, 0x5f, + 0xd9, 0xb4, 0x29, 0xd4, 0x18, 0x32, 0xc5, 0xcd, 0xba, 0xa5, 0xfc, 0xb2, 0x18, 0x17, 0xd1, 0xa7, + 0x09, 0xed, 0xda, 0xec, 0x20, 0xd8, 0x1f, 0xe5, 0x74, 0x67, 0x36, 0xfe, 0x75, 0xdd, 0x90, 0xb0, + 0xd7, 0xeb, 0x89, 0x7f, 0x9e, 0xed, 0x04, 0x6c, 0x20, 0x16, 0x0c, 0xf6, 0x4f, 0x60, 0x24, 0x93, + 0xb7, 0x90, 0x26, 0xfe, 0x65, 0xb6, 0xab, 0x46, 0xc9, 0x0b, 0x50, 0xfe, 0xc5, 0xb9, 0x44, 0xed, + 0x39, 0x96, 0xed, 0x1f, 0x95, 0x2a, 0x2e, 0x9d, 0x55, 0x98, 0x29, 0x75, 0x2d, 0xe7, 0x45, 0x2d, + 0x66, 0xac, 0xaa, 0xe8, 0x72, 0x20, 0xb1, 0x0c, 0xa6, 0x61, 0x67, 0x27, 0xe2, 0xba, 0xbd, 0x78, + 0xb8, 0xd2, 0x6b, 0x4d, 0xe8, 0x90, 0x56, 0xa1, 0xc1, 0x36, 0x7b, 0x08, 0x1b, 0x8c, 0xcc, 0x18, + 0xce, 0x47, 0xb2, 0x8c, 0x0f, 0xda, 0x81, 0xfe, 0xd6, 0x6c, 0x03, 0x7a, 0x06, 0x2a, 0xb3, 0x30, + 0xc4, 0x43, 0xa5, 0xb7, 0x52, 0xca, 0xb0, 0xf2, 0x66, 0xe7, 0x37, 0x6d, 0xa2, 0xb6, 0x44, 0x8b, + 0x6b, 0xcf, 0x3a, 0x9b, 0xf5, 0xc2, 0xd7, 0x78, 0x22, 0x0c, 0x99, 0xa7, 0x15, 0x6f, 0x01, 0x39, + 0xff, 0xff, 0x69, 0x84, 0xab, 0xd5, 0x18, 0xb4, 0x14, 0xd9, 0xab, 0xfa, 0x03, 0x90, 0x5b, 0xd1, + 0x24, 0x5a, 0xa7, 0x77, 0xb4, 0x40, 0x7e, 0xe1, 0x5d, 0xf2, 0xc5, 0xf6, 0x4b, 0x5e, 0x5f, 0x17, + 0xa9, 0x27, 0x45, 0xf6, 0x56, 0x76, 0xae, 0x6a, 0xa6, 0x17, 0xe2, 0x3a, 0x60, 0x8f, 0x86, 0x93, + 0x4c, 0x2f, 0xf1, 0xd3, 0x59, 0xde, 0x96, 0xbc, 0xe2, 0x6b, 0x68, 0x15, 0xd2, 0x60, 0x94, 0x82, + 0x75, 0xe3, 0x38, 0x5a, 0x0d, 0x99, 0x6a, 0x5f, 0xa4, 0x89, 0x72, 0x49, 0x23, 0x8e, 0x6a, 0x9a, + 0xb7, 0x63, 0x15, 0x8f, 0x67, 0x98, 0xd8, 0xa7, 0x52, 0xa9, 0x49, 0x38, 0x71, 0xc2, 0x80, 0x93, + 0x65, 0x76, 0xc6, 0x78, 0x1e, 0x1c, 0x08, 0x60, 0x79, 0x60, 0xba, 0xea, 0x09, 0x42, 0xaf, 0x42, + 0xbe, 0x7a, 0x93, 0xbb, 0x1d, 0xac, 0xf2, 0x4f, 0x41, 0xc7, 0x0b, 0xf0, 0xdf, 0x50, 0xf0, 0x6e, + 0xc7, 0xca, 0xf6, 0x9c, 0x43, 0x7a, 0x0c, 0xc7, 0x50, 0xe5, 0xa0, 0x72, 0xe3, 0xdf, 0xec, 0x71, + 0xa8, 0x97, 0x0d, 0x1e, 0x11, 0x95, 0x42, 0x1b, 0x0e, 0x27, 0x14, 0x4f, 0x7f, 0xdf, 0xbf, 0x47, + 0xbf, 0x6c, 0x3a, 0xdc, 0x3d, 0xb7, 0xf2, 0x67, 0xd6, 0xb1, 0x06, 0xf5, 0x87, 0xce, 0x7b, 0xfc, + 0xfb, 0x50, 0x1c, 0x79, 0x65, 0xad, 0x2a, 0xa0, 0xfb, 0x0d, 0xe5, 0x52, 0x9e, 0x93, 0x8a, 0x96, + 0x72, 0x8d, 0x8b, 0x01, 0xba, 0xf8, 0xf3, 0x63, 0xc5, 0x9f, 0x54, 0x83, 0x2a, 0xfe, 0xd7, 0x93, + 0x9d, 0xd9, 0x9b, 0xc2, 0x5c, 0xcd, 0x5e, 0x25, 0xbc, 0x6e, 0x28, 0xa3, 0xe9, 0x7a, 0x45, 0x81, + 0xfc, 0x45, 0x4d, 0xae, 0x4e, 0xba, 0x94, 0xe9, 0x6c, 0x32, 0x7c, 0x29, 0x40, 0xd7, 0xd5, 0xfc, + 0xfa, 0x05, 0xfc, 0x23, 0xac, 0x18, 0x28, 0xa0, 0x42, 0xce, 0x29, 0x84, 0x02, 0x5e, 0x0c, 0x7e, + 0xaf, 0x83, 0x26, 0x93, 0xe1, 0xc5, 0x45, 0xc8, 0x39, 0x5f, 0x98, 0x81, 0x83, 0x97, 0xa1, 0x2e, + 0xce, 0xb5, 0x68, 0xad, 0xa2, 0xe9, 0x66, 0x5b, 0x58, 0x05, 0xe6, 0x6a, 0xec, 0xdd, 0xe0, 0xa1, + 0xc3, 0xcf, 0x9e, 0x56, 0xf3, 0x3d, 0x8f, 0xd7, 0xcf, 0x3b, 0x34, 0x61, 0x3f, 0x0f, 0x6f, 0xe8, + 0xeb, 0x4b, 0x69, 0x71, 0xc5, 0x59, 0xd0, 0x9f, 0xfe, 0x47, 0x9d, 0xa2, 0x94, 0xe3, 0x2f, 0x84, + 0xb5, 0x7d, 0x87, 0x57, 0xf7, 0xaf, 0xe3, 0xcd, 0x3c, 0x4d, 0xd3, 0x8f, 0x71, 0xd4, 0x87, 0x39, + 0xb6, 0xff, 0x10, 0x7f, 0x8c, 0x7d, 0x8b, 0x5f, 0x24, 0xad, 0x16, 0xde, 0x77, 0xcc, 0x35, 0x8f, + 0xc2, 0xbf, 0x67, 0x61, 0xc3, 0xb8, 0x24, 0x83, 0xb4, 0xe5, 0xe9, 0x6d, 0xb6, 0x75, 0x4e, 0x07, + 0x16, 0x3b, 0x48, 0x7a, 0x62, 0x83, 0xd8, 0x6c, 0x5b, 0x69, 0xa9, 0x3c, 0x8f, 0x29, 0x31, 0xa6, + 0x4c, 0x04, 0xb0, 0xe4, 0x32, 0xde, 0xdc, 0x79, 0xdf, 0xb3, 0x9b, 0x19, 0xde, 0x85, 0x84, 0x32, + 0xc6, 0xa0, 0x78, 0xa6, 0x4e, 0xa2, 0xea, 0xed, 0x6c, 0xb5, 0x89, 0x96, 0x28, 0xa2, 0xcf, 0x55, + 0xd7, 0x05, 0x27, 0x75, 0x61, 0x5a, 0xb9, 0xdf, 0x30, 0xaf, 0x43, 0x93, 0x48, 0x6a, 0x7c, 0x3a, + 0x3b, 0x8c, 0x06, 0x7b, 0xe0, 0x9d, 0xc5, 0x0e, 0x13, 0x99, 0x91, 0xd3, 0x69, 0x29, 0x73, 0x96, + 0x15, 0x99, 0x85, 0x59, 0x46, 0xa1, 0x6a, 0x71, 0x15, 0xdc, 0xd5, 0x48, 0x07, 0xc8, 0x67, 0xed, + 0xbe, 0x08, 0x8d, 0xe7, 0xf9, 0x7d, 0x2e, 0x6f, 0x19, 0xe4, 0x4d, 0x5e, 0x77, 0x8a, 0xa3, 0x2c, + 0x49, 0xa4, 0xb3, 0xe4, 0x7e, 0xd3, 0x76, 0x5a, 0xae, 0x7c, 0xe3, 0xe0, 0x78, 0x4a, 0xc2, 0xe2, + 0x68, 0x67, 0x26, 0x66, 0xf2, 0xfa, 0x7d, 0xa4, 0x80, 0x68, 0xf0, 0xc3, 0x2b, 0xed, 0xf0, 0xef, + 0xa7, 0x6f, 0x4c, 0xb1, 0xdf, 0xf6, 0x4a, 0x1d, 0xc0, 0x9d, 0xe7, 0x76, 0x1a, 0xaf, 0x81, 0x72, + 0xef, 0x78, 0x6f, 0x28, 0xe5, 0x05, 0x8f, 0x7e, 0x3a, 0xf0, 0x7b, 0x85, 0x23, 0x2b, 0x5a, 0xfc, + 0x77, 0x03, 0x85, 0x48, 0xed, 0x78, 0x8f, 0xe5, 0x4f, 0xc1, 0x3d, 0xbc, 0xf5, 0x94, 0x6b, 0x05, + 0x85, 0x6c, 0x52, 0xde, 0x08, 0x1f, 0xc6, 0x15, 0x86, 0x01, 0xdc, 0x0b, 0xf8, 0xda, 0x7f, 0xe8, + 0xa7, 0xd9, 0x2a, 0x5e, 0x50, 0xa9, 0x13, 0x1c, 0x8e, 0x51, 0xe9, 0x98, 0x18, 0x79, 0x36, 0xef, + 0x51, 0x53, 0xbb, 0xea, 0xa9, 0xab, 0x02, 0x6a, 0xc5, 0x66, 0x50, 0xf8, 0xed, 0x2c, 0xfc, 0x6f, + 0xa9, 0x55, 0x3c, 0xd1, 0xcd, 0xce, 0xdb, 0x81, 0xb2, 0xa5, 0xd0, 0xde, 0xf6, 0xcf, 0x7f, 0x7a, + 0x66, 0x04, 0x3f, 0x48, 0xc3, 0x5e, 0x0a, 0x7f, 0xfa, 0xa9, 0x7c, 0xab, 0xb0, 0x21, 0x9d, 0xf5, + 0x90, 0x25, 0xa5, 0x39, 0x90, 0x28, 0x30, 0xef, 0xb7, 0x31, 0x5f, 0x35, 0x6b, 0xb4, 0x9f, 0x54, + 0x0a, 0x7f, 0x74, 0x84, 0xff, 0x88, 0x45, 0xb6, 0xe0, 0xf8, 0x41, 0x47, 0x6d, 0xca, 0x2f, 0x99, + 0x1f, 0xbe, 0x97, 0x4e, 0xfc, 0x50, 0x42, 0x54, 0xb8, 0x57, 0x0e, 0xfb, 0x24, 0x6b, 0xb5, 0x8b, + 0xbe, 0x64, 0xd8, 0x47, 0x0d, 0xdd, 0xb1, 0xd8, 0x4c, 0x6f, 0x8d, 0x0e, 0x68, 0xa9, 0xe4, 0xd4, + 0xe6, 0x5a, 0x5f, 0x54, 0x0f, 0xf7, 0xcf, 0x21, 0x15, 0x77, 0xdc, 0x54, 0x83, 0xb9, 0x2e, 0x40, + 0x5b, 0xf1, 0x7a, 0x8a, 0xb5, 0x38, 0x35, 0x7b, 0x4e, 0xdb, 0xee, 0xa8, 0x2d, 0x37, 0x9f, 0x3d, + 0x19, 0x0e, 0x71, 0xaa, 0x9c, 0x26, 0x91, 0x6d, 0x47, 0x87, 0xf4, 0x6c, 0x77, 0x53, 0x6b, 0xa3, + 0xaa, 0x4c, 0xda, 0x78, 0xb0, 0x89, 0xec, 0xd0, 0x6a, 0xe7, 0xe8, 0x47, 0x2e, 0xbd, 0xe3, 0x15, + 0xa2, 0x28, 0x7b, 0x0f, 0x5f, 0xec, 0x68, 0xa2, 0x51, 0x3d, 0x14, 0x78, 0xd6, 0xce, 0xbf, 0x58, + 0xec, 0xfa, 0x0f, 0x61, 0xe1, 0x03, 0xe8, 0x5c, 0xf6, 0x1e, 0x3c, 0xbc, 0xad, 0x66, 0x1f, 0x6e, + 0xe3, 0xe0, 0x2a, 0x9c, 0x20, 0x05, 0x71, 0x41, 0x4e, 0x45, 0x5c, 0xd1, 0x6c, 0xed, 0xaa, 0x7b, + 0x72, 0x62, 0x35, 0xa6, 0xc8, 0x25, 0xfd, 0xea, 0x0d, 0x45, 0x7a, 0x38, 0xee, 0x50, 0xce, 0xeb, + 0x4e, 0x04, 0x5a, 0x09, 0x62, 0x86, 0x54, 0xda, 0x72, 0x5c, 0xf3, 0x30, 0x57, 0xba, 0x9e, 0x3b, + 0xce, 0xeb, 0x80, 0x0e, 0x2c, 0xc1, 0x21, 0x5f, 0x76, 0x4b, 0x38, 0xbc, 0x53, 0x09, 0x4e, 0x1b, + 0x7f, 0x22, 0x0e, 0x87, 0x7a, 0xa6, 0x60, 0xd9, 0xa9, 0x89, 0xc6, 0x8c, 0x33, 0xf0, 0x9e, 0x88, + 0xa9, 0xc0, 0xb8, 0xaa, 0xcd, 0x8a, 0xf7, 0x3a, 0xf6, 0x4f, 0xac, 0x7a, 0x68, 0xe5, 0xdc, 0x3c, + 0xb7, 0x69, 0x56, 0x81, 0x59, 0x39, 0x37, 0x12, 0x1b, 0x5a, 0xc0, 0x38, 0x2f, 0xf6, 0x74, 0x23, + 0x07, 0xb4, 0xa3, 0xf7, 0x86, 0x4e, 0xcc, 0x60, 0xdd, 0xaf, 0x91, 0x4c, 0xed, 0xd5, 0xd9, 0x65, + 0x58, 0x66, 0x14, 0x64, 0x04, 0xd0, 0x16, 0x2b, 0x74, 0xde, 0xc5, 0x01, 0x5e, 0x6f, 0xe1, 0xe7, + 0x53, 0xd7, 0x79, 0xa8, 0x53, 0x66, 0x5b, 0x4a, 0xe8, 0x00, 0x3c, 0xa4, 0xdb, 0x0a, 0x67, 0x8c, + 0xb2, 0x2c, 0x67, 0x93, 0x8d, 0xaa, 0x28, 0x89, 0xc6, 0x91, 0xe3, 0x0f, 0x45, 0x57, 0x16, 0xc2, + 0x0d, 0x07, 0x8b, 0xaa, 0xaa, 0xf0, 0x63, 0xdb, 0x52, 0x3f, 0xc7, 0x4d, 0xfe, 0x4b, 0xe1, 0xf5, + 0xb2, 0x70, 0x7c, 0xcb, 0xce, 0x75, 0xb4, 0x4f, 0xdc, 0x32, 0xa7, 0xd2, 0x6a, 0x3c, 0xd0, 0x0c, + 0x19, 0x9e, 0x5f, 0xf2, 0x5d, 0xb6, 0x96, 0x73, 0x59, 0x6a, 0x09, 0x65, 0x98, 0x53, 0x56, 0x6a, + 0x71, 0xa3, 0x2b, 0xdf, 0xbc, 0xda, 0x53, 0xec, 0xf5, 0xa4, 0x12, 0xad, 0x02, 0x42, 0x73, 0x31, + 0xd7, 0x6e, 0x25, 0x07, 0xf6, 0xd5, 0x8b, 0xb2, 0xac, 0x27, 0xdb, 0x85, 0xaf, 0xed, 0xcb, 0x4b, + 0x71, 0x81, 0x1d, 0x4e, 0x0a, 0x6f, 0x1c, 0x8d, 0x73, 0xb9, 0x45, 0x6d, 0xbc, 0xab, 0x0a, 0x17, + 0xa1, 0x36, 0x5c, 0x45, 0xf3, 0xa1, 0x0a, 0x57, 0x31, 0xb6, 0x51, 0xee, 0xa0, 0x62, 0xac, 0xb0, + 0x2a, 0x82, 0x72, 0x06, 0x90, 0x92, 0x03, 0x4b, 0x2d, 0x55, 0x4f, 0x73, 0xa1, 0xd3, 0xc8, 0xc9, + 0x97, 0x67, 0xa3, 0x1e, 0x1b, 0x05, 0x1a, 0xa8, 0x69, 0x18, 0xae, 0xa9, 0x63, 0xdf, 0xc8, 0xf2, + 0xa7, 0xa6, 0x70, 0xcd, 0xdb, 0x6a, 0x20, 0xef, 0x47, 0x52, 0x42, 0xfc, 0xb1, 0x3c, 0xaa, 0x52, + 0xa9, 0xf5, 0xe4, 0x77, 0x29, 0x0c, 0xfd, 0xe9, 0xc3, 0x5a, 0x3c, 0xde, 0x7e, 0xb4, 0xbd, 0x6d, + 0xd6, 0xd3, 0x97, 0x9e, 0xe5, 0xeb, 0x19, 0x0e, 0x55, 0x81, 0xad, 0x02, 0x73, 0x88, 0xc6, 0xea, + 0x49, 0x55, 0xb8, 0xd3, 0x1f, 0xaa, 0x21, 0xbd, 0x07, 0x49, 0xc8, 0x77, 0xac, 0x02, 0x4e, 0x7e, + 0x9f, 0x9d, 0x98, 0x5a, 0x7b, 0x1d, 0xaf, 0x27, 0xbf, 0xea, 0xd3, 0xce, 0x1b, 0x67, 0x5b, 0x46, + 0x40, 0xe0, 0x8a, 0x14, 0xff, 0x58, 0x6d, 0xef, 0x92, 0xeb, 0xff, 0x05, 0x15, 0xdd, 0xcc, 0x5e, + 0xe4, 0x36, 0x01, 0x00, }; diff --git a/wled00/json.cpp b/wled00/json.cpp index 8e781fc82..61e76a650 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -293,7 +293,7 @@ void serializeInfo(JsonObject root) { root["ver"] = versionString; root["vid"] = VERSION; - root["cn"] = WLED_CODENAME; + //root["cn"] = WLED_CODENAME; JsonObject leds = root.createNestedObject("leds"); leds["count"] = ledCount; diff --git a/wled00/wled.h b/wled00/wled.h index f3ffe7800..66b8d495b 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2004300 +#define VERSION 2005010 // ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). From df1f516f6b6aaeb52e681062822fb601199cad8d Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sun, 3 May 2020 01:48:23 +0200 Subject: [PATCH 167/509] Added ACST and ACST/ACDT timezones ( closes #881 ) --- CHANGELOG.md | 4 ++++ wled00/html_settings.h | 2 ++ wled00/ntp.cpp | 7 ++++++- wled00/wled.h | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d79564271..128d5525c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ### Development versions after 0.9.1 release +#### Build 2005020 + +- Added ACST and ACST/ACDT timezones + #### Build 2005010 - Added module info page to web UI diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 1e6db0d03..d3b78d4d5 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -384,6 +384,8 @@ Time zone: + +
UTC offset: seconds (max. 18 hours)
Current local time is unknown. diff --git a/wled00/ntp.cpp b/wled00/ntp.cpp index d6332fd2c..4836ed344 100644 --- a/wled00/ntp.cpp +++ b/wled00/ntp.cpp @@ -60,8 +60,13 @@ Timezone tzNK(NKST, NKST); TimeChangeRule IST = {Last, Sun, Mar, 1, 330}; // India Standard Time = UTC + 5.5 hours Timezone tzIndia(IST, IST); +TimeChangeRule ACST = {First, Sun, Apr, 3, 570}; //Australian Central Standard = UTC + 9.5 hours +TimeChangeRule ACDT = {First, Sun, Oct, 2, 630}; //Australian Central Daylight = UTC + 10.5 hours +Timezone tzAUNorthern(ACST, ACST); +Timezone tzAUSouthern(ACDT, ACST); + // Pick your timezone from here. -Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia, &tzCASaskatchewan}; +Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia, &tzCASaskatchewan, &tzAUNorthern, &tzAUSouthern}; void handleNetworkTime() { diff --git a/wled00/wled.h b/wled00/wled.h index 66b8d495b..1a04b3e5e 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2005010 +#define VERSION 2005020 // ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). From 71886c162b7df2ce027b32c0334b83152e39884c Mon Sep 17 00:00:00 2001 From: cschwinne Date: Sun, 3 May 2020 20:57:53 +0200 Subject: [PATCH 168/509] Release of WLED v0.10.0 DMX Single RGW and Single DRGB modes now support an additional white channel Improved palettes derived from set colors and changed their names --- CHANGELOG.md | 9 ++++++++- platformio.ini | 2 +- wled00/FX.h | 2 +- wled00/FX_fcn.cpp | 26 +++++++++++++------------- wled00/data/index.htm | 2 +- wled00/data/settings_sec.htm | 2 +- wled00/e131.cpp | 7 +++++-- wled00/html_other.h | 2 +- wled00/html_settings.h | 2 +- wled00/wled.h | 6 +++--- 10 files changed, 35 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 128d5525c..dadc3c20a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ ## WLED changelog -### Development versions after 0.9.1 release +### WLED version 0.10.0 + +#### Build 2005030 + +- DMX Single RGW and Single DRGB modes now support an additional white channel +- Improved palettes derived from set colors and changed their names + +### Development versions between 0.9.1 and 0.10.0 release #### Build 2005020 diff --git a/platformio.ini b/platformio.ini index 2075a7db9..492799df2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -183,7 +183,7 @@ build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA -D WLED_DISABLE_ board = esp01_1m platform = ${common.platform_latest} board_build.ldscript = ${common.ldscript_1m0m} -build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED +build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED [env:esp01_1m_full] board = esp01_1m diff --git a/wled00/FX.h b/wled00/FX.h index 7022fede4..c690a4e50 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -672,7 +672,7 @@ const char JSON_mode_names[] PROGMEM = R"=====([ const char JSON_palette_names[] PROGMEM = R"=====([ -"Default","Random Cycle","Primary Color","Based on Primary","Set Colors","Based on Set","Party","Cloud","Lava","Ocean", +"Default","* Random Cycle","* Color 1","* Colors 1&2","* Color Gradient","* Colors Only","Party","Cloud","Lava","Ocean", "Forest","Rainbow","Rainbow Bands","Sunset","Rivendell","Breeze","Red & Blue","Yellowout","Analogous","Splash", "Pastel","Sunset 2","Beech","Vintage","Departure","Landscape","Beach","Sherbet","Hult","Hult 64", "Drywet","Jul","Grintage","Rewhi","Tertiary","Fire","Icefire","Cyane","Light Pink","Autumn", diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index e25ffb0ca..25e460e2a 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -743,25 +743,25 @@ void WS2812FX::handle_palette(void) case 2: {//primary color only CRGB prim = col_to_crgb(SEGCOLOR(0)); targetPalette = CRGBPalette16(prim); break;} - case 3: {//based on primary - //considering performance implications - CRGB prim = col_to_crgb(SEGCOLOR(0)); - CHSV prim_hsv = rgb2hsv_approximate(prim); - targetPalette = CRGBPalette16( - CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v), //color itself - CHSV(prim_hsv.h, MAX(prim_hsv.s - 50,0), prim_hsv.v), //less saturated - CHSV(prim_hsv.h, prim_hsv.s, MAX(prim_hsv.v - 50,0)), //darker - CHSV(prim_hsv.h, prim_hsv.s, prim_hsv.v)); //color itself - break;} - case 4: {//primary + secondary + case 3: {//primary + secondary CRGB prim = col_to_crgb(SEGCOLOR(0)); CRGB sec = col_to_crgb(SEGCOLOR(1)); - targetPalette = CRGBPalette16(sec,prim); break;} - case 5: {//based on primary + secondary + targetPalette = CRGBPalette16(prim,prim,sec,sec); break;} + case 4: {//primary + secondary + tertiary CRGB prim = col_to_crgb(SEGCOLOR(0)); CRGB sec = col_to_crgb(SEGCOLOR(1)); CRGB ter = col_to_crgb(SEGCOLOR(2)); targetPalette = CRGBPalette16(ter,sec,prim); break;} + case 5: {//primary + secondary (+tert if not off), more distinct + CRGB prim = col_to_crgb(SEGCOLOR(0)); + CRGB sec = col_to_crgb(SEGCOLOR(1)); + if (SEGCOLOR(2)) { + CRGB ter = col_to_crgb(SEGCOLOR(2)); + targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,ter,ter,ter,ter,ter,prim); + } else { + targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,sec,sec,sec); + } + break;} case 6: //Party colors targetPalette = PartyColors_p; break; case 7: //Cloud colors diff --git a/wled00/data/index.htm b/wled00/data/index.htm index e4c877790..9bf3de6b3 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -950,7 +950,7 @@ input[type=number]::-webkit-outer-spin-button {

-Made with by Aircoookie and the WLED community +Made with by Aircoookie and the WLED community

OKghv!PvB=#*P@(BkfP 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 Date: Sat, 18 Jan 2020 16:09:39 -0500 Subject: [PATCH 008/509] Update readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md index 4466821bc..0634f9a3b 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md @@ -1,9 +1,9 @@ # Enclosure and PCB ## IP67 rated enclosure -![Enclosure](assets/controller.jpg) +![Enclosure](controller.jpg) ## PCB -![PCB](assets/controller.jpg) +![PCB](controller.jpg) ``` ``` From 761245049f8c0e1ddec394d631cf171419af66dd Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:10:03 -0500 Subject: [PATCH 009/509] Update readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md index 0634f9a3b..43331df7f 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md @@ -4,6 +4,6 @@ ![Enclosure](controller.jpg) ## PCB -![PCB](controller.jpg) +![PCB](pcb.png) ``` ``` From b00c1dd0556ad426ba8b03ab2313d908afdd0bf1 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:14:32 -0500 Subject: [PATCH 010/509] Update readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index 2541e6955..69cd8e96e 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -2,7 +2,10 @@ This usermod is using ideas from @mrVanboy and @400killer ## Features - SSD1306 128x32 and 128x64 I2C OLED display (optional) +- On screen IP address and controller status (e.g. ON or OFF, recent effect) +- Auto display shutoff for saving display lifetime - Dallas temperature sensor (optional) +- Reporting temperature to MQTT broker ## Hardware ![Hardware connection](assets/controller.jpg) From 40c041c9e77c8895b77e66cc0a69acae753b54dd Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:15:37 -0500 Subject: [PATCH 011/509] Update readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index 69cd8e96e..5476fa19f 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -2,7 +2,7 @@ This usermod is using ideas from @mrVanboy and @400killer ## Features - SSD1306 128x32 and 128x64 I2C OLED display (optional) -- On screen IP address and controller status (e.g. ON or OFF, recent effect) +- On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) - Auto display shutoff for saving display lifetime - Dallas temperature sensor (optional) - Reporting temperature to MQTT broker From 2fc2a0cbdba9e06654a1409003da3d77f5bbadee Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:16:51 -0500 Subject: [PATCH 012/509] Update readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index 5476fa19f..c4dbbcfc5 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -10,8 +10,8 @@ This usermod is using ideas from @mrVanboy and @400killer ## Hardware ![Hardware connection](assets/controller.jpg) -## Requirements -Functionality checked with: +## Functionality +checked with: - ESP-07S - PlatformIO - SSD1306 128x32 I2C OLED display @@ -19,7 +19,7 @@ Functionality checked with: - KY-022 (infrared receiver) - Push button (N.O. momentary switch) -### Platformio +### Platformio requirements Uncomment `U8g2@~2.27.3`,`DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`: ```ini # platformio.ini From 9a9d2cb964e810d86f3335ba6492b33551b67521 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:17:45 -0500 Subject: [PATCH 013/509] Update readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index c4dbbcfc5..0bf8653bd 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -1,10 +1,10 @@ # Almost universal controller board for outdoor applications This usermod is using ideas from @mrVanboy and @400killer ## Features -- SSD1306 128x32 and 128x64 I2C OLED display (optional) +- SSD1306 128x32 and 128x64 I2C OLED display - On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) - Auto display shutoff for saving display lifetime -- Dallas temperature sensor (optional) +- Dallas temperature sensor - Reporting temperature to MQTT broker ## Hardware From 8831d74cbc03ea998e715e54544818b74d97019c Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 16:29:28 -0500 Subject: [PATCH 014/509] Update readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md index 43331df7f..4d1005d9c 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/assets/readme.md @@ -5,5 +5,3 @@ ## PCB ![PCB](pcb.png) -``` -``` From 43e0186efe6013f883ae56cca540bd09aca2a7f2 Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Sat, 18 Jan 2020 16:46:48 -0500 Subject: [PATCH 015/509] Update readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index 0bf8653bd..13cee46b6 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -10,8 +10,7 @@ This usermod is using ideas from @mrVanboy and @400killer ## Hardware ![Hardware connection](assets/controller.jpg) -## Functionality -checked with: +## Functionality checked with: - ESP-07S - PlatformIO - SSD1306 128x32 I2C OLED display From 57c0b408e5bb104e40affd988361caa872cf4e04 Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Sat, 18 Jan 2020 17:26:06 -0500 Subject: [PATCH 016/509] Update readme.md --- .../Enclosure_with_OLED_temp_ESP07/readme.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index 13cee46b6..aabf65e0d 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -1,22 +1,22 @@ # Almost universal controller board for outdoor applications This usermod is using ideas from @mrVanboy and @400killer ## Features -- SSD1306 128x32 and 128x64 I2C OLED display -- On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) -- Auto display shutoff for saving display lifetime -- Dallas temperature sensor -- Reporting temperature to MQTT broker +* SSD1306 128x32 and 128x64 I2C OLED display +* On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) +* Auto display shutoff for saving display lifetime +* Dallas temperature sensor +* Reporting temperature to MQTT broker ## Hardware ![Hardware connection](assets/controller.jpg) ## Functionality checked with: -- ESP-07S -- PlatformIO -- SSD1306 128x32 I2C OLED display -- DS18B20 (temperature sensor) -- KY-022 (infrared receiver) -- Push button (N.O. momentary switch) +* ESP-07S +* PlatformIO +* SSD1306 128x32 I2C OLED display +* DS18B20 (temperature sensor) +* KY-022 (infrared receiver) +* Push button (N.O. momentary switch) ### Platformio requirements Uncomment `U8g2@~2.27.3`,`DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`: @@ -33,4 +33,4 @@ lib_deps_external = DallasTemperature@~3.8.0 OneWire@~2.3.5 ... -``` +``` \ No newline at end of file From 1d897e491a9d25180cfc98d5e9da73d733f84834 Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Sat, 18 Jan 2020 17:31:36 -0500 Subject: [PATCH 017/509] Update readme.md --- .../Enclosure_with_OLED_temp_ESP07/readme.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index aabf65e0d..8a20dc1ba 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -1,22 +1,22 @@ # Almost universal controller board for outdoor applications This usermod is using ideas from @mrVanboy and @400killer ## Features -* SSD1306 128x32 and 128x64 I2C OLED display -* On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) -* Auto display shutoff for saving display lifetime -* Dallas temperature sensor -* Reporting temperature to MQTT broker +* SSD1306 128x32 and 128x64 I2C OLED display +* On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) +* Auto display shutoff for saving display lifetime +* Dallas temperature sensor +* Reporting temperature to MQTT broker ## Hardware ![Hardware connection](assets/controller.jpg) ## Functionality checked with: -* ESP-07S -* PlatformIO -* SSD1306 128x32 I2C OLED display -* DS18B20 (temperature sensor) -* KY-022 (infrared receiver) -* Push button (N.O. momentary switch) +* ESP-07S +* PlatformIO +* SSD1306 128x32 I2C OLED display +* DS18B20 (temperature sensor) +* KY-022 (infrared receiver) +* Push button (N.O. momentary switch) ### Platformio requirements Uncomment `U8g2@~2.27.3`,`DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`: From 71021da2619061c72ac286ad7dcd803ca87557ad Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Sat, 18 Jan 2020 17:36:04 -0500 Subject: [PATCH 018/509] Update readme.md --- .../Enclosure_with_OLED_temp_ESP07/readme.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index 8a20dc1ba..c8c873529 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -1,22 +1,22 @@ # Almost universal controller board for outdoor applications This usermod is using ideas from @mrVanboy and @400killer ## Features -* SSD1306 128x32 and 128x64 I2C OLED display -* On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) -* Auto display shutoff for saving display lifetime -* Dallas temperature sensor -* Reporting temperature to MQTT broker +* SSD1306 128x32 and 128x64 I2C OLED display +* On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) +* Auto display shutoff for saving display lifetime +* Dallas temperature sensor +* Reporting temperature to MQTT broker ## Hardware ![Hardware connection](assets/controller.jpg) ## Functionality checked with: -* ESP-07S -* PlatformIO -* SSD1306 128x32 I2C OLED display -* DS18B20 (temperature sensor) -* KY-022 (infrared receiver) -* Push button (N.O. momentary switch) +* ESP-07S +* PlatformIO +* SSD1306 128x32 I2C OLED display +* DS18B20 (temperature sensor) +* KY-022 (infrared receiver) +* Push button (N.O. momentary switch) ### Platformio requirements Uncomment `U8g2@~2.27.3`,`DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`: From 0cae048ada14931162d7536f65acddb9db96571d Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 17:40:52 -0500 Subject: [PATCH 019/509] Update readme.md --- .../Enclosure_with_OLED_temp_ESP07/readme.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index c8c873529..10894266b 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -1,22 +1,22 @@ # Almost universal controller board for outdoor applications This usermod is using ideas from @mrVanboy and @400killer ## Features -* SSD1306 128x32 and 128x64 I2C OLED display -* On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) -* Auto display shutoff for saving display lifetime -* Dallas temperature sensor -* Reporting temperature to MQTT broker +* SSD1306 128x32 and 128x64 I2C OLED display +* On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) +* Auto display shutoff for saving display lifetime +* Dallas temperature sensor +* Reporting temperature to MQTT broker ## Hardware ![Hardware connection](assets/controller.jpg) ## Functionality checked with: -* ESP-07S -* PlatformIO -* SSD1306 128x32 I2C OLED display -* DS18B20 (temperature sensor) -* KY-022 (infrared receiver) -* Push button (N.O. momentary switch) +* ESP-07S +* PlatformIO +* SSD1306 128x32 I2C OLED display +* DS18B20 (temperature sensor) +* KY-022 (infrared receiver) +* Push button (N.O. momentary switch) ### Platformio requirements Uncomment `U8g2@~2.27.3`,`DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`: @@ -33,4 +33,4 @@ lib_deps_external = DallasTemperature@~3.8.0 OneWire@~2.3.5 ... -``` \ No newline at end of file +``` From 71af63dfc71ea17f1bef9176d6032ea826c320a3 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 17:45:11 -0500 Subject: [PATCH 020/509] Update readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index 10894266b..598c0c0a3 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -10,7 +10,7 @@ This usermod is using ideas from @mrVanboy and @400killer ## Hardware ![Hardware connection](assets/controller.jpg) -## Functionality checked with: +## Functionality checked with * ESP-07S * PlatformIO * SSD1306 128x32 I2C OLED display From 4d646e67f3d0362d5e0d99775dfee211ad1e5fe3 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 20:03:18 -0500 Subject: [PATCH 021/509] Create ccpp.yml --- .github/workflows/ccpp.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/ccpp.yml diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml new file mode 100644 index 000000000..1247fb050 --- /dev/null +++ b/.github/workflows/ccpp.yml @@ -0,0 +1,19 @@ +name: C/C++ CI + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: configure + run: ./configure + - name: make + run: make + - name: make check + run: make check + - name: make distcheck + run: make distcheck From 1c5742c7d402109bd7ad07a6deabe2fa842e8de8 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 20:04:15 -0500 Subject: [PATCH 022/509] Delete ccpp.yml --- .github/workflows/ccpp.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/ccpp.yml diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml deleted file mode 100644 index 1247fb050..000000000 --- a/.github/workflows/ccpp.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: C/C++ CI - -on: [push] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v1 - - name: configure - run: ./configure - - name: make - run: make - - name: make check - run: make check - - name: make distcheck - run: make distcheck From 81aab35231e1380d03ebfb99aacda76533133556 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 20:22:44 -0500 Subject: [PATCH 023/509] Create main.yml --- .github/workflows/main.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..c4a9ef92b --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,9 @@ +name: Test +on: push +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Build all example sketches + uses: antimatter15/esp8266-arduino-builder-action@v4.0.0 From 1042ac141a96a5eec039611ca141e3a6bc4d39f1 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sat, 18 Jan 2020 20:27:35 -0500 Subject: [PATCH 024/509] Delete main.yml --- .github/workflows/main.yml | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index c4a9ef92b..000000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: Test -on: push -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Build all example sketches - uses: antimatter15/esp8266-arduino-builder-action@v4.0.0 From 38b2adcaadda3fc7da64166c49b84bcfa1cd3aea Mon Sep 17 00:00:00 2001 From: srg74 Date: Sun, 19 Jan 2020 18:53:11 -0500 Subject: [PATCH 025/509] Fixed wled06_usermod.ino And added link to readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/readme.md | 2 ++ .../Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino | 8 +------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index 598c0c0a3..047647d09 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -1,5 +1,7 @@ # Almost universal controller board for outdoor applications This usermod is using ideas from @mrVanboy and @400killer +## Firmware used +- [Original project repository](https://github.com/srg74/Controller-for-WLED-firmware) - Main controller repository ## Features * SSD1306 128x32 and 128x64 I2C OLED display * On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino b/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino index b3f1c5db5..31bba9e67 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino +++ b/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino @@ -17,15 +17,9 @@ long lastMeasure = 0; // or check the gallery: // https://github.com/olikraus/u8g2/wiki/gallery // --> First choise of cheap I2C OLED 128X32 -<<<<<<< HEAD U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA // --> Second choise of cheap I2C OLED 128X64 //U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA -======= -//U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA -// --> Second choise of cheap I2C OLED 128X64 -U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA ->>>>>>> 1680c014057bb993974950f37b14369b398ca647 // gets called once at boot. Do all initialization that doesn't depend on // network here void userSetup() { @@ -209,4 +203,4 @@ void userLoop() { u8x8.drawGlyph(0, 1, 68); // home icon u8x8.setFont(u8x8_font_open_iconic_weather_2x2); u8x8.drawGlyph(0, 2, 66 + (bri > 0 ? 3 : 0)); // sun/moon icon -} +} \ No newline at end of file From 607a66b983fb3bb0967d713d74f612d678e47ce8 Mon Sep 17 00:00:00 2001 From: srg74 <28492985+srg74@users.noreply.github.com> Date: Sun, 19 Jan 2020 18:54:48 -0500 Subject: [PATCH 026/509] Update readme.md --- usermods/Enclosure_with_OLED_temp_ESP07/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index 047647d09..4af36d59c 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -1,7 +1,7 @@ # Almost universal controller board for outdoor applications This usermod is using ideas from @mrVanboy and @400killer -## Firmware used -- [Original project repository](https://github.com/srg74/Controller-for-WLED-firmware) - Main controller repository +## Project repository +- [Original repository](https://github.com/srg74/Controller-for-WLED-firmware) - Main controller repository ## Features * SSD1306 128x32 and 128x64 I2C OLED display * On screen IP address, SSID and controller status (e.g. ON or OFF, recent effect) From b58a17a99e612ea303d8bf678079c3f7c77e6e3f Mon Sep 17 00:00:00 2001 From: srg74 Date: Mon, 20 Jan 2020 15:28:39 -0500 Subject: [PATCH 027/509] Display size is irrelevant --- usermods/Enclosure_with_OLED_temp_ESP07/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md index 4af36d59c..817fb7e4a 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/readme.md +++ b/usermods/Enclosure_with_OLED_temp_ESP07/readme.md @@ -29,7 +29,7 @@ Uncomment `U8g2@~2.27.3`,`DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[com ... lib_deps_external = ... - #For use SSD1306 0.91" OLED display uncomment following + #For use SSD1306 OLED display uncomment following U8g2@~2.27.3 #For Dallas sensor uncomment following 2 lines DallasTemperature@~3.8.0 From 3d0d027216b1ea0ec988bd587db038a682daafd8 Mon Sep 17 00:00:00 2001 From: srg74 Date: Fri, 24 Jan 2020 16:52:41 -0500 Subject: [PATCH 028/509] Update platformio.ini --- platformio.ini | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/platformio.ini b/platformio.ini index efd1bfe82..c382f9243 100644 --- a/platformio.ini +++ b/platformio.ini @@ -7,15 +7,15 @@ data_dir = ./wled00/data ;lib_extra_dirs = ./wled00/src lib_dir = ./wled00/src ; Please uncomment one of the 5 lines below to select your board -env_default = nodemcuv2 -; env_default = esp01 -; env_default = esp01_1m -; env_default = esp07 -; env_default = d1_mini -; env_default = esp32dev -; env_default = esp8285_4CH_MagicHome -; env_default = esp8285_4CH_H801 -; env_default = esp8285_5CH_H801 +default_envs = nodemcuv2 +; default_envs = esp01 +; default_envs = esp01_1m +; default_envs = esp07 +; default_envs = d1_mini +; default_envs = esp32dev +; default_envs = esp8285_4CH_MagicHome +; default_envs = esp8285_4CH_H801 +; default_envs = esp8285_5CH_H801 [common] framework = arduino From 47738c751cfc97ed80d7a02b52628e590e83b481 Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Wed, 5 Feb 2020 12:03:24 -0500 Subject: [PATCH 029/509] Update wled06_usermod.ino Controller design changed. New version with relay. Dallas sensor pin changed to GPIO 13. --- usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino b/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino index 31bba9e67..cfd94a872 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino +++ b/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino @@ -5,7 +5,7 @@ #define U8X8_PIN_SCL 5 #define U8X8_PIN_SDA 4 // Dallas sensor -OneWire oneWire(12); +OneWire oneWire(13); DallasTemperature sensor(&oneWire); long temptimer = millis(); long lastMeasure = 0; From f105436b41a1577f22b4ad09c1912670a55c09d8 Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Wed, 5 Feb 2020 12:23:06 -0500 Subject: [PATCH 030/509] Corrected comment Since 2 common size of OLED display can be used (0.91" and 0.96") removed comment about display size --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index c382f9243..842009550 100644 --- a/platformio.ini +++ b/platformio.ini @@ -51,7 +51,7 @@ lib_deps_external = https://github.com/crankyoldgit/IRremoteESP8266.git #Time@1.5 #Timezone@1.2.1 - #For use SSD1306 0.91" OLED display uncomment following + #For use SSD1306 OLED display uncomment following #U8g2@~2.27.2 #For Dallas sensor uncomment following 2 lines #DallasTemperature@~3.8.0 From adcd7fb1700b88059adc1d8931473087c5fe0ae3 Mon Sep 17 00:00:00 2001 From: Ser Ko Date: Wed, 5 Feb 2020 12:25:26 -0500 Subject: [PATCH 031/509] Added tested display sizes --- usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino b/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino index cfd94a872..2c55a9526 100644 --- a/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino +++ b/usermods/Enclosure_with_OLED_temp_ESP07/wled06_usermod.ino @@ -16,9 +16,9 @@ long lastMeasure = 0; // https://github.com/olikraus/u8g2/wiki/u8x8setupcpp // or check the gallery: // https://github.com/olikraus/u8g2/wiki/gallery -// --> First choise of cheap I2C OLED 128X32 +// --> First choise of cheap I2C OLED 128X32 0.91" U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA -// --> Second choise of cheap I2C OLED 128X64 +// --> Second choise of cheap I2C OLED 128X64 0.96" or 1.3" //U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(U8X8_PIN_NONE, U8X8_PIN_SCL, U8X8_PIN_SDA); // Pins are Reset, SCL, SDA // gets called once at boot. Do all initialization that doesn't depend on // network here From 05f5aaaeca5628197cd65c7da5f076bf594a490e Mon Sep 17 00:00:00 2001 From: cschwinne Date: Wed, 19 Feb 2020 15:53:42 +0100 Subject: [PATCH 032/509] Refactoring --- wled00/const.h | 26 ++++++++++++++++++++++++++ wled00/wled00.ino | 23 ++++++----------------- wled00/wled05_init.ino | 10 +++++----- 3 files changed, 37 insertions(+), 22 deletions(-) create mode 100644 wled00/const.h diff --git a/wled00/const.h b/wled00/const.h new file mode 100644 index 000000000..15345c7ca --- /dev/null +++ b/wled00/const.h @@ -0,0 +1,26 @@ +#ifndef wled_const_h +#define wled_const_h + +//Access point behavior +#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot +#define AP_BEHAVIOR_NO_CONN 1 //Open when no connection +#define AP_BEHAVIOR_ALWAYS 2 //Always open +#define AP_BEHAVIOR_BUTTON_ONLY 3 //Only when button pressed for 6 sec + +//realtime modes +#define REALTIME_MODE_INACTIVE 0 +#define REALTIME_MODE_GENERIC 1 +#define REALTIME_MODE_UDP 2 +#define REALTIME_MODE_HYPERION 3 +#define REALTIME_MODE_E131 4 +#define REALTIME_MODE_ADALIGHT 5 + +//E1.31 DMX modes +#define DMX_MODE_DISABLED 0 //not used +#define DMX_MODE_SINGLE_RGB 1 //all LEDs same RGB color (3 channels) +#define DMX_MODE_SINGLE_DRGB 2 //all LEDs same RGB color and master dimmer (4 channels) +#define DMX_MODE_EFFECT 3 //trigger standalone effects of WLED (11 channels) +#define DMX_MODE_MULTIPLE_RGB 4 //every LED is addressed with its own RGB (ledCount * 3 channels) +#define DMX_MODE_MULTIPLE_DRGB 5 //every LED is addressed with its own RGB and share a master dimmer (ledCount * 3 + 1 channels) + +#endif diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 89f08a5d2..6d0bae61b 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -75,6 +75,7 @@ #include "html_other.h" #include "FX.h" #include "ir_codes.h" +#include "const.h" #if IR_PIN < 0 @@ -90,7 +91,7 @@ #endif //version code in format yymmddb (b = daily build) -#define VERSION 2002181 +#define VERSION 2002191 char versionString[] = "0.9.1"; @@ -115,7 +116,7 @@ char cmDNS[33] = "x"; //mDNS address (placeholder, will char apSSID[33] = ""; //AP off by default (unless setup) byte apChannel = 1; //2.4GHz WiFi AP channel (1-13) byte apHide = 0; //hidden AP SSID -byte apBehavior = 0; //0: Open AP when no connection after boot 1: Open when no connection 2: Always open 3: Only when button pressed for 6 sec +byte apBehavior = AP_BEHAVIOR_BOOT_NO_CONN; //access point opens when no connection after boot by default IPAddress staticIP(0, 0, 0, 0); //static IP of ESP IPAddress staticGateway(0, 0, 0, 0); //gateway (router) IP IPAddress staticSubnet(255, 255, 255, 0); //most common subnet in home networks @@ -178,14 +179,8 @@ bool arlsDisableGammaCorrection = true; //activate if gamma correction is bool arlsForceMaxBri = false; //enable to force max brightness if source has very dark colors that would be black uint16_t e131Universe = 1; //settings for E1.31 (sACN) protocol (only DMX_MODE_MULTIPLE_* can span over consequtive universes) -#define DMX_MODE_DISABLED 0 //not used -#define DMX_MODE_SINGLE_RGB 1 //all LEDs same RGB color (3 channels) -#define DMX_MODE_SINGLE_DRGB 2 //all LEDs same RGB color and master dimmer (4 channels) -#define DMX_MODE_EFFECT 3 //trigger standalone effects of WLED (11 channels) -#define DMX_MODE_MULTIPLE_RGB 4 //every LED is addressed with its own RGB (ledCount * 3 channels) -#define DMX_MODE_MULTIPLE_DRGB 5 //every LED is addressed with its own RGB and share a master dimmer (ledCount * 3 + 1 channels) -uint8_t DMXMode; //DMX mode (s.a.) -uint16_t DMXAddress; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] +uint8_t DMXMode = DMX_MODE_MULTIPLE_RGB; //DMX mode (s.a.) +uint16_t DMXAddress = 1; //DMX start address of fixture, a.k.a. first Channel [for E1.31 (sACN) protocol] uint8_t DMXOldDimmer = 0; //only update brightness on change uint8_t e131LastSequenceNumber = 0; //to detect packet loss bool e131Multicast = false; //multicast or unicast @@ -362,13 +357,7 @@ bool presetApplyBri = false, presetApplyCol = true, presetApplyFx = true; bool saveCurrPresetCycConf = false; //realtime -#define REALTIME_MODE_INACTIVE 0 -#define REALTIME_MODE_GENERIC 1 -#define REALTIME_MODE_UDP 2 -#define REALTIME_MODE_HYPERION 3 -#define REALTIME_MODE_E131 4 -#define REALTIME_MODE_ADALIGHT 5 -byte realtimeMode = 0; +byte realtimeMode = REALTIME_MODE_INACTIVE; IPAddress realtimeIP = (0,0,0,0); unsigned long realtimeTimeout = 0; diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 0cc6ac7ec..b26358cb3 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -121,7 +121,7 @@ void beginStrip() void initAP(bool resetAP=false){ - if (apBehavior == 3 && !resetAP) return; + if (apBehavior == AP_BEHAVIOR_BUTTON_ONLY && !resetAP) return; if (!apSSID[0] || resetAP) strcpy(apSSID, "WLED-AP"); if (resetAP) strcpy(apPass,"wled1234"); @@ -172,7 +172,7 @@ void initConnection() if (!apActive) initAP(); //instantly go to ap mode return; } else if (!apActive) { - if (apBehavior == 2) + if (apBehavior == AP_BEHAVIOR_ALWAYS) { initAP(); } else @@ -246,7 +246,7 @@ uint32_t lastHeap; unsigned long heapTime = 0; void handleConnection() { - if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == 2)) return; + if (millis() < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) return; if (lastReconnectAttempt == 0) initConnection(); //reconnect WiFi to clear stale allocations if heap gets too low @@ -297,7 +297,7 @@ void handleConnection() { initConnection(); } if (millis() - lastReconnectAttempt > ((stac) ? 300000 : 20000) && WLED_WIFI_CONFIGURED) initConnection(); - if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == 1)) initAP(); + if (!apActive && millis() - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) initAP(); } else if (!interfacesInited) { //newly connected DEBUG_PRINTLN(""); DEBUG_PRINT("Connected! IP address: "); @@ -306,7 +306,7 @@ void handleConnection() { userConnected(); //shut down AP - if (apBehavior != 2 && apActive) + if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) { dnsServer.stop(); WiFi.softAPdisconnect(true); From d4c0542c84b6dd3a967cc2d2abf0bb227f81ec32 Mon Sep 17 00:00:00 2001 From: huggy-d1 Date: Wed, 19 Feb 2020 13:24:56 -0500 Subject: [PATCH 033/509] Update readme.md Minor spelling change --- usermods/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usermods/readme.md b/usermods/readme.md index 8cd2d486f..350212fb8 100644 --- a/usermods/readme.md +++ b/usermods/readme.md @@ -8,11 +8,11 @@ In order for other people to be able to have fun with your usermod, please keep - Create a folder in this folder with a descriptive name (for example `usermod_ds18b20_temp_sensor_mqtt`) - Include your custom `wled06_usermod.ino` file -- If your usermod requieres changes to other WLED files, please write a `readme.md` outlining the steps one has to take to use the usermod +- If your usermod requires changes to other WLED files, please write a `readme.md` outlining the steps one has to take to use the usermod - Create a pull request! - If your feature is useful for the majority of WLED users, I will consider adding it to the base code! While I do my best to not break too much, keep in mind that as WLED is being updated, usermods might break. I am not actively maintaining any usermod in this directory, that is your responsibility as the creator of the usermod. -Thank you for your help :) \ No newline at end of file +Thank you for your help :) From 65a32b4166832d8c627db1dc89fde995d17d9175 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Thu, 20 Feb 2020 00:45:09 +0100 Subject: [PATCH 034/509] Added new auto white modes (related to #573 ) --- wled00/FX.h | 4 +- wled00/FX_fcn.cpp | 21 +- wled00/const.h | 9 +- wled00/data/index.htm | 1970 ++++++++++++------------- wled00/html_settings.h | 10 +- wled00/html_ui.h | 2987 +++++++++++++++++++------------------- wled00/wled00.ino | 3 +- wled00/wled01_eeprom.ino | 4 +- wled00/wled02_xml.ino | 4 +- wled00/wled03_set.ino | 2 +- wled00/wled08_led.ino | 2 +- wled00/wled14_colors.ino | 2 +- wled00/wled19_json.ino | 2 +- 13 files changed, 2526 insertions(+), 2494 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index abfc11d31..9f1fda411 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -28,6 +28,7 @@ #define WS2812FX_h #include "NpbWrapper.h" +#include "const.h" #define FASTLED_INTERNAL //remove annoying pragma messages #include "FastLED.h" @@ -426,6 +427,7 @@ class WS2812FX { uint8_t mainSegment = 0, + rgbwMode = RGBW_MODE_DUAL, paletteFade = 0, paletteBlend = 0, colorOrder = 0, @@ -589,7 +591,7 @@ class WS2812FX { void fill(uint32_t); bool - _rgbwMode, + _useRgbw = false, _cronixieMode, _cronixieBacklightEnabled, _skipFirstMode, diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index c1ee11afa..73ddbf794 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -32,9 +32,9 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) { - if (supportWhite == _rgbwMode && countPixels == _length) return; + if (supportWhite == _useRgbw && countPixels == _length) return; RESET_RUNTIME; - _rgbwMode = supportWhite; + _useRgbw = supportWhite; _skipFirstMode = skipFirst; _length = countPixels; @@ -65,6 +65,7 @@ void WS2812FX::service() { { if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary { + if (SEGMENT.grouping == 0) SEGMENT.grouping = 1; //sanity check _virtualSegmentLength = SEGMENT.virtualLength(); doShow = true; handle_palette(); @@ -106,6 +107,20 @@ uint16_t WS2812FX::realPixelIndex(uint16_t i) { void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) { + //auto calculate white channel value if enabled + if (_useRgbw) { + if (rgbwMode == RGBW_MODE_AUTO_BRIGHTER || (w == 0 && (rgbwMode == RGBW_MODE_DUAL || rgbwMode == RGBW_MODE_LEGACY))) + { + //white value is set to lowest RGB channel + //thank you to @Def3nder! + w = r < g ? (r < b ? r : b) : (g < b ? g : b); + } else if (rgbwMode == RGBW_MODE_AUTO_ACCURATE && w == 0) + { + w = r < g ? (r < b ? r : b) : (g < b ? g : b); + r -= w; g -= w; b -= w; + } + } + RgbwColor col; switch (colorOrder) { @@ -256,7 +271,7 @@ void WS2812FX::show(void) { } - if (_rgbwMode) //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less + if (_useRgbw) //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less { powerSum *= 3; powerSum = powerSum >> 2; //same as /= 4 diff --git a/wled00/const.h b/wled00/const.h index 15345c7ca..1308bf5fe 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -3,10 +3,17 @@ //Access point behavior #define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot -#define AP_BEHAVIOR_NO_CONN 1 //Open when no connection +#define AP_BEHAVIOR_NO_CONN 1 //Open when no connection (either after boot or if connection is lost) #define AP_BEHAVIOR_ALWAYS 2 //Always open #define AP_BEHAVIOR_BUTTON_ONLY 3 //Only when button pressed for 6 sec +//RGB to RGBW conversion mode +#define RGBW_MODE_MANUAL_ONLY 0 //No automatic white channel calculation. Manual white channel slider +#define RGBW_MODE_AUTO_BRIGHTER 1 //New algorithm. Adds as much white as the darkest RGBW channel +#define RGBW_MODE_AUTO_ACCURATE 2 //New algorithm. Adds as much white as the darkest RGBW channel and subtracts this amount from each RGB channel +#define RGBW_MODE_DUAL 3 //Manual slider + auto calculation. Automatically calculates only if manual slider is set to off (0) +#define RGBW_MODE_LEGACY 4 //Old floating algorithm. Too slow for realtime and palette support + //realtime modes #define REALTIME_MODE_INACTIVE 0 #define REALTIME_MODE_GENERIC 1 diff --git a/wled00/data/index.htm b/wled00/data/index.htm index d9d1ccc95..3446f7ceb 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -1,668 +1,668 @@ - - - - - -WLED - + + + + + + WLED + @@ -672,144 +672,144 @@ display: none;