Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eda10b1cc3 | |||
| 359c7b31a9 | |||
| bbab062fad |
@@ -0,0 +1,6 @@
|
|||||||
|
[submodule "Arduino/McLighting/data/McLightingUI"]
|
||||||
|
path = Arduino/McLighting/data/McLightingUI
|
||||||
|
url = https://github.com/toblum/McLightingUI
|
||||||
|
[submodule "clients/web/McLightingUI"]
|
||||||
|
path = clients/web/McLightingUI
|
||||||
|
url = https://github.com/toblum/McLightingUI
|
||||||
+318
-235
@@ -1,8 +1,4 @@
|
|||||||
#include "definitions.h"
|
#include "definitions.h"
|
||||||
// ***************************************************************************
|
|
||||||
// Load library "ticker" for blinking status led, mqtt send and save state
|
|
||||||
// ***************************************************************************
|
|
||||||
#include <Ticker.h>
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
@@ -14,9 +10,13 @@
|
|||||||
#include <DNSServer.h>
|
#include <DNSServer.h>
|
||||||
#include <ESP8266WebServer.h>
|
#include <ESP8266WebServer.h>
|
||||||
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
|
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
|
||||||
#include <FS.h>
|
|
||||||
|
|
||||||
|
#include <WiFiClient.h>
|
||||||
#include <ESP8266mDNS.h>
|
#include <ESP8266mDNS.h>
|
||||||
|
#include <FS.h>
|
||||||
|
#if ENABLE_STATE_SAVE == 0
|
||||||
|
#include <EEPROM.h>
|
||||||
|
#endif
|
||||||
#include <WebSockets.h> //https://github.com/Links2004/arduinoWebSockets
|
#include <WebSockets.h> //https://github.com/Links2004/arduinoWebSockets
|
||||||
#include <WebSocketsServer.h>
|
#include <WebSocketsServer.h>
|
||||||
|
|
||||||
@@ -28,13 +28,14 @@
|
|||||||
GY33_MCU tcs;
|
GY33_MCU tcs;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
// MQTT
|
// MQTT
|
||||||
#if defined(ENABLE_MQTT)
|
#if defined(ENABLE_MQTT)
|
||||||
#if ENABLE_MQTT == 0
|
#if ENABLE_MQTT == 0
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Load libraries for PubSubClient
|
// Load libraries for PubSubClient
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#include <WiFiClient.h>
|
|
||||||
#include <PubSubClient.h>
|
#include <PubSubClient.h>
|
||||||
WiFiClient espClient;
|
WiFiClient espClient;
|
||||||
PubSubClient * mqtt_client;
|
PubSubClient * mqtt_client;
|
||||||
@@ -49,15 +50,16 @@
|
|||||||
AsyncMqttClient * mqtt_client;
|
AsyncMqttClient * mqtt_client;
|
||||||
WiFiEventHandler wifiConnectHandler;
|
WiFiEventHandler wifiConnectHandler;
|
||||||
WiFiEventHandler wifiDisconnectHandler;
|
WiFiEventHandler wifiDisconnectHandler;
|
||||||
Ticker mqttReconnectTimer;
|
|
||||||
Ticker wifiReconnectTimer;
|
|
||||||
#endif
|
|
||||||
#if defined(ENABLE_HOMEASSISTANT)
|
|
||||||
Ticker ha_send_data;
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CUSTOM_WS2812FX_ANIMATIONS)
|
#if defined(ARDUINOJSON_VERSION)
|
||||||
|
#if !(ARDUINOJSON_VERSION_MAJOR == 6 and ARDUINOJSON_VERSION_MINOR >= 8)
|
||||||
|
#error "Install ArduinoJson v6.8.x or higher"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_E131)
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Load libraries for E131 support
|
// Load libraries for E131 support
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
@@ -78,7 +80,6 @@
|
|||||||
#if defined(USE_HTML_MIN_GZ)
|
#if defined(USE_HTML_MIN_GZ)
|
||||||
#include "htm_index_gz.h"
|
#include "htm_index_gz.h"
|
||||||
#include "htm_edit_gz.h"
|
#include "htm_edit_gz.h"
|
||||||
#include "html_material_icons.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ WebSocketsServer webSocket = WebSocketsServer(81);
|
|||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Load and instanciate WS2812FX library
|
// Load and instanciate WS2812FX library
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#include "WS2812FX.h" // https://github.com/kitesurfer1404/WS2812FX
|
#include <WS2812FX.h> // https://github.com/kitesurfer1404/WS2812FX
|
||||||
WS2812FX * strip = NULL;
|
WS2812FX * strip = NULL;
|
||||||
|
|
||||||
#if defined(USE_WS2812FX_DMA)
|
#if defined(USE_WS2812FX_DMA)
|
||||||
@@ -113,64 +114,79 @@ WS2812FX * strip = NULL;
|
|||||||
|
|
||||||
#if USE_WS2812FX_DMA == 0 // Uses GPIO3/RXD0/RX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
#if USE_WS2812FX_DMA == 0 // Uses GPIO3/RXD0/RX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
||||||
#if !defined(LED_TYPE_WS2811)
|
#if !defined(LED_TYPE_WS2811)
|
||||||
NeoPixelBus<NeoRgbwFeature, NeoEsp8266Dma800KbpsMethod> * dma = NULL ; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
NeoEsp8266Dma800KbpsMethod * dma = NULL ; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||||
#else
|
#else
|
||||||
NeoPixelBus<NeoRgbwFeature, NeoEsp8266Dma400KbpsMethod> * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
NeoEsp8266Dma400KbpsMethod * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if USE_WS2812FX_DMA == 1 // Uses UART1: GPIO1/TXD0/TX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
#if USE_WS2812FX_DMA == 1 // Uses UART1: GPIO1/TXD0/TX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
||||||
#if !defined(LED_TYPE_WS2811)
|
#if !defined(LED_TYPE_WS2811)
|
||||||
NeoPixelBus<NeoRgbwFeature, NeoEsp8266Uart0800KbpsMethod> * dma = NULL; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
NeoEsp8266Uart0800KbpsMethod * dma = NULL; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||||
#else
|
#else
|
||||||
NeoPixelBus<NeoRgbwFeature, NeoEsp8266Uart0400KbpsMethod> * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
NeoEsp8266Uart0400KbpsMethod * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if USE_WS2812FX_DMA == 2 // Uses UART2: GPIO2/TXD1/D4, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
#if USE_WS2812FX_DMA == 2 // Uses UART2: GPIO2/TXD1/D4, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
||||||
#if !defined(LED_TYPE_WS2811)
|
#if !defined(LED_TYPE_WS2811)
|
||||||
NeoPixelBus<NeoRgbwFeature, NeoEsp8266Uart1800KbpsMethod> * dma = NULL; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
NeoEsp8266Uart1800KbpsMethod * dma = NULL; //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||||
#else
|
#else
|
||||||
NeoPixelBus<NeoRgbwFeature, NeoEsp8266Uart1400KbpsMethod> * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
NeoEsp8266Uart1400KbpsMethod * dma = NULL; //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void initDMA(uint16_t stripSize = NUMLEDS){
|
void initDMA(uint16_t stripSize = NUMLEDS){
|
||||||
if (dma != NULL) { delete(dma); }
|
if (dma != NULL) { delete(dma); }
|
||||||
|
uint8_t ledcolors = 3;
|
||||||
|
if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) {
|
||||||
|
ledcolors = 4;
|
||||||
|
}
|
||||||
#if USE_WS2812FX_DMA == 0 // Uses GPIO3/RXD0/RX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
#if USE_WS2812FX_DMA == 0 // Uses GPIO3/RXD0/RX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
||||||
#if !defined(LED_TYPE_WS2811)
|
#if !defined(LED_TYPE_WS2811)
|
||||||
dma = new NeoPixelBus<NeoRgbwFeature, NeoEsp8266Dma800KbpsMethod>(stripSize); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
dma = new NeoEsp8266Dma800KbpsMethod(stripSize, ledcolors); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||||
#else
|
#else
|
||||||
dma = new NeoPixelBus<NeoRgbwFeature, NeoEsp8266Dma400KbpsMethod>(stripSize); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
dma = new NeoEsp8266Dma400KbpsMethod(stripSize, ledcolors); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if USE_WS2812FX_DMA == 1 // Uses UART1: GPIO1/TXD0/TX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
#if USE_WS2812FX_DMA == 1 // Uses UART1: GPIO1/TXD0/TX, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
||||||
#if !defined(LED_TYPE_WS2811)
|
#if !defined(LED_TYPE_WS2811)
|
||||||
dma = new NeoPixelBus<NeoRgbwFeature, NeoEsp8266Uart0800KbpsMethod>(stripSize); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
dma = new NeoEsp8266Uart0800KbpsMethod(stripSize, ledcolors); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||||
#else
|
#else
|
||||||
dma = new NeoPixelBus<NeoRgbwFeature, NeoEsp8266Uart0400KbpsMethod>(stripSize); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
dma = new NeoEsp8266Uart0400KbpsMethod(stripSize, ledcolors); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if USE_WS2812FX_DMA == 2 // Uses UART2: GPIO2/TXD1/D4, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
#if USE_WS2812FX_DMA == 2 // Uses UART2: GPIO2/TXD1/D4, more info: https://github.com/Makuna/NeoPixelBus/wiki/ESP8266-NeoMethods
|
||||||
#if !defined(LED_TYPE_WS2811)
|
#if !defined(LED_TYPE_WS2811)
|
||||||
dma = new NeoPixelBus<NeoRgbwFeature, NeoEsp8266Uart1800KbpsMethod>(stripSize); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
dma = new NeoEsp8266Uart1800KbpsMethod(stripSize, ledcolors); //800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||||
#else
|
#else
|
||||||
dma = new NeoPixelBus<NeoRgbwFeature, NeoEsp8266Uart1400KbpsMethod>(stripSize); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
dma = new NeoEsp8266Uart1400KbpsMethod(stripSize, ledcolors); //400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
dma->Begin();
|
dma->Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DMA_Show(void) {
|
void DMA_Show(void) {
|
||||||
if(dma->CanShow()) {
|
if(dma->IsReadyToUpdate()) {
|
||||||
memcpy(dma->Pixels(), strip->getPixels(), dma->PixelsSize());
|
memcpy(dma->getPixels(), strip->getPixels(), dma->getPixelsSize());
|
||||||
dma->Dirty();
|
dma->Update(false);
|
||||||
dma->Show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// Load library "ticker" for blinking status led, mqtt send and save state
|
||||||
|
// ***************************************************************************
|
||||||
|
#include <Ticker.h>
|
||||||
Ticker ticker;
|
Ticker ticker;
|
||||||
|
|
||||||
|
#if defined(ENABLE_MQTT)
|
||||||
|
#if ENABLE_MQTT == 1
|
||||||
|
Ticker mqttReconnectTimer;
|
||||||
|
Ticker wifiReconnectTimer;
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_HOMEASSISTANT)
|
||||||
|
Ticker ha_send_data;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
void tick() {
|
void tick() {
|
||||||
//toggle state
|
//toggle state
|
||||||
@@ -183,6 +199,9 @@ void tick() {
|
|||||||
decode_results results;
|
decode_results results;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Ticker settings_save_state;
|
||||||
|
Ticker settings_save_conf;
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Saved state handling in WifiManager
|
// Saved state handling in WifiManager
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
@@ -229,22 +248,99 @@ void saveConfigCallback () {
|
|||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#include "spiffs_webserver.h"
|
#include "spiffs_webserver.h"
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// Include: Request handlers
|
||||||
|
// ***************************************************************************
|
||||||
|
#include "request_handlers.h"
|
||||||
|
|
||||||
|
#if defined(ENABLE_TV)
|
||||||
|
// ***************************************************************************
|
||||||
|
// Include: TV mode
|
||||||
|
// ***************************************************************************
|
||||||
|
#include "mode_tv.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CUSTOM_WS2812FX_ANIMATIONS)
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Include: Custom animations
|
// Include: Custom animations
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#include "mode_custom_ws2812fx_animations.h" // Add animations in this file
|
#include "mode_custom_ws2812fx_animations.h" // Add animations in this file
|
||||||
|
#endif
|
||||||
|
|
||||||
// ***************************************************************************
|
// function to Initialize the strip
|
||||||
// Include: helper functions
|
void initStrip(uint16_t stripSize = WS2812FXStripSettings.stripSize, char RGBOrder[5] = WS2812FXStripSettings.RGBOrder, uint8_t pin = WS2812FXStripSettings.pin, uint8_t fxoptions = WS2812FXStripSettings.fxoptions ){
|
||||||
// ***************************************************************************
|
DBG_OUTPUT_PORT.println("Initializing strip!");
|
||||||
#include "helper_functions.h"
|
/*#if defined(USE_WS2812FX_DMA)
|
||||||
|
if (dma != NULL) {
|
||||||
|
delete(dma);
|
||||||
|
}
|
||||||
|
#endif*/
|
||||||
|
if (strip != NULL) {
|
||||||
|
delete(strip);
|
||||||
|
WS2812FXStripSettings.stripSize = stripSize;
|
||||||
|
strcpy(WS2812FXStripSettings.RGBOrder, RGBOrder);
|
||||||
|
WS2812FXStripSettings.pin = pin;
|
||||||
|
WS2812FXStripSettings.fxoptions = fxoptions;
|
||||||
|
}
|
||||||
|
#if defined(ENABLE_E131)
|
||||||
|
|
||||||
// ***************************************************************************
|
#endif
|
||||||
// Include: other functions
|
if (ledstates != NULL) {
|
||||||
// ***************************************************************************
|
delete(ledstates);
|
||||||
#include "json_functions.h"
|
}
|
||||||
#include "filesystem_functions.h"
|
ledstates = new uint8_t [WS2812FXStripSettings.stripSize];
|
||||||
#include "request_handlers.h"
|
|
||||||
|
#if !defined(LED_TYPE_WS2811)
|
||||||
|
strip = new WS2812FX(stripSize, pin, checkRGBOrder(RGBOrder) + NEO_KHZ800);
|
||||||
|
#else
|
||||||
|
strip = new WS2812FX(stripSize, pin, checkRGBOrder(RGBOrder) + NEO_KHZ400);
|
||||||
|
#endif
|
||||||
|
// Parameter 1 = number of pixels in strip
|
||||||
|
// Parameter 2 = Arduino pin number (most are valid)
|
||||||
|
// Parameter 3 = pixel type flags, add together as needed:
|
||||||
|
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||||
|
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||||
|
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
|
||||||
|
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
|
||||||
|
|
||||||
|
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
|
||||||
|
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
|
||||||
|
// and minimize distance between Arduino and first pixel. Avoid connecting
|
||||||
|
// on a live circuit...if you must, connect GND first.
|
||||||
|
strip->init();
|
||||||
|
#if defined(USE_WS2812FX_DMA)
|
||||||
|
initDMA(stripSize);
|
||||||
|
strip->setCustomShow(DMA_Show);
|
||||||
|
#endif
|
||||||
|
strip->setBrightness(brightness);
|
||||||
|
//parameters: index, start, stop, mode, color, speed, options
|
||||||
|
strip->setSegment(0, 0, stripSize - 1, ws2812fx_mode, hex_colors, convertSpeed(ws2812fx_speed), fxoptions);
|
||||||
|
#if defined(CUSTOM_WS2812FX_ANIMATIONS)
|
||||||
|
strip->setCustomMode(0, F("Fire 2012"), myCustomEffect0);
|
||||||
|
//strip->setCustomMode(1, F("CustEffect"), myCustomEffect1);
|
||||||
|
gReverseDirection = (WS2812FXStripSettings.fxoptions & 128);
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_E131)
|
||||||
|
if (e131 != NULL) { delete(e131); }
|
||||||
|
e131 = new ESPAsyncE131(END_UNIVERSE - START_UNIVERSE + 1);
|
||||||
|
float universe_leds = 170.0; // a universe has only 512 (0..511) channels: 3*170 or 4*128 <= 512
|
||||||
|
if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) {
|
||||||
|
//universe_leds = 128.0;
|
||||||
|
}
|
||||||
|
float float_enduni = stripSize/universe_leds;
|
||||||
|
uint8_t END_UNIVERSE = stripSize/universe_leds;
|
||||||
|
if (float_enduni > END_UNIVERSE) {
|
||||||
|
END_UNIVERSE = END_UNIVERSE +1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (e131.begin(E131_UNICAST)) // Listen via Unicast
|
||||||
|
if (e131->begin(E131_MULTICAST, START_UNIVERSE, END_UNIVERSE)) {// Listen via Multicast
|
||||||
|
DBG_OUTPUT_PORT.println(F("Listening for data..."));
|
||||||
|
} else {
|
||||||
|
DBG_OUTPUT_PORT.println(F("*** e131.begin failed ***"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(ENABLE_MQTT)
|
#if defined(ENABLE_MQTT)
|
||||||
void initMqtt() {
|
void initMqtt() {
|
||||||
@@ -310,6 +406,9 @@ void setup() {
|
|||||||
delay(500);
|
delay(500);
|
||||||
DBG_OUTPUT_PORT.println("");
|
DBG_OUTPUT_PORT.println("");
|
||||||
DBG_OUTPUT_PORT.println("Starting...Main Setup");
|
DBG_OUTPUT_PORT.println("Starting...Main Setup");
|
||||||
|
#if ENABLE_STATE_SAVE == 0
|
||||||
|
EEPROM.begin(512);
|
||||||
|
#endif
|
||||||
// set builtin led pin as output
|
// set builtin led pin as output
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
pinMode(LED_BUILTIN, OUTPUT);
|
||||||
// button pin setup
|
// button pin setup
|
||||||
@@ -361,30 +460,37 @@ void setup() {
|
|||||||
|
|
||||||
#if defined(ENABLE_STATE_SAVE)
|
#if defined(ENABLE_STATE_SAVE)
|
||||||
//Strip Config
|
//Strip Config
|
||||||
|
#if ENABLE_STATE_SAVE == 1
|
||||||
(readConfigFS()) ? DBG_OUTPUT_PORT.println("WiFiManager config FS read success!"): DBG_OUTPUT_PORT.println("WiFiManager config FS Read failure!");
|
(readConfigFS()) ? DBG_OUTPUT_PORT.println("WiFiManager config FS read success!"): DBG_OUTPUT_PORT.println("WiFiManager config FS Read failure!");
|
||||||
delay(250);
|
delay(250);
|
||||||
(readStateFS()) ? DBG_OUTPUT_PORT.println("Strip state config FS read Success!") : DBG_OUTPUT_PORT.println("Strip state config FS read failure!");
|
(readStateFS()) ? DBG_OUTPUT_PORT.println("Strip state config FS read Success!") : DBG_OUTPUT_PORT.println("Strip state config FS read failure!");
|
||||||
char _stripSize[6], _fx_options[5], _rgbOrder[5]; //needed tempararily for WiFiManager Settings
|
#endif
|
||||||
|
#if ENABLE_STATE_SAVE == 0
|
||||||
|
(setConfByConfString(readEEPROM(0, 222)))? DBG_OUTPUT_PORT.println("WiFiManager config EEPROM read success!"): DBG_OUTPUT_PORT.println("WiFiManager config EEPROM Read failure!");
|
||||||
|
delay(250);
|
||||||
|
(setModeByStateString(readEEPROM(256, 66)))? DBG_OUTPUT_PORT.println("Strip state config EEPROM read Success!") : DBG_OUTPUT_PORT.println("Strip state config EEPROM read failure!");
|
||||||
|
#endif
|
||||||
|
char tmp_strip_size[6], tmp_fxoptions[5], tmp_rgbOrder[5]; //needed tempararily for WiFiManager Settings
|
||||||
WiFiManagerParameter custom_hostname("hostname", "Hostname", HOSTNAME, 64, " maxlength=64");
|
WiFiManagerParameter custom_hostname("hostname", "Hostname", HOSTNAME, 64, " maxlength=64");
|
||||||
#if defined(ENABLE_MQTT)
|
#if defined(ENABLE_MQTT)
|
||||||
char _mqtt_port[6]; //needed tempararily for WiFiManager Settings
|
char tmp_mqtt_port[6]; //needed tempararily for WiFiManager Settings
|
||||||
WiFiManagerParameter custom_mqtt_host("host", "MQTT hostname", mqtt_host, 64, " maxlength=64");
|
WiFiManagerParameter custom_mqtt_host("host", "MQTT hostname", mqtt_host, 64, " maxlength=64");
|
||||||
sprintf(_mqtt_port, "%d", mqtt_port);
|
sprintf(tmp_mqtt_port, "%d", mqtt_port);
|
||||||
WiFiManagerParameter custom_mqtt_port("port", "MQTT port", _mqtt_port, 5, " maxlength=5 type=\"number\"");
|
WiFiManagerParameter custom_mqtt_port("port", "MQTT port", tmp_mqtt_port, 5, " maxlength=5 type=\"number\"");
|
||||||
WiFiManagerParameter custom_mqtt_user("user", "MQTT user", mqtt_user, 32, " maxlength=32");
|
WiFiManagerParameter custom_mqtt_user("user", "MQTT user", mqtt_user, 32, " maxlength=32");
|
||||||
WiFiManagerParameter custom_mqtt_pass("pass", "MQTT pass", mqtt_pass, 32, " maxlength=32 type=\"password\"");
|
WiFiManagerParameter custom_mqtt_pass("pass", "MQTT pass", mqtt_pass, 32, " maxlength=32 type=\"password\"");
|
||||||
#endif
|
#endif
|
||||||
sprintf(_stripSize, "%d", Config.stripSize);
|
sprintf(tmp_strip_size, "%d", WS2812FXStripSettings.stripSize);
|
||||||
WiFiManagerParameter custom_strip_size("strip_size", "Number of LEDs", _stripSize, 4, " maxlength=4 type=\"number\"");
|
WiFiManagerParameter custom_strip_size("strip_size", "Number of LEDs", tmp_strip_size, 4, " maxlength=4 type=\"number\"");
|
||||||
#if !defined(USE_WS2812FX_DMA)
|
#if !defined(USE_WS2812FX_DMA)
|
||||||
char tmp_led_pin[3];
|
char tmp_led_pin[3];
|
||||||
sprintf(tmp_led_pin, "%d", Config.pin);
|
sprintf(tmp_led_pin, "%d", WS2812FXStripSettings.pin);
|
||||||
WiFiManagerParameter custom_led_pin("led_pin", "LED GPIO", tmp_led_pin, 2, " maxlength=2 type=\"number\"");
|
WiFiManagerParameter custom_led_pin("led_pin", "LED GPIO", tmp_led_pin, 2, " maxlength=2 type=\"number\"");
|
||||||
#endif
|
#endif
|
||||||
sprintf(_rgbOrder, "%s", Config.RGBOrder);
|
sprintf(tmp_rgbOrder, "%s", WS2812FXStripSettings.RGBOrder);
|
||||||
WiFiManagerParameter custom_rgbOrder("rgbOrder", "RGBOrder", _rgbOrder, 4, " maxlength=4");
|
WiFiManagerParameter custom_rgbOrder("rgbOrder", "RGBOrder", tmp_rgbOrder, 4, " maxlength=4");
|
||||||
sprintf(_fx_options, "%d", segState.options);
|
sprintf(tmp_fxoptions, "%d", WS2812FXStripSettings.fxoptions);
|
||||||
WiFiManagerParameter custom_fxoptions("fxoptions", "fxOptions", _fx_options, 3, " maxlength=3");
|
WiFiManagerParameter custom_fxoptions("fxoptions", "fxOptions", tmp_fxoptions, 3, " maxlength=3");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -434,8 +540,8 @@ void setup() {
|
|||||||
if (!wifiManager.autoConnect(HOSTNAME)) {
|
if (!wifiManager.autoConnect(HOSTNAME)) {
|
||||||
DBG_OUTPUT_PORT.println("failed to connect and hit timeout");
|
DBG_OUTPUT_PORT.println("failed to connect and hit timeout");
|
||||||
//reset and try again, or maybe put it to deep sleep
|
//reset and try again, or maybe put it to deep sleep
|
||||||
//ESP.reset(); //Will be removed when upgrading to standalone offline McLightingUI version
|
ESP.reset(); //Will be removed when upgrading to standalone offline McLightingUI version
|
||||||
//delay(1000); //Will be removed when upgrading to standalone offline McLightingUI version
|
delay(1000); //Will be removed when upgrading to standalone offline McLightingUI version
|
||||||
}
|
}
|
||||||
|
|
||||||
//save the custom parameters to FS/EEPROM
|
//save the custom parameters to FS/EEPROM
|
||||||
@@ -448,16 +554,31 @@ void setup() {
|
|||||||
strcpy(mqtt_user, custom_mqtt_user.getValue());
|
strcpy(mqtt_user, custom_mqtt_user.getValue());
|
||||||
strcpy(mqtt_pass, custom_mqtt_pass.getValue());
|
strcpy(mqtt_pass, custom_mqtt_pass.getValue());
|
||||||
#endif
|
#endif
|
||||||
strcpy(_stripSize, custom_strip_size.getValue());
|
strcpy(tmp_strip_size, custom_strip_size.getValue());
|
||||||
Config.stripSize = constrain(atoi(custom_strip_size.getValue()), 1, MAXLEDS);
|
WS2812FXStripSettings.stripSize = constrain(atoi(custom_strip_size.getValue()), 1, MAXLEDS);
|
||||||
#if !defined(USE_WS2812FX_DMA)
|
#if !defined(USE_WS2812FX_DMA)
|
||||||
checkPin(atoi(custom_led_pin.getValue()));
|
checkPin(atoi(custom_led_pin.getValue()));
|
||||||
#endif
|
#endif
|
||||||
strcpy(_rgbOrder, custom_rgbOrder.getValue());
|
strcpy(tmp_rgbOrder, custom_rgbOrder.getValue());
|
||||||
checkRGBOrder(_rgbOrder);
|
checkRGBOrder(tmp_rgbOrder);
|
||||||
segState.options = atoi(custom_fxoptions.getValue());
|
WS2812FXStripSettings.fxoptions = atoi(custom_fxoptions.getValue());
|
||||||
if (updateConfig) {
|
if (updateConfig) {
|
||||||
|
#if ENABLE_STATE_SAVE == 1
|
||||||
(writeConfigFS(updateConfig)) ? DBG_OUTPUT_PORT.println("WiFiManager config FS Save success!"): DBG_OUTPUT_PORT.println("WiFiManager config FS Save failure!");
|
(writeConfigFS(updateConfig)) ? DBG_OUTPUT_PORT.println("WiFiManager config FS Save success!"): DBG_OUTPUT_PORT.println("WiFiManager config FS Save failure!");
|
||||||
|
#endif
|
||||||
|
#if ENABLE_STATE_SAVE == 0
|
||||||
|
char last_conf[223];
|
||||||
|
DBG_OUTPUT_PORT.println("Saving WiFiManager config");
|
||||||
|
#if defined(ENABLE_MQTT)
|
||||||
|
snprintf(last_conf, sizeof(last_conf), "CNF|%64s|%64s|%5d|%32s|%32s|%4d|%2d|%4s|%3d", HOSTNAME, mqtt_host, mqtt_port, mqtt_user, mqtt_pass, WS2812FXStripSettings.stripSize, WS2812FXStripSettings.pin, WS2812FXStripSettings.RGBOrder, WS2812FXStripSettings.fxoptions);
|
||||||
|
#else
|
||||||
|
snprintf(last_conf, sizeof(last_conf), "CNF|%64s|%64s|%5d|%32s|%32s|%4d|%2d|%4s|%3d", HOSTNAME, "", "", "", "", WS2812FXStripSettings.stripSize, WS2812FXStripSettings.pin, WS2812FXStripSettings.RGBOrder, WS2812FXStripSettings.fxoptions);
|
||||||
|
#endif
|
||||||
|
last_conf[sizeof(last_conf)] = 0x00;
|
||||||
|
writeEEPROM(0, 222, last_conf);
|
||||||
|
EEPROM.commit();
|
||||||
|
updateConfig = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -536,11 +657,11 @@ void setup() {
|
|||||||
DBG_OUTPUT_PORT.print("Use http://");
|
DBG_OUTPUT_PORT.print("Use http://");
|
||||||
DBG_OUTPUT_PORT.print(HOSTNAME);
|
DBG_OUTPUT_PORT.print(HOSTNAME);
|
||||||
DBG_OUTPUT_PORT.println(".local/ when you have Bonjour installed.");
|
DBG_OUTPUT_PORT.println(".local/ when you have Bonjour installed.");
|
||||||
#if !defined(USE_HTML_MIN_GZ)
|
|
||||||
DBG_OUTPUT_PORT.print("New users: Open http://");
|
DBG_OUTPUT_PORT.print("New users: Open http://");
|
||||||
DBG_OUTPUT_PORT.print(WiFi.localIP());
|
DBG_OUTPUT_PORT.print(WiFi.localIP());
|
||||||
DBG_OUTPUT_PORT.println("/upload to upload the webpages first.");
|
DBG_OUTPUT_PORT.println("/upload to upload the webpages first.");
|
||||||
#endif
|
|
||||||
DBG_OUTPUT_PORT.println("");
|
DBG_OUTPUT_PORT.println("");
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
@@ -558,6 +679,8 @@ void setup() {
|
|||||||
MDNS.addService("http", "tcp", 80);
|
MDNS.addService("http", "tcp", 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prevmode = mode;
|
||||||
|
|
||||||
#if defined(ENABLE_BUTTON_GY33)
|
#if defined(ENABLE_BUTTON_GY33)
|
||||||
tcs.setConfig(MCU_LED_06, MCU_WHITE_ON);
|
tcs.setConfig(MCU_LED_06, MCU_WHITE_ON);
|
||||||
// delay(2000);
|
// delay(2000);
|
||||||
@@ -565,12 +688,12 @@ void setup() {
|
|||||||
#endif
|
#endif
|
||||||
#if defined(ENABLE_REMOTE)
|
#if defined(ENABLE_REMOTE)
|
||||||
irrecv.enableIRIn(); // Start the receiver
|
irrecv.enableIRIn(); // Start the receiver
|
||||||
|
snprintf(last_state, sizeof(last_state), "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", mode, ws2812fx_mode, ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue, main_color.white, back_color.red, back_color.green, back_color.blue, back_color.white, xtra_color.red, xtra_color.green, xtra_color.blue,xtra_color.white);
|
||||||
|
last_state[sizeof(last_state)]= 0x00;
|
||||||
#endif
|
#endif
|
||||||
fx_speed = segState.speed[State.segment];
|
|
||||||
brightness_trans = State.brightness;
|
|
||||||
initStrip();
|
|
||||||
strip->setBrightness(0);
|
|
||||||
DBG_OUTPUT_PORT.println("finished Main Setup!");
|
DBG_OUTPUT_PORT.println("finished Main Setup!");
|
||||||
|
|
||||||
|
initStrip();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
@@ -629,115 +752,144 @@ void loop() {
|
|||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Simple statemachine that handles the different modes
|
// Simple statemachine that handles the different modes
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
if ((mode != OFF) && (mode != TV) && (mode != E131)) { // strip->start() is only needed for modes with WS2812FX functionality
|
||||||
|
if(!strip->isRunning()) strip->start();
|
||||||
|
}
|
||||||
|
|
||||||
if ((State.mode == OFF) && ((strip->getBrightness() == 0) || !Config.transEffect)) {
|
if ((mode == OFF) || (mode == TV) || (mode == E131)) {
|
||||||
if(strip->isRunning()) {
|
if(strip->isRunning()) {
|
||||||
strip->strip_off(); // Workaround: to be shure,
|
strip->strip_off(); // Workaround: to be shure,
|
||||||
delay(10); // that strip is really off. Sometimes strip->stop isn't enought
|
delay(10); // that strip is really off. Sometimes strip->stop isn't enought
|
||||||
strip->stop(); // should clear memory
|
strip->stop(); // should clear memory
|
||||||
for (uint8_t i = 0; i < Config.segments; i++) {
|
|
||||||
autoCount[i] = 0;
|
|
||||||
autoDelay[i] = 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (prevmode != State.mode) { // Start temporarily to clear strip
|
if (prevmode != mode) { // Start temporarily to clear strip
|
||||||
strip->start();
|
strip->start();
|
||||||
strip->strip_off(); // Workaround: to be shure,
|
strip->strip_off(); // Workaround: to be shure,
|
||||||
delay(10); // that strip is really off. Sometimes strip->stop isn't enought
|
delay(10); // that strip is really off. Sometimes strip->stop isn't enought
|
||||||
strip->stop(); // should clear memory
|
strip->stop(); // should clear memory
|
||||||
for (uint8_t i = 0; i < Config.segments; i++) {
|
|
||||||
autoCount[i] = 0;
|
|
||||||
autoDelay[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (State.mode == OFF) {
|
if (( mode == AUTO) || (mode == HOLD)) { // strip->service() is only needed for modes with WS2812FX functionality
|
||||||
if (prevmode != State.mode) {
|
strip->service();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((prevmode == AUTO) && (mode != AUTO)) { handleAutoStop(); } // stop auto mode
|
||||||
|
|
||||||
|
if (mode == OFF) {
|
||||||
#if defined(ENABLE_MQTT)
|
#if defined(ENABLE_MQTT)
|
||||||
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =off", "");
|
if (prevmode != mode) { snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =off", ""); }
|
||||||
#endif
|
#endif
|
||||||
#if defined(POWER_SUPPLY)
|
#if defined(POWER_SUPPLY)
|
||||||
digitalWrite(POWER_SUPPLY, !POWER_ON); // power off -> external power supply
|
if (prevmode != mode) {digitalWrite(POWER_SUPPLY, !POWER_ON); } // power off -> external power supply
|
||||||
#endif
|
#endif
|
||||||
if (Config.transEffect) {
|
|
||||||
brightness_trans = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(POWER_SUPPLY)
|
#if defined(POWER_SUPPLY)
|
||||||
if (State.mode != OFF) {
|
if (mode != OFF) {
|
||||||
if (prevmode != State.mode) {digitalWrite(POWER_SUPPLY, POWER_ON); } // power on -> external power supply
|
if (prevmode != mode) {digitalWrite(POWER_SUPPLY, POWER_ON); } // power on -> external power supply
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (State.mode == SET) {
|
if (mode == AUTO) {
|
||||||
State.mode = HOLD;
|
if (prevmode != mode) {
|
||||||
// Segment
|
handleAutoStart();
|
||||||
if (prevsegment != State.segment) {
|
|
||||||
#if defined(ENABLE_MQTT)
|
#if defined(ENABLE_MQTT)
|
||||||
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK Ss%i", State.segment);
|
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =auto", "");
|
||||||
#endif
|
#endif
|
||||||
//prevsegment = State.segment;
|
|
||||||
}
|
}
|
||||||
// Mode
|
}
|
||||||
if (segState.mode[State.segment] != fx_mode) {
|
|
||||||
segState.mode[State.segment] = fx_mode;
|
#if defined(ENABLE_TV)
|
||||||
|
if (mode == TV) {
|
||||||
|
handleTV();
|
||||||
#if defined(ENABLE_MQTT)
|
#if defined(ENABLE_MQTT)
|
||||||
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK /%i", segState.mode[State.segment]);
|
if (prevmode != mode) { snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =tv", ""); }
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_E131)
|
||||||
|
if (mode == E131) {
|
||||||
|
handleE131();
|
||||||
|
#if defined(ENABLE_MQTT)
|
||||||
|
if (prevmode != mode) { snprintf(mqtt_buf, sizeof(mqtt_buf), "OK =e131", ""); }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (mode == INIT_STRIP) {
|
||||||
|
mode = prevmode;
|
||||||
|
//ws2812fx_mode = strip->getMode();
|
||||||
strip->strip_off();
|
strip->strip_off();
|
||||||
autoCount[State.segment] = 0;
|
delay(10);
|
||||||
autoDelay[State.segment] = 0;
|
if(strip->isRunning()) strip->stop();
|
||||||
//strip->setSpeed(State.segment, segState.speed[State.segment]);
|
initStrip();
|
||||||
//strip->setColors(State.segment, segState.colors[State.segment]);
|
prevmode = INIT_STRIP;
|
||||||
strip->setMode(State.segment, segState.mode[State.segment]);
|
|
||||||
//strip->trigger;
|
|
||||||
}
|
|
||||||
//Color
|
|
||||||
/*if (memcmp(segmentState.colors[prevsegment)], strip->getColors(prevsegment), sizeof(segmentState.colors[prevsegment)])) != 0) {
|
|
||||||
convertColors();
|
|
||||||
}*/
|
|
||||||
// Brightness
|
|
||||||
if (strip->getBrightness() != State.brightness) {
|
|
||||||
#if defined(ENABLE_MQTT)
|
|
||||||
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK %%%i", State.brightness);
|
|
||||||
#endif
|
|
||||||
brightness_trans = State.brightness;
|
|
||||||
}
|
|
||||||
// Speed
|
|
||||||
if (fx_speed != segState.speed[State.segment]) {
|
|
||||||
#if defined(ENABLE_MQTT)
|
|
||||||
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK ?%i", segState.speed[prevsegment]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
prevmode = SET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((State.mode == HOLD) || ((State.mode == OFF) && (strip->getBrightness() > 0) && Config.transEffect)) {
|
if (mode == SET_ALL) {
|
||||||
if(!strip->isRunning()) strip->start();
|
mode = HOLD;
|
||||||
strip->service();
|
if ((prevmode == OFF) || (prevmode == AUTO) || (prevmode == TV) || (prevmode == E131)) { setModeByStateString(last_state); }
|
||||||
bool playE131 = false;
|
#if defined(ENABLE_MQTT)
|
||||||
for (uint8_t i = 0; i < Config.segments; i++) {
|
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK /%i", ws2812fx_mode);
|
||||||
if (segState.mode[i] == FX_MODE_CUSTOM_0) { handleAutoPlay(i); }
|
#endif
|
||||||
if (segState.mode[i] == FX_MODE_CUSTOM_3) { playE131 = true; }
|
strip->setMode(ws2812fx_mode);
|
||||||
}
|
convertColors();
|
||||||
if (playE131 == true) { handleE131Play(); }
|
strip->setColors(0, hex_colors);
|
||||||
|
strip->setSpeed(convertSpeed(ws2812fx_speed));
|
||||||
|
strip->setBrightness(brightness);
|
||||||
|
prevmode = SET_ALL;
|
||||||
|
strip->trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevmode != State.mode) {
|
if (mode == SET_MODE) {
|
||||||
if (segState.mode[prevsegment] != FX_MODE_CUSTOM_0) {
|
mode = HOLD;
|
||||||
|
#if defined(ENABLE_MQTT)
|
||||||
|
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK /%i", ws2812fx_mode);
|
||||||
|
#endif
|
||||||
|
strip->setMode(ws2812fx_mode);
|
||||||
|
prevmode = SET_MODE;
|
||||||
|
strip->trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == SET_COLOR) {
|
||||||
convertColors();
|
convertColors();
|
||||||
if (memcmp(hexcolors_trans, strip->getColors(prevsegment), sizeof(hexcolors_trans)) != 0) {
|
strip->setColors(0, hex_colors);
|
||||||
DBG_OUTPUT_PORT.println("Color changed!");
|
mode = prevmode;
|
||||||
trans_cnt_max = convertColorsFade(prevsegment);
|
prevmode = SET_COLOR;
|
||||||
trans_cnt = 1;
|
//DBG_OUTPUT_PORT.printf("mode: %d\r\n", mode);
|
||||||
memcpy(segState.colors[prevsegment], hexcolors_trans, sizeof(hexcolors_trans));
|
if (mode == HOLD) strip->trigger();
|
||||||
}
|
}
|
||||||
strip->setSpeed(prevsegment, convertSpeed(fx_speed));
|
if (mode == SET_SPEED) {
|
||||||
|
#if defined(ENABLE_MQTT)
|
||||||
|
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK ?%i", ws2812fx_speed);
|
||||||
|
#endif
|
||||||
|
strip->setSpeed(convertSpeed(ws2812fx_speed));
|
||||||
|
mode = prevmode;
|
||||||
|
prevmode = SET_SPEED;
|
||||||
|
if (mode == HOLD) strip->trigger();
|
||||||
|
}
|
||||||
|
if (mode == SET_BRIGHTNESS) {
|
||||||
|
#if defined(ENABLE_MQTT)
|
||||||
|
snprintf(mqtt_buf, sizeof(mqtt_buf), "OK %%%i", brightness);
|
||||||
|
#endif
|
||||||
|
strip->setBrightness(brightness);
|
||||||
|
mode = prevmode;
|
||||||
|
prevmode = SET_BRIGHTNESS;
|
||||||
|
//DBG_OUTPUT_PORT.printf("mode: %d\r\n", mode);
|
||||||
|
if (mode == HOLD) strip->trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevmode != mode) {
|
||||||
|
if ((prevmode != AUTO) && (prevmode != INIT_STRIP)) { // do not save if AUTO Mode was set
|
||||||
|
#if defined(ENABLE_STATE_SAVE)
|
||||||
|
if(!settings_save_state.active()) settings_save_state.once(3, tickerSaveState);
|
||||||
|
#endif
|
||||||
|
snprintf(last_state, sizeof(last_state), "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", prevmode, ws2812fx_mode, ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue, main_color.white, back_color.red, back_color.green, back_color.blue, back_color.white, xtra_color.red, xtra_color.green, xtra_color.blue, xtra_color.white);
|
||||||
|
last_state[sizeof(last_state) - 1] = 0x00;
|
||||||
}
|
}
|
||||||
//strip->setBrightness(brightness_actual);
|
|
||||||
#if defined(ENABLE_MQTT)
|
#if defined(ENABLE_MQTT)
|
||||||
#if ENABLE_MQTT == 0
|
#if ENABLE_MQTT == 0
|
||||||
mqtt_client->publish(mqtt_outtopic, mqtt_buf);
|
mqtt_client->publish(mqtt_outtopic, mqtt_buf);
|
||||||
@@ -746,112 +898,43 @@ void loop() {
|
|||||||
mqtt_client->publish(mqtt_outtopic, qospub, false, mqtt_buf);
|
mqtt_client->publish(mqtt_outtopic, qospub, false, mqtt_buf);
|
||||||
#endif
|
#endif
|
||||||
#if defined(ENABLE_HOMEASSISTANT)
|
#if defined(ENABLE_HOMEASSISTANT)
|
||||||
if(ha_send_data.active()) ha_send_data.detach();
|
if(!ha_send_data.active()) ha_send_data.once(3, tickerSendState);
|
||||||
ha_send_data.once(DELAY_MQTT_HA_MESSAGE, tickerSendState);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
prevmode = State.mode;
|
|
||||||
|
|
||||||
#if defined(ENABLE_STATE_SAVE)
|
#if defined(ENABLE_STATE_SAVE)
|
||||||
if (updateState){
|
if (updateState){
|
||||||
(writeStateFS(updateState)) ? DBG_OUTPUT_PORT.println("State FS Save Success!") : DBG_OUTPUT_PORT.println("State FS Save failure!");
|
#if ENABLE_STATE_SAVE == 1
|
||||||
}
|
(writeStateFS(updateState)) ? DBG_OUTPUT_PORT.println(" State FS Save Success!") : DBG_OUTPUT_PORT.println("State FS Save failure!");
|
||||||
if (updateSegState) {
|
#endif
|
||||||
(writeSegmentStateFS(updateSegState, prevsegment)) ? DBG_OUTPUT_PORT.println("Segment State FS Save Success!") : DBG_OUTPUT_PORT.println("Segment State FS Save failure!");
|
#if ENABLE_STATE_SAVE == 0
|
||||||
|
writeEEPROM(384, 66, last_state); // 384 --> last_state (reserved 66 bytes)
|
||||||
|
EEPROM.commit();
|
||||||
|
updateState = false;
|
||||||
|
settings_save_state.detach();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (updateConfig) {
|
if (updateConfig) {
|
||||||
|
#if ENABLE_STATE_SAVE == 1
|
||||||
(writeConfigFS(updateConfig)) ? DBG_OUTPUT_PORT.println("Config FS Save success!"): DBG_OUTPUT_PORT.println("Config FS Save failure!");
|
(writeConfigFS(updateConfig)) ? DBG_OUTPUT_PORT.println("Config FS Save success!"): DBG_OUTPUT_PORT.println("Config FS Save failure!");
|
||||||
|
#endif
|
||||||
|
#if ENABLE_STATE_SAVE == 0
|
||||||
|
char last_conf[223];
|
||||||
|
#if defined(ENABLE_MQTT)
|
||||||
|
snprintf(last_conf, sizeof(last_conf), "CNF|%64s|%64s|%5d|%32s|%32s|%4d|%2d|%4s|%3d", HOSTNAME, mqtt_host, mqtt_port, mqtt_user, mqtt_pass, WS2812FXStripSettings.stripSize, WS2812FXStripSettings.pin, WS2812FXStripSettings.RGBOrder, WS2812FXStripSettings.fxoptions);
|
||||||
|
#else
|
||||||
|
snprintf(last_conf, sizeof(last_conf), "CNF|%64s|%64s|%5d|%32s|%32s|%4d|%2d|%4s|%3d", HOSTNAME, "", "", "", "", WS2812FXStripSettings.stripSize, WS2812FXStripSettings.pin, WS2812FXStripSettings.RGBOrder, WS2812FXStripSettings.fxoptions);
|
||||||
|
#endif
|
||||||
|
last_conf[sizeof(last_conf) - 1] = 0x00;
|
||||||
|
writeEEPROM(0, 222, last_conf);
|
||||||
|
EEPROM.commit();
|
||||||
|
updateConfig = false;
|
||||||
|
settings_save_conf.detach();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Async color transition
|
prevmode = mode;
|
||||||
if ((segState.mode[prevsegment] != FX_MODE_CUSTOM_0) && (memcmp(hexcolors_trans, strip->getColors(prevsegment), sizeof(hexcolors_trans)) != 0)) {
|
|
||||||
if (Config.transEffect) {
|
|
||||||
if ((trans_cnt > 0) && (trans_cnt < trans_cnt_max)) {
|
|
||||||
if (colorFadeDelay <= millis()) {
|
|
||||||
uint32_t _hexcolors_new[3] = {};
|
|
||||||
_hexcolors_new[0] = trans(hexcolors_trans[0], strip->getColors(prevsegment)[0], trans_cnt, trans_cnt_max);
|
|
||||||
_hexcolors_new[1] = trans(hexcolors_trans[1], strip->getColors(prevsegment)[1], trans_cnt, trans_cnt_max);
|
|
||||||
_hexcolors_new[2] = trans(hexcolors_trans[2], strip->getColors(prevsegment)[2], trans_cnt, trans_cnt_max);
|
|
||||||
strip->setColors(prevsegment, _hexcolors_new);
|
|
||||||
trans_cnt++;
|
|
||||||
colorFadeDelay = millis() + TRANS_COLOR_DELAY;
|
|
||||||
if (State.mode == HOLD) strip->trigger();
|
|
||||||
}
|
|
||||||
} else if (trans_cnt >= trans_cnt_max) {
|
|
||||||
strip->setColors(prevsegment, hexcolors_trans);
|
|
||||||
if (State.mode == HOLD) strip->trigger();
|
|
||||||
DBG_OUTPUT_PORT.println("Color transition finished!");
|
|
||||||
trans_cnt = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
strip->setColors(prevsegment, hexcolors_trans);
|
|
||||||
if (State.mode == HOLD) strip->trigger();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Async speed transition
|
|
||||||
if ((segState.mode[prevsegment] != FX_MODE_CUSTOM_0) && (segState.mode[prevsegment] != FX_MODE_CUSTOM_3) && (fx_speed != segState.speed[prevsegment])) {
|
|
||||||
if (Config.transEffect) {
|
|
||||||
//if (true == false) { // disabled for the moment
|
|
||||||
if (speedFadeDelay <= millis()) {
|
|
||||||
//DBG_OUTPUT_PORT.print("Speed trans actual: ");
|
|
||||||
if (fx_speed < segState.speed[prevsegment]) {
|
|
||||||
fx_speed++;
|
|
||||||
}
|
|
||||||
if (fx_speed > segState.speed[prevsegment]) {
|
|
||||||
fx_speed--;
|
|
||||||
}
|
|
||||||
//DBG_OUTPUT_PORT.println(fx_speed);
|
|
||||||
speedFadeDelay = millis() + TRANS_DELAY;
|
|
||||||
strip->setSpeed(prevsegment, convertSpeed(fx_speed));
|
|
||||||
if (State.mode == HOLD) strip->trigger();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fx_speed = segState.speed[prevsegment];
|
|
||||||
//DBG_OUTPUT_PORT.print("Speed actual: ");
|
|
||||||
strip->setSpeed(prevsegment, convertSpeed(fx_speed));
|
|
||||||
//DBG_OUTPUT_PORT.println(fx_speed);
|
|
||||||
if (State.mode == HOLD) strip->trigger();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Async brightness transition
|
|
||||||
if (strip->getBrightness() != brightness_trans) {
|
|
||||||
if (Config.transEffect) {
|
|
||||||
if(brightnessFadeDelay <= millis()) {
|
|
||||||
if (strip->getBrightness() < brightness_trans) {
|
|
||||||
strip->increaseBrightness(1);
|
|
||||||
}
|
|
||||||
if (strip->getBrightness() > brightness_trans) {
|
|
||||||
strip->decreaseBrightness(1);
|
|
||||||
}
|
|
||||||
brightnessFadeDelay = millis() + TRANS_DELAY;
|
|
||||||
if (State.mode == HOLD) strip->trigger();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
brightness_trans = State.brightness;
|
|
||||||
strip->setBrightness(brightness_trans);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Segment change only if color and speed transitions are finished, because they are segment specific
|
|
||||||
if (prevsegment != State.segment) {
|
|
||||||
DBG_OUTPUT_PORT.println("Segment not equal");
|
|
||||||
//if ((segState.mode[State.segment] == FX_MODE_CUSTOM_0) || (segState.mode[State.segment] == FX_MODE_CUSTOM_2) || (segState.mode[prevsegment] == FX_MODE_CUSTOM_0)) {
|
|
||||||
if ((segState.mode[State.segment] == FX_MODE_CUSTOM_0) || (segState.mode[prevsegment] == FX_MODE_CUSTOM_0)) {
|
|
||||||
fx_speed = segState.speed[State.segment];
|
|
||||||
DBG_OUTPUT_PORT.printf("Switched segment from: %i to %i", prevsegment, State.segment);
|
|
||||||
prevsegment = State.segment;
|
|
||||||
} else if ((memcmp(hexcolors_trans, strip->getColors(prevsegment), sizeof(hexcolors_trans)) == 0) && (fx_speed == segState.speed[prevsegment])) {
|
|
||||||
memcpy(hexcolors_trans, segState.colors[State.segment], sizeof(hexcolors_trans));
|
|
||||||
fx_speed = segState.speed[State.segment];
|
|
||||||
DBG_OUTPUT_PORT.printf("Switched segment from: %i to %i\r\n", prevsegment, State.segment);
|
|
||||||
prevsegment = State.segment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(ENABLE_REMOTE)
|
#if defined(ENABLE_REMOTE)
|
||||||
handleRemote();
|
handleRemote();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,651 +0,0 @@
|
|||||||
/*
|
|
||||||
WS2812FX.h - Library for WS2812 LED effects.
|
|
||||||
|
|
||||||
Harm Aldick - 2016
|
|
||||||
www.aldick.org
|
|
||||||
FEATURES
|
|
||||||
* A lot of blinken modes and counting
|
|
||||||
* WS2812FX can be used as drop-in replacement for Adafruit NeoPixel Library
|
|
||||||
NOTES
|
|
||||||
* Uses the Adafruit NeoPixel library. Get it here:
|
|
||||||
https://github.com/adafruit/Adafruit_NeoPixel
|
|
||||||
LICENSE
|
|
||||||
The MIT License (MIT)
|
|
||||||
Copyright (c) 2016 Harm Aldick
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
CHANGELOG
|
|
||||||
2016-05-28 Initial beta release
|
|
||||||
2016-06-03 Code cleanup, minor improvements, new modes
|
|
||||||
2016-06-04 2 new fx, fixed setColor (now also resets _mode_color)
|
|
||||||
2017-02-02 added external trigger functionality (e.g. for sound-to-light)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef WS2812FX_h
|
|
||||||
#define WS2812FX_h
|
|
||||||
|
|
||||||
#define FSH(x) (__FlashStringHelper*)(x)
|
|
||||||
|
|
||||||
#include <Adafruit_NeoPixel.h>
|
|
||||||
|
|
||||||
#define DEFAULT_BRIGHTNESS (uint8_t)50
|
|
||||||
#define DEFAULT_MODE (uint8_t)0
|
|
||||||
#define DEFAULT_SPEED (uint16_t)1000
|
|
||||||
#define DEFAULT_COLOR (uint32_t)0xFF0000
|
|
||||||
|
|
||||||
#if defined(ESP8266) || defined(ESP32)
|
|
||||||
//#pragma message("Compiling for ESP")
|
|
||||||
#define SPEED_MIN (uint16_t)2
|
|
||||||
#else
|
|
||||||
//#pragma message("Compiling for Arduino")
|
|
||||||
#define SPEED_MIN (uint16_t)10
|
|
||||||
#endif
|
|
||||||
#define SPEED_MAX (uint16_t)65535
|
|
||||||
|
|
||||||
#define BRIGHTNESS_MIN (uint8_t)0
|
|
||||||
#define BRIGHTNESS_MAX (uint8_t)255
|
|
||||||
|
|
||||||
/* each segment uses 36 bytes of SRAM memory, so if you're application fails because of
|
|
||||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
|
||||||
#define MAX_NUM_SEGMENTS 10
|
|
||||||
#define NUM_COLORS 3 /* number of colors per segment */
|
|
||||||
#define MAX_CUSTOM_MODES 10
|
|
||||||
#define SEGMENT _segments[_segment_index]
|
|
||||||
#define SEGMENT_RUNTIME _segment_runtimes[_segment_index]
|
|
||||||
#define SEGMENT_LENGTH (uint16_t)(SEGMENT.stop - SEGMENT.start + 1)
|
|
||||||
|
|
||||||
// some common colors
|
|
||||||
#define RED (uint32_t)0xFF0000
|
|
||||||
#define GREEN (uint32_t)0x00FF00
|
|
||||||
#define BLUE (uint32_t)0x0000FF
|
|
||||||
#define WHITE (uint32_t)0xFFFFFF
|
|
||||||
#define BLACK (uint32_t)0x000000
|
|
||||||
#define YELLOW (uint32_t)0xFFFF00
|
|
||||||
#define CYAN (uint32_t)0x00FFFF
|
|
||||||
#define MAGENTA (uint32_t)0xFF00FF
|
|
||||||
#define PURPLE (uint32_t)0x400080
|
|
||||||
#define ORANGE (uint32_t)0xFF3000
|
|
||||||
#define PINK (uint32_t)0xFF1493
|
|
||||||
#define ULTRAWHITE (uint32_t)0xFFFFFFFF
|
|
||||||
#define DARK(c) (uint32_t)((c >> 4) & 0x0f0f0f0f)
|
|
||||||
|
|
||||||
// segment options
|
|
||||||
// bit 7: reverse animation
|
|
||||||
// bits 4-6: fade rate (0-7)
|
|
||||||
// bit 3: gamma correction
|
|
||||||
// bits 1-2: size
|
|
||||||
// bits 0: TBD
|
|
||||||
#define NO_OPTIONS (uint8_t)B00000000
|
|
||||||
#define REVERSE (uint8_t)B10000000
|
|
||||||
#define IS_REVERSE ((SEGMENT.options & REVERSE) == REVERSE)
|
|
||||||
#define FADE_XFAST (uint8_t)B00010000
|
|
||||||
#define FADE_FAST (uint8_t)B00100000
|
|
||||||
#define FADE_MEDIUM (uint8_t)B00110000
|
|
||||||
#define FADE_SLOW (uint8_t)B01000000
|
|
||||||
#define FADE_XSLOW (uint8_t)B01010000
|
|
||||||
#define FADE_XXSLOW (uint8_t)B01100000
|
|
||||||
#define FADE_GLACIAL (uint8_t)B01110000
|
|
||||||
#define FADE_RATE ((SEGMENT.options >> 4) & 7)
|
|
||||||
#define GAMMA (uint8_t)B00001000
|
|
||||||
#define IS_GAMMA ((SEGMENT.options & GAMMA) == GAMMA)
|
|
||||||
#define SIZE_SMALL (uint8_t)B00000000
|
|
||||||
#define SIZE_MEDIUM (uint8_t)B00000010
|
|
||||||
#define SIZE_LARGE (uint8_t)B00000100
|
|
||||||
#define SIZE_XLARGE (uint8_t)B00000110
|
|
||||||
#define SIZE_OPTION ((SEGMENT.options >> 1) & 3)
|
|
||||||
|
|
||||||
// segment runtime options (aux_param2)
|
|
||||||
#define FRAME (uint8_t)B10000000
|
|
||||||
#define SET_FRAME (SEGMENT_RUNTIME.aux_param2 |= FRAME)
|
|
||||||
#define CLR_FRAME (SEGMENT_RUNTIME.aux_param2 &= ~FRAME)
|
|
||||||
#define CYCLE (uint8_t)B01000000
|
|
||||||
#define SET_CYCLE (SEGMENT_RUNTIME.aux_param2 |= CYCLE)
|
|
||||||
#define CLR_CYCLE (SEGMENT_RUNTIME.aux_param2 &= ~CYCLE)
|
|
||||||
|
|
||||||
#define MODE_COUNT (sizeof(_names)/sizeof(_names[0]))
|
|
||||||
|
|
||||||
#define FX_MODE_STATIC 0
|
|
||||||
#define FX_MODE_BLINK 1
|
|
||||||
#define FX_MODE_BREATH 2
|
|
||||||
#define FX_MODE_COLOR_WIPE 3
|
|
||||||
#define FX_MODE_COLOR_WIPE_INV 4
|
|
||||||
#define FX_MODE_COLOR_WIPE_REV 5
|
|
||||||
#define FX_MODE_COLOR_WIPE_REV_INV 6
|
|
||||||
#define FX_MODE_COLOR_WIPE_RANDOM 7
|
|
||||||
#define FX_MODE_RANDOM_COLOR 8
|
|
||||||
#define FX_MODE_SINGLE_DYNAMIC 9
|
|
||||||
#define FX_MODE_MULTI_DYNAMIC 10
|
|
||||||
#define FX_MODE_RAINBOW 11
|
|
||||||
#define FX_MODE_RAINBOW_CYCLE 12
|
|
||||||
#define FX_MODE_SCAN 13
|
|
||||||
#define FX_MODE_DUAL_SCAN 14
|
|
||||||
#define FX_MODE_FADE 15
|
|
||||||
#define FX_MODE_THEATER_CHASE 16
|
|
||||||
#define FX_MODE_THEATER_CHASE_RAINBOW 17
|
|
||||||
#define FX_MODE_RUNNING_LIGHTS 18
|
|
||||||
#define FX_MODE_TWINKLE 19
|
|
||||||
#define FX_MODE_TWINKLE_RANDOM 20
|
|
||||||
#define FX_MODE_TWINKLE_FADE 21
|
|
||||||
#define FX_MODE_TWINKLE_FADE_RANDOM 22
|
|
||||||
#define FX_MODE_SPARKLE 23
|
|
||||||
#define FX_MODE_FLASH_SPARKLE 24
|
|
||||||
#define FX_MODE_HYPER_SPARKLE 25
|
|
||||||
#define FX_MODE_STROBE 26
|
|
||||||
#define FX_MODE_STROBE_RAINBOW 27
|
|
||||||
#define FX_MODE_MULTI_STROBE 28
|
|
||||||
#define FX_MODE_BLINK_RAINBOW 29
|
|
||||||
#define FX_MODE_CHASE_WHITE 30
|
|
||||||
#define FX_MODE_CHASE_COLOR 31
|
|
||||||
#define FX_MODE_CHASE_RANDOM 32
|
|
||||||
#define FX_MODE_CHASE_RAINBOW 33
|
|
||||||
#define FX_MODE_CHASE_FLASH 34
|
|
||||||
#define FX_MODE_CHASE_FLASH_RANDOM 35
|
|
||||||
#define FX_MODE_CHASE_RAINBOW_WHITE 36
|
|
||||||
#define FX_MODE_CHASE_BLACKOUT 37
|
|
||||||
#define FX_MODE_CHASE_BLACKOUT_RAINBOW 38
|
|
||||||
#define FX_MODE_COLOR_SWEEP_RANDOM 39
|
|
||||||
#define FX_MODE_RUNNING_COLOR 40
|
|
||||||
#define FX_MODE_RUNNING_RED_BLUE 41
|
|
||||||
#define FX_MODE_RUNNING_RANDOM 42
|
|
||||||
#define FX_MODE_LARSON_SCANNER 43
|
|
||||||
#define FX_MODE_COMET 44
|
|
||||||
#define FX_MODE_FIREWORKS 45
|
|
||||||
#define FX_MODE_FIREWORKS_RANDOM 46
|
|
||||||
#define FX_MODE_MERRY_CHRISTMAS 47
|
|
||||||
#define FX_MODE_FIRE_FLICKER 48
|
|
||||||
#define FX_MODE_FIRE_FLICKER_SOFT 49
|
|
||||||
#define FX_MODE_FIRE_FLICKER_INTENSE 50
|
|
||||||
#define FX_MODE_CIRCUS_COMBUSTUS 51
|
|
||||||
#define FX_MODE_HALLOWEEN 52
|
|
||||||
#define FX_MODE_BICOLOR_CHASE 53
|
|
||||||
#define FX_MODE_TRICOLOR_CHASE 54
|
|
||||||
#define FX_MODE_ICU 55
|
|
||||||
#define FX_MODE_CUSTOM 56 // keep this for backward compatiblity
|
|
||||||
#define FX_MODE_CUSTOM_0 56 // custom modes need to go at the end
|
|
||||||
#define FX_MODE_CUSTOM_1 57
|
|
||||||
#define FX_MODE_CUSTOM_2 58
|
|
||||||
#define FX_MODE_CUSTOM_3 59
|
|
||||||
#define FX_MODE_CUSTOM_4 60
|
|
||||||
#define FX_MODE_CUSTOM_5 61
|
|
||||||
#define FX_MODE_CUSTOM_6 62
|
|
||||||
#define FX_MODE_CUSTOM_7 63
|
|
||||||
#define FX_MODE_CUSTOM_8 64
|
|
||||||
#define FX_MODE_CUSTOM_9 65
|
|
||||||
|
|
||||||
// create GLOBAL names to allow WS2812FX to compile with sketches and other libs that store strings
|
|
||||||
// in PROGMEM (get rid of the "section type conflict with __c" errors once and for all. Amen.)
|
|
||||||
const char name_0[] PROGMEM = "Static";
|
|
||||||
const char name_1[] PROGMEM = "Blink";
|
|
||||||
const char name_2[] PROGMEM = "Breath";
|
|
||||||
const char name_3[] PROGMEM = "Color Wipe";
|
|
||||||
const char name_4[] PROGMEM = "Color Wipe Inverse";
|
|
||||||
const char name_5[] PROGMEM = "Color Wipe Reverse";
|
|
||||||
const char name_6[] PROGMEM = "Color Wipe Reverse Inverse";
|
|
||||||
const char name_7[] PROGMEM = "Color Wipe Random";
|
|
||||||
const char name_8[] PROGMEM = "Random Color";
|
|
||||||
const char name_9[] PROGMEM = "Single Dynamic";
|
|
||||||
const char name_10[] PROGMEM = "Multi Dynamic";
|
|
||||||
const char name_11[] PROGMEM = "Rainbow";
|
|
||||||
const char name_12[] PROGMEM = "Rainbow Cycle";
|
|
||||||
const char name_13[] PROGMEM = "Scan";
|
|
||||||
const char name_14[] PROGMEM = "Dual Scan";
|
|
||||||
const char name_15[] PROGMEM = "Fade";
|
|
||||||
const char name_16[] PROGMEM = "Theater Chase";
|
|
||||||
const char name_17[] PROGMEM = "Theater Chase Rainbow";
|
|
||||||
const char name_18[] PROGMEM = "Running Lights";
|
|
||||||
const char name_19[] PROGMEM = "Twinkle";
|
|
||||||
const char name_20[] PROGMEM = "Twinkle Random";
|
|
||||||
const char name_21[] PROGMEM = "Twinkle Fade";
|
|
||||||
const char name_22[] PROGMEM = "Twinkle Fade Random";
|
|
||||||
const char name_23[] PROGMEM = "Sparkle";
|
|
||||||
const char name_24[] PROGMEM = "Flash Sparkle";
|
|
||||||
const char name_25[] PROGMEM = "Hyper Sparkle";
|
|
||||||
const char name_26[] PROGMEM = "Strobe";
|
|
||||||
const char name_27[] PROGMEM = "Strobe Rainbow";
|
|
||||||
const char name_28[] PROGMEM = "Multi Strobe";
|
|
||||||
const char name_29[] PROGMEM = "Blink Rainbow";
|
|
||||||
const char name_30[] PROGMEM = "Chase White";
|
|
||||||
const char name_31[] PROGMEM = "Chase Color";
|
|
||||||
const char name_32[] PROGMEM = "Chase Random";
|
|
||||||
const char name_33[] PROGMEM = "Chase Rainbow";
|
|
||||||
const char name_34[] PROGMEM = "Chase Flash";
|
|
||||||
const char name_35[] PROGMEM = "Chase Flash Random";
|
|
||||||
const char name_36[] PROGMEM = "Chase Rainbow White";
|
|
||||||
const char name_37[] PROGMEM = "Chase Blackout";
|
|
||||||
const char name_38[] PROGMEM = "Chase Blackout Rainbow";
|
|
||||||
const char name_39[] PROGMEM = "Color Sweep Random";
|
|
||||||
const char name_40[] PROGMEM = "Running Color";
|
|
||||||
const char name_41[] PROGMEM = "Running Red Blue";
|
|
||||||
const char name_42[] PROGMEM = "Running Random";
|
|
||||||
const char name_43[] PROGMEM = "Larson Scanner";
|
|
||||||
const char name_44[] PROGMEM = "Comet";
|
|
||||||
const char name_45[] PROGMEM = "Fireworks";
|
|
||||||
const char name_46[] PROGMEM = "Fireworks Random";
|
|
||||||
const char name_47[] PROGMEM = "Merry Christmas";
|
|
||||||
const char name_48[] PROGMEM = "Fire Flicker";
|
|
||||||
const char name_49[] PROGMEM = "Fire Flicker (soft)";
|
|
||||||
const char name_50[] PROGMEM = "Fire Flicker (intense)";
|
|
||||||
const char name_51[] PROGMEM = "Circus Combustus";
|
|
||||||
const char name_52[] PROGMEM = "Halloween";
|
|
||||||
const char name_53[] PROGMEM = "Bicolor Chase";
|
|
||||||
const char name_54[] PROGMEM = "Tricolor Chase";
|
|
||||||
const char name_55[] PROGMEM = "ICU";
|
|
||||||
const char name_56[] PROGMEM = "Custom 0"; // custom modes need to go at the end
|
|
||||||
const char name_57[] PROGMEM = "Custom 1";
|
|
||||||
const char name_58[] PROGMEM = "Custom 2";
|
|
||||||
const char name_59[] PROGMEM = "Custom 3";
|
|
||||||
const char name_60[] PROGMEM = "Custom 4";
|
|
||||||
const char name_61[] PROGMEM = "Custom 5";
|
|
||||||
const char name_62[] PROGMEM = "Custom 6";
|
|
||||||
const char name_63[] PROGMEM = "Custom 7";
|
|
||||||
const char name_64[] PROGMEM = "Custom 8";
|
|
||||||
const char name_65[] PROGMEM = "Custom 9";
|
|
||||||
|
|
||||||
static const __FlashStringHelper* _names[] = {
|
|
||||||
FSH(name_0),
|
|
||||||
FSH(name_1),
|
|
||||||
FSH(name_2),
|
|
||||||
FSH(name_3),
|
|
||||||
FSH(name_4),
|
|
||||||
FSH(name_5),
|
|
||||||
FSH(name_6),
|
|
||||||
FSH(name_7),
|
|
||||||
FSH(name_8),
|
|
||||||
FSH(name_9),
|
|
||||||
FSH(name_10),
|
|
||||||
FSH(name_11),
|
|
||||||
FSH(name_12),
|
|
||||||
FSH(name_13),
|
|
||||||
FSH(name_14),
|
|
||||||
FSH(name_15),
|
|
||||||
FSH(name_16),
|
|
||||||
FSH(name_17),
|
|
||||||
FSH(name_18),
|
|
||||||
FSH(name_19),
|
|
||||||
FSH(name_20),
|
|
||||||
FSH(name_21),
|
|
||||||
FSH(name_22),
|
|
||||||
FSH(name_23),
|
|
||||||
FSH(name_24),
|
|
||||||
FSH(name_25),
|
|
||||||
FSH(name_26),
|
|
||||||
FSH(name_27),
|
|
||||||
FSH(name_28),
|
|
||||||
FSH(name_29),
|
|
||||||
FSH(name_30),
|
|
||||||
FSH(name_31),
|
|
||||||
FSH(name_32),
|
|
||||||
FSH(name_33),
|
|
||||||
FSH(name_34),
|
|
||||||
FSH(name_35),
|
|
||||||
FSH(name_36),
|
|
||||||
FSH(name_37),
|
|
||||||
FSH(name_38),
|
|
||||||
FSH(name_39),
|
|
||||||
FSH(name_40),
|
|
||||||
FSH(name_41),
|
|
||||||
FSH(name_42),
|
|
||||||
FSH(name_43),
|
|
||||||
FSH(name_44),
|
|
||||||
FSH(name_45),
|
|
||||||
FSH(name_46),
|
|
||||||
FSH(name_47),
|
|
||||||
FSH(name_48),
|
|
||||||
FSH(name_49),
|
|
||||||
FSH(name_50),
|
|
||||||
FSH(name_51),
|
|
||||||
FSH(name_52),
|
|
||||||
FSH(name_53),
|
|
||||||
FSH(name_54),
|
|
||||||
FSH(name_55),
|
|
||||||
FSH(name_56),
|
|
||||||
FSH(name_57),
|
|
||||||
FSH(name_58),
|
|
||||||
FSH(name_59),
|
|
||||||
FSH(name_60),
|
|
||||||
FSH(name_61),
|
|
||||||
FSH(name_62),
|
|
||||||
FSH(name_63),
|
|
||||||
FSH(name_64),
|
|
||||||
FSH(name_65)
|
|
||||||
};
|
|
||||||
|
|
||||||
class WS2812FX : public Adafruit_NeoPixel {
|
|
||||||
|
|
||||||
typedef uint16_t (WS2812FX::*mode_ptr)(void);
|
|
||||||
|
|
||||||
// segment parameters
|
|
||||||
public:
|
|
||||||
typedef struct Segment { // 20 bytes
|
|
||||||
uint16_t start;
|
|
||||||
uint16_t stop;
|
|
||||||
uint16_t speed;
|
|
||||||
uint8_t mode;
|
|
||||||
uint8_t options;
|
|
||||||
uint32_t colors[NUM_COLORS];
|
|
||||||
} segment;
|
|
||||||
|
|
||||||
// segment runtime parameters
|
|
||||||
typedef struct Segment_runtime { // 16 bytes
|
|
||||||
unsigned long next_time;
|
|
||||||
uint32_t counter_mode_step;
|
|
||||||
uint32_t counter_mode_call;
|
|
||||||
uint8_t aux_param; // auxilary param (usually stores a color_wheel index)
|
|
||||||
uint8_t aux_param2; // auxilary param (usually stores bitwise options)
|
|
||||||
uint16_t aux_param3; // auxilary param (usually stores a segment index)
|
|
||||||
} segment_runtime;
|
|
||||||
|
|
||||||
WS2812FX(uint16_t n, uint8_t p, neoPixelType t) : Adafruit_NeoPixel(n, p, t) {
|
|
||||||
_mode[FX_MODE_STATIC] = &WS2812FX::mode_static;
|
|
||||||
_mode[FX_MODE_BLINK] = &WS2812FX::mode_blink;
|
|
||||||
_mode[FX_MODE_COLOR_WIPE] = &WS2812FX::mode_color_wipe;
|
|
||||||
_mode[FX_MODE_COLOR_WIPE_INV] = &WS2812FX::mode_color_wipe_inv;
|
|
||||||
_mode[FX_MODE_COLOR_WIPE_REV] = &WS2812FX::mode_color_wipe_rev;
|
|
||||||
_mode[FX_MODE_COLOR_WIPE_REV_INV] = &WS2812FX::mode_color_wipe_rev_inv;
|
|
||||||
_mode[FX_MODE_COLOR_WIPE_RANDOM] = &WS2812FX::mode_color_wipe_random;
|
|
||||||
_mode[FX_MODE_RANDOM_COLOR] = &WS2812FX::mode_random_color;
|
|
||||||
_mode[FX_MODE_SINGLE_DYNAMIC] = &WS2812FX::mode_single_dynamic;
|
|
||||||
_mode[FX_MODE_MULTI_DYNAMIC] = &WS2812FX::mode_multi_dynamic;
|
|
||||||
_mode[FX_MODE_RAINBOW] = &WS2812FX::mode_rainbow;
|
|
||||||
_mode[FX_MODE_RAINBOW_CYCLE] = &WS2812FX::mode_rainbow_cycle;
|
|
||||||
_mode[FX_MODE_SCAN] = &WS2812FX::mode_scan;
|
|
||||||
_mode[FX_MODE_DUAL_SCAN] = &WS2812FX::mode_dual_scan;
|
|
||||||
_mode[FX_MODE_FADE] = &WS2812FX::mode_fade;
|
|
||||||
_mode[FX_MODE_THEATER_CHASE] = &WS2812FX::mode_theater_chase;
|
|
||||||
_mode[FX_MODE_THEATER_CHASE_RAINBOW] = &WS2812FX::mode_theater_chase_rainbow;
|
|
||||||
_mode[FX_MODE_TWINKLE] = &WS2812FX::mode_twinkle;
|
|
||||||
_mode[FX_MODE_TWINKLE_RANDOM] = &WS2812FX::mode_twinkle_random;
|
|
||||||
_mode[FX_MODE_TWINKLE_FADE] = &WS2812FX::mode_twinkle_fade;
|
|
||||||
_mode[FX_MODE_TWINKLE_FADE_RANDOM] = &WS2812FX::mode_twinkle_fade_random;
|
|
||||||
_mode[FX_MODE_SPARKLE] = &WS2812FX::mode_sparkle;
|
|
||||||
_mode[FX_MODE_FLASH_SPARKLE] = &WS2812FX::mode_flash_sparkle;
|
|
||||||
_mode[FX_MODE_HYPER_SPARKLE] = &WS2812FX::mode_hyper_sparkle;
|
|
||||||
_mode[FX_MODE_STROBE] = &WS2812FX::mode_strobe;
|
|
||||||
_mode[FX_MODE_STROBE_RAINBOW] = &WS2812FX::mode_strobe_rainbow;
|
|
||||||
_mode[FX_MODE_MULTI_STROBE] = &WS2812FX::mode_multi_strobe;
|
|
||||||
_mode[FX_MODE_BLINK_RAINBOW] = &WS2812FX::mode_blink_rainbow;
|
|
||||||
_mode[FX_MODE_CHASE_WHITE] = &WS2812FX::mode_chase_white;
|
|
||||||
_mode[FX_MODE_CHASE_COLOR] = &WS2812FX::mode_chase_color;
|
|
||||||
_mode[FX_MODE_CHASE_RANDOM] = &WS2812FX::mode_chase_random;
|
|
||||||
_mode[FX_MODE_CHASE_RAINBOW] = &WS2812FX::mode_chase_rainbow;
|
|
||||||
_mode[FX_MODE_CHASE_FLASH] = &WS2812FX::mode_chase_flash;
|
|
||||||
_mode[FX_MODE_CHASE_FLASH_RANDOM] = &WS2812FX::mode_chase_flash_random;
|
|
||||||
_mode[FX_MODE_CHASE_RAINBOW_WHITE] = &WS2812FX::mode_chase_rainbow_white;
|
|
||||||
_mode[FX_MODE_CHASE_BLACKOUT] = &WS2812FX::mode_chase_blackout;
|
|
||||||
_mode[FX_MODE_CHASE_BLACKOUT_RAINBOW] = &WS2812FX::mode_chase_blackout_rainbow;
|
|
||||||
_mode[FX_MODE_COLOR_SWEEP_RANDOM] = &WS2812FX::mode_color_sweep_random;
|
|
||||||
_mode[FX_MODE_RUNNING_COLOR] = &WS2812FX::mode_running_color;
|
|
||||||
_mode[FX_MODE_RUNNING_RED_BLUE] = &WS2812FX::mode_running_red_blue;
|
|
||||||
_mode[FX_MODE_RUNNING_RANDOM] = &WS2812FX::mode_running_random;
|
|
||||||
_mode[FX_MODE_LARSON_SCANNER] = &WS2812FX::mode_larson_scanner;
|
|
||||||
_mode[FX_MODE_COMET] = &WS2812FX::mode_comet;
|
|
||||||
_mode[FX_MODE_FIREWORKS] = &WS2812FX::mode_fireworks;
|
|
||||||
_mode[FX_MODE_FIREWORKS_RANDOM] = &WS2812FX::mode_fireworks_random;
|
|
||||||
_mode[FX_MODE_MERRY_CHRISTMAS] = &WS2812FX::mode_merry_christmas;
|
|
||||||
_mode[FX_MODE_FIRE_FLICKER] = &WS2812FX::mode_fire_flicker;
|
|
||||||
_mode[FX_MODE_FIRE_FLICKER_SOFT] = &WS2812FX::mode_fire_flicker_soft;
|
|
||||||
_mode[FX_MODE_FIRE_FLICKER_INTENSE] = &WS2812FX::mode_fire_flicker_intense;
|
|
||||||
_mode[FX_MODE_CIRCUS_COMBUSTUS] = &WS2812FX::mode_circus_combustus;
|
|
||||||
_mode[FX_MODE_HALLOWEEN] = &WS2812FX::mode_halloween;
|
|
||||||
_mode[FX_MODE_BICOLOR_CHASE] = &WS2812FX::mode_bicolor_chase;
|
|
||||||
_mode[FX_MODE_TRICOLOR_CHASE] = &WS2812FX::mode_tricolor_chase;
|
|
||||||
// if flash memory is constrained (I'm looking at you Arduino Nano), replace modes
|
|
||||||
// that use a lot of flash with mode_static (reduces flash footprint by about 2100 bytes)
|
|
||||||
#ifdef REDUCED_MODES
|
|
||||||
_mode[FX_MODE_BREATH] = &WS2812FX::mode_static;
|
|
||||||
_mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_static;
|
|
||||||
_mode[FX_MODE_ICU] = &WS2812FX::mode_static;
|
|
||||||
#else
|
|
||||||
_mode[FX_MODE_BREATH] = &WS2812FX::mode_breath;
|
|
||||||
_mode[FX_MODE_RUNNING_LIGHTS] = &WS2812FX::mode_running_lights;
|
|
||||||
_mode[FX_MODE_ICU] = &WS2812FX::mode_icu;
|
|
||||||
#endif
|
|
||||||
_mode[FX_MODE_CUSTOM_0] = &WS2812FX::mode_custom_0;
|
|
||||||
_mode[FX_MODE_CUSTOM_1] = &WS2812FX::mode_custom_1;
|
|
||||||
_mode[FX_MODE_CUSTOM_2] = &WS2812FX::mode_custom_2;
|
|
||||||
_mode[FX_MODE_CUSTOM_3] = &WS2812FX::mode_custom_3;
|
|
||||||
_mode[FX_MODE_CUSTOM_4] = &WS2812FX::mode_custom_4;
|
|
||||||
_mode[FX_MODE_CUSTOM_5] = &WS2812FX::mode_custom_5;
|
|
||||||
_mode[FX_MODE_CUSTOM_6] = &WS2812FX::mode_custom_6;
|
|
||||||
_mode[FX_MODE_CUSTOM_7] = &WS2812FX::mode_custom_7;
|
|
||||||
_mode[FX_MODE_CUSTOM_8] = &WS2812FX::mode_custom_8;
|
|
||||||
_mode[FX_MODE_CUSTOM_9] = &WS2812FX::mode_custom_9;
|
|
||||||
|
|
||||||
brightness = DEFAULT_BRIGHTNESS + 1; // Adafruit_NeoPixel internally offsets brightness by 1
|
|
||||||
_running = false;
|
|
||||||
_num_segments = 1;
|
|
||||||
_segments[0].mode = DEFAULT_MODE;
|
|
||||||
_segments[0].colors[0] = DEFAULT_COLOR;
|
|
||||||
_segments[0].start = 0;
|
|
||||||
_segments[0].stop = n - 1;
|
|
||||||
_segments[0].speed = DEFAULT_SPEED;
|
|
||||||
resetSegmentRuntimes();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
// timer(void),
|
|
||||||
init(void),
|
|
||||||
service(void),
|
|
||||||
start(void),
|
|
||||||
stop(void),
|
|
||||||
pause(void),
|
|
||||||
resume(void),
|
|
||||||
strip_off(void),
|
|
||||||
fade_out(void),
|
|
||||||
fade_out(uint32_t),
|
|
||||||
setMode(uint8_t m),
|
|
||||||
setMode(uint8_t seg, uint8_t m),
|
|
||||||
setOptions(uint8_t seg, uint8_t o),
|
|
||||||
setCustomMode(uint16_t (*p)()),
|
|
||||||
setCustomShow(void (*p)()),
|
|
||||||
setSpeed(uint16_t s),
|
|
||||||
setSpeed(uint8_t seg, uint16_t s),
|
|
||||||
increaseSpeed(uint8_t s),
|
|
||||||
decreaseSpeed(uint8_t s),
|
|
||||||
setColor(uint8_t r, uint8_t g, uint8_t b),
|
|
||||||
setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w),
|
|
||||||
setColor(uint32_t c),
|
|
||||||
setColor(uint8_t seg, uint32_t c),
|
|
||||||
setColors(uint8_t seg, uint32_t* c),
|
|
||||||
setBrightness(uint8_t b),
|
|
||||||
increaseBrightness(uint8_t s),
|
|
||||||
decreaseBrightness(uint8_t s),
|
|
||||||
setLength(uint16_t b),
|
|
||||||
increaseLength(uint16_t s),
|
|
||||||
decreaseLength(uint16_t s),
|
|
||||||
trigger(void),
|
|
||||||
setNumSegments(uint8_t n),
|
|
||||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, bool reverse),
|
|
||||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, uint32_t color, uint16_t speed, uint8_t options),
|
|
||||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed, bool reverse),
|
|
||||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t mode, const uint32_t colors[], uint16_t speed, uint8_t options),
|
|
||||||
resetSegments(),
|
|
||||||
resetSegmentRuntimes(),
|
|
||||||
resetSegmentRuntime(uint8_t),
|
|
||||||
setPixelColor(uint16_t n, uint32_t c),
|
|
||||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b),
|
|
||||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w),
|
|
||||||
copyPixels(uint16_t d, uint16_t s, uint16_t c),
|
|
||||||
show(void);
|
|
||||||
|
|
||||||
boolean
|
|
||||||
isRunning(void),
|
|
||||||
isTriggered(void),
|
|
||||||
isFrame(void),
|
|
||||||
isFrame(uint8_t),
|
|
||||||
isCycle(void),
|
|
||||||
isCycle(uint8_t);
|
|
||||||
|
|
||||||
uint8_t
|
|
||||||
random8(void),
|
|
||||||
random8(uint8_t),
|
|
||||||
getMode(void),
|
|
||||||
getMode(uint8_t),
|
|
||||||
getModeCount(void),
|
|
||||||
setCustomMode(const __FlashStringHelper* name, uint16_t (*p)()),
|
|
||||||
setCustomMode(uint8_t i, const __FlashStringHelper* name, uint16_t (*p)()),
|
|
||||||
getNumSegments(void),
|
|
||||||
get_random_wheel_index(uint8_t),
|
|
||||||
getOptions(uint8_t),
|
|
||||||
getNumBytesPerPixel(void),
|
|
||||||
getSegmentIndex(void);
|
|
||||||
|
|
||||||
uint16_t
|
|
||||||
random16(void),
|
|
||||||
random16(uint16_t),
|
|
||||||
getSpeed(void),
|
|
||||||
getSpeed(uint8_t),
|
|
||||||
getLength(void),
|
|
||||||
getNumBytes(void);
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
color_wheel(uint8_t),
|
|
||||||
getColor(void),
|
|
||||||
getColor(uint8_t),
|
|
||||||
intensitySum(void);
|
|
||||||
|
|
||||||
uint32_t* getColors(uint8_t);
|
|
||||||
uint32_t* intensitySums(void);
|
|
||||||
|
|
||||||
const __FlashStringHelper* getModeName(uint8_t m);
|
|
||||||
|
|
||||||
WS2812FX::Segment* getSegment(void);
|
|
||||||
|
|
||||||
WS2812FX::Segment* getSegment(uint8_t);
|
|
||||||
|
|
||||||
WS2812FX::Segment* getSegments(void);
|
|
||||||
|
|
||||||
WS2812FX::Segment_runtime* getSegmentRuntime(void);
|
|
||||||
|
|
||||||
WS2812FX::Segment_runtime* getSegmentRuntime(uint8_t);
|
|
||||||
|
|
||||||
WS2812FX::Segment_runtime* getSegmentRuntimes(void);
|
|
||||||
|
|
||||||
// mode helper functions
|
|
||||||
uint16_t
|
|
||||||
blink(uint32_t, uint32_t, bool strobe),
|
|
||||||
color_wipe(uint32_t, uint32_t, bool),
|
|
||||||
twinkle(uint32_t, uint32_t),
|
|
||||||
twinkle_fade(uint32_t),
|
|
||||||
chase(uint32_t, uint32_t, uint32_t),
|
|
||||||
running(uint32_t, uint32_t),
|
|
||||||
fireworks(uint32_t),
|
|
||||||
fire_flicker(int),
|
|
||||||
tricolor_chase(uint32_t, uint32_t, uint32_t),
|
|
||||||
scan(uint32_t, uint32_t, bool);
|
|
||||||
uint32_t
|
|
||||||
color_blend(uint32_t, uint32_t, uint8_t);
|
|
||||||
|
|
||||||
// builtin modes
|
|
||||||
uint16_t
|
|
||||||
mode_static(void),
|
|
||||||
mode_blink(void),
|
|
||||||
mode_blink_rainbow(void),
|
|
||||||
mode_strobe(void),
|
|
||||||
mode_strobe_rainbow(void),
|
|
||||||
mode_color_wipe(void),
|
|
||||||
mode_color_wipe_inv(void),
|
|
||||||
mode_color_wipe_rev(void),
|
|
||||||
mode_color_wipe_rev_inv(void),
|
|
||||||
mode_color_wipe_random(void),
|
|
||||||
mode_color_sweep_random(void),
|
|
||||||
mode_random_color(void),
|
|
||||||
mode_single_dynamic(void),
|
|
||||||
mode_multi_dynamic(void),
|
|
||||||
mode_breath(void),
|
|
||||||
mode_fade(void),
|
|
||||||
mode_scan(void),
|
|
||||||
mode_dual_scan(void),
|
|
||||||
mode_theater_chase(void),
|
|
||||||
mode_theater_chase_rainbow(void),
|
|
||||||
mode_rainbow(void),
|
|
||||||
mode_rainbow_cycle(void),
|
|
||||||
mode_running_lights(void),
|
|
||||||
mode_twinkle(void),
|
|
||||||
mode_twinkle_random(void),
|
|
||||||
mode_twinkle_fade(void),
|
|
||||||
mode_twinkle_fade_random(void),
|
|
||||||
mode_sparkle(void),
|
|
||||||
mode_flash_sparkle(void),
|
|
||||||
mode_hyper_sparkle(void),
|
|
||||||
mode_multi_strobe(void),
|
|
||||||
mode_chase_white(void),
|
|
||||||
mode_chase_color(void),
|
|
||||||
mode_chase_random(void),
|
|
||||||
mode_chase_rainbow(void),
|
|
||||||
mode_chase_flash(void),
|
|
||||||
mode_chase_flash_random(void),
|
|
||||||
mode_chase_rainbow_white(void),
|
|
||||||
mode_chase_blackout(void),
|
|
||||||
mode_chase_blackout_rainbow(void),
|
|
||||||
mode_running_color(void),
|
|
||||||
mode_running_red_blue(void),
|
|
||||||
mode_running_random(void),
|
|
||||||
mode_larson_scanner(void),
|
|
||||||
mode_comet(void),
|
|
||||||
mode_fireworks(void),
|
|
||||||
mode_fireworks_random(void),
|
|
||||||
mode_merry_christmas(void),
|
|
||||||
mode_halloween(void),
|
|
||||||
mode_fire_flicker(void),
|
|
||||||
mode_fire_flicker_soft(void),
|
|
||||||
mode_fire_flicker_intense(void),
|
|
||||||
mode_circus_combustus(void),
|
|
||||||
mode_bicolor_chase(void),
|
|
||||||
mode_tricolor_chase(void),
|
|
||||||
mode_icu(void),
|
|
||||||
mode_custom_0(void),
|
|
||||||
mode_custom_1(void),
|
|
||||||
mode_custom_2(void),
|
|
||||||
mode_custom_3(void),
|
|
||||||
mode_custom_4(void),
|
|
||||||
mode_custom_5(void),
|
|
||||||
mode_custom_6(void),
|
|
||||||
mode_custom_7(void),
|
|
||||||
mode_custom_8(void),
|
|
||||||
mode_custom_9(void);
|
|
||||||
private:
|
|
||||||
uint16_t _rand16seed;
|
|
||||||
uint16_t (*customModes[MAX_CUSTOM_MODES])(void) {
|
|
||||||
[]{ return (uint16_t)1000; },
|
|
||||||
[]{ return (uint16_t)1000; },
|
|
||||||
[]{ return (uint16_t)1000; },
|
|
||||||
[]{ return (uint16_t)1000; },
|
|
||||||
[]{ return (uint16_t)1000; },
|
|
||||||
[]{ return (uint16_t)1000; },
|
|
||||||
[]{ return (uint16_t)1000; },
|
|
||||||
[]{ return (uint16_t)1000; },
|
|
||||||
[]{ return (uint16_t)1000; },
|
|
||||||
[]{ return (uint16_t)1000; }
|
|
||||||
};
|
|
||||||
void (*customShow)(void) = NULL;
|
|
||||||
|
|
||||||
boolean
|
|
||||||
_running,
|
|
||||||
_triggered;
|
|
||||||
|
|
||||||
mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element
|
|
||||||
|
|
||||||
uint8_t _segment_index = 0;
|
|
||||||
uint8_t _num_segments = 1;
|
|
||||||
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 20 bytes per element
|
|
||||||
// start, stop, speed, mode, options, color[]
|
|
||||||
{ 0, 7, DEFAULT_SPEED, FX_MODE_STATIC, NO_OPTIONS, {DEFAULT_COLOR}}
|
|
||||||
};
|
|
||||||
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 16 bytes per element
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -182,9 +182,7 @@
|
|||||||
var mkfile = document.createElement("button");
|
var mkfile = document.createElement("button");
|
||||||
mkfile.innerHTML = 'MkFile';
|
mkfile.innerHTML = 'MkFile';
|
||||||
document.getElementById(element).appendChild(mkfile);
|
document.getElementById(element).appendChild(mkfile);
|
||||||
var para = document.createElement("text");
|
|
||||||
para.innerHTML = " Press Ctrl-S for save, Ctrl-Z for undo, Ctrl-Shift-Z for redo";
|
|
||||||
document.getElementById(element).appendChild(para);
|
|
||||||
function httpPostProcessRequest(){
|
function httpPostProcessRequest(){
|
||||||
if (xmlHttp.readyState == 4){
|
if (xmlHttp.readyState == 4){
|
||||||
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
+269
-365
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,4 @@
|
|||||||
#define USE_WS2812FX_DMA 0 // 0 = Used PIN is ignored & set to RX/GPIO3; 1 = Used PIN is ignored & set to TX/GPIO1; 2 = Used PIN is ignored & set to D4/GPIO2; Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
#define USE_WS2812FX_DMA 0 // 0 = Used PIN is ignored & set to RX/GPIO3; 1 = Used PIN is ignored & set to TX/GPIO1; 2 = Uses PIN is ignored & set to D4/GPIO2; Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
||||||
// or comment it out
|
// or comment it out
|
||||||
#if defined(USE_WS2812FX_DMA)
|
#if defined(USE_WS2812FX_DMA)
|
||||||
#define MAXLEDS 384 // due to memory limit of esp8266 at the moment only 384 leds are supported in DMA Mode. More can crash if mqtt is used.
|
#define MAXLEDS 384 // due to memory limit of esp8266 at the moment only 384 leds are supported in DMA Mode. More can crash if mqtt is used.
|
||||||
@@ -12,60 +12,48 @@
|
|||||||
#define FX_OPTIONS 48 // ws2812fx Options 48 = SIZE_SMALL + FADE_MEDIUM is configurable just for the start; for WS2812FX setSegment OPTIONS, see: https://github.com/kitesurfer1404/WS2812FX/blob/master/extras/WS2812FX%20Users%20Guide.md
|
#define FX_OPTIONS 48 // ws2812fx Options 48 = SIZE_SMALL + FADE_MEDIUM is configurable just for the start; for WS2812FX setSegment OPTIONS, see: https://github.com/kitesurfer1404/WS2812FX/blob/master/extras/WS2812FX%20Users%20Guide.md
|
||||||
//#define LED_TYPE_WS2811 // Uncomment, if LED type uses 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
//#define LED_TYPE_WS2811 // Uncomment, if LED type uses 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||||
#define LED_BUILTIN 2 // ESP-12F has the built in LED on GPIO2, see https://github.com/esp8266/Arduino/issues/2192
|
#define LED_BUILTIN 2 // ESP-12F has the built in LED on GPIO2, see https://github.com/esp8266/Arduino/issues/2192
|
||||||
|
#define POWER_SUPPLY 12 // PIN (12 / D6) If defined, enable output to control external power supply
|
||||||
|
#if defined(POWER_SUPPLY)
|
||||||
|
#define POWER_ON HIGH // Define the output state to turn on the power supply, either HIGH or LOW. Opposite will be uses for power off.
|
||||||
|
#endif
|
||||||
|
|
||||||
char HOSTNAME[65] = "McLightingRGBW"; // Friedly hostname is configurable just for the start. Hostname should not contain spaces as this can break Home Assistant discovery if used.
|
char HOSTNAME[65] = "McLightingRGBW"; // Friedly hostname is configurable just for the start. Hostname should not contain spaces as this can break Home Assistant discovery if used.
|
||||||
|
|
||||||
#define ENABLE_OTA 1 // If defined, enable Arduino OTA code. If set to 0 enable Arduino OTA code, if set to 1 enable ESP8266HTTPUpdateServer OTA code.
|
#define ENABLE_OTA 1 // If defined, enable Arduino OTA code. If set to 0 enable Arduino OTA code, if set to 1 enable ESP8266HTTPUpdateServer OTA code.
|
||||||
#define ENABLE_MQTT 1 // If defined use MQTT OR AMQTT, if set to 0 enable MQTT client code, see: https://github.com/toblum/McLighting/wiki/MQTT-API, if set to 1, enable Async MQTT code, see: https://github.com/marvinroger/async-mqtt-client
|
#define ENABLE_MQTT 1 // If defined use MQTT OR AMQTT, if set to 0 enable MQTT client code, see: https://github.com/toblum/McLighting/wiki/MQTT-API, if set to 1, enable Async MQTT code, see: https://github.com/marvinroger/async-mqtt-client
|
||||||
//#define ENABLE_MQTT_HOSTNAME_CHIPID // Uncomment/comment to add ESPChipID to end of MQTT hostname
|
//#define ENABLE_MQTT_HOSTNAME_CHIPID // Uncomment/comment to add ESPChipID to end of MQTT hostname
|
||||||
//#define ENABLE_MQTT_INCLUDE_IP // uncomment/comment to add the IP-adress to the MQTT message
|
|
||||||
#define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT must be active
|
#define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT must be active
|
||||||
#define MQTT_HOME_ASSISTANT_SUPPORT // If defined, use AMQTT and select Tools -> IwIP Variant -> Higher Bandwidth
|
#define MQTT_HOME_ASSISTANT_SUPPORT // If defined, use AMQTT and select Tools -> IwIP Variant -> Higher Bandwidth
|
||||||
#define DELAY_MQTT_HA_MESSAGE 5 // HA Status is send after DELAY_MQTT_HA_MESSAGE seconds, to save bandwith
|
#define ENABLE_BUTTON 14 // If defined, enable button handling code, see: https://github.com/toblum/McLighting/wiki/Button-control, the value defines the input pin (14 / D5) for switching the LED strip on / off, connect this PIN to ground to trigger button.
|
||||||
|
|
||||||
//#define ENABLE_BUTTON 14 // If defined, enable button handling code, see: https://github.com/toblum/McLighting/wiki/Button-control, the value defines the input pin (14 / D5) for switching the LED strip on / off, connect this PIN to ground to trigger button.
|
|
||||||
//#define ENABLE_BUTTON_GY33 12 // If defined, enable button handling code for GY-33 color sensor to scan color. The value defines the input pin (12 / D6) for read color data with RGB sensor, connect this PIN to ground to trigger button.
|
//#define ENABLE_BUTTON_GY33 12 // If defined, enable button handling code for GY-33 color sensor to scan color. The value defines the input pin (12 / D6) for read color data with RGB sensor, connect this PIN to ground to trigger button.
|
||||||
//#define POWER_SUPPLY 12 // PIN (12 / D6) If defined, enable output to control external power supply
|
|
||||||
#if defined(POWER_SUPPLY)
|
|
||||||
#define POWER_ON HIGH // Define the output state to turn on the power supply, either HIGH or LOW. Opposite will be uses for power off.
|
|
||||||
#endif
|
|
||||||
#define ENABLE_REMOTE 13 // If defined, enable Remote Control via TSOP31238. The value defines the input pin (13 / D7) for TSOP31238 Out
|
|
||||||
|
|
||||||
#if defined(ENABLE_BUTTON_GY33)
|
#if defined(ENABLE_BUTTON_GY33)
|
||||||
#define GAMMA 2.5 // Gamma correction for GY-33 sensor
|
#define GAMMA 2.5 // Gamma correction for GY-33 sensor
|
||||||
#endif
|
#endif
|
||||||
|
//#define ENABLE_REMOTE 13 // If defined, enable Remote Control via TSOP31238. The value defines the input pin (13 / D7) for TSOP31238 Out
|
||||||
|
|
||||||
#define ENABLE_STATE_SAVE // If defined, load saved state on reboot and save state on SPIFFS
|
#define ENABLE_STATE_SAVE 1 // If defined, load saved state on reboot and save state. If set to 0 from EEPROM, if set to 1 from SPIFFS
|
||||||
|
|
||||||
|
#define ENABLE_LEGACY_ANIMATIONS // Enable Legacy Animations
|
||||||
#define CUSTOM_WS2812FX_ANIMATIONS // uncomment and put animations in "custom_ws2812fx_animations.h"
|
#define CUSTOM_WS2812FX_ANIMATIONS // uncomment and put animations in "custom_ws2812fx_animations.h"
|
||||||
#define USE_HTML_MIN_GZ // uncomment for using index.htm & edit.htm from PROGMEM instead of SPIFFS
|
#define ENABLE_E131 // E1.31 implementation You have to uncomment #define USE_WS2812FX_DMA and set it to 0
|
||||||
|
#define ENABLE_TV // Enable TV Animation
|
||||||
|
#define USE_HTML_MIN_GZ // uncomment for using index.htm & edit.htm from PROGMEM instead of SPIFFs
|
||||||
|
|
||||||
#define TRANS_COLOR_DELAY 5 // Delay for color transition
|
#if defined(ENABLE_E131)
|
||||||
#define TRANS_DELAY 10 // Delay for brightness and speed transition
|
|
||||||
|
|
||||||
// Experimental: Enable transitions of color, brightness and speed. It does not work properly for all effects.
|
|
||||||
bool transEffectOverride = false;
|
|
||||||
uint8_t trans_cnt = 0;
|
|
||||||
int trans_cnt_max = 0;
|
|
||||||
unsigned long colorFadeDelay = 0;
|
|
||||||
unsigned long brightnessFadeDelay = 0;
|
|
||||||
unsigned long speedFadeDelay = 0;
|
|
||||||
|
|
||||||
#if defined(CUSTOM_WS2812FX_ANIMATIONS)
|
|
||||||
#define MULTICAST false
|
#define MULTICAST false
|
||||||
#define START_UNIVERSE 1 // First DMX Universe to listen for
|
#define START_UNIVERSE 1 // First DMX Universe to listen for
|
||||||
uint8_t END_UNIVERSE = START_UNIVERSE; // Total number of Universes to listen for, starting at UNIVERSE
|
uint8_t END_UNIVERSE = START_UNIVERSE; // Total number of Universes to listen for, starting at UNIVERSE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
uint8_t prevsegment = 0;
|
|
||||||
|
|
||||||
#if defined(ENABLE_REMOTE)
|
#if defined(ENABLE_REMOTE)
|
||||||
uint8_t selected_color = 1;
|
uint8_t selected_color = 1;
|
||||||
uint64_t last_remote_cmd;
|
uint64_t last_remote_cmd;
|
||||||
enum RMT_BTN {ON_OFF, MODE_UP, MODE_DOWN, RED_UP, RED_DOWN, GREEN_UP, GREEN_DOWN, BLUE_UP, BLUE_DOWN, WHITE_UP, WHITE_DOWN, BRIGHTNESS_UP, BRIGHTNESS_DOWN, SPEED_UP, SPEED_DOWN, COL_M, COL_B, COL_X, AUTOMODE, CUST_1, CUST_2, CUST_3, SEG_UP, SEG_DOWN, REPEATCMD, BTN_CNT};
|
enum RMT_BTN {ON_OFF, MODE_UP, MODE_DOWN, RED_UP, RED_DOWN, GREEN_UP, GREEN_DOWN, BLUE_UP, BLUE_DOWN, WHITE_UP, WHITE_DOWN, BRIGHTNESS_UP, BRIGHTNESS_DOWN, SPEED_UP, SPEED_DOWN, COL_M, COL_B, COL_X, AUTOMODE, CUST_1, CUST_2, CUST_3, CUST_4, CUST_5, REPEATCMD, BTN_CNT};
|
||||||
// Change your IR Commands here. You can see them in console, after you pressed a button on the remote
|
// Change your IR Commands here. You can see them in console, after you pressed a button on the remote
|
||||||
uint64_t rmt_commands[BTN_CNT] = {0xF7C03F, 0xF7708F, 0xF7F00F, 0xF720DF, 0xF710EF, 0xF7A05F, 0xF7906F, 0xF7609F, 0xF750AF, 0xF7E01F, 0xF7D02F, 0xF730CF, 0xF7B04F, 0xF748B7, 0xF7C837, 0xF700FF, 0xF7807F, 0xF740BF, 0xF708F7, 0xF78877, 0xF728D7, 0xF7A857, 0xF76897, 0xF7E817, 0xFFFFFFFFFFFFFFFF};
|
uint64_t rmt_commands[BTN_CNT] = {0xF7C03F, 0xF7708F, 0xF7F00F, 0xF720DF, 0xF710EF, 0xF7A05F, 0xF7906F, 0xF7609F, 0xF750AF, 0xF7E01F, 0xF7D02F, 0xF730CF, 0xF7B04F, 0xF748B7, 0xF7C837, 0xF700FF, 0xF7807F, 0xF740BF, 0xF708F7, 0xF78877, 0xF728D7, 0xF7A857, 0xF76897, 0xF7E817, 0xFFFFFFFFFFFFFFFF};
|
||||||
#endif
|
#endif
|
||||||
#define WIFIMGR_PORTAL_TIMEOUT 180
|
//#define WIFIMGR_PORTAL_TIMEOUT 180
|
||||||
//#define WIFIMGR_SET_MANUAL_IP
|
//#define WIFIMGR_SET_MANUAL_IP
|
||||||
|
|
||||||
#if defined(WIFIMGR_SET_MANUAL_IP)
|
#if defined(WIFIMGR_SET_MANUAL_IP)
|
||||||
@@ -98,11 +86,11 @@ uint8_t prevsegment = 0;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// parameters for automatically cycling favorite patterns
|
// parameters for automatically cycling favorite patterns
|
||||||
uint32_t autoParams[][6] = { // main_color, back_color, xtra_color, speed, mode, duration (milliseconds)
|
uint32_t autoParams[][6] = { // main_color, back_color, xtra_color, speed, mode, duration (seconds)
|
||||||
{0x00ff0000, 0x0000ff00, 0x00000000, 200, 1, 5000}, // blink red/geen for 5 seconds
|
{0x00ff0000, 0x0000ff00, 0x00000000, 200, 1, 5000}, // blink red/geen for 5 seconds
|
||||||
{0x0000ff00, 0x000000ff, 0x00000000, 180, 3, 10000}, // wipe green/blue for 10 seconds
|
{0x0000ff00, 0x000000ff, 0x00000000, 200, 3, 10000}, // wipe green/blue for 10 seconds
|
||||||
{0x000000ff, 0x00ff0000, 0x00000000, 100, 14, 10000}, // dual scan blue on red for 10 seconds
|
{0x000000ff, 0x00ff0000, 0x00000000, 60, 14, 10000}, // dual scan blue on red for 10 seconds
|
||||||
{0x000000ff, 0x00ff0000, 0x00000000, 100, 45, 15000}, // fireworks blue/red for 15 seconds
|
{0x000000ff, 0x00ff0000, 0x00000000, 40, 45, 15000}, // fireworks blue/red for 15 seconds
|
||||||
{0x00ff0000, 0x0000ff00, 0x000000ff, 40, 54, 15000} // tricolor chase red/green/blue for 15 seconds
|
{0x00ff0000, 0x0000ff00, 0x000000ff, 40, 54, 15000} // tricolor chase red/green/blue for 15 seconds
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -148,51 +136,20 @@ uint32_t autoParams[][6] = { // main_color, back_color, xtra_color, speed, mod
|
|||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#define DBG_OUTPUT_PORT Serial // Set debug output port
|
#define DBG_OUTPUT_PORT Serial // Set debug output port
|
||||||
|
|
||||||
uint8_t autoCount[10] = {}; // Global variable for storing the counter for automated playback for each segment
|
|
||||||
unsigned long autoDelay[10] = {}; // Global variable for storing the time to next auto effect for each segment
|
|
||||||
struct {
|
|
||||||
uint16_t start = 0;
|
|
||||||
uint16_t stop = NUMLEDS - 1;
|
|
||||||
uint8_t mode[10] = {}; // Global variable for storing the WS2812FX mode to set for each segment
|
|
||||||
uint8_t speed[10] = {}; // Global variable for storing the speed for effects --> smaller == slower
|
|
||||||
uint32_t colors[10][3] = {}; // 2 dim. Color array for setting colors of WS2812FX
|
|
||||||
uint8_t options = FX_OPTIONS;
|
|
||||||
} segState;
|
|
||||||
|
|
||||||
// List of all color modes
|
// List of all color modes
|
||||||
enum MODE {OFF, HOLD, SET};
|
#if defined(ENABLE_LEGACY_ANIMATIONS)
|
||||||
MODE prevmode = HOLD; // Do not change
|
enum MODE {OFF, AUTO, TV, E131, CUSTOM, HOLD, SET_ALL, SET_MODE, SET_COLOR, SET_SPEED, SET_BRIGHTNESS, INIT_STRIP, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW};
|
||||||
|
#else
|
||||||
|
enum MODE {OFF, AUTO, TV, E131, CUSTOM, HOLD, SET_ALL, SET_MODE, SET_COLOR, SET_SPEED, SET_BRIGHTNESS, INIT_STRIP};
|
||||||
|
#endif
|
||||||
|
MODE mode = SET_ALL; // Standard mode that is active when software starts
|
||||||
|
MODE prevmode = mode;
|
||||||
|
|
||||||
struct {
|
uint8_t ws2812fx_speed = 196; // Global variable for storing the delay between color changes --> smaller == faster
|
||||||
uint8_t segment = 0; // Actual selected segment
|
uint8_t brightness = 196; // Global variable for storing the brightness (255 == 100%)
|
||||||
MODE mode = SET; // Standard mode that is active when software starts
|
uint8_t ws2812fx_mode = 0; // Global variable for storing the WS2812FX modes
|
||||||
uint8_t brightness = 196; // Global variable for storing the brightness (255 == 100%)
|
|
||||||
} State;
|
|
||||||
|
|
||||||
struct {
|
uint32_t hex_colors[3] = {}; // Color array for setting WS2812FX
|
||||||
uint8_t segments = 1;
|
|
||||||
uint16_t stripSize = NUMLEDS;
|
|
||||||
char RGBOrder[5] = RGBORDER;
|
|
||||||
#if defined(USE_WS2812FX_DMA)
|
|
||||||
#if USE_WS2812FX_DMA == 0
|
|
||||||
uint8_t pin = 3;
|
|
||||||
#endif
|
|
||||||
#if USE_WS2812FX_DMA == 1
|
|
||||||
uint8_t pin = 1;
|
|
||||||
#endif
|
|
||||||
#if USE_WS2812FX_DMA == 2
|
|
||||||
uint8_t pin = 2;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
uint8_t pin = LED_PIN;
|
|
||||||
#endif
|
|
||||||
bool transEffect = false;
|
|
||||||
} Config;
|
|
||||||
|
|
||||||
uint8_t fx_speed = 196; // Global variable for storing the speed for effects while fading --> smaller == slower
|
|
||||||
uint8_t fx_mode = 0;
|
|
||||||
uint8_t brightness_trans = 0; // Global variable for storing the brightness before change
|
|
||||||
uint32_t hexcolors_trans[3] = {}; // Color array of colors of WS2812FX before fading
|
|
||||||
struct ledstate // Data structure to store a state of a single led
|
struct ledstate // Data structure to store a state of a single led
|
||||||
{
|
{
|
||||||
uint8_t red;
|
uint8_t red;
|
||||||
@@ -208,19 +165,18 @@ LEDState back_color = { 0, 0, 0, 0 }; // Store the "2nd color" of the strip u
|
|||||||
LEDState xtra_color = { 0, 0, 0, 0 }; // Store the "3rd color" of the strip used in single color modes
|
LEDState xtra_color = { 0, 0, 0, 0 }; // Store the "3rd color" of the strip used in single color modes
|
||||||
|
|
||||||
bool updateConfig = false; // For WiFiManger custom config and config
|
bool updateConfig = false; // For WiFiManger custom config and config
|
||||||
|
char last_state[67]; // Keeps the state representation before auto or off mode
|
||||||
|
bool updateState = false;
|
||||||
|
|
||||||
// Button handling
|
// Button handling
|
||||||
|
|
||||||
#if defined(ENABLE_BUTTON) || defined(ENABLE_BUTTON_GY33)
|
|
||||||
const unsigned long keySampleIntervalMs = 25;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ENABLE_BUTTON)
|
#if defined(ENABLE_BUTTON)
|
||||||
//#define BTN_MODE_SHORT "STA|mo|fxm| s| b| r1| g1| b1| w1| r2| g2| b2| w2| r3| g3| b3| w3" // Example
|
//#define BTN_MODE_SHORT "STA|mo|fxm| s| b| r1| g1| b1| w1| r2| g2| b2| w2| r3| g3| b3| w3" // Example
|
||||||
#define BTN_MODE_SHORT "STA| 5| 0|196|255| 0| 0| 0|255| 0| 0| 0| 0| 0| 0| 0| 0" // Static white
|
#define BTN_MODE_SHORT "STA| 5| 0|196|255| 0| 0| 0|255| 0| 0| 0| 0| 0| 0| 0| 0" // Static white
|
||||||
#define BTN_MODE_MEDIUM "STA| 5| 48|196|200|255|102| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0" // Fire flicker
|
#define BTN_MODE_MEDIUM "STA| 5| 48|196|200|255|102| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0" // Fire flicker
|
||||||
#define BTN_MODE_LONG "STA| 5| 46|196|200|255|102| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0" // Fireworks random
|
#define BTN_MODE_LONG "STA| 5| 46|196|200|255|102| 0| 0| 0| 0| 0| 0| 0| 0| 0| 0" // Fireworks random
|
||||||
unsigned long keyPrevMillis = 0;
|
unsigned long keyPrevMillis = 0;
|
||||||
|
const unsigned long keySampleIntervalMs = 25;
|
||||||
byte longKeyPressCountMax = 80; // 80 * 25 = 2000 ms
|
byte longKeyPressCountMax = 80; // 80 * 25 = 2000 ms
|
||||||
byte mediumKeyPressCountMin = 20; // 20 * 25 = 500 ms
|
byte mediumKeyPressCountMin = 20; // 20 * 25 = 500 ms
|
||||||
byte KeyPressCount = 0;
|
byte KeyPressCount = 0;
|
||||||
@@ -229,8 +185,28 @@ bool updateConfig = false; // For WiFiManger custom config and config
|
|||||||
|
|
||||||
#if defined(ENABLE_BUTTON_GY33)
|
#if defined(ENABLE_BUTTON_GY33)
|
||||||
unsigned long keyPrevMillis_gy33 = 0;
|
unsigned long keyPrevMillis_gy33 = 0;
|
||||||
|
const unsigned long keySampleIntervalMs_gy33 = 25;
|
||||||
byte longKeyPressCountMax_gy33 = 80; // 80 * 25 = 2000 ms
|
byte longKeyPressCountMax_gy33 = 80; // 80 * 25 = 2000 ms
|
||||||
byte mediumKeyPressCountMin_gy33 = 20; // 20 * 25 = 500 ms
|
byte mediumKeyPressCountMin_gy33 = 20; // 20 * 25 = 500 ms
|
||||||
byte KeyPressCount_gy33 = 0;
|
byte KeyPressCount_gy33 = 0;
|
||||||
byte prevKeyState_gy33 = HIGH; // button is active low
|
byte prevKeyState_gy33 = HIGH; // button is active low
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint16_t stripSize = NUMLEDS;
|
||||||
|
char RGBOrder[5] = RGBORDER;
|
||||||
|
#if defined(USE_WS2812FX_DMA)
|
||||||
|
#if USE_WS2812FX_DMA == 0
|
||||||
|
uint8_t pin = 3;
|
||||||
|
#endif
|
||||||
|
#if USE_WS2812FX_DMA == 1
|
||||||
|
uint8_t pin = 2;
|
||||||
|
#endif
|
||||||
|
#if USE_WS2812FX_DMA == 2
|
||||||
|
uint8_t pin = 1;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
uint8_t pin = LED_PIN;
|
||||||
|
#endif
|
||||||
|
uint8_t fxoptions = FX_OPTIONS;
|
||||||
|
} WS2812FXStripSettings;
|
||||||
|
|||||||
@@ -1,262 +0,0 @@
|
|||||||
#if defined(ENABLE_STATE_SAVE)
|
|
||||||
|
|
||||||
Ticker save_state;
|
|
||||||
Ticker save_seg_state;
|
|
||||||
Ticker save_conf;
|
|
||||||
|
|
||||||
bool updateState = false;
|
|
||||||
bool updateSegState = false;
|
|
||||||
|
|
||||||
void tickerSaveState(){
|
|
||||||
updateState = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tickerSaveConfig(){
|
|
||||||
updateConfig = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tickerSaveSegmentState(){
|
|
||||||
updateSegState = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write configuration to FS JSON
|
|
||||||
bool writeConfigFS(bool save){
|
|
||||||
if (save) {
|
|
||||||
//FS save
|
|
||||||
DBG_OUTPUT_PORT.println("Saving config: ");
|
|
||||||
File configFile = SPIFFS.open("/config.json", "w");
|
|
||||||
if (!configFile) {
|
|
||||||
DBG_OUTPUT_PORT.println("Failed!");
|
|
||||||
save_conf.detach();
|
|
||||||
updateConfig = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
DBG_OUTPUT_PORT.println(listConfigJSON());
|
|
||||||
configFile.print(listConfigJSON());
|
|
||||||
configFile.close();
|
|
||||||
save_conf.detach();
|
|
||||||
updateConfig = false;
|
|
||||||
return true;
|
|
||||||
//end save
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.println("SaveConfig is false!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read search_str to FS
|
|
||||||
bool readConfigFS() {
|
|
||||||
//read configuration from FS JSON
|
|
||||||
if (SPIFFS.exists("/config.json")) {
|
|
||||||
//file exists, reading and loading
|
|
||||||
DBG_OUTPUT_PORT.print("Reading config file... ");
|
|
||||||
File configFile = SPIFFS.open("/config.json", "r");
|
|
||||||
if (configFile) {
|
|
||||||
DBG_OUTPUT_PORT.println("Opened!");
|
|
||||||
size_t size = configFile.size();
|
|
||||||
std::unique_ptr<char[]> buf(new char[size]);
|
|
||||||
configFile.readBytes(buf.get(), size);
|
|
||||||
configFile.close();
|
|
||||||
#if defined(ENABLE_MQTT)
|
|
||||||
const size_t bufferSize = JSON_OBJECT_SIZE(11) + 150;
|
|
||||||
#else
|
|
||||||
const size_t bufferSize = JSON_OBJECT_SIZE(7) + 100;
|
|
||||||
#endif
|
|
||||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
|
||||||
DeserializationError error = deserializeJson(jsonBuffer, buf.get());
|
|
||||||
DBG_OUTPUT_PORT.print("Config: ");
|
|
||||||
if (!error) {
|
|
||||||
DBG_OUTPUT_PORT.println("Parsed!");
|
|
||||||
JsonObject root = jsonBuffer.as<JsonObject>();
|
|
||||||
serializeJson(root, DBG_OUTPUT_PORT);
|
|
||||||
DBG_OUTPUT_PORT.println("");
|
|
||||||
strcpy(HOSTNAME, root["hostname"]);
|
|
||||||
#if defined(ENABLE_MQTT)
|
|
||||||
strcpy(mqtt_host, root["mqtt_host"]);
|
|
||||||
mqtt_port = root["mqtt_port"].as<uint16_t>();
|
|
||||||
strcpy(mqtt_user, root["mqtt_user"]);
|
|
||||||
strcpy(mqtt_pass, root["mqtt_pass"]);
|
|
||||||
#endif
|
|
||||||
Config.segments = constrain(root["ws_seg"].as<uint8_t>(), 1, MAX_NUM_SEGMENTS - 1);
|
|
||||||
Config.stripSize = constrain(root["ws_cnt"].as<uint16_t>(), 1, MAXLEDS);
|
|
||||||
char _rgbOrder[5];
|
|
||||||
strcpy(_rgbOrder, root["ws_rgbo"]);
|
|
||||||
checkRGBOrder(_rgbOrder);
|
|
||||||
uint8_t temp_pin;
|
|
||||||
checkPin((uint8_t) root["ws_pin"]);
|
|
||||||
Config.transEffect = root["ws_trans"].as<bool>();
|
|
||||||
jsonBuffer.clear();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.print("Failed to load json config: ");
|
|
||||||
DBG_OUTPUT_PORT.println(error.c_str());
|
|
||||||
jsonBuffer.clear();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.println("Failed to open /config.json");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.println("Coudnt find config.json");
|
|
||||||
writeConfigFS(true);
|
|
||||||
}
|
|
||||||
//end read
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool writeStateFS(bool save){
|
|
||||||
if (save) {
|
|
||||||
//save the strip state to FS JSON
|
|
||||||
DBG_OUTPUT_PORT.print("Saving state: ");
|
|
||||||
//SPIFFS.remove("/stripstate.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file");
|
|
||||||
File configFile = SPIFFS.open("/stripstate.json", "w");
|
|
||||||
if (!configFile) {
|
|
||||||
DBG_OUTPUT_PORT.println("Failed!");
|
|
||||||
save_state.detach();
|
|
||||||
updateState = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
DBG_OUTPUT_PORT.println(listStateJSON());
|
|
||||||
configFile.print(listStateJSON());
|
|
||||||
configFile.close();
|
|
||||||
char filename[28];
|
|
||||||
save_state.detach();
|
|
||||||
updateState = false;
|
|
||||||
return true;
|
|
||||||
//end save
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.println("SaveState is false!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool readStateFS() {
|
|
||||||
//read strip state from FS JSON
|
|
||||||
if (SPIFFS.exists("/stripstate.json")) {
|
|
||||||
//file exists, reading and loading
|
|
||||||
DBG_OUTPUT_PORT.print("Reading state file... ");
|
|
||||||
File configFile = SPIFFS.open("/stripstate.json", "r");
|
|
||||||
if (configFile) {
|
|
||||||
DBG_OUTPUT_PORT.println("Opened!");
|
|
||||||
size_t size = configFile.size();
|
|
||||||
// Allocate a buffer to store contents of the file.
|
|
||||||
std::unique_ptr<char[]> buf(new char[size]);
|
|
||||||
configFile.readBytes(buf.get(), size);
|
|
||||||
configFile.close();
|
|
||||||
const size_t bufferSize = JSON_OBJECT_SIZE(3) + 50;
|
|
||||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
|
||||||
DeserializationError error = deserializeJson(jsonBuffer, buf.get());
|
|
||||||
DBG_OUTPUT_PORT.print("Config: ");
|
|
||||||
if (!error) {
|
|
||||||
DBG_OUTPUT_PORT.print("Parsed");
|
|
||||||
JsonObject root = jsonBuffer.as<JsonObject>();
|
|
||||||
serializeJson(root, DBG_OUTPUT_PORT);
|
|
||||||
DBG_OUTPUT_PORT.println("");
|
|
||||||
State.segment = root["segment"];
|
|
||||||
State.mode = static_cast<MODE>(root["mode"].as<uint8_t>());
|
|
||||||
State.brightness = root["brightness"];
|
|
||||||
jsonBuffer.clear();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.print("Failed to load json config: ");
|
|
||||||
DBG_OUTPUT_PORT.println(error.c_str());
|
|
||||||
jsonBuffer.clear();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.println("Failed to open \"/stripstate.json\"");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.println("Couldn't find \"/stripstate.json\"");
|
|
||||||
writeStateFS(true);
|
|
||||||
}
|
|
||||||
//end read
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool writeSegmentStateFS(bool save, uint8_t seg){
|
|
||||||
if (save) {
|
|
||||||
//save the segment state to FS JSON
|
|
||||||
DBG_OUTPUT_PORT.print("Saving segment state: ");
|
|
||||||
char filename[28];
|
|
||||||
snprintf(filename, 28, "/stripstate_segment_%02i.json", seg);
|
|
||||||
filename[27] = 0x00;
|
|
||||||
File configFile = SPIFFS.open(filename, "w");
|
|
||||||
if (!configFile) {
|
|
||||||
DBG_OUTPUT_PORT.println("Failed!");
|
|
||||||
save_seg_state.detach();
|
|
||||||
updateSegState = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
DBG_OUTPUT_PORT.println(listSegmentStateJSON(seg));
|
|
||||||
configFile.print(listSegmentStateJSON(seg));
|
|
||||||
configFile.close();
|
|
||||||
save_seg_state.detach();
|
|
||||||
updateSegState = false;
|
|
||||||
return true;
|
|
||||||
//end save
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.println("SaveSegmentState is false!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool readSegmentStateFS(uint8_t _seg) {
|
|
||||||
//read strip state from FS JSON
|
|
||||||
char filename[28];
|
|
||||||
snprintf(filename, 28, "/stripstate_segment_%02i.json", _seg);
|
|
||||||
filename[27] = 0x00;
|
|
||||||
if (SPIFFS.exists(filename)) {
|
|
||||||
//file exists, reading and loading
|
|
||||||
DBG_OUTPUT_PORT.printf("Reading segmentstate file: %s\r\n", filename);
|
|
||||||
File configFile = SPIFFS.open(filename, "r");
|
|
||||||
if (configFile) {
|
|
||||||
DBG_OUTPUT_PORT.println("Opened!");
|
|
||||||
size_t size = configFile.size();
|
|
||||||
// Allocate a buffer to store contents of the file.
|
|
||||||
std::unique_ptr<char[]> buf(new char[size]);
|
|
||||||
configFile.readBytes(buf.get(), size);
|
|
||||||
configFile.close();
|
|
||||||
const size_t bufferSize = JSON_ARRAY_SIZE(12) + JSON_OBJECT_SIZE(7) + 100;
|
|
||||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
|
||||||
DeserializationError error = deserializeJson(jsonBuffer, buf.get());
|
|
||||||
DBG_OUTPUT_PORT.print("Config: ");
|
|
||||||
if (!error) {
|
|
||||||
DBG_OUTPUT_PORT.print("Parsed");
|
|
||||||
JsonObject root = jsonBuffer.as<JsonObject>();
|
|
||||||
serializeJson(root, DBG_OUTPUT_PORT);
|
|
||||||
DBG_OUTPUT_PORT.println("");
|
|
||||||
segState.start = constrain(root["start"].as<uint16_t>(), 0, Config.stripSize - 1) ;
|
|
||||||
segState.stop = constrain(root["stop"].as<uint16_t>(), 0, Config.stripSize - 1);
|
|
||||||
segState.mode[_seg] = root["fx_mode"].as<uint8_t>();
|
|
||||||
segState.speed[_seg] = root["speed"].as<uint8_t>();
|
|
||||||
main_color.white = root["color"][0].as<uint8_t>();
|
|
||||||
main_color.red = root["color"][1].as<uint8_t>();
|
|
||||||
main_color.green = root["color"][2].as<uint8_t>();
|
|
||||||
main_color.blue = root["color"][3].as<uint8_t>();
|
|
||||||
back_color.white = root["color"][4].as<uint8_t>();
|
|
||||||
back_color.red = root["color"][5].as<uint8_t>();
|
|
||||||
back_color.green = root["color"][6].as<uint8_t>();
|
|
||||||
back_color.blue = root["color"][7].as<uint8_t>();
|
|
||||||
xtra_color.white = root["color"][8].as<uint8_t>();
|
|
||||||
xtra_color.red = root["color"][9].as<uint8_t>();
|
|
||||||
xtra_color.green = root["color"][10].as<uint8_t>();
|
|
||||||
xtra_color.blue = root["color"][11].as<uint8_t>();
|
|
||||||
segState.options = constrain(root["ws_fxopt"].as<uint8_t>(), 0, 255) & 0xFE;
|
|
||||||
convertColors();
|
|
||||||
jsonBuffer.clear();
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.print("Failed to load json config: ");
|
|
||||||
DBG_OUTPUT_PORT.println(error.c_str());
|
|
||||||
jsonBuffer.clear();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.printf("Failed to open \"/%s\"\r\n", filename);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.printf("Couldn't find \"/%s\"", filename);
|
|
||||||
writeSegmentStateFS(true, _seg);
|
|
||||||
}
|
|
||||||
//end read
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,323 +0,0 @@
|
|||||||
// Prototypes
|
|
||||||
bool readSegmentStateFS(uint8_t _seg);
|
|
||||||
// End Prototypes
|
|
||||||
|
|
||||||
void getACK(char *buffer) {
|
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
server.send(200, "text/plain", buffer );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call convertColors whenever main_color, back_color or xtra_color changes.
|
|
||||||
void convertColors() {
|
|
||||||
hexcolors_trans[0] = (uint32_t)(main_color.white << 24) | (main_color.red << 16) | (main_color.green << 8) | main_color.blue;
|
|
||||||
hexcolors_trans[1] = (uint32_t)(back_color.white << 24) | (back_color.red << 16) | (back_color.green << 8) | back_color.blue;
|
|
||||||
hexcolors_trans[2] = (uint32_t)(xtra_color.white << 24) | (xtra_color.red << 16) | (xtra_color.green << 8) | xtra_color.blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*uint32_t* convertColors2(uint8_t _w, uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _w2, uint8_t _r2, uint8_t _g2, uint8_t _b2, uint8_t _w3, uint8_t _r3, uint8_t _g3, uint8_t _b3) {
|
|
||||||
uint32_t _hexcolors[3] = {};
|
|
||||||
_hexcolors[0] = (uint32_t)(_w << 24) | (_r << 16) | (_g << 8) | _b;
|
|
||||||
_hexcolors[1] = (uint32_t)(_w2 << 24) | (_r2 << 16) | (_g2 << 8) | _b2;
|
|
||||||
_hexcolors[2] = (uint32_t)(_w3 << 24) | (_r3 << 16) | (_g3 << 8) | _b3;
|
|
||||||
return _hexcolors;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
uint16_t convertSpeed(uint8_t _mcl_speed) {
|
|
||||||
uint16_t _fx_speed = 0;
|
|
||||||
if (_mcl_speed < 50) {
|
|
||||||
_fx_speed = 65535 - (_mcl_speed * 1000);
|
|
||||||
} else if (_mcl_speed < 100) {
|
|
||||||
_fx_speed = 16675 - ((_mcl_speed-49) * 250);
|
|
||||||
} else if (_mcl_speed < 150) {
|
|
||||||
_fx_speed = 4075 - ((_mcl_speed-99) * 50);
|
|
||||||
} else if (_mcl_speed < 200) {
|
|
||||||
_fx_speed = 1550 - ((_mcl_speed-149) * 25);
|
|
||||||
} else {
|
|
||||||
_fx_speed = 280 - ((_mcl_speed-199) * 5);
|
|
||||||
}
|
|
||||||
_fx_speed = constrain(_fx_speed, SPEED_MIN, SPEED_MAX);
|
|
||||||
return _fx_speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*uint8_t unconvertSpeed(uint16_t _fx_speed) {
|
|
||||||
uint16_t _mcl_speed = 0;
|
|
||||||
if (_fx_speed <= 280) {
|
|
||||||
_mcl_speed = ((280 - _fx_speed)/5) + 199;
|
|
||||||
} else if (_fx_speed < 1550) {
|
|
||||||
_mcl_speed = ((1550 - _fx_speed)/25) + 149;
|
|
||||||
} else if (_fx_speed < 4075) {
|
|
||||||
_mcl_speed = ((4075 - _fx_speed)/50) + 99;
|
|
||||||
} else if (_mcl_speed < 16500) {
|
|
||||||
_mcl_speed = ((16675 - _fx_speed)/250) + 49;
|
|
||||||
} else {
|
|
||||||
_mcl_speed = ((65535 - _fx_speed)/1000);
|
|
||||||
}
|
|
||||||
return _mcl_speed;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
bool checkPin(uint8_t pin) {
|
|
||||||
#if defined(USE_WS2812FX_DMA)
|
|
||||||
#if USE_WS2812FX_DMA == 0
|
|
||||||
pin = 3;
|
|
||||||
#endif
|
|
||||||
#if USE_WS2812FX_DMA == 1
|
|
||||||
pin = 1;
|
|
||||||
#endif
|
|
||||||
#if USE_WS2812FX_DMA == 2
|
|
||||||
pin = 2;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
if (((pin >= 0 && pin <= 5) || (pin >= 12 && pin <= 16)) && (pin != Config.pin)) {
|
|
||||||
Config.pin = pin;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
neoPixelType checkRGBOrder(char rgbOrder[5]) {
|
|
||||||
for( uint8_t i=0 ; i < sizeof(rgbOrder) ; ++i ) rgbOrder[i] = toupper(rgbOrder[i]) ;
|
|
||||||
DBG_OUTPUT_PORT.printf("Checking RGB Order: %s ...", rgbOrder);
|
|
||||||
neoPixelType returnOrder = 0;
|
|
||||||
if (strcmp(rgbOrder, "GRB") == 0) {
|
|
||||||
returnOrder = NEO_GRB;
|
|
||||||
} else if (strcmp(rgbOrder, "GBR") == 0) {
|
|
||||||
returnOrder = NEO_GBR;
|
|
||||||
} else if (strcmp(rgbOrder, "RGB") == 0) {
|
|
||||||
returnOrder = NEO_RGB;
|
|
||||||
} else if (strcmp(rgbOrder, "RBG") == 0) {
|
|
||||||
returnOrder = NEO_RBG;
|
|
||||||
} else if (strcmp(rgbOrder, "BRG") == 0) {
|
|
||||||
returnOrder = NEO_BRG;
|
|
||||||
} else if (strcmp(rgbOrder, "BGR") == 0) {
|
|
||||||
returnOrder = NEO_BGR;
|
|
||||||
} else if (strcmp(rgbOrder, "WGRB") == 0) {
|
|
||||||
returnOrder = NEO_WGRB;
|
|
||||||
} else if (strcmp(rgbOrder, "WGBR") == 0) {
|
|
||||||
returnOrder = NEO_WGBR;
|
|
||||||
} else if (strcmp(rgbOrder, "WRGB") == 0) {
|
|
||||||
returnOrder = NEO_WRGB;
|
|
||||||
} else if (strcmp(rgbOrder, "WRBG") == 0) {
|
|
||||||
returnOrder = NEO_WRBG;
|
|
||||||
} else if (strcmp(rgbOrder, "WBRG") == 0) {
|
|
||||||
returnOrder = NEO_WBRG;
|
|
||||||
} else if (strcmp(rgbOrder, "WBGR") == 0) {
|
|
||||||
returnOrder = NEO_WBGR;
|
|
||||||
} else if (strcmp(rgbOrder, "GWRB") == 0) {
|
|
||||||
returnOrder = NEO_GWRB;
|
|
||||||
} else if (strcmp(rgbOrder, "GWBR") == 0) {
|
|
||||||
returnOrder = NEO_GWBR;
|
|
||||||
} else if (strcmp(rgbOrder, "RWGB") == 0) {
|
|
||||||
returnOrder = NEO_RWGB;
|
|
||||||
} else if (strcmp(rgbOrder, "RWBG") == 0) {
|
|
||||||
returnOrder = NEO_RWBG;
|
|
||||||
} else if (strcmp(rgbOrder, "BWRG") == 0) {
|
|
||||||
returnOrder = NEO_BWRG;
|
|
||||||
} else if (strcmp(rgbOrder, "BWGR") == 0) {
|
|
||||||
returnOrder = NEO_BWGR;
|
|
||||||
} else if (strcmp(rgbOrder, "GRWB") == 0) {
|
|
||||||
returnOrder = NEO_GRWB;
|
|
||||||
} else if (strcmp(rgbOrder, "GBWR") == 0) {
|
|
||||||
returnOrder = NEO_GBWR;
|
|
||||||
} else if (strcmp(rgbOrder, "RGWB") == 0) {
|
|
||||||
returnOrder = NEO_RGWB;
|
|
||||||
} else if (strcmp(rgbOrder, "RBWG") == 0) {
|
|
||||||
returnOrder = NEO_RBWG;
|
|
||||||
} else if (strcmp(rgbOrder, "BRWG") == 0){
|
|
||||||
returnOrder = NEO_BRWG;
|
|
||||||
} else if (strcmp(rgbOrder, "BGWR") == 0) {
|
|
||||||
returnOrder = NEO_GRBW;
|
|
||||||
} else if (strcmp(rgbOrder, "GRBW") == 0) {
|
|
||||||
returnOrder = NEO_GRBW;
|
|
||||||
} else if (strcmp(rgbOrder, "GBWR") == 0) {
|
|
||||||
returnOrder = NEO_GBRW;
|
|
||||||
} else if (strcmp(rgbOrder, "RGBW") == 0) {
|
|
||||||
returnOrder = NEO_RGBW;
|
|
||||||
} else if (strcmp(rgbOrder, "RBGW") == 0) {
|
|
||||||
returnOrder = NEO_RBGW;
|
|
||||||
} else if (strcmp(rgbOrder, "BRGW") == 0) {
|
|
||||||
returnOrder = NEO_BRGW;
|
|
||||||
} else if (strcmp(rgbOrder, "BGRW") == 0) {
|
|
||||||
returnOrder = NEO_BGRW;
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.print("invalid input!");
|
|
||||||
uint16_t check = checkRGBOrder(Config.RGBOrder);
|
|
||||||
if (check != 0) {
|
|
||||||
returnOrder = static_cast<neoPixelType>(check);
|
|
||||||
strcpy(rgbOrder, Config.RGBOrder);
|
|
||||||
} else {
|
|
||||||
returnOrder = static_cast<neoPixelType>(checkRGBOrder(RGBORDER));
|
|
||||||
strcpy(rgbOrder, RGBORDER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DBG_OUTPUT_PORT.println("success!");
|
|
||||||
strcpy(Config.RGBOrder, rgbOrder);
|
|
||||||
return returnOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
// function to Initialize the strip
|
|
||||||
void initStrip(uint16_t _stripSize = Config.stripSize, uint8_t _num_segments = Config.segments, char _RGBOrder[5] = Config.RGBOrder, uint8_t _pin = Config.pin){
|
|
||||||
DBG_OUTPUT_PORT.println("Initializing strip!");
|
|
||||||
/*#if defined(USE_WS2812FX_DMA)
|
|
||||||
if (dma != NULL) {
|
|
||||||
delete(dma);
|
|
||||||
}
|
|
||||||
#endif*/
|
|
||||||
if (strip != NULL) {
|
|
||||||
strip->strip_off();
|
|
||||||
delay(10);
|
|
||||||
if(strip->isRunning()) strip->stop();
|
|
||||||
strip->resetSegments();
|
|
||||||
strip->resetSegmentRuntimes();
|
|
||||||
delete(strip);
|
|
||||||
Config.stripSize = _stripSize;
|
|
||||||
strcpy(Config.RGBOrder, _RGBOrder);
|
|
||||||
Config.pin = _pin;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ledstates != NULL) {
|
|
||||||
delete(ledstates);
|
|
||||||
}
|
|
||||||
ledstates = new uint8_t [_stripSize];
|
|
||||||
|
|
||||||
#if !defined(LED_TYPE_WS2811)
|
|
||||||
strip = new WS2812FX(_stripSize, _pin, checkRGBOrder(_RGBOrder) + NEO_KHZ800);
|
|
||||||
#else
|
|
||||||
strip = new WS2812FX(_stripSize, _pin, checkRGBOrder(_RGBOrder) + NEO_KHZ400);
|
|
||||||
#endif
|
|
||||||
// Parameter 1 = number of pixels in strip
|
|
||||||
// Parameter 2 = Arduino pin number (most are valid)
|
|
||||||
// Parameter 3 = pixel type flags, add together as needed:
|
|
||||||
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
|
||||||
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
|
||||||
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
|
|
||||||
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
|
|
||||||
|
|
||||||
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
|
|
||||||
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
|
|
||||||
// and minimize distance between Arduino and first pixel. Avoid connecting
|
|
||||||
// on a live circuit...if you must, connect GND first.
|
|
||||||
strip->init();
|
|
||||||
#if defined(USE_WS2812FX_DMA)
|
|
||||||
initDMA(_stripSize);
|
|
||||||
strip->setCustomShow(DMA_Show);
|
|
||||||
#endif
|
|
||||||
//parameters: index, start, stop, mode, color, speed, options
|
|
||||||
for (uint8_t _seg=0; _seg < Config.segments; _seg++) {
|
|
||||||
if (_seg != State.segment) { // Read actual segment last
|
|
||||||
(readSegmentStateFS(_seg)) ? DBG_OUTPUT_PORT.println("Segment state config FS read Success!") : DBG_OUTPUT_PORT.println("Segment state config FS read failure!");
|
|
||||||
memcpy(segState.colors[_seg], hexcolors_trans, sizeof(hexcolors_trans));
|
|
||||||
strip->setSegment(_seg, segState.start, segState.stop, segState.mode[_seg], segState.colors[_seg], convertSpeed(segState.speed[_seg]), segState.options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//read actual segment last to set all vars correctly
|
|
||||||
(readSegmentStateFS(State.segment)) ? DBG_OUTPUT_PORT.println("Segment state config FS read Success!") : DBG_OUTPUT_PORT.println("Segment state config FS read failure!");
|
|
||||||
memcpy(segState.colors[State.segment], hexcolors_trans, sizeof(hexcolors_trans));
|
|
||||||
strip->setSegment(State.segment, segState.start, segState.stop , segState.mode[State.segment], hexcolors_trans, convertSpeed(segState.speed[State.segment]), segState.options);
|
|
||||||
fx_speed = segState.speed[State.segment];
|
|
||||||
fx_mode = segState.mode[State.segment];
|
|
||||||
brightness_trans = State.brightness;
|
|
||||||
prevsegment = State.segment;
|
|
||||||
strip->setCustomMode(0, F("Autoplay"), handleAuto);
|
|
||||||
strip->setCustomMode(1, F("Custom WS"), handleCustomWS);
|
|
||||||
strip->setCustomMode(9, F("Segment OFF"), handleSegmentOFF);
|
|
||||||
#if defined(CUSTOM_WS2812FX_ANIMATIONS)
|
|
||||||
strip->setCustomMode(2, F("TV"), handleTV);
|
|
||||||
strip->setCustomMode(3, F("E1.31"), handleE131);
|
|
||||||
strip->setCustomMode(4, F("Fire 2012"), handleFire2012);
|
|
||||||
strip->setCustomMode(5, F("Gradient"), handleGradient);
|
|
||||||
DBG_OUTPUT_PORT.print("Number of Segments: ");
|
|
||||||
DBG_OUTPUT_PORT.println(strip->getNumSegments());
|
|
||||||
|
|
||||||
if (e131 != NULL) { delete(e131); }
|
|
||||||
e131 = new ESPAsyncE131(END_UNIVERSE - START_UNIVERSE + 1);
|
|
||||||
float universe_leds = 170.0; // a universe has only 512 (0..511) channels: 3*170 or 4*128 <= 512
|
|
||||||
if (strstr(Config.RGBOrder, "W") != NULL) {
|
|
||||||
//universe_leds = 128.0;
|
|
||||||
}
|
|
||||||
float float_enduni = _stripSize/universe_leds;
|
|
||||||
uint8_t END_UNIVERSE = _stripSize/universe_leds;
|
|
||||||
if (float_enduni > END_UNIVERSE) {
|
|
||||||
END_UNIVERSE = END_UNIVERSE +1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (e131.begin(E131_UNICAST)) // Listen via Unicast
|
|
||||||
if (e131->begin(E131_MULTICAST, START_UNIVERSE, END_UNIVERSE)) {// Listen via Multicast
|
|
||||||
DBG_OUTPUT_PORT.println(F("Listening for data..."));
|
|
||||||
} else {
|
|
||||||
DBG_OUTPUT_PORT.println(F("*** e131.begin failed ***"));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void getSegmentParams(uint8_t _seg) {
|
|
||||||
segState.start = strip->getSegment(_seg)->start;
|
|
||||||
segState.stop = strip->getSegment(_seg)->stop;
|
|
||||||
//segState.mode[_seg] = strip->getMode(_seg);
|
|
||||||
//segState.speed[_seg] = unconvertSpeed(strip->getSpeed(_seg));
|
|
||||||
//fx_mode = segState.mode[_seg];
|
|
||||||
//fx_speed = segState.speed[_seg];
|
|
||||||
main_color.white = ((segState.colors[_seg][0] >> 24) & 0xFF);
|
|
||||||
main_color.red = ((segState.colors[_seg][0] >> 16) & 0xFF);
|
|
||||||
main_color.green = ((segState.colors[_seg][0] >> 8) & 0xFF);
|
|
||||||
main_color.blue = ((segState.colors[_seg][0]) & 0xFF);
|
|
||||||
back_color.white = ((segState.colors[_seg][1] >> 24) & 0xFF);
|
|
||||||
back_color.red = ((segState.colors[_seg][1] >> 16) & 0xFF);
|
|
||||||
back_color.green = ((segState.colors[_seg][1] >> 8) & 0xFF);
|
|
||||||
back_color.blue = ((segState.colors[_seg][1]) & 0xFF);
|
|
||||||
xtra_color.white = ((segState.colors[_seg][2] >> 24) & 0xFF);
|
|
||||||
xtra_color.red = ((segState.colors[_seg][2] >> 16) & 0xFF);
|
|
||||||
xtra_color.green = ((segState.colors[_seg][2] >> 8) & 0xFF);
|
|
||||||
xtra_color.blue = ((segState.colors[_seg][2] >> 0) & 0xFF);
|
|
||||||
segState.options = strip->getOptions(_seg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSegmentSize() {
|
|
||||||
strip->strip_off();
|
|
||||||
delay(10);
|
|
||||||
if(strip->isRunning()) strip->stop();
|
|
||||||
strip->resetSegmentRuntimes();
|
|
||||||
strip->setSegment(State.segment, segState.start, segState.stop , segState.mode[State.segment], hexcolors_trans, convertSpeed(segState.speed[State.segment]), segState.options);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t calculateColorTransitionSteps(uint8_t _seg) {
|
|
||||||
//compare all colors and calculate steps
|
|
||||||
int _trans_cnt_max = 0;
|
|
||||||
int _calculate_max[4] = {};
|
|
||||||
for (uint8_t i=0; i<3; i++){
|
|
||||||
for (uint8_t j=0; j<4; j++) {
|
|
||||||
_calculate_max[j] = ((strip->getColors(_seg)[i] >> ((3-j)*8)) & 0xFF) - ((hexcolors_trans[i] >> ((3-j)*8)) & 0xFF);
|
|
||||||
_calculate_max[j] = abs(_calculate_max[j]);
|
|
||||||
_trans_cnt_max = max(_trans_cnt_max, _calculate_max[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _trans_cnt_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t convertColorsFade(uint8_t _seg) {
|
|
||||||
if (Config.transEffect) {
|
|
||||||
if (trans_cnt > 1) {
|
|
||||||
//memcpy(segState.colors[_seg], strip->getColors(_seg), sizeof(segState.colors[_seg]));
|
|
||||||
DBG_OUTPUT_PORT.println("Color transistion aborted. Restarting...!");
|
|
||||||
trans_cnt = 1;
|
|
||||||
}
|
|
||||||
return calculateColorTransitionSteps(_seg);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t scale_wrgb(uint32_t wrgb, uint8_t level) {
|
|
||||||
uint8_t w = (uint16_t)(((wrgb >> 24) & 0xFF) * level / 255);
|
|
||||||
uint8_t r = (uint16_t)(((wrgb >> 16) & 0xFF) * level / 255);
|
|
||||||
uint8_t g = (uint16_t)(((wrgb >> 8) & 0xFF) * level / 255);
|
|
||||||
uint8_t b = (uint16_t)(((wrgb) & 0xFF) * level / 255);
|
|
||||||
return (w << 24) | (r << 16) | (g << 8) | b;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t trans(uint32_t _newcolor, uint32_t _oldcolor, uint8_t _level, uint8_t _steps) {
|
|
||||||
if (_steps == 0) { _steps = 1; };
|
|
||||||
_level = (uint16_t)(_level * 255 / _steps);
|
|
||||||
_newcolor = scale_wrgb(_newcolor, _level);
|
|
||||||
_oldcolor = scale_wrgb(_oldcolor, 255-_level);
|
|
||||||
return _newcolor + _oldcolor;
|
|
||||||
}
|
|
||||||
+460
-465
@@ -1,468 +1,463 @@
|
|||||||
#include <pgmspace.h>
|
#include <pgmspace.h>
|
||||||
#define edit_htm_gz_len 5563
|
|
||||||
|
#define edit_htm_gz_len 5489
|
||||||
static const char edit_htm_gz[] PROGMEM ={
|
static const char edit_htm_gz[] PROGMEM ={
|
||||||
0x1f, 0x8b, 0x08, 0x08, 0x79, 0x1c, 0x96, 0x5d, 0x04, 0x00, 0x65, 0x64,
|
0x1f, 0x8b, 0x08, 0x08, 0x10, 0x9c, 0x83, 0x5c, 0x04, 0x00, 0x65, 0x64,
|
||||||
0x69, 0x74, 0x2e, 0x68, 0x74, 0x6d, 0x00, 0xed, 0x1d, 0x6b, 0x57, 0xea,
|
0x69, 0x74, 0x2e, 0x68, 0x74, 0x6d, 0x00, 0xed, 0x1c, 0x67, 0x7b, 0xf2,
|
||||||
0x46, 0xf0, 0x7b, 0xcf, 0xe9, 0x7f, 0x48, 0xd3, 0x87, 0x50, 0x9e, 0xa2,
|
0x36, 0xf0, 0x7b, 0x7f, 0x85, 0xeb, 0x8e, 0x40, 0x99, 0x21, 0x24, 0x6f,
|
||||||
0xd7, 0x2a, 0x6a, 0x5b, 0x40, 0x40, 0x45, 0x8a, 0x08, 0x2a, 0xda, 0xd7,
|
0x66, 0x5b, 0x76, 0x12, 0xa0, 0x84, 0x91, 0x84, 0xa4, 0xeb, 0x31, 0xb6,
|
||||||
0x09, 0xc9, 0x02, 0xd1, 0x90, 0xc4, 0x24, 0x08, 0x7a, 0x6b, 0x7f, 0x7b,
|
0x00, 0x27, 0xc6, 0x76, 0x6c, 0x13, 0x20, 0x69, 0xfa, 0xdb, 0x7b, 0x92,
|
||||||
0x67, 0x1f, 0x79, 0x27, 0x10, 0xd4, 0x3e, 0x4f, 0xb9, 0xed, 0x25, 0xec,
|
0xbc, 0x07, 0x38, 0xa3, 0xf3, 0x29, 0xef, 0x00, 0x4b, 0x77, 0xa7, 0xbb,
|
||||||
0xce, 0xcc, 0xce, 0xcc, 0xce, 0xce, 0xce, 0xce, 0xee, 0xe6, 0x1e, 0x7c,
|
0xd3, 0xe9, 0x74, 0x3a, 0x49, 0x3e, 0xfe, 0xbc, 0xda, 0xa9, 0x0c, 0x6e,
|
||||||
0x76, 0xd4, 0xa9, 0xf5, 0x6f, 0xce, 0xeb, 0xdc, 0xc4, 0x9a, 0x2a, 0xdf,
|
0x2e, 0x6a, 0xcc, 0xd4, 0x98, 0x49, 0xdf, 0x7e, 0x76, 0x8c, 0xbf, 0x18,
|
||||||
0x7e, 0xfa, 0xc9, 0x01, 0xfe, 0xe6, 0x14, 0x41, 0x1d, 0x1f, 0xf2, 0x48,
|
0x89, 0x93, 0x27, 0x27, 0x2c, 0x92, 0xd9, 0x6f, 0x3f, 0x63, 0x98, 0xe3,
|
||||||
0xe5, 0xa1, 0x84, 0xe3, 0x0e, 0x26, 0x48, 0x90, 0xc8, 0x13, 0x3c, 0x5b,
|
0x29, 0xe2, 0x04, 0xfc, 0x03, 0x7e, 0x1a, 0xa2, 0x21, 0xa1, 0x6f, 0xfb,
|
||||||
0xb2, 0xa5, 0xa0, 0x6f, 0x7b, 0xe7, 0x27, 0x8d, 0x46, 0x8f, 0xab, 0x4b,
|
0x17, 0x67, 0xf5, 0x7a, 0x9f, 0xa9, 0x09, 0xa2, 0xa1, 0x68, 0xc7, 0x39,
|
||||||
0xb2, 0xa5, 0x19, 0x07, 0x05, 0x52, 0x68, 0x43, 0x98, 0xd6, 0x93, 0x82,
|
0x52, 0x68, 0x02, 0xe8, 0xc6, 0x4a, 0x42, 0x8c, 0xb1, 0x52, 0xd1, 0x09,
|
||||||
0x38, 0xeb, 0x49, 0x47, 0x87, 0xbc, 0x85, 0x16, 0x56, 0x41, 0x34, 0x4d,
|
0x6b, 0xa0, 0xa5, 0x91, 0xe3, 0x75, 0x9d, 0x65, 0x66, 0x48, 0x10, 0xb9,
|
||||||
0x9e, 0x9b, 0x22, 0x49, 0x16, 0x0e, 0x79, 0x53, 0x34, 0x10, 0xa3, 0x4b,
|
0x13, 0x56, 0xe7, 0x35, 0x44, 0x89, 0x92, 0x4f, 0x96, 0x57, 0x64, 0x0c,
|
||||||
0x3e, 0x79, 0x51, 0x53, 0x31, 0x50, 0x1b, 0xa9, 0x33, 0xee, 0x23, 0x94,
|
0xd3, 0x46, 0xf2, 0x9c, 0x79, 0x86, 0x42, 0xfa, 0x79, 0xca, 0x88, 0xb2,
|
||||||
0xb2, 0xcf, 0x73, 0x4e, 0x56, 0x25, 0xb4, 0x28, 0x73, 0x5b, 0xc5, 0xe2,
|
0x80, 0x96, 0x87, 0xcc, 0x4e, 0x3e, 0x7f, 0x64, 0x97, 0xaa, 0x8a, 0x2e,
|
||||||
0xbe, 0x5b, 0xac, 0x6b, 0xa6, 0x6c, 0xc9, 0x9a, 0x5a, 0xe6, 0x84, 0xa1,
|
0x1a, 0xa2, 0x22, 0x1f, 0x32, 0xdc, 0x48, 0x57, 0xa4, 0xb9, 0x81, 0x9c,
|
||||||
0xa9, 0x29, 0x33, 0x0b, 0x79, 0x2a, 0x15, 0x34, 0xb2, 0xca, 0xdc, 0x07,
|
0x3a, 0x09, 0x8d, 0x8d, 0x43, 0x66, 0x57, 0x5d, 0x3a, 0x45, 0x23, 0x45,
|
||||||
0x7d, 0xe1, 0x29, 0x1b, 0x6a, 0x86, 0x84, 0x8c, 0x32, 0xb7, 0xa9, 0x2f,
|
0x13, 0x90, 0x76, 0xc8, 0x6c, 0xab, 0x4b, 0x06, 0xc0, 0x45, 0x81, 0xf9,
|
||||||
0x38, 0x40, 0x90, 0x25, 0xee, 0xf3, 0xed, 0xed, 0x6d, 0x2f, 0x80, 0x20,
|
0xa2, 0x58, 0x2c, 0xba, 0xea, 0x39, 0xfe, 0x7e, 0xa2, 0x29, 0x73, 0x59,
|
||||||
0xde, 0x8f, 0x0d, 0x6d, 0xa6, 0x4a, 0x39, 0x51, 0x53, 0x34, 0x00, 0xfd,
|
0xc8, 0xf0, 0x8a, 0xa4, 0x00, 0xe4, 0x17, 0xf5, 0x5d, 0xfc, 0xc7, 0x01,
|
||||||
0xbc, 0xf1, 0x01, 0xff, 0xf1, 0xc0, 0x48, 0xb2, 0xa9, 0x2b, 0xc2, 0x53,
|
0x11, 0x44, 0x5d, 0x95, 0xb8, 0xd5, 0x21, 0x23, 0x2b, 0x32, 0x72, 0x53,
|
||||||
0x99, 0x53, 0x35, 0x15, 0xf9, 0x88, 0x2f, 0x72, 0xe6, 0x44, 0x90, 0xb4,
|
0x5e, 0x66, 0xf4, 0x29, 0x27, 0x28, 0x8b, 0x43, 0x26, 0x0f, 0x7f, 0xb6,
|
||||||
0x79, 0x99, 0x2b, 0xc2, 0x9f, 0xcd, 0x22, 0xb4, 0x62, 0x8c, 0x87, 0x42,
|
0xf3, 0xd0, 0x84, 0x36, 0x19, 0x71, 0x09, 0x26, 0x9f, 0x36, 0xff, 0x66,
|
||||||
0x8a, 0x2b, 0x66, 0xd9, 0x7f, 0xf9, 0x6d, 0x2e, 0xed, 0x41, 0x19, 0x81,
|
0x8b, 0x4c, 0xd2, 0xc1, 0x18, 0x83, 0x98, 0x19, 0x5d, 0x7c, 0x42, 0xc0,
|
||||||
0xb8, 0x39, 0x53, 0x7e, 0x46, 0xc0, 0x52, 0xc9, 0xe6, 0xd4, 0xad, 0x19,
|
0x4e, 0xc1, 0x64, 0xd2, 0xa9, 0x18, 0x73, 0x33, 0x51, 0x82, 0x56, 0x74,
|
||||||
0x09, 0x53, 0x59, 0x81, 0x86, 0x4c, 0x41, 0x35, 0x73, 0x26, 0x32, 0xe4,
|
0x4e, 0xd6, 0x33, 0x3a, 0xd2, 0xc4, 0xb1, 0x0f, 0x60, 0x81, 0xc4, 0xc9,
|
||||||
0x51, 0x10, 0x62, 0x8e, 0xe4, 0xf1, 0xc4, 0x2a, 0x0f, 0x35, 0x45, 0x72,
|
0xd4, 0x38, 0x1c, 0x29, 0x92, 0x60, 0xd5, 0xbc, 0x84, 0x69, 0x70, 0x2e,
|
||||||
0xaa, 0x5e, 0x22, 0xb5, 0x39, 0x53, 0xbc, 0x0a, 0x55, 0x64, 0x13, 0x1a,
|
0xb9, 0x94, 0x28, 0x89, 0x3a, 0xb4, 0x89, 0x3b, 0xc3, 0xcf, 0xbf, 0xa1,
|
||||||
0xc6, 0x5d, 0x13, 0x12, 0xc3, 0xd2, 0x74, 0xe0, 0x3f, 0xa0, 0x48, 0x7f,
|
0xa8, 0xc0, 0xb8, 0x57, 0x79, 0x9e, 0x82, 0x19, 0xa7, 0x4d, 0x44, 0xd9,
|
||||||
0xc9, 0x54, 0x30, 0xc6, 0xb2, 0xea, 0x2f, 0xd3, 0x05, 0x49, 0x92, 0xd5,
|
0x53, 0xa4, 0x72, 0x82, 0x20, 0xca, 0x13, 0x28, 0x5b, 0xc7, 0x01, 0x34,
|
||||||
0x31, 0x14, 0x2e, 0x67, 0x04, 0x9a, 0xc6, 0x8c, 0x84, 0xbb, 0xd0, 0x40,
|
0x0a, 0x1c, 0x04, 0x3b, 0x4c, 0x43, 0x12, 0x67, 0x88, 0x8f, 0xc8, 0xd5,
|
||||||
0x8a, 0x60, 0xc9, 0x8f, 0xc8, 0xdb, 0x8e, 0xac, 0xe6, 0xe6, 0xb2, 0x64,
|
0x84, 0x28, 0x67, 0x16, 0xa2, 0x60, 0x4c, 0x0f, 0x99, 0xbd, 0xbc, 0x5b,
|
||||||
0x4d, 0xca, 0xdc, 0x4e, 0xd1, 0xa7, 0x1e, 0x71, 0x66, 0x98, 0xd0, 0x3b,
|
0x23, 0xfc, 0x5c, 0xd3, 0xa1, 0x33, 0x00, 0x59, 0x04, 0xb2, 0xda, 0xda,
|
||||||
0x80, 0x2e, 0x03, 0x65, 0x63, 0x45, 0x93, 0xa6, 0x2e, 0xa8, 0xde, 0x46,
|
0xd6, 0x74, 0x95, 0x93, 0x5d, 0xed, 0xd1, 0x6e, 0xa4, 0xdd, 0x1c, 0xec,
|
||||||
0x69, 0xd7, 0xb2, 0xbe, 0x0f, 0xf7, 0xab, 0xac, 0x2a, 0xb2, 0x8a, 0x72,
|
0x43, 0x51, 0x96, 0x44, 0x19, 0x65, 0x46, 0x92, 0xc2, 0xdf, 0x87, 0xc8,
|
||||||
0x43, 0x45, 0x13, 0xef, 0xa3, 0x24, 0xdc, 0xd1, 0x17, 0x2b, 0x65, 0x2c,
|
0xb5, 0xa7, 0x2e, 0x37, 0x48, 0x76, 0x38, 0x55, 0x1e, 0x91, 0xc6, 0x3c,
|
||||||
0x4f, 0xb4, 0x47, 0x64, 0x70, 0x1f, 0x3d, 0x16, 0xc5, 0x1a, 0x5c, 0x81,
|
0xbb, 0x2c, 0xc7, 0x6c, 0x6c, 0x3d, 0x86, 0xc9, 0xa6, 0xcd, 0x5e, 0xad,
|
||||||
0xc2, 0x98, 0x75, 0x78, 0xac, 0xd7, 0xeb, 0x0e, 0x8a, 0x8b, 0x68, 0x9a,
|
0x56, 0xb3, 0x30, 0x6c, 0x34, 0x5d, 0xcf, 0x18, 0x30, 0x32, 0x1e, 0x45,
|
||||||
0x39, 0x0b, 0x86, 0xce, 0xa3, 0x8c, 0xe6, 0xd0, 0xb3, 0x59, 0x7f, 0x09,
|
0xb4, 0x80, 0x5e, 0x4c, 0xfb, 0x4a, 0x1c, 0xad, 0x3a, 0x1c, 0x47, 0x74,
|
||||||
0x51, 0x71, 0x88, 0xef, 0xd5, 0x5d, 0x18, 0x36, 0x0a, 0x57, 0xc8, 0xe8,
|
0xd8, 0xc6, 0xee, 0x7f, 0xf9, 0x2c, 0xb4, 0x51, 0x51, 0x56, 0xe7, 0x06,
|
||||||
0xa6, 0x65, 0x55, 0x9f, 0x59, 0xdc, 0xc7, 0x84, 0x23, 0x52, 0xd3, 0x05,
|
0xf3, 0x1c, 0x6b, 0xb0, 0x29, 0x2a, 0xc7, 0x8b, 0xc6, 0x0a, 0x9a, 0xdb,
|
||||||
0x51, 0xb6, 0x9e, 0xa0, 0xd1, 0xd5, 0x94, 0x3f, 0xfa, 0x0d, 0x1d, 0x33,
|
0x40, 0xf4, 0xd9, 0x63, 0xc6, 0x98, 0x0f, 0x6d, 0xc6, 0x49, 0xcc, 0x36,
|
||||||
0x64, 0x4c, 0x05, 0x85, 0xdb, 0xc4, 0x43, 0xf7, 0x0a, 0x19, 0x92, 0xa0,
|
0x1e, 0x92, 0x57, 0x48, 0x13, 0x38, 0x99, 0x4b, 0x33, 0x25, 0x4d, 0xe4,
|
||||||
0x0a, 0x59, 0xae, 0x62, 0xc8, 0x02, 0x48, 0xdf, 0x8b, 0x1a, 0x1f, 0xb9,
|
0x40, 0xe2, 0x7e, 0x88, 0xf1, 0x67, 0x66, 0xca, 0x53, 0x66, 0x0e, 0x85,
|
||||||
0xa9, 0xf6, 0x9c, 0x9b, 0x41, 0x29, 0xd4, 0x28, 0x48, 0xb4, 0x42, 0x86,
|
0x50, 0x21, 0x21, 0xde, 0xf0, 0x1b, 0x32, 0x0c, 0x8c, 0xd1, 0xbd, 0x68,
|
||||||
0x0e, 0x83, 0x67, 0x78, 0x2f, 0x5b, 0x4b, 0x61, 0x3c, 0x75, 0x49, 0x75,
|
0xac, 0x03, 0x71, 0x55, 0xc5, 0xd2, 0x43, 0x84, 0x49, 0xe5, 0xf3, 0xe3,
|
||||||
0x12, 0x67, 0x6c, 0xc5, 0xe2, 0x28, 0x99, 0x01, 0xc7, 0x93, 0xb5, 0x8d,
|
0x18, 0x26, 0x1a, 0x49, 0xd1, 0x34, 0x04, 0x87, 0x2e, 0x36, 0x92, 0x8c,
|
||||||
0xca, 0x25, 0x83, 0xcd, 0x27, 0x27, 0x21, 0x51, 0x33, 0x04, 0xaa, 0x76,
|
0x80, 0x78, 0x45, 0xe3, 0xa8, 0x96, 0xc1, 0x98, 0x90, 0x26, 0x89, 0x1b,
|
||||||
0xb0, 0x33, 0x64, 0x28, 0x72, 0x12, 0x46, 0x69, 0xe7, 0x65, 0xc0, 0xbd,
|
0xf9, 0xa3, 0xfd, 0x94, 0x02, 0xff, 0x3c, 0x42, 0x12, 0x7c, 0xe3, 0x21,
|
||||||
0x0f, 0x91, 0x02, 0xdf, 0xc4, 0x43, 0x84, 0x0d, 0x84, 0xfc, 0x29, 0x81,
|
0x1f, 0x34, 0x03, 0xf2, 0xa7, 0x00, 0x9e, 0x26, 0x16, 0xb5, 0xdf, 0x09,
|
||||||
0x77, 0x4a, 0x4a, 0xf1, 0x77, 0x42, 0x29, 0x34, 0xae, 0x92, 0xea, 0x8f,
|
0x15, 0xff, 0x88, 0x89, 0xa5, 0x2e, 0xc2, 0x46, 0x3a, 0xac, 0xf0, 0xf0,
|
||||||
0xb0, 0x93, 0x8d, 0x2a, 0x2c, 0x97, 0x87, 0x68, 0xa4, 0x19, 0x88, 0xfb,
|
0x70, 0x84, 0xc6, 0x8a, 0x86, 0x98, 0xe7, 0x37, 0xea, 0x8d, 0xf0, 0x76,
|
||||||
0xf8, 0x06, 0x3d, 0x12, 0x1e, 0xcb, 0xc0, 0x93, 0x30, 0x54, 0x90, 0x64,
|
0x08, 0xcc, 0x70, 0x23, 0x09, 0x09, 0xb6, 0xc8, 0x41, 0x72, 0x02, 0x1a,
|
||||||
0x8b, 0x1f, 0x45, 0x52, 0x42, 0x23, 0x61, 0xa6, 0x58, 0x51, 0x06, 0x9c,
|
0x73, 0x73, 0xc9, 0x08, 0xb1, 0xcf, 0xec, 0x5e, 0xac, 0x36, 0xf8, 0x29,
|
||||||
0xdf, 0x49, 0xda, 0x90, 0x38, 0x41, 0xe2, 0x3d, 0x92, 0xca, 0xaa, 0x66,
|
0xe2, 0xef, 0x91, 0x70, 0x28, 0x2b, 0x46, 0xc2, 0x6e, 0x30, 0x19, 0xa9,
|
||||||
0xa5, 0x9c, 0x56, 0xd3, 0xf1, 0x3a, 0x22, 0x4e, 0x67, 0x35, 0xf1, 0xf5,
|
0x16, 0xe2, 0x41, 0x3e, 0x52, 0x2f, 0x6e, 0x7f, 0x32, 0xd7, 0xa4, 0x04,
|
||||||
0x94, 0xe4, 0xf5, 0x41, 0x33, 0x43, 0x49, 0xf1, 0x92, 0x60, 0x09, 0x65,
|
0x2b, 0x70, 0x06, 0x77, 0x28, 0xce, 0xb8, 0x09, 0xca, 0xa9, 0xf2, 0xe4,
|
||||||
0x79, 0x2a, 0x8c, 0x51, 0x41, 0x57, 0xc7, 0xfb, 0x43, 0xc1, 0x44, 0x3b,
|
0x68, 0xc4, 0xe9, 0x68, 0xaf, 0x98, 0x16, 0xaf, 0xca, 0x9d, 0xde, 0x22,
|
||||||
0xdb, 0x59, 0xf9, 0xaa, 0xda, 0xb9, 0x98, 0x17, 0x5b, 0xcd, 0xb1, 0x56,
|
0xdf, 0x6c, 0x4c, 0x94, 0x12, 0x7c, 0x7e, 0xe8, 0x5f, 0x4e, 0x6b, 0x97,
|
||||||
0x81, 0xcf, 0x0f, 0xbd, 0xcb, 0x49, 0xfd, 0x72, 0x0c, 0x4f, 0x55, 0xfc,
|
0x13, 0xf8, 0x55, 0xc6, 0x8f, 0x95, 0x49, 0xa5, 0x74, 0x83, 0x7f, 0xd4,
|
||||||
0xb3, 0x36, 0xae, 0x55, 0x6e, 0xf0, 0x43, 0xa3, 0x83, 0xe6, 0x97, 0xf8,
|
0x3b, 0x68, 0x71, 0x89, 0x7f, 0x34, 0x86, 0xbd, 0xfa, 0xf5, 0x69, 0x6f,
|
||||||
0xa1, 0x39, 0xb8, 0x68, 0x5c, 0x1f, 0x5f, 0xf4, 0x87, 0xa5, 0xdb, 0xa2,
|
0x30, 0x2a, 0xdc, 0xe6, 0x85, 0x42, 0x7d, 0x75, 0xdb, 0x2d, 0x97, 0x6f,
|
||||||
0x54, 0x6a, 0x3c, 0xdd, 0x76, 0xab, 0xd5, 0xdb, 0xe6, 0x9e, 0x7c, 0xdb,
|
0x1b, 0x07, 0xe2, 0x6d, 0xbf, 0x7c, 0x3e, 0xba, 0xae, 0xcb, 0xb7, 0x57,
|
||||||
0xab, 0x9e, 0x0e, 0xaf, 0x1b, 0xea, 0xed, 0xd5, 0xa9, 0x72, 0x73, 0x7d,
|
0xe7, 0xd2, 0xcd, 0x75, 0x6f, 0x97, 0xe7, 0x25, 0xe9, 0x02, 0x23, 0xa8,
|
||||||
0xf1, 0x41, 0x14, 0x15, 0xe5, 0x1c, 0x23, 0xe8, 0x8b, 0xd3, 0x8b, 0x7a,
|
0xcb, 0xf3, 0x5e, 0xad, 0x7e, 0x89, 0x7e, 0xd0, 0x74, 0xa9, 0xbd, 0x3d,
|
||||||
0xe3, 0x12, 0xfd, 0x60, 0x98, 0x4a, 0x7b, 0x73, 0x56, 0x2c, 0x56, 0xba,
|
0xcf, 0xe7, 0x4b, 0xdd, 0x49, 0x03, 0x5c, 0xf4, 0x8a, 0x93, 0xea, 0xf5,
|
||||||
0xe3, 0x26, 0xb8, 0xf7, 0x27, 0x41, 0x69, 0x34, 0x3a, 0xad, 0x4c, 0x4d,
|
0x4e, 0x33, 0x55, 0x91, 0xce, 0xce, 0x9a, 0xdd, 0xe6, 0xea, 0xe1, 0xf2,
|
||||||
0x39, 0x39, 0x69, 0x75, 0x5b, 0x4f, 0x0f, 0x97, 0x57, 0xdd, 0xc7, 0x7e,
|
0xaa, 0xfb, 0x38, 0xa8, 0xd5, 0x76, 0xaa, 0xb3, 0xd2, 0xb4, 0xb5, 0x28,
|
||||||
0xbd, 0xbe, 0x75, 0x34, 0xad, 0x4c, 0xce, 0xe6, 0x95, 0xc9, 0xe5, 0x6e,
|
0x4d, 0x2f, 0xf7, 0xbb, 0xb7, 0xca, 0x69, 0xb1, 0x54, 0xe8, 0x16, 0x26,
|
||||||
0xf7, 0x56, 0x3b, 0xde, 0xae, 0x94, 0xba, 0xa5, 0x71, 0xbb, 0xd7, 0x10,
|
0xed, 0x7e, 0x9d, 0xe3, 0x51, 0xb1, 0x5d, 0x31, 0xce, 0xf7, 0xfb, 0x17,
|
||||||
0x44, 0xb4, 0xdd, 0xae, 0x59, 0xa7, 0xbb, 0xbd, 0xf3, 0x6a, 0x63, 0x5e,
|
0xe5, 0xfa, 0xa2, 0x74, 0xdf, 0x9b, 0x8b, 0xa7, 0x4d, 0xb5, 0xb4, 0xa7,
|
||||||
0xb9, 0xbf, 0x98, 0xc9, 0xc7, 0x2d, 0xbd, 0xb2, 0x63, 0x5e, 0xfc, 0x50,
|
0xf7, 0x7e, 0xc8, 0xb5, 0xe6, 0x9f, 0x9e, 0x1a, 0xbb, 0xe2, 0x76, 0xf1,
|
||||||
0x38, 0x9b, 0x7d, 0xf3, 0xdc, 0xfc, 0x20, 0x6f, 0x6e, 0xdf, 0x8b, 0x96,
|
0x9e, 0x37, 0xb8, 0xcb, 0x87, 0x5e, 0x63, 0xda, 0x18, 0xca, 0xf3, 0x83,
|
||||||
0x70, 0xf9, 0x70, 0xd1, 0x9c, 0x34, 0x07, 0xea, 0x6c, 0xaf, 0x53, 0x38,
|
0x4e, 0xee, 0xc2, 0xf8, 0xd4, 0x7e, 0xd2, 0xdb, 0xe2, 0xbd, 0xf4, 0x58,
|
||||||
0xb7, 0xbe, 0x69, 0x3f, 0x9b, 0x6d, 0xf9, 0x5e, 0x79, 0x6c, 0x64, 0xf6,
|
0x4f, 0x1d, 0x18, 0x85, 0xfb, 0xeb, 0x41, 0xf5, 0x71, 0x75, 0xa6, 0x95,
|
||||||
0xac, 0xd2, 0xfd, 0x75, 0xff, 0xe8, 0xf1, 0xe9, 0xc4, 0xa8, 0x98, 0x95,
|
0xf4, 0x52, 0x9e, 0x6b, 0xf6, 0x7a, 0xe2, 0xf6, 0x20, 0x5f, 0xc9, 0x4d,
|
||||||
0xa2, 0xd0, 0xba, 0xb8, 0x90, 0x37, 0xfb, 0xc5, 0x5a, 0x61, 0x72, 0xba,
|
0xcf, 0x8b, 0xad, 0xcb, 0x91, 0xb1, 0x9b, 0xdb, 0xd7, 0x7e, 0x50, 0xaf,
|
||||||
0x7d, 0x76, 0x39, 0xb4, 0x3e, 0x14, 0x76, 0x8d, 0x1f, 0xf4, 0xeb, 0x2b,
|
0xaf, 0x24, 0x75, 0xbf, 0xd7, 0xd7, 0x0e, 0xce, 0x8b, 0xf9, 0x51, 0x71,
|
||||||
0x45, 0xdf, 0xbd, 0xe8, 0x19, 0x7b, 0xa7, 0xdb, 0xc5, 0xe1, 0xf6, 0xee,
|
0x7f, 0xbc, 0xac, 0x73, 0x83, 0xee, 0x41, 0x6a, 0x6c, 0xec, 0xd7, 0x6e,
|
||||||
0x68, 0xd1, 0x10, 0xfa, 0xdd, 0xbd, 0xcc, 0xc8, 0xda, 0xad, 0xdf, 0xee,
|
0xf7, 0xda, 0xe7, 0x37, 0xa3, 0x7c, 0xe7, 0x3e, 0x25, 0xc8, 0x37, 0x0d,
|
||||||
0xb4, 0x4f, 0x6f, 0x86, 0xc5, 0xce, 0x7d, 0x46, 0x52, 0x6f, 0x9a, 0xfa,
|
0x75, 0x76, 0x31, 0x19, 0x2e, 0x9a, 0x67, 0xa5, 0xc7, 0xd6, 0x72, 0xff,
|
||||||
0xf4, 0x7c, 0x3c, 0x98, 0xb7, 0x4e, 0x2a, 0x8f, 0x67, 0x8b, 0xdd, 0xc7,
|
0xf1, 0x66, 0xc8, 0xef, 0x36, 0x84, 0x76, 0xa9, 0x7b, 0x3e, 0xe9, 0xd6,
|
||||||
0x9b, 0x81, 0xf8, 0xa1, 0x29, 0xb5, 0x2b, 0xdd, 0xd3, 0x71, 0xb7, 0x7e,
|
0xee, 0xd5, 0xbb, 0xde, 0x60, 0xba, 0xb3, 0x37, 0xe8, 0x17, 0x2e, 0x53,
|
||||||
0xaf, 0xdf, 0x5d, 0xf4, 0x27, 0x5b, 0x3b, 0xfd, 0x5e, 0xe9, 0x32, 0x73,
|
0xd5, 0xeb, 0xeb, 0x5c, 0x75, 0xfb, 0xd3, 0xf5, 0xfc, 0x66, 0x32, 0xdb,
|
||||||
0x74, 0x7d, 0x5d, 0x38, 0xda, 0xfc, 0xe6, 0x7a, 0x76, 0x33, 0x9e, 0xee,
|
0x57, 0x17, 0xe7, 0xab, 0x9b, 0x6d, 0x59, 0xbd, 0xd5, 0x6f, 0x9b, 0x9d,
|
||||||
0xea, 0xf3, 0xd3, 0xa7, 0x9b, 0x4d, 0x55, 0xbf, 0x35, 0x6f, 0x5b, 0x9d,
|
0xe5, 0xd9, 0xac, 0x73, 0xb5, 0x7d, 0x96, 0x9b, 0x16, 0x53, 0x9d, 0xbd,
|
||||||
0xc5, 0xc9, 0xb4, 0x73, 0xb5, 0x79, 0x52, 0x98, 0x6c, 0x67, 0x3a, 0x3b,
|
0xc7, 0xda, 0x64, 0xb7, 0x51, 0xb9, 0x2d, 0xab, 0x93, 0x59, 0x69, 0x6f,
|
||||||
0x8f, 0xf5, 0xf1, 0x87, 0x66, 0xed, 0xb6, 0xaa, 0x8f, 0xa7, 0x95, 0x9d,
|
0x3a, 0xdc, 0x5f, 0x9c, 0x36, 0x2f, 0x4f, 0xab, 0xbd, 0xf2, 0xb0, 0x7b,
|
||||||
0xc9, 0x60, 0x77, 0x7e, 0xdc, 0xba, 0x3c, 0x3e, 0xba, 0xa8, 0x0e, 0xba,
|
0x23, 0xf2, 0xdd, 0xa2, 0x26, 0xf1, 0x3b, 0x83, 0x71, 0xfe, 0xaa, 0xad,
|
||||||
0x37, 0xb2, 0xd8, 0xdd, 0x36, 0x14, 0x71, 0xab, 0x3f, 0x2a, 0x5e, 0xb5,
|
0xef, 0x57, 0x4f, 0xcb, 0xfd, 0xfd, 0xbd, 0x62, 0xbd, 0x70, 0x53, 0xd7,
|
||||||
0xcd, 0xdd, 0xa3, 0xe3, 0x6a, 0x6f, 0x77, 0x67, 0xbb, 0x51, 0xba, 0x69,
|
0xd5, 0xbb, 0xc9, 0xe5, 0xcd, 0x5d, 0x73, 0x98, 0x2b, 0x3d, 0xed, 0x4c,
|
||||||
0x98, 0xfa, 0xdd, 0xf8, 0xf2, 0xe6, 0xae, 0x35, 0x28, 0x54, 0x9e, 0xb7,
|
0x74, 0xa1, 0x2b, 0x14, 0x10, 0x2a, 0x9f, 0x2e, 0x66, 0x42, 0xe3, 0x7a,
|
||||||
0xc6, 0xa6, 0xd4, 0x95, 0x4a, 0x08, 0x55, 0x8f, 0xe7, 0x53, 0xa9, 0x79,
|
0x78, 0xca, 0x4f, 0xca, 0x8d, 0xfe, 0xfd, 0xed, 0xb0, 0x33, 0x54, 0xa6,
|
||||||
0x3d, 0x38, 0x16, 0xc7, 0xd5, 0x66, 0xef, 0xfe, 0x76, 0xd0, 0x19, 0x68,
|
0x7c, 0x6d, 0x88, 0x46, 0x3d, 0xa5, 0xcb, 0x97, 0x26, 0x77, 0x0f, 0x10,
|
||||||
0x13, 0xb1, 0x3e, 0x40, 0xc3, 0x0b, 0xad, 0x2b, 0x56, 0xc6, 0x77, 0x0f,
|
0x36, 0xfd, 0x70, 0x93, 0x2a, 0x5d, 0xad, 0xe6, 0x3b, 0xb7, 0x3b, 0x7a,
|
||||||
0x10, 0x88, 0xfd, 0x70, 0x93, 0xa9, 0x5c, 0x3d, 0xcd, 0xb6, 0x6e, 0xb7,
|
0xa9, 0xf9, 0x30, 0x6e, 0x2a, 0x8d, 0xb6, 0x8e, 0x16, 0x65, 0x54, 0x3b,
|
||||||
0xcc, 0x4a, 0xeb, 0x61, 0xd4, 0xd2, 0x9a, 0x6d, 0x13, 0xcd, 0xab, 0xa8,
|
0xeb, 0x5c, 0x4c, 0xba, 0xcb, 0xe5, 0xc5, 0xf9, 0xd9, 0x1d, 0xdf, 0x38,
|
||||||
0x7e, 0xd2, 0x39, 0x1f, 0x77, 0x17, 0x8b, 0xf3, 0xd3, 0x93, 0x3b, 0xb1,
|
0xdd, 0x7b, 0x30, 0x5a, 0xb9, 0x7c, 0x49, 0x28, 0x55, 0x9f, 0x9a, 0x0d,
|
||||||
0x79, 0xbc, 0xf3, 0x60, 0x9d, 0x15, 0x8a, 0x15, 0xa9, 0x72, 0xf4, 0xdc,
|
0x79, 0x3e, 0xaf, 0xa6, 0x0a, 0x46, 0xab, 0xf9, 0xa9, 0xbb, 0x5f, 0x9d,
|
||||||
0x6a, 0xaa, 0xb3, 0xd9, 0x51, 0xa6, 0x64, 0x9d, 0xb5, 0xbe, 0xe9, 0xee,
|
0x9e, 0x9e, 0x8e, 0x3a, 0xe5, 0xeb, 0x54, 0xb3, 0xf6, 0xc4, 0x9f, 0xb6,
|
||||||
0x1e, 0x4d, 0x8e, 0x8f, 0x87, 0x9d, 0xea, 0x75, 0xa6, 0x55, 0x7f, 0x16,
|
0xe6, 0x37, 0xfc, 0x7e, 0xa1, 0x7d, 0x5f, 0xbb, 0x44, 0xf7, 0x2d, 0x71,
|
||||||
0x8f, 0xcf, 0x66, 0x37, 0xe2, 0x6e, 0xa9, 0x7d, 0x5f, 0xbf, 0x44, 0xf7,
|
0x31, 0x7f, 0xbc, 0x3a, 0x4d, 0x4d, 0xe6, 0xdd, 0x72, 0xf7, 0xa9, 0xd3,
|
||||||
0x67, 0xf2, 0x7c, 0xf6, 0x78, 0x75, 0x9c, 0x19, 0xcf, 0xba, 0xd5, 0xee,
|
0x28, 0x0e, 0x85, 0xd2, 0x68, 0xbf, 0xd6, 0xe1, 0x7b, 0xfc, 0x43, 0xf7,
|
||||||
0x73, 0xa7, 0xb9, 0x3d, 0x90, 0x2a, 0xc3, 0xdd, 0x7a, 0x47, 0xbc, 0x10,
|
0xb1, 0x7a, 0x7f, 0x53, 0x10, 0x2b, 0xad, 0xf9, 0xb2, 0x56, 0x39, 0x2f,
|
||||||
0x1f, 0xba, 0x8f, 0x47, 0xf7, 0x37, 0x25, 0xb9, 0x76, 0x36, 0x5b, 0xd4,
|
0xee, 0x9c, 0x2b, 0xa3, 0xf6, 0x50, 0x99, 0x1b, 0x0f, 0x8d, 0x49, 0x95,
|
||||||
0x6b, 0xa7, 0xdb, 0x5b, 0xa7, 0xda, 0xb0, 0x3d, 0xd0, 0x66, 0xd6, 0x43,
|
0x2b, 0x0c, 0x3e, 0x5d, 0x3e, 0xb4, 0x9a, 0x0b, 0xe3, 0xa0, 0xd9, 0x5b,
|
||||||
0x73, 0x7c, 0x24, 0x94, 0xfa, 0xdf, 0x5c, 0x3e, 0x9c, 0xb5, 0xe6, 0xd6,
|
0xcd, 0x97, 0xcd, 0xab, 0xf2, 0xea, 0xe1, 0x6a, 0x38, 0x7c, 0x38, 0x53,
|
||||||
0x5e, 0xeb, 0xe2, 0x69, 0xb6, 0x68, 0x5d, 0x55, 0x9f, 0x1e, 0xae, 0x06,
|
0x2a, 0x95, 0xcb, 0x4a, 0xe9, 0x61, 0x7a, 0xd9, 0x11, 0x95, 0xc1, 0x75,
|
||||||
0x83, 0x87, 0x13, 0xad, 0x56, 0xbb, 0xac, 0x55, 0x1e, 0x26, 0x97, 0x1d,
|
0xe5, 0x53, 0xa3, 0x38, 0xe8, 0xd6, 0x3a, 0xd5, 0x7c, 0xe9, 0x62, 0x55,
|
||||||
0x59, 0xeb, 0x5f, 0xd7, 0xbe, 0x69, 0x6e, 0xf7, 0xbb, 0xf5, 0xce, 0x51,
|
0xc8, 0x7d, 0x6a, 0x14, 0x86, 0xea, 0x7c, 0xfb, 0xbc, 0x98, 0x92, 0x96,
|
||||||
0xb1, 0x72, 0xfe, 0x54, 0x2a, 0x7c, 0xd3, 0x2c, 0x0d, 0xf4, 0xd9, 0xe6,
|
0xa8, 0x5b, 0x1c, 0x0c, 0xcb, 0xa3, 0xb3, 0x41, 0x55, 0x55, 0xae, 0x90,
|
||||||
0xe9, 0x76, 0x46, 0x59, 0xa0, 0xee, 0x76, 0x7f, 0x50, 0x1d, 0x9e, 0xf4,
|
0x04, 0x96, 0x51, 0xbe, 0xaa, 0x8f, 0x16, 0xf3, 0x5d, 0xa5, 0xdd, 0x3e,
|
||||||
0x8f, 0x74, 0xed, 0x0a, 0x29, 0x60, 0x19, 0xd5, 0xab, 0xc6, 0x70, 0x3e,
|
0xbf, 0x2c, 0x4f, 0x95, 0xe1, 0x6a, 0xd7, 0x98, 0x09, 0x3d, 0xbe, 0xbd,
|
||||||
0xfb, 0xa0, 0xb5, 0xdb, 0xa7, 0x97, 0xd5, 0x89, 0x36, 0x78, 0xfa, 0x60,
|
0x58, 0xcd, 0x2e, 0x0a, 0x9d, 0x56, 0x97, 0x6b, 0xdd, 0x2d, 0x0f, 0x72,
|
||||||
0x4d, 0xa5, 0x0b, 0xb1, 0x3d, 0x7f, 0x9a, 0x9e, 0x97, 0x3a, 0x67, 0x5d,
|
0x8f, 0x72, 0x59, 0xd9, 0xbb, 0xda, 0x69, 0xee, 0x89, 0x4f, 0xa5, 0xc1,
|
||||||
0xe1, 0xec, 0x6e, 0xb1, 0x57, 0x78, 0x54, 0xab, 0xda, 0xce, 0xd5, 0x56,
|
0xac, 0x2f, 0xb7, 0xb9, 0x7c, 0xf5, 0xe1, 0xd3, 0x18, 0x69, 0x67, 0xca,
|
||||||
0x6b, 0x47, 0x7e, 0xae, 0xf4, 0xa7, 0x3d, 0xb5, 0x2d, 0x14, 0x8f, 0x1e,
|
0xf4, 0x7c, 0xaa, 0x6d, 0xab, 0xf9, 0xed, 0x27, 0x4d, 0x7a, 0x2a, 0x1e,
|
||||||
0xbe, 0x19, 0x21, 0xe3, 0x44, 0x9b, 0x9c, 0x4e, 0x8c, 0x4d, 0xbd, 0xb8,
|
0x68, 0xb7, 0xf5, 0x62, 0x07, 0xba, 0xe0, 0xfc, 0x7e, 0x58, 0xd8, 0x79,
|
||||||
0xf9, 0x6c, 0x28, 0xcf, 0xdb, 0x7b, 0xc6, 0x6d, 0x63, 0xbb, 0x03, 0x5d,
|
0xbc, 0xea, 0x3e, 0xdd, 0xa8, 0xa9, 0xc5, 0xe8, 0xa6, 0x71, 0x95, 0x6b,
|
||||||
0x70, 0x7a, 0x3f, 0x28, 0x6d, 0x3d, 0x5e, 0x75, 0x9f, 0x6f, 0xf4, 0xcc,
|
0xaa, 0xc3, 0xe6, 0xdd, 0x23, 0x0c, 0xe6, 0x7d, 0x43, 0x3f, 0x6b, 0x56,
|
||||||
0x7c, 0x78, 0xd3, 0xbc, 0x2a, 0xb4, 0xf4, 0x41, 0xeb, 0xee, 0x11, 0x06,
|
0xb4, 0xf6, 0x0f, 0xa5, 0x9b, 0xfa, 0xf2, 0xae, 0xd0, 0x68, 0xf6, 0x77,
|
||||||
0xf4, 0xae, 0x65, 0x9e, 0xb4, 0x6a, 0x46, 0xfb, 0x87, 0xca, 0x4d, 0x63,
|
0x6f, 0xaf, 0x97, 0x93, 0x22, 0x5a, 0x34, 0xf5, 0xf3, 0x31, 0xd7, 0x68,
|
||||||
0x71, 0x57, 0x6a, 0xb6, 0x7a, 0x1f, 0x6e, 0xaf, 0x17, 0xe3, 0x6d, 0x34,
|
0x9f, 0xdd, 0xec, 0x36, 0x87, 0x0f, 0x17, 0x4f, 0xfb, 0xad, 0x72, 0xf9,
|
||||||
0x6f, 0x99, 0xa7, 0x23, 0xa1, 0xd9, 0x3e, 0xb9, 0xf9, 0xd0, 0x1a, 0x3c,
|
0x6e, 0x2f, 0xb5, 0xaa, 0x3e, 0x5e, 0x5d, 0x7c, 0x3a, 0x80, 0x6f, 0x35,
|
||||||
0x9c, 0x3f, 0xef, 0x9e, 0x55, 0xab, 0x77, 0x3b, 0x99, 0xa7, 0xa3, 0xc7,
|
0x77, 0x50, 0x3f, 0x50, 0xce, 0x96, 0x3b, 0x1d, 0x51, 0x3f, 0xbd, 0x5e,
|
||||||
0xab, 0xf3, 0x6f, 0xf6, 0xe0, 0x5b, 0x2f, 0xec, 0x35, 0xf6, 0xb4, 0x93,
|
0xa0, 0x4f, 0x1d, 0x4e, 0xca, 0x9f, 0x2e, 0x2b, 0x30, 0x88, 0xba, 0x30,
|
||||||
0xc5, 0x56, 0x47, 0x36, 0x8f, 0xaf, 0xe7, 0xe8, 0x9b, 0x8e, 0xa0, 0x14,
|
0x22, 0x6b, 0x67, 0x5d, 0x18, 0x90, 0xb5, 0x33, 0x18, 0x9a, 0xa4, 0x68,
|
||||||
0x8f, 0x17, 0x35, 0x18, 0x44, 0x5d, 0x18, 0x91, 0xf5, 0x93, 0x2e, 0x0c,
|
0x0a, 0xff, 0x9d, 0xe1, 0x0a, 0x5a, 0x54, 0x83, 0xc7, 0x29, 0x85, 0x5d,
|
||||||
0xc8, 0xfa, 0x09, 0x0c, 0x4d, 0x52, 0x34, 0x81, 0xbf, 0x4e, 0x70, 0x05,
|
0x54, 0xf7, 0x6b, 0xb9, 0xf2, 0xed, 0xa4, 0x74, 0x91, 0x7f, 0x98, 0x36,
|
||||||
0x2d, 0xaa, 0xc3, 0xcf, 0x09, 0x85, 0x9d, 0x1f, 0xed, 0xd6, 0x0b, 0xd5,
|
0xef, 0x76, 0xb4, 0x61, 0xe7, 0x53, 0x09, 0x7f, 0x6a, 0x52, 0x7d, 0x70,
|
||||||
0xdb, 0x71, 0xe5, 0xbc, 0xf8, 0x30, 0x69, 0xdd, 0x6d, 0x19, 0x83, 0xce,
|
0xdf, 0x9f, 0x77, 0x67, 0x95, 0x0a, 0x9b, 0x04, 0x4f, 0x9c, 0xd1, 0x90,
|
||||||
0x37, 0x15, 0xfc, 0xa9, 0x2b, 0x8d, 0xfe, 0x7d, 0x6f, 0xd6, 0x9d, 0xd6,
|
0x8a, 0x38, 0xe3, 0x2d, 0x6e, 0x07, 0x4f, 0x40, 0x71, 0x5d, 0xd1, 0x86,
|
||||||
0x6a, 0x7c, 0x1a, 0x5c, 0x73, 0xce, 0x40, 0x3a, 0x12, 0xac, 0x57, 0xba,
|
0x68, 0x69, 0x4a, 0x03, 0x51, 0x66, 0x7b, 0xcf, 0x1d, 0xb2, 0x11, 0xc8,
|
||||||
0x1e, 0x3c, 0x3b, 0x25, 0x76, 0x47, 0xab, 0x02, 0xad, 0x09, 0x0d, 0x6a,
|
0xf0, 0x2a, 0x98, 0xf5, 0x0c, 0x91, 0xe7, 0xa4, 0x0c, 0x27, 0x89, 0x13,
|
||||||
0xb9, 0xcd, 0x1d, 0x5f, 0xcc, 0x47, 0x60, 0x63, 0xea, 0x60, 0x5a, 0xb4,
|
0x98, 0x99, 0x66, 0xa2, 0x20, 0x48, 0xb1, 0x26, 0x95, 0x50, 0xff, 0x98,
|
||||||
0x64, 0x51, 0x50, 0x72, 0x82, 0x22, 0x8f, 0x61, 0xd6, 0x9a, 0xca, 0x92,
|
0x71, 0xc2, 0x92, 0xed, 0x7d, 0x75, 0xb9, 0x31, 0x00, 0x89, 0x12, 0x93,
|
||||||
0xa4, 0x24, 0x9d, 0x6c, 0xa2, 0x5d, 0x65, 0xce, 0x8d, 0x65, 0x36, 0x77,
|
0x84, 0x69, 0x38, 0x22, 0x61, 0x59, 0x87, 0x57, 0x12, 0x8e, 0x9a, 0x02,
|
||||||
0xf5, 0x45, 0x92, 0xa0, 0x25, 0x56, 0x62, 0x12, 0xe8, 0xe1, 0x28, 0x86,
|
0xf8, 0xa7, 0x54, 0x73, 0x3a, 0xc5, 0xf3, 0x6a, 0x5c, 0xe1, 0xc2, 0xf8,
|
||||||
0xe7, 0x3d, 0x4c, 0x93, 0xd0, 0x96, 0x89, 0x12, 0x9a, 0x78, 0xd9, 0xa4,
|
0x26, 0x84, 0x32, 0x3b, 0x31, 0x27, 0x66, 0x6b, 0x62, 0x62, 0x52, 0x31,
|
||||||
0x8b, 0x67, 0xdf, 0xe4, 0x72, 0x46, 0xf1, 0x4f, 0x48, 0xe5, 0xb6, 0x92,
|
0xa6, 0x0e, 0x6f, 0x13, 0x20, 0x44, 0xb0, 0x89, 0xdc, 0x37, 0x0c, 0x0d,
|
||||||
0x4f, 0xe0, 0xf6, 0x9c, 0xc5, 0x65, 0x92, 0xcc, 0x28, 0xfe, 0x66, 0xa8,
|
0x98, 0x18, 0x4e, 0xb8, 0xe3, 0x78, 0x50, 0x00, 0x03, 0x81, 0xd1, 0x0c,
|
||||||
0x2c, 0xe1, 0x66, 0x0a, 0x5f, 0x73, 0x34, 0xda, 0xe2, 0x04, 0xe9, 0x4e,
|
0x7f, 0xd3, 0x08, 0x49, 0xd1, 0x98, 0xd1, 0x7c, 0x32, 0x16, 0x97, 0xcc,
|
||||||
0x10, 0x41, 0x17, 0x1c, 0x04, 0x55, 0x53, 0xfc, 0x4d, 0xa3, 0x2b, 0xcd,
|
0x37, 0x39, 0x13, 0xe7, 0x7b, 0xb2, 0x70, 0x63, 0xe8, 0xba, 0x8d, 0xe1,
|
||||||
0xe0, 0x86, 0xb3, 0xf1, 0x48, 0x5e, 0x70, 0x5f, 0x17, 0x6c, 0xa4, 0xef,
|
0x64, 0x81, 0x49, 0x58, 0x51, 0x17, 0x0e, 0xe1, 0x05, 0x60, 0x97, 0x47,
|
||||||
0xc9, 0x2a, 0x91, 0xa3, 0x8b, 0x44, 0x4e, 0x50, 0x25, 0x2e, 0x65, 0xc7,
|
0x19, 0x55, 0x5c, 0x22, 0x29, 0x43, 0x62, 0x99, 0xc3, 0x7c, 0x92, 0xa2,
|
||||||
0x6c, 0x78, 0x65, 0x20, 0x01, 0xcf, 0x22, 0xca, 0xe9, 0xf2, 0x02, 0x29,
|
0x52, 0x2e, 0x83, 0xb2, 0x39, 0xc5, 0x4e, 0x00, 0xc7, 0xc9, 0x30, 0xdb,
|
||||||
0x39, 0x12, 0xff, 0x94, 0x8b, 0x69, 0x86, 0xcb, 0x78, 0x0d, 0x8b, 0x48,
|
0x51, 0xe6, 0xcd, 0x12, 0x8b, 0xc3, 0x8c, 0xc9, 0x61, 0xc6, 0xe2, 0x30,
|
||||||
0xca, 0x83, 0x11, 0xa0, 0xa0, 0xc2, 0x5c, 0x48, 0x65, 0x60, 0x25, 0x36,
|
0x63, 0x72, 0x28, 0xca, 0x63, 0x51, 0x16, 0x0d, 0xc4, 0x6c, 0xeb, 0x44,
|
||||||
0x97, 0x39, 0xc6, 0x65, 0xce, 0xe6, 0x32, 0xc7, 0xb8, 0x94, 0xd5, 0x91,
|
0x50, 0x47, 0x54, 0x93, 0x71, 0x8b, 0xf6, 0x3d, 0x5a, 0x8d, 0x35, 0x6e,
|
||||||
0xac, 0xca, 0x16, 0xe2, 0x36, 0x4d, 0x5b, 0x5e, 0x57, 0x62, 0xc6, 0xbe,
|
0x86, 0xf4, 0xd8, 0xa4, 0x6d, 0x1a, 0x6e, 0x56, 0xc7, 0x9a, 0x32, 0x83,
|
||||||
0x4d, 0xfe, 0x1e, 0x3d, 0x8d, 0x0c, 0x61, 0x8a, 0xcc, 0xc4, 0xd4, 0x5d,
|
0x12, 0xa7, 0x32, 0x18, 0x8b, 0xdb, 0x5c, 0xb8, 0x81, 0x0c, 0x25, 0x2e,
|
||||||
0x22, 0x3e, 0x7e, 0x47, 0x86, 0x36, 0x85, 0x22, 0x56, 0x1d, 0x13, 0xdf,
|
0x96, 0x23, 0x85, 0xbf, 0xe3, 0xbe, 0x98, 0xab, 0x92, 0xc2, 0x09, 0x64,
|
||||||
0x3b, 0xbc, 0xf8, 0xc0, 0x2c, 0x2d, 0x39, 0xa2, 0x4f, 0x9e, 0x90, 0x60,
|
0xf1, 0x11, 0x2b, 0x42, 0xf7, 0xaf, 0xf0, 0x34, 0x3a, 0x36, 0x83, 0x6b,
|
||||||
0x9f, 0xcf, 0x74, 0x45, 0x13, 0x24, 0xb2, 0xb8, 0x49, 0x18, 0xf8, 0x87,
|
0xbe, 0xc0, 0xd0, 0x2e, 0xec, 0x47, 0x8e, 0xec, 0x42, 0xd1, 0xae, 0x72,
|
||||||
0x96, 0x94, 0x06, 0x1e, 0xc4, 0xab, 0x56, 0x99, 0x6c, 0xa8, 0x97, 0x76,
|
0x84, 0xc8, 0x10, 0x42, 0x64, 0x09, 0x1c, 0x6a, 0xf8, 0xa1, 0x6b, 0x32,
|
||||||
0xe3, 0xbd, 0x40, 0x69, 0xdb, 0xad, 0x73, 0x05, 0xca, 0x11, 0x5a, 0x64,
|
0x5a, 0x88, 0x17, 0x42, 0xfe, 0x25, 0xd7, 0x17, 0xd8, 0x4a, 0x5e, 0x25,
|
||||||
0xfd, 0x1d, 0x3d, 0x32, 0xa2, 0xd7, 0x7f, 0xb4, 0x14, 0x2f, 0xb8, 0xc2,
|
0xa5, 0x97, 0xe1, 0x91, 0x62, 0x18, 0xca, 0x2c, 0x5a, 0x52, 0x67, 0x9c,
|
||||||
0xab, 0xbb, 0xcf, 0xb1, 0xfd, 0xac, 0x29, 0x70, 0x80, 0xf1, 0xa1, 0x66,
|
0x17, 0xf2, 0x84, 0xe5, 0x40, 0x9f, 0x38, 0xe4, 0x1c, 0xa6, 0x10, 0x49,
|
||||||
0x59, 0xda, 0x74, 0x99, 0xd0, 0xae, 0x4f, 0x28, 0x15, 0x29, 0xef, 0xa1,
|
0x73, 0xa4, 0x99, 0x2f, 0x54, 0x8d, 0x98, 0xf0, 0x3b, 0x18, 0xb4, 0x7a,
|
||||||
0x9e, 0xc2, 0x24, 0xc3, 0xcc, 0x21, 0x92, 0x78, 0xc9, 0x72, 0x9f, 0xeb,
|
0x22, 0x06, 0xcb, 0x0e, 0x87, 0x0e, 0x2f, 0x2e, 0x16, 0xd6, 0x68, 0x1b,
|
||||||
0x06, 0x31, 0xf2, 0xb7, 0x31, 0x6a, 0x77, 0x4e, 0x22, 0xde, 0x09, 0xa7,
|
0x6b, 0x36, 0x28, 0xda, 0xae, 0x9f, 0xda, 0x71, 0x0e, 0xd6, 0x87, 0x4e,
|
||||||
0x61, 0x96, 0x5c, 0x4e, 0x96, 0x75, 0x00, 0xd1, 0x75, 0x58, 0xca, 0x0f,
|
0xde, 0x86, 0xd7, 0x44, 0xd5, 0xb0, 0x32, 0x33, 0xe3, 0xb9, 0xcc, 0x63,
|
||||||
0x61, 0x8a, 0x07, 0x05, 0xbc, 0x2e, 0x75, 0x93, 0x4a, 0xa2, 0x21, 0xeb,
|
0xb1, 0x18, 0x18, 0xf8, 0x9c, 0x81, 0xea, 0xa2, 0x84, 0x2e, 0x4d, 0x23,
|
||||||
0x96, 0x93, 0x36, 0x1a, 0xcd, 0x54, 0x11, 0x8b, 0xc8, 0x89, 0x06, 0x4c,
|
0x4c, 0x98, 0xe3, 0x26, 0xcd, 0xe0, 0xce, 0x4a, 0x33, 0x54, 0x3b, 0x49,
|
||||||
0x61, 0xa8, 0x21, 0x2b, 0xe8, 0x92, 0x19, 0x69, 0x8a, 0x0d, 0xb1, 0x2c,
|
0x87, 0xa1, 0x47, 0x4e, 0x63, 0x96, 0x33, 0xe9, 0xd4, 0x30, 0xd4, 0x23,
|
||||||
0x87, 0x7b, 0x30, 0xcb, 0x51, 0x55, 0xa5, 0x3d, 0x6c, 0x3d, 0x0a, 0x06,
|
0x77, 0xa1, 0xb9, 0xdc, 0x38, 0x61, 0x04, 0x85, 0x9f, 0x63, 0x0a, 0x59,
|
||||||
0xb7, 0x98, 0x2a, 0xc7, 0x96, 0xa5, 0xef, 0xfb, 0x4a, 0xd9, 0x72, 0xe6,
|
0x4a, 0xbc, 0x46, 0xe9, 0x25, 0x58, 0x52, 0xcf, 0x3a, 0x79, 0x13, 0x8a,
|
||||||
0x90, 0x93, 0x34, 0x71, 0x86, 0x69, 0xe4, 0x29, 0xf9, 0x3a, 0xa5, 0x98,
|
0x90, 0xc5, 0xb9, 0x24, 0xc0, 0x62, 0xc7, 0xc0, 0x04, 0xeb, 0xaf, 0x9c,
|
||||||
0xe2, 0x49, 0x3d, 0xef, 0xcd, 0xe7, 0x90, 0x92, 0x3c, 0x4e, 0x76, 0x01,
|
0x41, 0xe8, 0x2f, 0xaa, 0x12, 0x06, 0x18, 0x73, 0x92, 0x8e, 0xfc, 0xf5,
|
||||||
0x1a, 0x3f, 0x02, 0x3e, 0xf8, 0x50, 0xed, 0x14, 0xd6, 0x14, 0xb2, 0xae,
|
0x32, 0x37, 0xc3, 0x75, 0x24, 0xa6, 0x76, 0x90, 0x1d, 0x16, 0x26, 0xc8,
|
||||||
0x60, 0x88, 0x91, 0xa0, 0x98, 0x28, 0x04, 0xa0, 0x0a, 0x53, 0x5c, 0x49,
|
0x30, 0xdb, 0x2f, 0xaf, 0xce, 0x04, 0x4b, 0xb6, 0x64, 0x96, 0x53, 0x55,
|
||||||
0x82, 0x74, 0x0f, 0xba, 0xcb, 0xc6, 0x18, 0x59, 0x8c, 0x87, 0xea, 0xd3,
|
0x24, 0x0b, 0x95, 0xa9, 0x28, 0x09, 0x09, 0x42, 0x29, 0xe9, 0x95, 0x45,
|
||||||
0x89, 0x64, 0x4b, 0x98, 0xce, 0x0b, 0xba, 0x8e, 0x54, 0xa9, 0x36, 0x91,
|
0xe5, 0x8c, 0xe9, 0x6b, 0x44, 0xc1, 0xf0, 0x59, 0x51, 0xc0, 0xac, 0xd0,
|
||||||
0x15, 0x29, 0x45, 0x48, 0xa5, 0x03, 0x02, 0xe9, 0x82, 0x35, 0x59, 0x4b,
|
0xd1, 0x9c, 0xc1, 0x25, 0xac, 0x17, 0xc0, 0x16, 0x15, 0xaf, 0x0f, 0x7d,
|
||||||
0x1e, 0x8c, 0x90, 0x97, 0x25, 0xcc, 0x0d, 0x1d, 0xf5, 0x39, 0x5c, 0xc2,
|
0x75, 0xb6, 0x24, 0x61, 0x78, 0xe6, 0x1a, 0xe8, 0x8a, 0x93, 0xe6, 0x04,
|
||||||
0x07, 0x20, 0x1c, 0x81, 0xf1, 0x6a, 0x34, 0x58, 0xe9, 0x88, 0x13, 0x89,
|
0x26, 0xf7, 0x56, 0x51, 0x31, 0x35, 0x9f, 0xa4, 0xa3, 0x39, 0x18, 0xa8,
|
||||||
0xc9, 0xd6, 0x58, 0x57, 0x82, 0x32, 0x23, 0x40, 0x85, 0x57, 0x0b, 0x8c,
|
0xbc, 0x46, 0x56, 0x0a, 0xe0, 0x16, 0x96, 0x96, 0x64, 0x45, 0x59, 0x46,
|
||||||
0xc9, 0x05, 0xe5, 0x1d, 0xce, 0xc0, 0x6c, 0xd5, 0x25, 0x12, 0x53, 0x00,
|
0xda, 0xe9, 0xa0, 0xdd, 0x02, 0xe4, 0x2d, 0x6a, 0x3e, 0x5b, 0x6f, 0xe4,
|
||||||
0x9f, 0xc8, 0xb4, 0x28, 0x2f, 0xab, 0x2a, 0x32, 0x8e, 0xfb, 0xed, 0x33,
|
0x8b, 0x52, 0xf4, 0x71, 0x36, 0xbb, 0x17, 0x44, 0xed, 0x55, 0x8c, 0x11,
|
||||||
0xc0, 0xde, 0xa0, 0xc6, 0xb4, 0xf1, 0x5a, 0xd6, 0x28, 0xc9, 0x20, 0x73,
|
0x0c, 0x2f, 0x5f, 0xed, 0xfb, 0xaa, 0xa8, 0xbd, 0x95, 0x2d, 0x42, 0x2f,
|
||||||
0xd3, 0x7b, 0x49, 0x36, 0xd6, 0xe3, 0x8d, 0xa0, 0xf8, 0x59, 0x6b, 0xdf,
|
0xc0, 0x15, 0x36, 0xd4, 0x57, 0xb2, 0x85, 0x51, 0xfc, 0x7c, 0xe1, 0x41,
|
||||||
0x1f, 0xc9, 0xc6, 0xab, 0x39, 0x23, 0x04, 0xc3, 0x8c, 0x61, 0xc3, 0x5d,
|
0xf7, 0x76, 0xc6, 0x30, 0x45, 0xd2, 0x04, 0xfc, 0xf5, 0x8d, 0xe9, 0x29,
|
||||||
0x97, 0x33, 0x8c, 0x13, 0x64, 0x0d, 0x0f, 0xc4, 0x37, 0xf0, 0x86, 0x49,
|
0x8c, 0xcc, 0x0b, 0x45, 0x37, 0x2e, 0x34, 0x85, 0x47, 0xba, 0xde, 0x43,
|
||||||
0x86, 0x4d, 0xd8, 0x10, 0xe2, 0x59, 0xa3, 0x16, 0xe8, 0xc1, 0x21, 0xf0,
|
0x0f, 0x73, 0xa4, 0x1b, 0x09, 0x32, 0x84, 0xed, 0xd1, 0x33, 0x66, 0x12,
|
||||||
0x3e, 0xb6, 0x78, 0x8e, 0x3b, 0x37, 0x90, 0x69, 0x72, 0x35, 0xcb, 0x50,
|
0xe6, 0x20, 0xce, 0x02, 0xfb, 0xc2, 0xaa, 0x6f, 0x70, 0x06, 0x48, 0x75,
|
||||||
0x72, 0x3d, 0x0e, 0x22, 0x1b, 0xc8, 0xaf, 0x3e, 0xa2, 0x2c, 0x2d, 0xb8,
|
0xc2, 0x14, 0x4d, 0x38, 0x07, 0xd2, 0x06, 0xd4, 0x01, 0x66, 0xae, 0x33,
|
||||||
0x25, 0x05, 0xe0, 0xa3, 0x34, 0x56, 0xd0, 0x9b, 0xc8, 0x23, 0x8b, 0x15,
|
0x9f, 0x9f, 0x60, 0xe7, 0x95, 0x64, 0x38, 0x09, 0x69, 0x20, 0x6f, 0xad,
|
||||||
0x1b, 0x48, 0xd2, 0xde, 0x60, 0xa0, 0x86, 0x40, 0x39, 0x0b, 0x38, 0xad,
|
0xd7, 0xeb, 0xf4, 0x7e, 0x64, 0x53, 0x5e, 0xa8, 0x14, 0xfb, 0x33, 0xc4,
|
||||||
0x09, 0x78, 0x9e, 0x73, 0xcd, 0xb4, 0xce, 0x0d, 0x4d, 0x04, 0xc6, 0x2e,
|
0x5f, 0x29, 0xa7, 0x0d, 0x5d, 0x55, 0x64, 0x1d, 0x0d, 0xd0, 0x92, 0x0e,
|
||||||
0xd0, 0xc3, 0x0c, 0x99, 0x56, 0x2a, 0xed, 0x9b, 0xfa, 0xe5, 0x11, 0x97,
|
0x35, 0xe7, 0x83, 0x24, 0xdd, 0x8c, 0x79, 0x9c, 0x0f, 0xf1, 0x3d, 0x80,
|
||||||
0x62, 0x5e, 0x2a, 0x0f, 0x22, 0x4b, 0x4f, 0x3d, 0x0b, 0xe4, 0xe6, 0x0e,
|
0x34, 0x06, 0xbc, 0xe9, 0x05, 0x18, 0x6d, 0x82, 0x8c, 0x83, 0x47, 0x3c,
|
||||||
0x0f, 0xb9, 0x6d, 0x1b, 0xd0, 0x05, 0x75, 0x20, 0x4d, 0x00, 0x9a, 0x99,
|
0x00, 0x7c, 0xe8, 0x2f, 0xeb, 0x26, 0xd9, 0xa0, 0xab, 0xa3, 0xc4, 0x3c,
|
||||||
0xdc, 0x67, 0x87, 0xd8, 0x4f, 0xa7, 0x39, 0x41, 0x41, 0x06, 0x28, 0xa9,
|
0x32, 0x9a, 0x3c, 0x42, 0xaf, 0xc8, 0xe0, 0x79, 0x87, 0xed, 0x16, 0x7e,
|
||||||
0x7e, 0x71, 0xd1, 0xb9, 0xf8, 0x91, 0xcf, 0xf8, 0xa1, 0x32, 0xfc, 0xcf,
|
0xb2, 0xb5, 0x76, 0x14, 0x84, 0xcc, 0x2a, 0x32, 0xd1, 0x19, 0x96, 0x14,
|
||||||
0x65, 0xce, 0x2d, 0x04, 0x1d, 0xe9, 0x9a, 0x6a, 0xa2, 0x3e, 0x68, 0x94,
|
0xf1, 0x53, 0xc8, 0xa5, 0x83, 0xe6, 0x22, 0xd4, 0x4e, 0xd1, 0x1d, 0xf3,
|
||||||
0xb2, 0xed, 0x7e, 0x90, 0x62, 0xda, 0xd1, 0xa0, 0xfb, 0x21, 0x0e, 0x16,
|
0x81, 0x08, 0x6f, 0x56, 0x05, 0x67, 0x65, 0xb6, 0x56, 0x37, 0x1f, 0x3d,
|
||||||
0xd0, 0x46, 0x80, 0x39, 0x39, 0x87, 0xd1, 0x98, 0x22, 0x23, 0xfc, 0x11,
|
0xed, 0xd8, 0x40, 0x66, 0x9f, 0x27, 0xa8, 0x53, 0x48, 0x33, 0x6a, 0x38,
|
||||||
0x0f, 0xed, 0x20, 0x81, 0x97, 0x15, 0xf1, 0x46, 0xd8, 0xa7, 0x53, 0x82,
|
0x37, 0x00, 0x93, 0x60, 0x2f, 0x2e, 0x07, 0x00, 0xc1, 0xe6, 0xb0, 0xbf,
|
||||||
0x7e, 0x51, 0x19, 0xab, 0xd0, 0xa9, 0x2a, 0xcc, 0x34, 0x83, 0xf6, 0x19,
|
0x66, 0x43, 0xe1, 0x74, 0x4c, 0xca, 0x22, 0x0d, 0x10, 0x41, 0x5d, 0xf9,
|
||||||
0xfe, 0x65, 0xab, 0xcf, 0xdf, 0xa4, 0x2d, 0x95, 0xa6, 0x12, 0xe5, 0x61,
|
0x2c, 0x16, 0xe4, 0xe4, 0x25, 0x91, 0xbf, 0x67, 0x4e, 0x6c, 0x2d, 0x26,
|
||||||
0x89, 0x91, 0x38, 0x81, 0x7d, 0x0d, 0x50, 0x61, 0x4c, 0x07, 0x50, 0x7c,
|
0x90, 0xcf, 0x8c, 0x5c, 0x1d, 0x93, 0x25, 0x69, 0xfd, 0xce, 0x38, 0xc1,
|
||||||
0xd7, 0xf4, 0xb0, 0x05, 0x4c, 0x8f, 0xc0, 0x27, 0xb3, 0xf6, 0x1a, 0xec,
|
0x66, 0xd9, 0x24, 0x98, 0xd2, 0x09, 0x04, 0xaa, 0x49, 0x48, 0x0e, 0x1b,
|
||||||
0xa7, 0xbf, 0x25, 0x07, 0x8a, 0xf5, 0x7d, 0x8a, 0xfa, 0xbd, 0x2c, 0xa7,
|
0x73, 0x4d, 0x76, 0xf1, 0x63, 0x76, 0xc4, 0x9a, 0x5e, 0x35, 0xe7, 0x9c,
|
||||||
0xc7, 0x30, 0x04, 0x40, 0x29, 0xfe, 0xfc, 0xb2, 0x0f, 0x20, 0x7c, 0x01,
|
0x2c, 0xf6, 0x28, 0x97, 0x9a, 0x14, 0x0e, 0xf5, 0xe2, 0x1b, 0xf6, 0xaf,
|
||||||
0xcf, 0x4e, 0x7c, 0x34, 0xa0, 0x89, 0x89, 0xd9, 0xc4, 0x09, 0x48, 0x58,
|
0x65, 0x56, 0x42, 0xf2, 0x04, 0x7c, 0xfc, 0x31, 0x53, 0xb0, 0x78, 0xf4,
|
||||||
0x67, 0xc1, 0xf1, 0x08, 0xe2, 0x8a, 0x8a, 0x2c, 0xde, 0x73, 0x87, 0x8e,
|
0x77, 0x15, 0xf5, 0x3e, 0x0e, 0x8a, 0x97, 0x14, 0xd4, 0x7a, 0x05, 0xfe,
|
||||||
0x3a, 0x53, 0x28, 0x68, 0x57, 0x9e, 0x6e, 0xca, 0x93, 0x5d, 0x96, 0xce,
|
0x9c, 0x08, 0x4c, 0x5a, 0x0c, 0x00, 0x4a, 0x9c, 0x6e, 0x9c, 0x59, 0xc0,
|
||||||
0x28, 0xc5, 0xe7, 0xf9, 0x34, 0xd8, 0xd6, 0x21, 0x04, 0xf4, 0x69, 0xb0,
|
0x39, 0x53, 0x3b, 0xf9, 0xb0, 0x86, 0x19, 0xb3, 0x59, 0x8c, 0xa5, 0xcf,
|
||||||
0x7a, 0x6b, 0x66, 0xa8, 0x5e, 0xa6, 0x58, 0x9f, 0x2c, 0xeb, 0x64, 0x36,
|
0x47, 0xba, 0xa1, 0xc1, 0xe4, 0x9e, 0x80, 0x2d, 0x87, 0x30, 0x32, 0x1e,
|
||||||
0xd1, 0xe6, 0xb1, 0xe3, 0xbc, 0x34, 0x94, 0x18, 0xb0, 0x97, 0xa0, 0x73,
|
0xa5, 0xbd, 0x84, 0xab, 0xd8, 0xeb, 0xc1, 0x5e, 0xfc, 0x5e, 0x3c, 0x96,
|
||||||
0x5b, 0x9b, 0x63, 0x05, 0xa9, 0x63, 0x98, 0xd4, 0x0e, 0xb8, 0x92, 0xcd,
|
0xda, 0xe8, 0x5c, 0x8b, 0x4d, 0x42, 0x37, 0xf5, 0x46, 0x05, 0xf0, 0x09,
|
||||||
0x68, 0xa8, 0xdf, 0xa8, 0x9b, 0x75, 0x71, 0x02, 0xc4, 0xa0, 0xda, 0x2f,
|
0x1b, 0x94, 0xe6, 0xe5, 0xdf, 0x35, 0xcc, 0x48, 0x14, 0x91, 0x66, 0x5c,
|
||||||
0xf7, 0x67, 0x44, 0x6e, 0xda, 0x68, 0x08, 0x52, 0x11, 0x4c, 0xeb, 0xc4,
|
0xe2, 0xfe, 0x98, 0xff, 0x39, 0xed, 0x32, 0x81, 0x75, 0xe3, 0xaf, 0xd3,
|
||||||
0x86, 0x2e, 0x30, 0x2d, 0x15, 0x23, 0xdb, 0xe6, 0x58, 0xcb, 0x18, 0xcd,
|
0x7f, 0xff, 0x00, 0x24, 0x2d, 0x83, 0xdc, 0x54, 0xda, 0xb7, 0xf5, 0x49,
|
||||||
0x9c, 0x0d, 0x4d, 0xcb, 0x80, 0xe0, 0x26, 0x05, 0x9b, 0x40, 0x51, 0x74,
|
0x84, 0x35, 0x63, 0x48, 0x1a, 0x63, 0xf8, 0xe4, 0x23, 0x91, 0x87, 0x1f,
|
||||||
0xfc, 0xca, 0x7b, 0x89, 0x51, 0x76, 0xc0, 0x5b, 0xbf, 0x84, 0xe6, 0xad,
|
0x1a, 0xdc, 0x34, 0x00, 0xe6, 0x12, 0xdf, 0x1d, 0xfe, 0x94, 0x4d, 0xfc,
|
||||||
0x64, 0xfa, 0xa3, 0x71, 0x06, 0xb6, 0x10, 0x93, 0x29, 0x90, 0x8a, 0x11,
|
0xf8, 0x4b, 0xf6, 0xe7, 0x54, 0x32, 0xf9, 0xdd, 0x97, 0xb9, 0x2c, 0x5a,
|
||||||
0x90, 0x39, 0x4a, 0xa8, 0x97, 0x7f, 0xdf, 0x00, 0x24, 0x71, 0x54, 0x96,
|
0x22, 0x3e, 0x61, 0x91, 0x4a, 0xfe, 0xb8, 0xfd, 0xb3, 0x1f, 0x11, 0x97,
|
||||||
0xf3, 0x08, 0xfd, 0x63, 0xf1, 0xe7, 0xac, 0xc7, 0x20, 0x96, 0x8e, 0xcc,
|
0x13, 0xcc, 0xec, 0x37, 0xc9, 0x9f, 0xb2, 0x04, 0x33, 0x12, 0xcd, 0x11,
|
||||||
0x4e, 0xef, 0x5d, 0x86, 0x26, 0x69, 0x1d, 0xa4, 0xa7, 0x32, 0xbf, 0xb2,
|
0x06, 0x07, 0x46, 0xca, 0x98, 0x20, 0xe3, 0x71, 0x44, 0xf2, 0xe5, 0x63,
|
||||||
0x7b, 0xe2, 0x2c, 0x1c, 0x83, 0xd2, 0x30, 0x2b, 0x20, 0x25, 0x09, 0xbe,
|
0x58, 0x9d, 0x08, 0xc1, 0xe1, 0x84, 0x61, 0x2c, 0x81, 0xbf, 0x65, 0xf6,
|
||||||
0x42, 0xe0, 0xe0, 0xd1, 0x01, 0xb2, 0x90, 0xfa, 0xae, 0xfc, 0x53, 0x3e,
|
0x93, 0x66, 0x8b, 0xe4, 0xcb, 0x3b, 0x62, 0xf6, 0xbd, 0x33, 0x85, 0x5b,
|
||||||
0xf5, 0xe3, 0x2f, 0xf9, 0x9f, 0x33, 0xe9, 0xf4, 0x77, 0x5f, 0x14, 0xf2,
|
0x03, 0x7e, 0x91, 0x5f, 0xc2, 0xd8, 0xc1, 0x4a, 0xd8, 0xc4, 0x0d, 0x80,
|
||||||
0x68, 0x81, 0xc4, 0x94, 0x4d, 0x2b, 0xfd, 0xe3, 0xe6, 0xcf, 0x21, 0x4c,
|
0x10, 0xb5, 0xb3, 0x78, 0x5b, 0x95, 0x4d, 0x12, 0x14, 0xfa, 0xc4, 0x06,
|
||||||
0x5c, 0x41, 0x50, 0xf3, 0x5f, 0xa7, 0x7f, 0xca, 0x13, 0xd4, 0x95, 0x78,
|
0x67, 0x39, 0x0f, 0xc2, 0x9d, 0x8a, 0x26, 0x26, 0x02, 0x79, 0x9a, 0xb0,
|
||||||
0x20, 0x10, 0x8e, 0x0f, 0xb5, 0x11, 0xc1, 0xc6, 0xa3, 0x8b, 0x6c, 0x52,
|
0x51, 0xdc, 0x3a, 0x3f, 0x53, 0x0c, 0x78, 0x1a, 0xf8, 0x1f, 0x90, 0xd6,
|
||||||
0x8c, 0x60, 0x1d, 0x27, 0x45, 0x0c, 0x32, 0x0c, 0x64, 0x4b, 0xfd, 0x2d,
|
0x70, 0xef, 0x98, 0x2b, 0x6d, 0x29, 0xc7, 0x32, 0xbf, 0xfd, 0xe6, 0x32,
|
||||||
0xb7, 0x9b, 0x66, 0x6d, 0x92, 0x2f, 0xff, 0x30, 0xda, 0x0d, 0xcc, 0x2a,
|
0xe2, 0x08, 0x6f, 0xe4, 0x13, 0xce, 0x45, 0x85, 0xd0, 0x48, 0x59, 0x5c,
|
||||||
0x5e, 0x35, 0x84, 0xe4, 0x7e, 0x89, 0x64, 0x09, 0xab, 0x62, 0x25, 0x47,
|
0x78, 0x5a, 0xa6, 0x72, 0x45, 0x63, 0x3a, 0x0f, 0xde, 0xce, 0x59, 0xc7,
|
||||||
0x00, 0x43, 0xf4, 0xcf, 0xe3, 0xcd, 0x70, 0x3e, 0x4d, 0x70, 0xe8, 0x2f,
|
0x4e, 0x6a, 0x3b, 0x69, 0x37, 0x16, 0x73, 0x09, 0xed, 0x9b, 0xe4, 0x07,
|
||||||
0x3e, 0x62, 0x5e, 0xf4, 0x61, 0xdc, 0xe9, 0x68, 0xcc, 0x30, 0xc8, 0xaf,
|
0x10, 0x3d, 0x58, 0x81, 0x53, 0xc4, 0x0a, 0xc6, 0x5a, 0x68, 0x9d, 0x44,
|
||||||
0x31, 0x1f, 0xcb, 0xb2, 0xfb, 0x98, 0xe1, 0xc0, 0x0d, 0xc1, 0xdf, 0x80,
|
0x06, 0x5e, 0xac, 0x09, 0xc2, 0x7a, 0x03, 0x40, 0x12, 0x9a, 0xf4, 0x14,
|
||||||
0xb5, 0x54, 0x04, 0xd7, 0x80, 0x69, 0x63, 0x05, 0x9e, 0xfb, 0xed, 0x37,
|
0x65, 0xdd, 0x4a, 0x47, 0x10, 0x1f, 0x5d, 0x58, 0x16, 0x06, 0x80, 0x81,
|
||||||
0x8f, 0x59, 0xc7, 0xf8, 0xaa, 0xa0, 0x84, 0x1e, 0x32, 0x84, 0x48, 0xc6,
|
0xa8, 0xfa, 0x0f, 0x66, 0xa0, 0xef, 0xce, 0x9a, 0xbc, 0x35, 0x9e, 0xb7,
|
||||||
0x66, 0xc4, 0xdf, 0x38, 0x15, 0x6e, 0x09, 0xae, 0xfb, 0xc3, 0xdf, 0x4f,
|
0x28, 0x47, 0x44, 0x82, 0x78, 0x02, 0xad, 0x2a, 0x0b, 0x19, 0x7f, 0x13,
|
||||||
0xcb, 0x38, 0xca, 0x6c, 0xa6, 0x9d, 0xe6, 0xd6, 0xc9, 0x41, 0x04, 0x82,
|
0xb3, 0x20, 0x4a, 0xd8, 0xd4, 0xd2, 0x96, 0x60, 0xa2, 0x64, 0x48, 0x66,
|
||||||
0x83, 0x3e, 0x44, 0x1e, 0x76, 0xd0, 0x15, 0xb7, 0xc4, 0xb3, 0x17, 0xa4,
|
0x65, 0x2b, 0x99, 0xd5, 0x35, 0xde, 0xec, 0xca, 0x14, 0xfb, 0x9d, 0x55,
|
||||||
0x87, 0xb1, 0x51, 0x1b, 0xcf, 0x40, 0xf8, 0x40, 0xcc, 0x49, 0x02, 0x9b,
|
0x7b, 0x62, 0x68, 0x73, 0xf7, 0x82, 0xed, 0x25, 0x92, 0x85, 0x0b, 0xaa,
|
||||||
0x0b, 0x4d, 0x5b, 0xb6, 0x14, 0x94, 0xe4, 0x47, 0x2f, 0x9a, 0x8d, 0x02,
|
0xc8, 0xf8, 0x1c, 0xb0, 0xb4, 0xcb, 0x58, 0x68, 0x19, 0x2f, 0x61, 0xb3,
|
||||||
0x70, 0x20, 0xb2, 0xf9, 0x03, 0x5b, 0x02, 0x79, 0x13, 0x51, 0xaf, 0x8e,
|
0x66, 0xde, 0x12, 0x6b, 0x0d, 0xef, 0x5a, 0xb9, 0x47, 0x8a, 0xd5, 0x91,
|
||||||
0x23, 0x6d, 0xd2, 0xb4, 0xb9, 0x88, 0x80, 0x09, 0x4f, 0xb9, 0x47, 0xda,
|
0x41, 0x48, 0x92, 0xdc, 0x0c, 0x03, 0xf5, 0x06, 0xe2, 0xc7, 0xe2, 0x6c,
|
||||||
0x5c, 0xc5, 0xdf, 0xc4, 0x48, 0xa8, 0x2a, 0x56, 0x35, 0xb6, 0x21, 0x31,
|
0xc2, 0x80, 0x80, 0x27, 0xec, 0x56, 0x8a, 0x48, 0xb8, 0xc5, 0x32, 0x84,
|
||||||
0x9c, 0x1c, 0x49, 0x56, 0x6d, 0xa4, 0xf3, 0xa6, 0x21, 0xb2, 0x6e, 0xcd,
|
0xd6, 0x09, 0x3b, 0xe3, 0x96, 0xe6, 0x2e, 0xf6, 0x76, 0x3e, 0xff, 0xd5,
|
||||||
0xf0, 0xdf, 0xd9, 0xb5, 0x87, 0x96, 0x31, 0xf3, 0xad, 0x6a, 0x5f, 0x96,
|
0x11, 0x03, 0xcf, 0x66, 0xba, 0x84, 0x16, 0x58, 0xe9, 0x43, 0x6e, 0x6e,
|
||||||
0xb0, 0x71, 0x4e, 0x35, 0xba, 0x06, 0x17, 0x3c, 0xed, 0x3d, 0x1e, 0x5a,
|
0x28, 0x47, 0x76, 0x72, 0x95, 0x26, 0x55, 0x59, 0x26, 0xf7, 0xed, 0xd6,
|
||||||
0xc7, 0x0b, 0xfe, 0x3c, 0xcb, 0x15, 0x63, 0xed, 0xe1, 0xed, 0x43, 0xdf,
|
0x06, 0xe5, 0xe0, 0x81, 0x2d, 0xd5, 0x15, 0x09, 0x56, 0xdd, 0x78, 0x4b,
|
||||||
0xf8, 0xb1, 0xfb, 0x34, 0x0c, 0x4a, 0x32, 0xca, 0x91, 0xb0, 0xfe, 0x25,
|
0x39, 0x81, 0x93, 0xbb, 0x8e, 0x8e, 0x1c, 0x93, 0xc3, 0xbb, 0xbd, 0xeb,
|
||||||
0xca, 0x81, 0x3c, 0x1d, 0x73, 0x20, 0xe6, 0x21, 0xbf, 0x91, 0x21, 0x72,
|
0xcc, 0x6d, 0x2e, 0x79, 0xe7, 0x1b, 0x24, 0x79, 0x8c, 0x04, 0x63, 0x27,
|
||||||
0x6e, 0xf0, 0x1c, 0x21, 0x76, 0xc8, 0x4f, 0x85, 0x05, 0x3b, 0x7b, 0xb0,
|
0xfd, 0x7e, 0x9a, 0x23, 0x1c, 0xac, 0x21, 0x2a, 0x89, 0x5e, 0xa2, 0x98,
|
||||||
0x59, 0x2c, 0x7e, 0xb9, 0xcf, 0xc1, 0x6f, 0x96, 0x76, 0xa2, 0x05, 0x76,
|
0x8a, 0x87, 0x2c, 0xa5, 0x10, 0x20, 0x2c, 0xea, 0x15, 0x9a, 0xd7, 0x5c,
|
||||||
0x9e, 0x56, 0x98, 0x59, 0xda, 0xbe, 0x93, 0xd2, 0xa6, 0xa9, 0x6c, 0x9e,
|
0x33, 0xb4, 0x88, 0x90, 0x59, 0x33, 0xff, 0x19, 0x9c, 0x7a, 0x54, 0x59,
|
||||||
0x2b, 0x7c, 0xbb, 0x91, 0x40, 0x45, 0x60, 0xfa, 0x4a, 0x43, 0x53, 0x20,
|
0x78, 0x0f, 0x63, 0x84, 0x40, 0xd2, 0x37, 0xc3, 0x98, 0x6c, 0x05, 0x7c,
|
||||||
0x4d, 0x81, 0x8f, 0x00, 0xa4, 0x70, 0x5a, 0xdd, 0xd5, 0x94, 0xc7, 0x02,
|
0x38, 0x01, 0xf6, 0x58, 0x04, 0x7b, 0x8c, 0x53, 0xea, 0xdf, 0x56, 0x14,
|
||||||
0xf1, 0xce, 0xfc, 0x32, 0xeb, 0x9b, 0x29, 0x81, 0x99, 0x09, 0x29, 0x3e,
|
0x49, 0xe2, 0x54, 0x1d, 0x1d, 0xe7, 0xc8, 0x23, 0x7b, 0x14, 0x44, 0xdb,
|
||||||
0x93, 0xc1, 0xe8, 0xe9, 0x90, 0x33, 0x17, 0x08, 0x13, 0x4b, 0xc8, 0x2a,
|
0x1c, 0x3b, 0xc1, 0x27, 0x9e, 0x12, 0x02, 0xf9, 0x0d, 0x87, 0x73, 0x1b,
|
||||||
0x72, 0x80, 0x2c, 0xa6, 0xe3, 0x23, 0x4c, 0x49, 0x84, 0x49, 0xcb, 0x66,
|
0x7f, 0xa4, 0x08, 0x2b, 0x17, 0x11, 0xbd, 0xbc, 0xaa, 0x58, 0xfe, 0x24,
|
||||||
0x8d, 0xe6, 0x90, 0x97, 0x0c, 0x37, 0x22, 0x69, 0x9e, 0xe5, 0x9a, 0x23,
|
0xb1, 0xe5, 0x3a, 0x9a, 0xb0, 0x95, 0xb4, 0xe7, 0x47, 0x1c, 0x0e, 0x78,
|
||||||
0xe6, 0x28, 0x5d, 0x95, 0xde, 0xc4, 0x1b, 0xa1, 0x90, 0x0e, 0x4e, 0x45,
|
0xf1, 0x35, 0x34, 0x83, 0xcd, 0x6a, 0x53, 0x51, 0x92, 0x7f, 0x2d, 0x65,
|
||||||
0x8c, 0xb3, 0xb0, 0xa3, 0x27, 0xe0, 0xfe, 0x95, 0xe2, 0x01, 0xde, 0xd5,
|
0x3d, 0x3a, 0xbd, 0x81, 0xd7, 0x60, 0xfa, 0xf4, 0x15, 0xdd, 0x11, 0xd2,
|
||||||
0xf8, 0xb6, 0xa6, 0x29, 0x8a, 0xa0, 0x9b, 0xe8, 0xa0, 0x40, 0x7e, 0xf2,
|
0x21, 0x94, 0x86, 0x0f, 0x8a, 0x16, 0x86, 0x69, 0xbe, 0x47, 0x97, 0x7d,
|
||||||
0xfb, 0x11, 0x78, 0x09, 0xc2, 0x2e, 0xf8, 0x24, 0x53, 0x45, 0x38, 0x2f,
|
0x8e, 0xe2, 0x83, 0x68, 0xf1, 0x34, 0x4f, 0x86, 0x0e, 0xe2, 0xc6, 0x1b,
|
||||||
0xe4, 0x72, 0xef, 0x10, 0x18, 0x6a, 0xd2, 0x93, 0x87, 0x8a, 0x59, 0x7d,
|
0x2d, 0x51, 0xe5, 0x34, 0x28, 0xf8, 0x41, 0x11, 0xc2, 0xf4, 0x8f, 0x29,
|
||||||
0xaa, 0xd9, 0x8e, 0x26, 0xb5, 0xe1, 0x39, 0x56, 0xb2, 0x91, 0x76, 0xe6,
|
0x64, 0x79, 0x2c, 0x08, 0x00, 0xb8, 0x83, 0x2d, 0x66, 0x27, 0x49, 0xc8,
|
||||||
0x52, 0x1c, 0x3f, 0xf8, 0xf1, 0x0d, 0x34, 0x85, 0xf3, 0x04, 0x4c, 0x5b,
|
0xbb, 0x75, 0xea, 0x87, 0xfe, 0xb1, 0xf0, 0x73, 0xd2, 0x47, 0x93, 0x44,
|
||||||
0x4a, 0x68, 0x8d, 0xe6, 0xfc, 0x76, 0x7b, 0x05, 0xaf, 0xee, 0xcc, 0xc9,
|
0xb0, 0x0d, 0x64, 0x10, 0x50, 0x73, 0xc0, 0xff, 0x83, 0xba, 0xdd, 0x9c,
|
||||||
0x3a, 0xdd, 0x12, 0xd1, 0x31, 0x94, 0x48, 0x10, 0x8c, 0x96, 0x46, 0x75,
|
0xd2, 0x63, 0x8e, 0x92, 0xda, 0x12, 0xfe, 0x17, 0xfe, 0xb2, 0x31, 0x82,
|
||||||
0xc0, 0x05, 0x5d, 0x52, 0xda, 0xfa, 0x8f, 0xc4, 0x4b, 0xd8, 0x01, 0x64,
|
0xa7, 0x9c, 0xa3, 0xff, 0x7b, 0xf9, 0x03, 0x7a, 0xd9, 0xe7, 0x74, 0x49,
|
||||||
0x2c, 0x21, 0x61, 0xb4, 0xd2, 0x2c, 0x61, 0xb1, 0x0e, 0x05, 0x3f, 0x68,
|
0xd2, 0xf2, 0x5d, 0x5e, 0x97, 0x52, 0xf0, 0xc0, 0x90, 0xa2, 0x50, 0xb3,
|
||||||
0x52, 0x64, 0x37, 0x60, 0x12, 0x79, 0x11, 0x0b, 0x03, 0x10, 0xde, 0x20,
|
0x21, 0xd9, 0x42, 0xdb, 0x6c, 0x02, 0x38, 0xb1, 0xac, 0xc6, 0x4a, 0xd3,
|
||||||
0x8d, 0xdb, 0x4a, 0x13, 0xfa, 0x5e, 0xd5, 0x06, 0xa1, 0x7f, 0x2c, 0xfd,
|
0xd6, 0xa4, 0x35, 0x3d, 0xef, 0xce, 0xc6, 0xda, 0x02, 0x38, 0xea, 0xa7,
|
||||||
0x9c, 0x0e, 0x12, 0x25, 0x11, 0x70, 0x13, 0x59, 0x04, 0x96, 0x39, 0x81,
|
0xf8, 0xa1, 0x8e, 0x03, 0xa2, 0xd5, 0x0b, 0x9a, 0x04, 0xa6, 0x40, 0x34,
|
||||||
0x7f, 0x56, 0xff, 0xb3, 0xf9, 0x3f, 0xe9, 0xa0, 0xa9, 0x2f, 0xe0, 0x6f,
|
0x58, 0x0d, 0xe9, 0x42, 0x13, 0x30, 0x18, 0x55, 0x1f, 0x33, 0xdb, 0x49,
|
||||||
0xe9, 0x2f, 0x1c, 0x32, 0x78, 0x56, 0xda, 0xff, 0xbf, 0xbb, 0xdf, 0xad,
|
0x0f, 0xb2, 0x15, 0x43, 0x99, 0x18, 0x3e, 0x5a, 0x64, 0xdc, 0x85, 0xc1,
|
||||||
0xbb, 0x83, 0xfe, 0x98, 0xa4, 0x7f, 0xdf, 0xe6, 0x90, 0x29, 0x09, 0x3f,
|
0x3b, 0x81, 0x73, 0x64, 0x5b, 0x49, 0x2f, 0x4d, 0xa7, 0x97, 0xff, 0x2e,
|
||||||
0x10, 0x29, 0x8b, 0xb4, 0x20, 0x92, 0x73, 0x75, 0x2c, 0x28, 0x8c, 0x94,
|
0x73, 0x7b, 0x09, 0x24, 0x53, 0x90, 0x84, 0x13, 0x9e, 0xef, 0xb1, 0x30,
|
||||||
0xcc, 0x80, 0xec, 0xac, 0x77, 0x5d, 0x59, 0x62, 0x03, 0xde, 0xdc, 0xb6,
|
0x93, 0x84, 0x07, 0xc8, 0x2c, 0x0b, 0xb3, 0xb1, 0x2a, 0x44, 0xcc, 0x86,
|
||||||
0x2b, 0x84, 0xdb, 0x0d, 0x94, 0x40, 0xb4, 0x37, 0x81, 0x48, 0xf7, 0x9c,
|
0x3d, 0x7d, 0xfb, 0x91, 0x62, 0xa5, 0xb7, 0xe8, 0x28, 0xa6, 0x84, 0xcc,
|
||||||
0x66, 0xd5, 0x29, 0x14, 0x0d, 0x74, 0xa3, 0x3a, 0x93, 0x41, 0x86, 0xa3,
|
0xdc, 0xf9, 0x3f, 0x41, 0xa3, 0x91, 0xc1, 0x24, 0x11, 0xeb, 0xbf, 0x11,
|
||||||
0xf2, 0x03, 0x6e, 0x33, 0xed, 0xc3, 0xb6, 0x83, 0x2e, 0x86, 0x11, 0x24,
|
0x4a, 0x92, 0x90, 0x0d, 0x67, 0x8b, 0x41, 0x24, 0x53, 0xf7, 0xbe, 0xae,
|
||||||
0x46, 0x46, 0x62, 0x14, 0x82, 0x1b, 0x76, 0xc7, 0x36, 0x96, 0x0e, 0x12,
|
0xa1, 0x48, 0x61, 0x3d, 0x8f, 0xcf, 0x2d, 0xdb, 0xfd, 0x1e, 0xc0, 0x89,
|
||||||
0x75, 0xfb, 0xfb, 0x6f, 0xb3, 0xbd, 0x97, 0x70, 0xc6, 0x06, 0x29, 0x38,
|
0x93, 0xf3, 0x0a, 0x49, 0x42, 0xfe, 0xe3, 0x3c, 0x38, 0xf1, 0x17, 0x54,
|
||||||
0x75, 0xfc, 0x26, 0x6b, 0x63, 0x34, 0xfc, 0x50, 0xac, 0x30, 0xca, 0xde,
|
0x4f, 0x67, 0xf8, 0x30, 0xd9, 0x1b, 0x14, 0x65, 0x2e, 0xcc, 0xde, 0xaf,
|
||||||
0x8e, 0x20, 0xd8, 0xb6, 0x9c, 0x49, 0x3e, 0x84, 0x95, 0x2c, 0x9b, 0x46,
|
0x2b, 0xd7, 0x2a, 0xef, 0x9f, 0xa7, 0x28, 0x9f, 0xb9, 0xe2, 0xf5, 0xeb,
|
||||||
0x47, 0x36, 0x25, 0xc5, 0x76, 0x24, 0xfe, 0x21, 0x8a, 0x5d, 0x12, 0x82,
|
0x7b, 0x27, 0x3b, 0x8b, 0x86, 0x07, 0xca, 0x2a, 0x0c, 0x75, 0x46, 0x66,
|
||||||
0x12, 0xe1, 0xfe, 0x43, 0x01, 0x28, 0x89, 0xf2, 0x70, 0xda, 0x1a, 0xe4,
|
0x9d, 0xa5, 0x6a, 0x3f, 0x5e, 0xdc, 0x49, 0xcf, 0xbd, 0xa2, 0xff, 0x07,
|
||||||
0x62, 0xbd, 0x10, 0xec, 0x25, 0x8a, 0x16, 0x39, 0x71, 0xc1, 0xf2, 0xc3,
|
0x79, 0xa4, 0xff, 0x7d, 0xfc, 0x47, 0x6b, 0x34, 0xdc, 0xc7, 0xeb, 0x53,
|
||||||
0x31, 0x82, 0x30, 0x52, 0xa2, 0x0c, 0x5b, 0x44, 0xfa, 0xf3, 0x9f, 0xe8,
|
0x65, 0x51, 0x71, 0xda, 0x49, 0x20, 0xea, 0xe5, 0xd3, 0xb0, 0xea, 0x26,
|
||||||
0xe2, 0x89, 0x1f, 0xa1, 0xda, 0x3a, 0xc1, 0x47, 0x01, 0x5f, 0xa3, 0x2e,
|
0x1b, 0x82, 0xcf, 0x81, 0x2d, 0x8c, 0x47, 0x0a, 0xfe, 0x8a, 0x6c, 0x15,
|
||||||
0xb6, 0xc0, 0x7b, 0x0f, 0x8d, 0x79, 0xd6, 0x8b, 0xff, 0x48, 0x75, 0x05,
|
0xc1, 0xc4, 0x47, 0x82, 0x60, 0x01, 0x3c, 0x50, 0x20, 0x5f, 0xef, 0xe3,
|
||||||
0xad, 0x17, 0x2f, 0x88, 0xdf, 0x3c, 0x27, 0xda, 0x44, 0xfc, 0x60, 0x76,
|
0xdf, 0xa9, 0xf9, 0x2e, 0xb2, 0xe6, 0xd0, 0xa9, 0xb1, 0x7e, 0x98, 0xcd,
|
||||||
0x69, 0xa4, 0x9f, 0x62, 0x75, 0xb6, 0xca, 0x43, 0x88, 0x89, 0xe7, 0x46,
|
0x39, 0x40, 0xe1, 0x2d, 0xb6, 0xe0, 0x70, 0x44, 0xb0, 0x49, 0xa7, 0xea,
|
||||||
0x6f, 0x9e, 0xe0, 0x9f, 0xe5, 0xac, 0xfe, 0x9f, 0x05, 0xfe, 0x24, 0xc5,
|
0xbb, 0xc8, 0xaa, 0xcd, 0x8d, 0x62, 0x28, 0x7f, 0xab, 0x12, 0x6d, 0x0f,
|
||||||
0xc6, 0xcd, 0x02, 0xe6, 0x44, 0x9b, 0xd7, 0xdc, 0xb6, 0x52, 0x88, 0xce,
|
0x65, 0xc1, 0x4c, 0x00, 0x72, 0x08, 0xd9, 0xd5, 0x48, 0x60, 0x7c, 0xe2,
|
||||||
0x03, 0x59, 0x58, 0xc8, 0x93, 0x4d, 0xd8, 0x8f, 0xe1, 0x3d, 0x95, 0x47,
|
0xc3, 0x05, 0x7b, 0x43, 0x60, 0x83, 0xd2, 0x38, 0x5a, 0xf7, 0x66, 0xfc,
|
||||||
0x0a, 0xbf, 0x4e, 0x52, 0x8c, 0xa0, 0xe2, 0xe3, 0x5c, 0xb0, 0xa2, 0xee,
|
0x3c, 0x16, 0x12, 0x0e, 0x1f, 0xc8, 0x62, 0x6d, 0x91, 0x6c, 0xd2, 0x7a,
|
||||||
0x6b, 0xb0, 0x6d, 0x10, 0x90, 0xc2, 0xad, 0xf9, 0x2e, 0xb6, 0xa6, 0xec,
|
0x68, 0x53, 0x04, 0xfc, 0x05, 0x1c, 0x6d, 0xa9, 0xcb, 0xf5, 0xe0, 0x54,
|
||||||
0xd6, 0xd8, 0x0f, 0xac, 0x3d, 0x17, 0x28, 0xa6, 0xc9, 0x33, 0x38, 0xb0,
|
0x08, 0xf8, 0xdf, 0x06, 0xf6, 0x18, 0xbb, 0x69, 0x49, 0xde, 0x70, 0xc2,
|
||||||
0x12, 0x6e, 0xd3, 0xad, 0xfa, 0x2e, 0xb6, 0x6a, 0x75, 0xab, 0x18, 0x2a,
|
0x21, 0x12, 0x5c, 0xca, 0xd0, 0x79, 0xc8, 0x49, 0x65, 0x6d, 0x46, 0xf0,
|
||||||
0xd4, 0xac, 0x42, 0x1b, 0x44, 0x79, 0x30, 0x18, 0x00, 0x1d, 0x40, 0x4e,
|
0xf4, 0xa0, 0x67, 0xf8, 0x3b, 0x68, 0x01, 0x83, 0x24, 0x89, 0x38, 0xe6,
|
||||||
0x37, 0x1e, 0x1a, 0x1f, 0xc5, 0xf1, 0x00, 0xdf, 0x50, 0xe0, 0xb0, 0x40,
|
0xc4, 0x2d, 0x8f, 0x32, 0x1e, 0xeb, 0xc8, 0xb8, 0xc6, 0x15, 0x7e, 0x68,
|
||||||
0xae, 0xea, 0xfd, 0xc9, 0x45, 0x9f, 0xad, 0xc4, 0x20, 0x84, 0x12, 0x65,
|
0x9a, 0xa6, 0x0b, 0x03, 0x3f, 0x25, 0x35, 0x11, 0x1a, 0x52, 0xe4, 0x99,
|
||||||
0x1b, 0x24, 0x5f, 0xb5, 0x02, 0x9c, 0x89, 0x81, 0xbf, 0x80, 0xa9, 0x0d,
|
0x02, 0x77, 0x0a, 0xe0, 0x20, 0x6c, 0xd0, 0x61, 0x78, 0xb4, 0xe4, 0xd8,
|
||||||
0x7d, 0xb1, 0x02, 0x9e, 0x0a, 0x02, 0x7f, 0xbb, 0xd0, 0x3e, 0xd3, 0x67,
|
0xcb, 0x31, 0x51, 0x3c, 0xce, 0xb0, 0x3b, 0x65, 0xdf, 0x32, 0x09, 0xda,
|
||||||
0x36, 0xe5, 0x0f, 0x3d, 0x5c, 0x2a, 0xee, 0x7a, 0x28, 0x10, 0xf1, 0xba,
|
0x1b, 0x94, 0xeb, 0xa4, 0xbb, 0xf6, 0x06, 0x30, 0x40, 0xf9, 0x9e, 0x22,
|
||||||
0xd9, 0xb2, 0x04, 0x18, 0xbe, 0xae, 0xf4, 0xb9, 0x04, 0x17, 0x2f, 0x6c,
|
0x8c, 0x40, 0x3a, 0xc4, 0xe4, 0x1b, 0x66, 0xf0, 0xbf, 0x72, 0xfe, 0xf4,
|
||||||
0x9b, 0x24, 0xe1, 0xc7, 0x1d, 0x7a, 0x65, 0xd2, 0x46, 0x23, 0x13, 0x59,
|
0x69, 0xdd, 0xf9, 0xbc, 0xbc, 0xc6, 0x37, 0x39, 0xa9, 0xf7, 0x16, 0xe2,
|
||||||
0xd7, 0xb8, 0x22, 0x04, 0x4e, 0xf3, 0x81, 0x51, 0xf0, 0xc7, 0xa4, 0x26,
|
0xe8, 0xd2, 0x2a, 0x4d, 0x36, 0x5a, 0xd2, 0x0c, 0xbe, 0x1b, 0x15, 0x8c,
|
||||||
0x4e, 0x4f, 0x9a, 0x3a, 0xd5, 0xe0, 0x66, 0x09, 0x1c, 0x76, 0x8e, 0xf6,
|
0x44, 0x01, 0xea, 0x35, 0x53, 0x05, 0x80, 0xd3, 0x13, 0x36, 0x89, 0x04,
|
||||||
0x22, 0xae, 0xae, 0x5c, 0xdb, 0x39, 0x20, 0x1d, 0x80, 0x33, 0xfc, 0x6e,
|
0x21, 0xce, 0xd0, 0xbd, 0x8d, 0xe4, 0x77, 0x2c, 0x7b, 0x48, 0x4c, 0x2c,
|
||||||
0xd9, 0xb7, 0x5c, 0x8a, 0xf6, 0x0a, 0x65, 0x3c, 0xed, 0xad, 0xbd, 0x01,
|
0x05, 0x4f, 0x29, 0xb2, 0xc1, 0x04, 0x36, 0xde, 0x52, 0x16, 0x48, 0xab,
|
||||||
0x0c, 0xe8, 0x03, 0x5f, 0x11, 0x46, 0x20, 0xfd, 0xc2, 0x38, 0x87, 0x89,
|
0xc0, 0xd1, 0xfa, 0x84, 0xdf, 0x92, 0xe8, 0x69, 0xcb, 0x35, 0x2d, 0xe3,
|
||||||
0xfe, 0x2f, 0x9d, 0x63, 0x83, 0xaa, 0x77, 0x3f, 0x2f, 0xeb, 0x7a, 0x2c,
|
0xc9, 0xc4, 0xd3, 0x36, 0xc5, 0xc8, 0x62, 0x05, 0x55, 0xe8, 0xd1, 0x52,
|
||||||
0x37, 0xf1, 0x7f, 0x86, 0x04, 0xba, 0x44, 0xcb, 0x92, 0x5d, 0x9f, 0x2c,
|
0x73, 0x0b, 0xc9, 0xd3, 0x4e, 0x80, 0x5b, 0x8f, 0x65, 0x13, 0x12, 0x01,
|
||||||
0x87, 0xef, 0xd3, 0x45, 0x44, 0xb0, 0x00, 0xb6, 0xd6, 0x54, 0x02, 0xf0,
|
0x90, 0x38, 0xd3, 0x93, 0x37, 0x12, 0x36, 0xd5, 0x90, 0xdc, 0x10, 0xae,
|
||||||
0xf4, 0xe8, 0x53, 0x2a, 0x45, 0xc8, 0x73, 0x74, 0x8f, 0x25, 0xfd, 0x1d,
|
0x5a, 0x70, 0xa4, 0xc5, 0x0d, 0x41, 0xa3, 0x0d, 0xbb, 0x2e, 0xac, 0xb3,
|
||||||
0xcf, 0x97, 0x89, 0xbd, 0x65, 0xe0, 0x57, 0x86, 0x6c, 0x79, 0x81, 0xc9,
|
0x80, 0xe2, 0x59, 0x88, 0x2d, 0x9d, 0x69, 0x8e, 0xa0, 0xd8, 0xf9, 0x3a,
|
||||||
0x9f, 0x69, 0x73, 0x64, 0xd4, 0xe0, 0x1e, 0x45, 0x2a, 0x64, 0x55, 0xf4,
|
0x19, 0x51, 0x16, 0xe7, 0xe6, 0x41, 0xb1, 0x55, 0x7a, 0xd2, 0xc9, 0x52,
|
||||||
0x14, 0xed, 0x92, 0xb6, 0xf1, 0x64, 0xe3, 0x6f, 0x9d, 0xa2, 0xe4, 0xb1,
|
0xa6, 0x53, 0xaf, 0xc3, 0xf8, 0x80, 0x2d, 0x5f, 0x95, 0x9b, 0x90, 0x93,
|
||||||
0xa6, 0x6a, 0xf4, 0xe8, 0x30, 0xdb, 0xd3, 0xf2, 0xb5, 0x14, 0x66, 0xd8,
|
0xa4, 0x3e, 0x80, 0xb0, 0x89, 0xd1, 0x64, 0x38, 0x4d, 0x92, 0x46, 0xfe,
|
||||||
0x67, 0xe8, 0x84, 0x46, 0x18, 0x26, 0xd1, 0x04, 0xe6, 0x8f, 0xa1, 0x99,
|
0x69, 0xd6, 0xbf, 0x69, 0x4d, 0xa0, 0xe3, 0x5b, 0x78, 0x59, 0xe3, 0x60,
|
||||||
0x2e, 0xd2, 0x2b, 0xc3, 0x5c, 0x06, 0x48, 0x1b, 0x5d, 0x11, 0x6a, 0x3a,
|
0x8f, 0xd6, 0x63, 0xe3, 0xd6, 0xcd, 0x92, 0xf7, 0xda, 0x39, 0x46, 0x21,
|
||||||
0xc0, 0x4b, 0x43, 0x41, 0x1b, 0x2a, 0xb1, 0xc1, 0x38, 0x42, 0x32, 0x03,
|
0x09, 0xaf, 0xd7, 0x1c, 0x3f, 0x63, 0x28, 0x8a, 0x7d, 0xc0, 0x8c, 0x3c,
|
||||||
0x05, 0x15, 0xcf, 0x96, 0x8a, 0x8a, 0xf2, 0x78, 0x6b, 0x00, 0x54, 0x7c,
|
0xc1, 0x45, 0x46, 0x36, 0x00, 0xf2, 0xfe, 0x21, 0xe4, 0xec, 0x8f, 0xda,
|
||||||
0x44, 0xcf, 0xa2, 0x39, 0x6a, 0x75, 0x01, 0x4c, 0x18, 0x34, 0xb0, 0x37,
|
0xb7, 0x77, 0x3e, 0xc7, 0x74, 0xec, 0x5d, 0x52, 0x96, 0xf9, 0xfa, 0x6b,
|
||||||
0xad, 0x0b, 0x63, 0x72, 0x4a, 0x38, 0x08, 0x11, 0x35, 0x7d, 0x32, 0xb6,
|
0x47, 0x1d, 0x66, 0xb3, 0xd6, 0x33, 0xe6, 0xce, 0xfa, 0xcd, 0xae, 0x1d,
|
||||||
0xb3, 0x24, 0x31, 0x15, 0x9e, 0x90, 0x83, 0x7b, 0xec, 0x04, 0x7e, 0x2d,
|
0x31, 0x04, 0xef, 0xd5, 0x83, 0x97, 0xd4, 0x87, 0x8d, 0x5e, 0xd8, 0x77,
|
||||||
0xb3, 0xaf, 0x1a, 0x02, 0x6c, 0x26, 0xfb, 0x0c, 0xdf, 0xbe, 0x5e, 0xf4,
|
0x07, 0x34, 0x4b, 0x07, 0x7f, 0xfa, 0xe8, 0x26, 0x0d, 0xc5, 0xd8, 0xc9,
|
||||||
0x76, 0xe3, 0xc7, 0x38, 0x24, 0xb7, 0xb6, 0xd6, 0x69, 0x41, 0x8e, 0xe2,
|
0x27, 0xfa, 0xa4, 0xc0, 0xbc, 0xb5, 0x41, 0xf1, 0x97, 0x67, 0x27, 0x49,
|
||||||
0x38, 0xc7, 0x01, 0xc9, 0x2f, 0xb8, 0x15, 0xcb, 0x87, 0x61, 0xde, 0x61,
|
0xcb, 0xaf, 0x19, 0xdc, 0x58, 0xdc, 0x98, 0xbe, 0xeb, 0xf3, 0xf5, 0xc2,
|
||||||
0x64, 0xb9, 0x9b, 0xb8, 0xce, 0x65, 0xae, 0xcf, 0x30, 0x21, 0x67, 0x2b,
|
0xd9, 0xb5, 0x4e, 0x86, 0xf7, 0x6f, 0x48, 0xcf, 0x92, 0xf6, 0x23, 0xdd,
|
||||||
0x97, 0xe7, 0xbe, 0xfa, 0xca, 0xd5, 0x09, 0x6b, 0xd7, 0xfe, 0x8d, 0xf9,
|
0xe5, 0x1a, 0x9e, 0x9d, 0x9d, 0x9b, 0xb8, 0xaa, 0xfb, 0xdb, 0xfd, 0xa2,
|
||||||
0xb3, 0x9f, 0xf9, 0xe5, 0xe3, 0x88, 0x20, 0xae, 0x3f, 0xaa, 0x49, 0x7d,
|
0x25, 0x6b, 0x9a, 0xf0, 0xed, 0xf3, 0x8c, 0x6f, 0x73, 0x8c, 0x70, 0x04,
|
||||||
0xe4, 0xb0, 0xc6, 0x47, 0xc9, 0x0e, 0x1d, 0x3d, 0xfc, 0x15, 0xe3, 0x9e,
|
0xb9, 0x05, 0x2b, 0xb9, 0x04, 0xcd, 0xb0, 0xdb, 0x6b, 0x12, 0x03, 0xcd,
|
||||||
0xb4, 0x95, 0xe4, 0xf4, 0x01, 0x51, 0x2b, 0x85, 0x16, 0xed, 0x7d, 0x92,
|
0xf4, 0xf7, 0x26, 0xa0, 0x28, 0xc9, 0xcd, 0x49, 0x28, 0x09, 0x9c, 0x02,
|
||||||
0xbf, 0x21, 0x23, 0x4a, 0xda, 0x5e, 0x73, 0xd4, 0x63, 0xa9, 0x93, 0xfa,
|
0x69, 0xd1, 0xb2, 0x0d, 0xdf, 0x41, 0x9f, 0x04, 0xd9, 0x9b, 0x04, 0x98,
|
||||||
0xb6, 0xcf, 0x56, 0x88, 0xe8, 0x54, 0xbb, 0xd9, 0xe5, 0xbf, 0x25, 0x33,
|
0xfc, 0x11, 0x7c, 0x1d, 0x03, 0x3c, 0x7c, 0xa7, 0x52, 0xc1, 0x9c, 0x32,
|
||||||
0x4c, 0x38, 0x88, 0x77, 0xa8, 0x2b, 0xf9, 0x26, 0x1b, 0x49, 0x6b, 0xe8,
|
0x21, 0x62, 0xd1, 0xfa, 0x51, 0xfc, 0xf9, 0x28, 0x14, 0xa0, 0x26, 0x05,
|
||||||
0xf0, 0x9f, 0xe0, 0x39, 0x6d, 0x99, 0xb3, 0x84, 0xfb, 0xa0, 0xef, 0x7c,
|
0x56, 0x89, 0xb8, 0xd8, 0x74, 0xc0, 0x27, 0xd6, 0x71, 0x66, 0xbf, 0xb9,
|
||||||
0xbd, 0xeb, 0x84, 0xc3, 0xe5, 0x67, 0xb0, 0x3c, 0x4c, 0xd1, 0x5c, 0xbf,
|
0x9b, 0xb8, 0x40, 0x3e, 0x34, 0x5a, 0x22, 0x24, 0xb0, 0xeb, 0x31, 0x7f,
|
||||||
0xb3, 0xc0, 0xb1, 0xd0, 0xd4, 0x7c, 0x7b, 0xbe, 0x8b, 0x12, 0x4d, 0x90,
|
0xe2, 0xb8, 0x29, 0x9e, 0x49, 0x5a, 0x74, 0x03, 0x73, 0x94, 0x8f, 0x72,
|
||||||
0xf3, 0x52, 0xc0, 0x65, 0x90, 0x46, 0x6d, 0x63, 0x09, 0x9e, 0x5d, 0x4a,
|
0x80, 0xdc, 0xfa, 0x9d, 0x3b, 0x4a, 0x36, 0xc4, 0x44, 0x36, 0x18, 0x84,
|
||||||
0x91, 0xfd, 0x53, 0x00, 0x2a, 0xee, 0xc3, 0xd7, 0x01, 0x20, 0xc0, 0x77,
|
0x3f, 0x75, 0xf7, 0xfc, 0x9a, 0xe3, 0x45, 0x18, 0x83, 0x9c, 0x11, 0x7a,
|
||||||
0x26, 0x13, 0x91, 0xd8, 0x26, 0x64, 0x6c, 0x6a, 0x3f, 0xca, 0x3f, 0xef,
|
0xd3, 0xa1, 0x1c, 0x7d, 0x21, 0x1a, 0x20, 0x36, 0x80, 0x05, 0x7d, 0x0d,
|
||||||
0x47, 0x43, 0xd4, 0x95, 0xf0, 0xea, 0x13, 0x97, 0x33, 0x37, 0x7d, 0x68,
|
0x38, 0x72, 0x38, 0x7c, 0x0d, 0x67, 0xaf, 0x0f, 0x43, 0x6a, 0xc8, 0xa9,
|
||||||
0x1f, 0x54, 0x0f, 0x8d, 0x02, 0x86, 0x0d, 0x2d, 0x44, 0x06, 0x5b, 0x84,
|
0x9d, 0xe8, 0x1a, 0x29, 0xa2, 0xea, 0x4e, 0x8f, 0xac, 0x50, 0xe4, 0x88,
|
||||||
0x06, 0xf6, 0x4d, 0xec, 0x11, 0x87, 0x5d, 0x49, 0xed, 0xd4, 0xa6, 0x1c,
|
0x2a, 0x3e, 0xaa, 0x99, 0x28, 0x78, 0x55, 0x8d, 0xaa, 0xd1, 0xa3, 0x9a,
|
||||||
0x9a, 0xcf, 0x02, 0xb4, 0xc3, 0x04, 0x57, 0xec, 0x2d, 0x52, 0xc2, 0x91,
|
0x5f, 0x06, 0x38, 0x76, 0x06, 0x35, 0xf1, 0xb2, 0x71, 0x8e, 0xd1, 0x5a,
|
||||||
0x36, 0xb3, 0xda, 0x42, 0x82, 0x59, 0xc3, 0x8f, 0x6b, 0x1d, 0x9c, 0xc2,
|
0x08, 0xa6, 0x8b, 0xdb, 0xd8, 0xeb, 0x24, 0xa6, 0xfc, 0x67, 0x76, 0x3b,
|
||||||
0x28, 0xe4, 0xf0, 0xd3, 0x2b, 0x4f, 0x1a, 0x99, 0x73, 0xd9, 0x02, 0x05,
|
0x5c, 0xb5, 0x8d, 0xea, 0x28, 0x35, 0xaa, 0x66, 0x22, 0x8e, 0x23, 0x6a,
|
||||||
0x00, 0x5c, 0x84, 0x3f, 0x02, 0xb7, 0x0f, 0xc7, 0xeb, 0xe1, 0x6c, 0x73,
|
0x44, 0x5e, 0xf9, 0x8b, 0xb4, 0x6b, 0x4c, 0x45, 0xdd, 0x7d, 0x12, 0xda,
|
||||||
0x39, 0xaa, 0x8a, 0x1c, 0x46, 0x5a, 0x52, 0xa5, 0xc4, 0xd5, 0xdd, 0x99,
|
0x35, 0x5d, 0x58, 0x4a, 0xf6, 0x6e, 0x69, 0xf9, 0xf7, 0x87, 0xb6, 0x72,
|
||||||
0xf1, 0x35, 0x9a, 0x1a, 0x57, 0x27, 0xc6, 0x36, 0x15, 0x8b, 0xa1, 0xeb,
|
0x5b, 0x64, 0x2f, 0xca, 0x7f, 0xbe, 0x8b, 0xd2, 0x82, 0x5a, 0xda, 0xb0,
|
||||||
0xb1, 0x55, 0x66, 0x2c, 0x0f, 0x8b, 0x30, 0xe3, 0xee, 0xb0, 0x27, 0x3e,
|
0xff, 0xb0, 0x92, 0x67, 0x42, 0xb5, 0x0a, 0xdd, 0x93, 0x6a, 0x9e, 0x4c,
|
||||||
0x39, 0xe1, 0xb1, 0x62, 0x1b, 0x87, 0x7a, 0x94, 0x04, 0xbe, 0x82, 0x85,
|
0xaa, 0xc1, 0x29, 0xd5, 0x06, 0x4e, 0x93, 0xd8, 0x72, 0xe3, 0xde, 0x32,
|
||||||
0xa9, 0xff, 0x5c, 0x53, 0x80, 0x5b, 0xdb, 0xb1, 0x3d, 0xa7, 0xc7, 0x56,
|
0x65, 0x84, 0x7c, 0x05, 0x8e, 0x88, 0x05, 0x25, 0x01, 0x7a, 0x1f, 0xba,
|
||||||
0x8d, 0xe5, 0x51, 0x5c, 0x95, 0x2c, 0x6a, 0x7f, 0xad, 0xae, 0xad, 0x89,
|
0xf9, 0xfb, 0xf1, 0xb1, 0x45, 0xd4, 0xc6, 0x6f, 0xf0, 0x14, 0x5b, 0xe8,
|
||||||
0x6c, 0x7a, 0x4f, 0x8b, 0x7b, 0x66, 0x1a, 0x47, 0xe5, 0xfe, 0x5d, 0xb8,
|
0xa1, 0x2d, 0x9c, 0xb9, 0xac, 0x8c, 0xcc, 0xae, 0x0d, 0x98, 0x8a, 0xd3,
|
||||||
0xe0, 0x7e, 0xd6, 0x46, 0x61, 0x83, 0x6c, 0x9e, 0x85, 0x0e, 0xb4, 0x51,
|
0xf7, 0xa4, 0xf2, 0x2d, 0x07, 0xfa, 0xa3, 0x8f, 0xf4, 0x07, 0x00, 0x99,
|
||||||
0x6a, 0x50, 0xcd, 0x5a, 0x0f, 0x1e, 0xca, 0xf2, 0x4d, 0xca, 0x76, 0xa1,
|
0x8f, 0x3a, 0xe3, 0x1f, 0xe8, 0xfa, 0x37, 0x99, 0x6c, 0x94, 0xe1, 0x7e,
|
||||||
0x77, 0x62, 0x2e, 0xd2, 0x89, 0x39, 0x3c, 0x2d, 0x3b, 0xd0, 0x59, 0x12,
|
0x8c, 0xf9, 0xc6, 0x35, 0xe2, 0x50, 0x79, 0x3e, 0xcc, 0xa0, 0x3f, 0xc8,
|
||||||
0xb0, 0x26, 0xd8, 0x21, 0xa7, 0xcc, 0x90, 0xaf, 0xd0, 0xa9, 0xb8, 0xb0,
|
0xac, 0xff, 0x2c, 0xe3, 0x8e, 0x65, 0xe2, 0x96, 0xa1, 0xfb, 0x9e, 0x63,
|
||||||
0x38, 0x98, 0xe2, 0xfb, 0x6e, 0x60, 0xff, 0x09, 0x41, 0x4a, 0xfc, 0xe6,
|
0x78, 0xc4, 0xf0, 0x79, 0xc5, 0x49, 0xd0, 0xdb, 0x67, 0x88, 0xff, 0x8c,
|
||||||
0x75, 0xf8, 0xec, 0x5e, 0xcc, 0x19, 0x35, 0x9c, 0x4c, 0xad, 0x0d, 0x59,
|
0x0b, 0x1c, 0x64, 0xe0, 0x39, 0x2d, 0x7c, 0xcc, 0x91, 0x72, 0xf3, 0xe6,
|
||||||
0x3f, 0x87, 0x6d, 0xc7, 0xb5, 0x04, 0x5a, 0xfb, 0xaa, 0x6b, 0x10, 0xf1,
|
0x86, 0x49, 0x75, 0xdd, 0x01, 0xf2, 0x6a, 0xad, 0x55, 0x1b, 0xd4, 0xde,
|
||||||
0x17, 0x21, 0xc2, 0x90, 0xdc, 0xbb, 0x5d, 0x8d, 0x08, 0xdb, 0xc1, 0xeb,
|
0x71, 0x84, 0x3c, 0xa8, 0x38, 0x30, 0x99, 0xca, 0xc8, 0x8e, 0xca, 0xff,
|
||||||
0x8c, 0x38, 0xd6, 0x94, 0xdf, 0xc9, 0xa0, 0x13, 0x9b, 0x75, 0xb4, 0x50,
|
0x4c, 0x97, 0x92, 0xcb, 0xf1, 0x60, 0x0c, 0x1a, 0xc9, 0x18, 0x81, 0xb5,
|
||||||
0xef, 0x67, 0xe2, 0xef, 0x65, 0xe8, 0x7f, 0x9a, 0xb9, 0x27, 0x33, 0x7a,
|
0x6f, 0x74, 0x38, 0x27, 0xd4, 0xe1, 0x44, 0xac, 0x1c, 0xce, 0xfb, 0x9d,
|
||||||
0xc7, 0xf4, 0x03, 0x05, 0xc9, 0x9c, 0x66, 0xdc, 0x3c, 0xe4, 0xee, 0x23,
|
0x1f, 0xb0, 0x69, 0xc3, 0xba, 0x3b, 0xd4, 0xb9, 0xc4, 0xbe, 0x02, 0x14,
|
||||||
0x38, 0xe7, 0xab, 0xff, 0x9c, 0x2b, 0x30, 0x64, 0x3c, 0xba, 0x6d, 0xbc,
|
0x50, 0x89, 0x69, 0xba, 0xde, 0x06, 0xe3, 0x1b, 0x93, 0x1b, 0x2b, 0xbe,
|
||||||
0xd7, 0xd1, 0x7b, 0x76, 0xf7, 0x85, 0xd1, 0x5d, 0x7a, 0xd0, 0xfe, 0xa8,
|
0x61, 0x91, 0x6e, 0x88, 0x81, 0x4b, 0xcc, 0xa0, 0x51, 0xa3, 0xd7, 0x08,
|
||||||
0x7e, 0x56, 0xef, 0xd7, 0xdf, 0x76, 0xd4, 0x3e, 0x42, 0x83, 0x60, 0x44,
|
0x70, 0x2c, 0xfe, 0x1d, 0x5c, 0xde, 0x38, 0x61, 0xc9, 0xb1, 0x54, 0x9a,
|
||||||
0xb5, 0xa1, 0x13, 0xf3, 0xff, 0xc9, 0x0e, 0xa7, 0x50, 0x10, 0xc1, 0x3e,
|
0xc6, 0x8a, 0xb6, 0x09, 0x79, 0x2e, 0xd1, 0x38, 0xdd, 0xe9, 0x11, 0x60,
|
||||||
0x0c, 0x92, 0xbf, 0x82, 0x31, 0xb0, 0xda, 0x1f, 0x1d, 0x52, 0x7f, 0x14,
|
0x42, 0x33, 0xac, 0x1e, 0xf1, 0xaa, 0x25, 0xae, 0xb7, 0xa3, 0x16, 0x42,
|
||||||
0xb3, 0x36, 0x39, 0xed, 0x75, 0x7e, 0xc0, 0x06, 0x0f, 0x4b, 0xfe, 0x48,
|
0x62, 0x90, 0xa3, 0x0d, 0x67, 0xae, 0xc9, 0xcb, 0xc2, 0xec, 0xdb, 0xa3,
|
||||||
0xd7, 0xb3, 0xd6, 0xad, 0xaa, 0xb0, 0x6e, 0x98, 0x4d, 0xfb, 0x5b, 0x5d,
|
0xd4, 0xe2, 0xd3, 0xe4, 0x45, 0x63, 0x69, 0xc0, 0x87, 0x42, 0xf8, 0x5a,
|
||||||
0xc3, 0xbc, 0xbc, 0x68, 0x6b, 0x98, 0x1a, 0xe9, 0x91, 0x24, 0xc8, 0xc4,
|
0xa9, 0x74, 0xe0, 0x06, 0xcd, 0xb4, 0x05, 0x70, 0x75, 0xb8, 0x83, 0x5d,
|
||||||
0x2c, 0x9a, 0x75, 0x7a, 0xfd, 0x02, 0x47, 0xfa, 0xdf, 0xc1, 0xf5, 0x97,
|
0xa7, 0xe3, 0xc4, 0x3f, 0xd0, 0x9d, 0x61, 0x48, 0x28, 0x92, 0x7b, 0x92,
|
||||||
0x43, 0x9e, 0x1c, 0xd4, 0xa5, 0x79, 0xb5, 0x25, 0x36, 0xa2, 0xce, 0x14,
|
0x12, 0x27, 0xca, 0xec, 0x87, 0xdc, 0x5b, 0xf8, 0xc0, 0x28, 0x93, 0x2c,
|
||||||
0xb6, 0x0c, 0x70, 0x3b, 0x07, 0xf8, 0x30, 0x2c, 0xbb, 0x73, 0x42, 0xea,
|
0x2e, 0xfc, 0x3c, 0x32, 0x23, 0xd0, 0xd0, 0xfd, 0x51, 0xd4, 0xca, 0xc2,
|
||||||
0x49, 0xec, 0x13, 0xa9, 0xc9, 0x90, 0x00, 0x66, 0x7f, 0xf5, 0xd9, 0x74,
|
0x46, 0xa0, 0xeb, 0x8c, 0xf5, 0xf0, 0x77, 0xba, 0x0b, 0xfc, 0x8e, 0x7b,
|
||||||
0xf2, 0x52, 0x3c, 0xe7, 0x1a, 0x32, 0x1d, 0x0b, 0x59, 0xf2, 0x4a, 0xbd,
|
0xe4, 0xe8, 0xc5, 0xde, 0xf5, 0x48, 0xbc, 0x0b, 0x87, 0xff, 0x15, 0x56,
|
||||||
0x2c, 0x90, 0x80, 0x42, 0xf8, 0x7a, 0xd2, 0xd9, 0xb0, 0x0e, 0x1b, 0xef,
|
0x13, 0xeb, 0xc1, 0x01, 0xe0, 0x95, 0x08, 0x91, 0xab, 0x10, 0x3d, 0xba,
|
||||||
0x19, 0x00, 0x36, 0xe0, 0xda, 0x7f, 0x83, 0x0e, 0xa1, 0x90, 0x1f, 0x70,
|
0x4a, 0x9d, 0xaa, 0x6f, 0x59, 0x6d, 0x29, 0xf2, 0xab, 0x16, 0x3c, 0x54,
|
||||||
0xc7, 0x28, 0xa1, 0x49, 0x2e, 0xda, 0x2a, 0x82, 0xac, 0xf2, 0xef, 0x74,
|
0x0a, 0xdc, 0xb1, 0x71, 0x7c, 0x86, 0x65, 0xf1, 0x04, 0xcd, 0xe7, 0x5d,
|
||||||
0xeb, 0xe3, 0x5d, 0xa3, 0x56, 0xb2, 0x80, 0x09, 0xf2, 0xc9, 0x0d, 0x41,
|
0x83, 0xd6, 0x42, 0x2f, 0x82, 0x7a, 0x73, 0x9f, 0x49, 0xb3, 0x14, 0x06,
|
||||||
0x4f, 0xf7, 0xfb, 0xb1, 0x8b, 0x17, 0x07, 0x83, 0x2e, 0x65, 0x56, 0x20,
|
0x12, 0xb9, 0x1d, 0x96, 0xb5, 0xae, 0x82, 0x04, 0xf1, 0x49, 0x23, 0x01,
|
||||||
0xdc, 0x99, 0x1e, 0xf8, 0x3b, 0xe1, 0x51, 0xa0, 0x57, 0xc5, 0x57, 0x60,
|
0xfc, 0xe7, 0xcf, 0xfc, 0xcc, 0x47, 0x8e, 0x8f, 0xe4, 0x46, 0x0e, 0xc9,
|
||||||
0x89, 0x1e, 0x24, 0xf1, 0x57, 0x58, 0xad, 0xac, 0x80, 0x07, 0x88, 0x75,
|
0xc0, 0x0b, 0x34, 0x41, 0x8a, 0xed, 0x8b, 0xc8, 0x33, 0x18, 0xbc, 0x51,
|
||||||
0x31, 0xe2, 0x97, 0x39, 0xe6, 0x92, 0x3a, 0x7d, 0xa2, 0xbf, 0x6e, 0x5d,
|
0x1c, 0xe2, 0xaf, 0xb5, 0x1c, 0xba, 0x6f, 0x34, 0x43, 0xea, 0xd8, 0x56,
|
||||||
0xa7, 0xa9, 0x6b, 0xae, 0xaa, 0xa8, 0x30, 0xb8, 0x97, 0x13, 0x7a, 0x15,
|
0x9b, 0x43, 0xc9, 0x14, 0xd2, 0x36, 0xa4, 0xa4, 0x17, 0x87, 0x0e, 0x91,
|
||||||
0x7b, 0x20, 0x10, 0xcc, 0xb0, 0x27, 0x0e, 0x1b, 0x10, 0xbd, 0x55, 0xec,
|
0x80, 0x20, 0xce, 0x88, 0x76, 0xfc, 0x31, 0x76, 0x71, 0x47, 0xee, 0x3a,
|
||||||
0x4f, 0xd1, 0xa6, 0x59, 0x29, 0x8c, 0x31, 0x72, 0x07, 0x2f, 0x4f, 0x6e,
|
0x73, 0xcf, 0x03, 0xaa, 0xe0, 0x8d, 0x0f, 0x59, 0xfc, 0x60, 0xdf, 0x92,
|
||||||
0xd5, 0xc4, 0x50, 0x20, 0x2d, 0x05, 0x29, 0xf8, 0x6c, 0x8d, 0x41, 0xc4,
|
0xf0, 0xc8, 0x93, 0xcb, 0xa9, 0x70, 0x61, 0xec, 0x5f, 0x7e, 0x51, 0xd6,
|
||||||
0x0e, 0x9c, 0x74, 0x12, 0x3e, 0xc9, 0xa8, 0x0c, 0x35, 0x43, 0x8a, 0x9d,
|
0x35, 0xb1, 0x45, 0x4b, 0x62, 0xbb, 0xb8, 0x34, 0x83, 0xef, 0xb2, 0x11,
|
||||||
0x5b, 0xee, 0x53, 0x18, 0xd9, 0xf1, 0x7c, 0xe2, 0xaf, 0xe5, 0x7c, 0x7a,
|
0x97, 0xfb, 0xa7, 0xc4, 0x4a, 0x7f, 0xc1, 0x2d, 0x3c, 0x8c, 0x51, 0x96,
|
||||||
0x6f, 0xcc, 0x43, 0xae, 0xdb, 0x55, 0xa1, 0x4b, 0x8b, 0x09, 0xeb, 0xd8,
|
0x94, 0x51, 0xe2, 0x47, 0x5c, 0x00, 0xd7, 0xf0, 0x9e, 0x89, 0x34, 0x87,
|
||||||
0x57, 0xda, 0x8f, 0x64, 0x8f, 0xf2, 0xb0, 0x3c, 0xee, 0x90, 0x77, 0xdd,
|
0xd4, 0x7e, 0x5e, 0x92, 0xb1, 0x82, 0xaa, 0x0f, 0xb9, 0x95, 0x97, 0xcb,
|
||||||
0x37, 0x76, 0x87, 0xfb, 0xbe, 0x4a, 0xb6, 0x75, 0x03, 0x75, 0xf0, 0x2a,
|
0xc1, 0x08, 0x8c, 0x0a, 0x25, 0x3e, 0xc8, 0x7a, 0x36, 0xdf, 0x42, 0x8a,
|
||||||
0x92, 0x3c, 0xfe, 0xe1, 0x5c, 0x37, 0x09, 0xc8, 0x55, 0x28, 0xe8, 0x70,
|
0x71, 0x17, 0xe6, 0x4d, 0x37, 0x6a, 0xac, 0x7b, 0x32, 0xf1, 0x02, 0x36,
|
||||||
0x37, 0xef, 0x3f, 0x70, 0x71, 0xd9, 0x3b, 0x25, 0x2e, 0x11, 0xc7, 0x71,
|
0x4a, 0x07, 0x94, 0x46, 0xdf, 0x46, 0x90, 0xd8, 0x68, 0xb7, 0xf4, 0x7c,
|
||||||
0x86, 0x59, 0x0e, 0x5f, 0x1d, 0x24, 0xfe, 0xf9, 0x4f, 0x0a, 0xbb, 0xfe,
|
0x40, 0x00, 0x8f, 0xf5, 0x2d, 0xaa, 0x2c, 0x00, 0x12, 0x46, 0xf6, 0x61,
|
||||||
0x92, 0x8b, 0x8f, 0x18, 0xa5, 0xaa, 0x68, 0xc3, 0xd4, 0x8f, 0xb8, 0x00,
|
0x18, 0xd3, 0x90, 0xf4, 0x75, 0x43, 0x80, 0x84, 0x32, 0x53, 0x74, 0xa9,
|
||||||
0x6e, 0x3e, 0x7e, 0x24, 0x12, 0x95, 0xa9, 0x3d, 0xbd, 0xa4, 0x93, 0xc5,
|
0xd1, 0x23, 0xbd, 0x6f, 0xb1, 0xfa, 0x18, 0x76, 0x1f, 0xe8, 0x73, 0x8c,
|
||||||
0x67, 0xef, 0x75, 0x11, 0xb2, 0x50, 0x80, 0xc1, 0x19, 0x1b, 0x8c, 0xbc,
|
0xbf, 0x3e, 0x9c, 0xa3, 0x4c, 0xb9, 0x62, 0xb8, 0x78, 0x51, 0x1c, 0x71,
|
||||||
0x9b, 0x2d, 0xad, 0xbe, 0xe4, 0x95, 0xe4, 0x82, 0xd1, 0xab, 0xee, 0x29,
|
0x86, 0x7e, 0x5f, 0xfa, 0xf9, 0x89, 0x1d, 0x59, 0x58, 0xdd, 0x81, 0x7b,
|
||||||
0x39, 0x97, 0x8f, 0x92, 0xc5, 0x7e, 0x94, 0x10, 0xe8, 0x8e, 0xbe, 0x05,
|
0xbb, 0x0f, 0xfc, 0x10, 0x8d, 0x61, 0x1d, 0xb7, 0x15, 0x01, 0x54, 0x0c,
|
||||||
0x23, 0xb5, 0xda, 0x8e, 0xe9, 0x79, 0x88, 0x10, 0x22, 0x1f, 0x5c, 0xb9,
|
0x5e, 0x31, 0x37, 0x83, 0x5f, 0xa6, 0x63, 0x76, 0x08, 0xbb, 0x7a, 0x63,
|
||||||
0xd9, 0x10, 0x24, 0x28, 0xed, 0xc1, 0xe8, 0xa6, 0x21, 0xee, 0xda, 0x83,
|
0x00, 0x53, 0x81, 0x09, 0x8a, 0x67, 0x05, 0x0c, 0x4b, 0xbe, 0x83, 0xc0,
|
||||||
0x82, 0x44, 0x43, 0x13, 0x74, 0x69, 0xb0, 0x33, 0xd0, 0xaf, 0x1a, 0x07,
|
0x5f, 0x12, 0x43, 0xe9, 0x93, 0x03, 0x2f, 0x22, 0x99, 0x97, 0xce, 0xe8,
|
||||||
0x09, 0x46, 0x42, 0xa8, 0xfb, 0x09, 0x81, 0xe5, 0x91, 0x21, 0xe5, 0xcb,
|
0x4b, 0x7a, 0x56, 0x36, 0x68, 0x14, 0x3b, 0x97, 0x3a, 0xea, 0x2b, 0x63,
|
||||||
0x1b, 0x0e, 0x26, 0x0c, 0x08, 0x99, 0xbb, 0x0c, 0x3a, 0xdc, 0xcf, 0x0e,
|
0x63, 0x00, 0xef, 0x50, 0x49, 0x10, 0x15, 0x6c, 0xc4, 0x00, 0xd0, 0x3e,
|
||||||
0x9d, 0xc8, 0xc4, 0xee, 0x1a, 0xdc, 0xf5, 0x3d, 0x60, 0x8a, 0xe8, 0x0e,
|
0x24, 0xbf, 0x13, 0x85, 0x50, 0xa6, 0x4f, 0xe1, 0x90, 0x84, 0x04, 0xff,
|
||||||
0xab, 0xbb, 0xad, 0x49, 0xa0, 0x6d, 0x70, 0x9b, 0x85, 0x29, 0x3c, 0x31,
|
0x8c, 0x12, 0x8f, 0xdf, 0x3b, 0xda, 0x82, 0x79, 0xc9, 0xa2, 0x1b, 0x04,
|
||||||
0xf7, 0xed, 0xa5, 0xed, 0xf6, 0x4c, 0x1f, 0x26, 0x0d, 0x06, 0x8b, 0xe7,
|
0xee, 0xc3, 0x16, 0xc8, 0x05, 0x2c, 0xc1, 0x8d, 0x36, 0xb9, 0xad, 0x95,
|
||||||
0x0f, 0x0c, 0x4c, 0xbe, 0x23, 0xa0, 0xbf, 0x20, 0x76, 0xd3, 0x23, 0x67,
|
0xb0, 0x76, 0x3d, 0xfc, 0x86, 0xa7, 0xcc, 0x66, 0x70, 0x95, 0x41, 0xcf,
|
||||||
0x7e, 0x64, 0x32, 0x8b, 0x9d, 0xd0, 0x77, 0x4c, 0x3d, 0xb9, 0xb0, 0x71,
|
0xc2, 0x92, 0xa4, 0x42, 0x7f, 0x27, 0xbc, 0x46, 0x84, 0x5d, 0xcd, 0x21,
|
||||||
0x1c, 0x5d, 0x9a, 0xa8, 0xa7, 0x8d, 0xac, 0x3e, 0xbc, 0xe1, 0x27, 0x45,
|
0xb3, 0xa5, 0x73, 0x8f, 0xc8, 0x04, 0xd8, 0x4a, 0x7b, 0x00, 0x46, 0x30,
|
||||||
0x34, 0xb1, 0x1a, 0x05, 0x60, 0x7b, 0x90, 0xb1, 0x4f, 0x95, 0xa2, 0x19,
|
0xe3, 0x37, 0x11, 0xbc, 0x5e, 0xeb, 0x79, 0x21, 0xca, 0x00, 0x59, 0x31,
|
||||||
0x3f, 0x86, 0xf3, 0x21, 0x0a, 0xfc, 0x6f, 0x55, 0x44, 0xfc, 0x52, 0xde,
|
0x34, 0x29, 0xd3, 0xdf, 0x4a, 0xe3, 0xf7, 0x4c, 0xf1, 0xf0, 0x6c, 0x62,
|
||||||
0x33, 0x98, 0xc3, 0x1c, 0xca, 0x61, 0xe8, 0x1e, 0x6c, 0xe3, 0x9c, 0xc3,
|
0x41, 0xd1, 0x8b, 0x17, 0x11, 0x47, 0xa7, 0x87, 0xce, 0x3a, 0xcc, 0xbc,
|
||||||
0xb2, 0xdf, 0x6a, 0x93, 0x4b, 0x71, 0x29, 0x67, 0xe7, 0x26, 0x68, 0x89,
|
0xb0, 0xe8, 0x4f, 0x2e, 0x78, 0xbd, 0x7c, 0xda, 0x56, 0x9d, 0x35, 0xa4,
|
||||||
0xda, 0x74, 0x0a, 0xf7, 0x42, 0xcc, 0x3c, 0x2c, 0x78, 0x6a, 0xf4, 0x39,
|
0x60, 0xf7, 0x96, 0x25, 0x1e, 0xdf, 0x6f, 0x62, 0xbe, 0xd6, 0xb0, 0x59,
|
||||||
0x15, 0x30, 0x29, 0xec, 0x87, 0xca, 0xdc, 0x06, 0x7e, 0x25, 0x07, 0x83,
|
0x77, 0x64, 0xfc, 0x4a, 0x5a, 0xa2, 0x0a, 0xc7, 0xda, 0xde, 0xa1, 0x14,
|
||||||
0xd8, 0xc8, 0xfa, 0x21, 0x86, 0x10, 0x29, 0xb4, 0x10, 0xbc, 0x3e, 0xee,
|
0x08, 0x0f, 0x94, 0x57, 0x28, 0xe5, 0x36, 0xa8, 0x94, 0xdb, 0x37, 0x2a,
|
||||||
0xe3, 0x5c, 0x56, 0x01, 0x94, 0xbe, 0xa6, 0x63, 0x23, 0x8b, 0x5f, 0x9d,
|
0x25, 0xc4, 0x80, 0xf0, 0xc3, 0x25, 0x30, 0xd4, 0xe6, 0x64, 0x48, 0x47,
|
||||||
0x26, 0xc2, 0x6f, 0x86, 0x06, 0x45, 0x2f, 0x01, 0x4c, 0x1c, 0xea, 0x96,
|
0x6b, 0x50, 0x80, 0xd9, 0x23, 0x1d, 0xff, 0x37, 0xa8, 0x46, 0x43, 0xaf,
|
||||||
0xdd, 0xb5, 0x1e, 0xbb, 0x28, 0x1a, 0xca, 0x6a, 0xf8, 0x67, 0x82, 0xac,
|
0x52, 0x4d, 0x7f, 0x2a, 0x8e, 0x8d, 0x10, 0x05, 0xd1, 0x8a, 0x3f, 0x57,
|
||||||
0xa3, 0x41, 0x7b, 0xa0, 0xc1, 0xfe, 0x34, 0x4f, 0x66, 0x85, 0x90, 0xc5,
|
0x4d, 0x1a, 0xfa, 0x38, 0x35, 0x99, 0x9e, 0xd2, 0x0a, 0x54, 0xc3, 0x8f,
|
||||||
0x05, 0x1b, 0xc4, 0x86, 0xde, 0x51, 0xf1, 0x2b, 0x9c, 0x89, 0x46, 0x3c,
|
0xa9, 0xb8, 0x92, 0xd9, 0xa1, 0x2b, 0x3e, 0x2b, 0x98, 0xb6, 0xea, 0x8e,
|
||||||
0xd6, 0xf7, 0x26, 0xe5, 0xe0, 0xd7, 0x93, 0xac, 0xa3, 0x9c, 0xdb, 0xb0,
|
0xde, 0x14, 0x1c, 0xc7, 0x0e, 0x53, 0x3f, 0xc2, 0xb5, 0x46, 0x4a, 0xfe,
|
||||||
0x72, 0x6e, 0x5f, 0xad, 0x9c, 0x08, 0x7b, 0xc2, 0x3f, 0x2e, 0x81, 0xa7,
|
0xe2, 0x5b, 0x55, 0x9b, 0x0d, 0x38, 0xeb, 0x6a, 0xdf, 0x84, 0xa6, 0xc8,
|
||||||
0xb6, 0xa0, 0x42, 0xd6, 0xdc, 0x80, 0x02, 0xcc, 0x21, 0xb1, 0x82, 0xbf,
|
0x65, 0x38, 0xa8, 0xd5, 0xc2, 0x07, 0x7d, 0xbd, 0x77, 0x97, 0xf1, 0x3f,
|
||||||
0x4b, 0x45, 0x06, 0x5a, 0x4f, 0x45, 0xf4, 0x35, 0x2f, 0x61, 0x45, 0xd1,
|
0x1d, 0xa4, 0x79, 0x7e, 0xf1, 0xbf, 0xb3, 0x48, 0x33, 0x70, 0x39, 0x18,
|
||||||
0x8a, 0x3f, 0x5b, 0x5d, 0x06, 0x7a, 0x5f, 0x75, 0x31, 0x6f, 0xea, 0xc4,
|
0x13, 0x1c, 0x29, 0x06, 0x15, 0xf3, 0x64, 0x4b, 0x38, 0x3b, 0xd5, 0x10,
|
||||||
0xbc, 0xd1, 0xc7, 0x75, 0x3c, 0x29, 0xf7, 0xe8, 0x65, 0xa5, 0x1d, 0x9c,
|
0xce, 0xf2, 0xa9, 0x12, 0x30, 0x9d, 0xc8, 0xfd, 0xf8, 0xdd, 0xd7, 0x3f,
|
||||||
0xdb, 0x95, 0xfb, 0xaf, 0x0c, 0xb5, 0x93, 0xc7, 0xbb, 0xef, 0xe2, 0x7e,
|
0xa7, 0x60, 0x69, 0x7c, 0x02, 0x5f, 0xc9, 0x13, 0xf8, 0xf1, 0xf5, 0xcf,
|
||||||
0xe3, 0xe5, 0x7f, 0x09, 0xae, 0xe2, 0x59, 0x1b, 0xee, 0x3a, 0x3e, 0xb4,
|
0xdf, 0x24, 0x73, 0x13, 0x31, 0xed, 0xf4, 0xc4, 0x2c, 0x0d, 0x6f, 0x55,
|
||||||
0x8a, 0xd7, 0xd4, 0x2a, 0x1c, 0x63, 0x3b, 0xc3, 0x67, 0xa4, 0x03, 0x57,
|
0x4b, 0xd3, 0x17, 0x1e, 0x30, 0xcf, 0xa4, 0xb9, 0x1f, 0xa1, 0xe4, 0x67,
|
||||||
0xca, 0xf1, 0xff, 0x26, 0x08, 0xf5, 0xf1, 0x25, 0xfc, 0x8e, 0x22, 0x0b,
|
0xa0, 0x4d, 0x0a, 0x8f, 0xcc, 0x8e, 0x0e, 0x06, 0xe2, 0x9e, 0x5c, 0x80,
|
||||||
0x57, 0x80, 0x79, 0xc1, 0x81, 0x6c, 0xd0, 0xb6, 0x48, 0x36, 0xbf, 0xf3,
|
0x1d, 0x74, 0xa4, 0x09, 0x09, 0xf2, 0xc2, 0x01, 0xf3, 0x27, 0xd6, 0x99,
|
||||||
0x13, 0x03, 0xe1, 0xe4, 0xa3, 0xae, 0x00, 0xef, 0xa9, 0xc2, 0x8f, 0xdf,
|
0xf9, 0x93, 0xce, 0x36, 0xc1, 0x2b, 0xd6, 0x9e, 0xbd, 0xcc, 0x04, 0x8b,
|
||||||
0x7d, 0xf5, 0x73, 0x06, 0x16, 0xe2, 0x87, 0xf0, 0x95, 0x3e, 0x84, 0x87,
|
0x8b, 0x58, 0xcb, 0xe7, 0x39, 0xe0, 0x61, 0x2f, 0xb0, 0x62, 0xe7, 0xe6,
|
||||||
0xaf, 0x7e, 0xfe, 0x3a, 0x5d, 0x18, 0xcb, 0x59, 0xb7, 0x53, 0xa6, 0x59,
|
0x2f, 0x80, 0xc7, 0x68, 0x01, 0x2c, 0x53, 0x6f, 0xc7, 0x39, 0xba, 0x76,
|
||||||
0x78, 0x75, 0x60, 0x96, 0xbe, 0xa3, 0x82, 0xfb, 0x48, 0xda, 0xfb, 0x11,
|
0xf6, 0xbc, 0x21, 0x8b, 0x5e, 0x05, 0xc6, 0x5d, 0xa8, 0x1f, 0x42, 0x52,
|
||||||
0x4a, 0x7e, 0x06, 0xda, 0xa4, 0x70, 0xdf, 0xee, 0xf5, 0x70, 0x54, 0xef,
|
0x4b, 0x90, 0xef, 0x74, 0x88, 0x49, 0x94, 0xb9, 0x30, 0x96, 0x20, 0x7f,
|
||||||
0xcb, 0x3e, 0x38, 0xd1, 0x4a, 0x96, 0xd0, 0x20, 0xaf, 0x87, 0x60, 0x8f,
|
0x83, 0x47, 0x7d, 0x8e, 0xbb, 0xe3, 0x96, 0x90, 0x9e, 0x19, 0xe9, 0x39,
|
||||||
0x58, 0x77, 0xec, 0x91, 0x4d, 0x4c, 0xe1, 0xbb, 0xef, 0xbe, 0x7d, 0xda,
|
0x6c, 0x05, 0xdb, 0xd9, 0xed, 0xec, 0x01, 0xfe, 0x95, 0x85, 0xa5, 0xb9,
|
||||||
0x14, 0x8f, 0x8b, 0x78, 0xdb, 0x2b, 0x7a, 0xe0, 0xa3, 0xde, 0xbe, 0xc6,
|
0xfb, 0xc5, 0xe8, 0xae, 0xc5, 0x39, 0xec, 0xb9, 0xe3, 0x64, 0x96, 0x71,
|
||||||
0xcf, 0xd8, 0x13, 0x20, 0x60, 0xbc, 0x30, 0x9a, 0xad, 0xbc, 0x83, 0x02,
|
0xc2, 0xce, 0x8d, 0x71, 0x66, 0x9f, 0xfd, 0xd6, 0x69, 0x1a, 0xb3, 0x61,
|
||||||
0x5d, 0xa9, 0xfb, 0x5f, 0xf1, 0x46, 0x2f, 0x67, 0xe3, 0xee, 0x34, 0xcb,
|
0xbd, 0x7f, 0xfd, 0x18, 0x9f, 0xcc, 0x63, 0x14, 0x7a, 0xbb, 0x9a, 0x75,
|
||||||
0x90, 0x5d, 0x93, 0xd4, 0x3b, 0x13, 0xc2, 0x19, 0x6d, 0x26, 0x8d, 0x14,
|
0xf7, 0xff, 0x11, 0x6b, 0x32, 0x09, 0x47, 0xf5, 0x18, 0x11, 0x2a, 0x2d,
|
||||||
0x48, 0x20, 0x61, 0x7f, 0x50, 0x10, 0xee, 0x84, 0x05, 0xa4, 0x87, 0x86,
|
0x11, 0x31, 0x29, 0x28, 0xf3, 0xd5, 0x62, 0xa9, 0x43, 0x6b, 0xcc, 0x1e,
|
||||||
0x66, 0x01, 0x9b, 0xc4, 0x66, 0x7e, 0x33, 0xbf, 0x87, 0x9f, 0xf2, 0x90,
|
0x09, 0xad, 0xb3, 0x22, 0x4d, 0xfb, 0xfa, 0xb3, 0x75, 0xa1, 0x99, 0xbc,
|
||||||
0x09, 0xf0, 0xfe, 0xb3, 0x03, 0x9e, 0x5c, 0x00, 0x1c, 0x31, 0xc0, 0x49,
|
0x28, 0xd8, 0x8b, 0x22, 0x92, 0x9b, 0xe1, 0x18, 0xcb, 0x7b, 0x57, 0xdc,
|
||||||
0x35, 0xeb, 0x90, 0x9f, 0x59, 0xa3, 0xdc, 0x2e, 0xff, 0xad, 0xa7, 0x6d,
|
0x44, 0xdd, 0xf2, 0xa0, 0x6e, 0x01, 0x2a, 0x45, 0xa0, 0xe2, 0x62, 0x29,
|
||||||
0xcc, 0x88, 0xf3, 0x0f, 0x1c, 0x1c, 0xe0, 0x13, 0x8c, 0x9c, 0x46, 0xef,
|
0xe1, 0x45, 0xf4, 0x39, 0xfa, 0x42, 0xfa, 0x3f, 0x00, 0x33, 0xfc, 0x14,
|
||||||
0xbd, 0xf3, 0x5e, 0x4b, 0xd8, 0xe7, 0x6d, 0x3e, 0xe1, 0x4c, 0x23, 0x27,
|
0xf6, 0xa1, 0x5e, 0x00, 0x00
|
||||||
0x43, 0xad, 0x2d, 0x28, 0xa6, 0x06, 0x65, 0xc1, 0x6a, 0x2c, 0x7c, 0x74,
|
|
||||||
0x15, 0xeb, 0x9b, 0xe8, 0x4a, 0x3b, 0x5c, 0x75, 0xae, 0xa5, 0xdb, 0x17,
|
|
||||||
0xcd, 0xc9, 0xbb, 0xb4, 0x03, 0x38, 0x32, 0xb9, 0xb8, 0x8f, 0xd1, 0xfc,
|
|
||||||
0x57, 0xf9, 0x19, 0xee, 0x86, 0x0f, 0x77, 0x03, 0x70, 0x29, 0x02, 0x93,
|
|
||||||
0x1a, 0xcb, 0x0a, 0x8f, 0x07, 0x05, 0xf6, 0x6f, 0x3f, 0xfc, 0x01, 0x35,
|
|
||||||
0x65, 0x9f, 0x7f, 0x0d, 0x62, 0x00, 0x00
|
|
||||||
};
|
};
|
||||||
|
|||||||
+1666
-1740
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,260 +0,0 @@
|
|||||||
#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
|
|
||||||
|
|
||||||
#if defined(ARDUINOJSON_VERSION)
|
|
||||||
#if !(ARDUINOJSON_VERSION_MAJOR == 6 and ARDUINOJSON_VERSION_MINOR >= 8)
|
|
||||||
#error "Install ArduinoJson v6.8.x or higher"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char * listStateJSONfull() {
|
|
||||||
const size_t bufferSize = JSON_ARRAY_SIZE(12) + JSON_OBJECT_SIZE(19) + 250;
|
|
||||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
|
||||||
JsonObject root = jsonBuffer.to<JsonObject>();
|
|
||||||
root["segment"] = State.segment;
|
|
||||||
root["start"] = segState.start;
|
|
||||||
root["stop"] = segState.stop;
|
|
||||||
root["mode"] = (uint8_t) State.mode;
|
|
||||||
root["fx_mode"] = segState.mode[State.segment];
|
|
||||||
root["speed"] = segState.speed[State.segment];
|
|
||||||
root["brightness"] = State.brightness;
|
|
||||||
JsonArray color = root.createNestedArray("color");
|
|
||||||
color.add(main_color.white);
|
|
||||||
color.add(main_color.red);
|
|
||||||
color.add(main_color.green);
|
|
||||||
color.add(main_color.blue);
|
|
||||||
color.add(back_color.white);
|
|
||||||
color.add(back_color.red);
|
|
||||||
color.add(back_color.green);
|
|
||||||
color.add(back_color.blue);
|
|
||||||
color.add(xtra_color.white);
|
|
||||||
color.add(xtra_color.red);
|
|
||||||
color.add(xtra_color.green);
|
|
||||||
color.add(xtra_color.blue);
|
|
||||||
root["ws_fxopt"] = segState.options;
|
|
||||||
root["hostname"] = HOSTNAME;
|
|
||||||
#if defined(ENABLE_MQTT)
|
|
||||||
root["mqtt_host"] = mqtt_host;
|
|
||||||
root["mqtt_port"] = mqtt_port;
|
|
||||||
root["mqtt_user"] = mqtt_user;
|
|
||||||
root["mqtt_pass"] = mqtt_pass;
|
|
||||||
#endif
|
|
||||||
root["ws_seg"] = Config.segments;
|
|
||||||
root["ws_cnt"] = Config.stripSize;
|
|
||||||
root["ws_rgbo"] = Config.RGBOrder;
|
|
||||||
root["ws_pin"] = Config.pin;
|
|
||||||
root["ws_trans"] = Config.transEffect;
|
|
||||||
uint16_t msg_len = measureJson(root) + 1;
|
|
||||||
char * buffer = (char *) malloc(msg_len);
|
|
||||||
serializeJson(root, buffer, msg_len);
|
|
||||||
jsonBuffer.clear();
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * listStateJSON() {
|
|
||||||
const size_t bufferSize = JSON_OBJECT_SIZE(3) + 25;
|
|
||||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
|
||||||
JsonObject root = jsonBuffer.to<JsonObject>();
|
|
||||||
root["segment"] = State.segment;
|
|
||||||
root["mode"] = (uint8_t) State.mode;
|
|
||||||
root["brightness"] = State.brightness;
|
|
||||||
uint16_t msg_len = measureJson(root) + 1;
|
|
||||||
char * buffer = (char *) malloc(msg_len);
|
|
||||||
serializeJson(root, buffer, msg_len);
|
|
||||||
jsonBuffer.clear();
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * listSegmentStateJSON(uint8_t _seg) {
|
|
||||||
const size_t bufferSize = JSON_ARRAY_SIZE(12) + JSON_OBJECT_SIZE(6) + 100;
|
|
||||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
|
||||||
JsonObject root = jsonBuffer.to<JsonObject>();
|
|
||||||
root["start"] = strip->getSegment(_seg)->start;
|
|
||||||
root["stop"] = strip->getSegment(_seg)->stop;
|
|
||||||
root["fx_mode"] = segState.mode[_seg];
|
|
||||||
root["speed"] = segState.speed[_seg];
|
|
||||||
JsonArray color = root.createNestedArray("color");
|
|
||||||
//color.add((strip->getColors(_seg)[0] >> 24) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][0] >> 24) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][0] >> 16) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][0] >> 8) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][0]) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][1] >> 24) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][1] >> 16) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][1] >> 8) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][1]) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][2] >> 24) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][2] >> 16) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][2] >> 8) & 0xFF);
|
|
||||||
color.add((segState.colors[_seg][2]) & 0xFF);
|
|
||||||
root["ws_fxopt"] = strip->getOptions(_seg);
|
|
||||||
uint16_t msg_len = measureJson(root) + 1;
|
|
||||||
char * buffer = (char *) malloc(msg_len);
|
|
||||||
serializeJson(root, buffer, msg_len);
|
|
||||||
jsonBuffer.clear();
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void getStateJSON() {
|
|
||||||
char * buffer = listStateJSONfull();
|
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
server.send ( 200, "application/json", buffer);
|
|
||||||
free (buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
char * listConfigJSON() {
|
|
||||||
#if defined(ENABLE_MQTT)
|
|
||||||
const size_t bufferSize = JSON_OBJECT_SIZE(10) + 150;
|
|
||||||
#else
|
|
||||||
const size_t bufferSize = JSON_OBJECT_SIZE(6) + 100;
|
|
||||||
#endif
|
|
||||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
|
||||||
JsonObject root = jsonBuffer.to<JsonObject>();
|
|
||||||
root["hostname"] = HOSTNAME;
|
|
||||||
#if defined(ENABLE_MQTT)
|
|
||||||
root["mqtt_host"] = mqtt_host;
|
|
||||||
root["mqtt_port"] = mqtt_port;
|
|
||||||
root["mqtt_user"] = mqtt_user;
|
|
||||||
root["mqtt_pass"] = mqtt_pass;
|
|
||||||
#endif
|
|
||||||
root["ws_seg"] = Config.segments;
|
|
||||||
root["ws_cnt"] = Config.stripSize;
|
|
||||||
root["ws_rgbo"] = Config.RGBOrder;
|
|
||||||
root["ws_pin"] = Config.pin;
|
|
||||||
root["ws_trans"] = Config.transEffect;
|
|
||||||
uint16_t msg_len = measureJson(root) + 1;
|
|
||||||
char * buffer = (char *) malloc(msg_len);
|
|
||||||
serializeJson(root, buffer, msg_len);
|
|
||||||
jsonBuffer.clear();
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void getConfigJSON() {
|
|
||||||
char * buffer = listConfigJSON();
|
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
server.send ( 200, "application/json", buffer);
|
|
||||||
free (buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
char * listModesJSON() {
|
|
||||||
const size_t bufferSize = JSON_ARRAY_SIZE(strip->getModeCount() + 1) + (strip->getModeCount() + 1)*JSON_OBJECT_SIZE(2) + 2000;
|
|
||||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
|
||||||
JsonArray root = jsonBuffer.to<JsonArray>();
|
|
||||||
JsonObject objectoff = root.createNestedObject();
|
|
||||||
objectoff["mode"] = "off";
|
|
||||||
objectoff["name"] = "OFF";
|
|
||||||
for (uint8_t i = 0; i < strip->getModeCount(); i++) {
|
|
||||||
JsonObject object = root.createNestedObject();
|
|
||||||
object["mode"] = i;
|
|
||||||
object["name"] = strip->getModeName(i);
|
|
||||||
}
|
|
||||||
uint16_t msg_len = measureJson(root) + 1;
|
|
||||||
char * buffer = (char *) malloc(msg_len);
|
|
||||||
serializeJson(root, buffer, msg_len);
|
|
||||||
jsonBuffer.clear();
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void getModesJSON() {
|
|
||||||
char * buffer = listModesJSON();
|
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
server.send ( 200, "application/json", buffer);
|
|
||||||
free (buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
char * listESPStateJSON() {
|
|
||||||
const size_t bufferSize = JSON_OBJECT_SIZE(31) + 1500;
|
|
||||||
DynamicJsonDocument jsonBuffer(bufferSize);
|
|
||||||
JsonObject root = jsonBuffer.to<JsonObject>();
|
|
||||||
root["HOSTNAME"] = HOSTNAME;
|
|
||||||
root["version"] = SKETCH_VERSION;
|
|
||||||
root["heap"] = ESP.getFreeHeap();
|
|
||||||
root["sketch_size"] = ESP.getSketchSize();
|
|
||||||
root["free_sketch_space"] = ESP.getFreeSketchSpace();
|
|
||||||
root["flash_chip_size"] = ESP.getFlashChipSize();
|
|
||||||
root["flash_chip_real_size"] = ESP.getFlashChipRealSize();
|
|
||||||
root["flash_chip_speed"] = ESP.getFlashChipSpeed();
|
|
||||||
root["sdk_version"] = ESP.getSdkVersion();
|
|
||||||
root["core_version"] = ESP.getCoreVersion();
|
|
||||||
root["cpu_freq"] = ESP.getCpuFreqMHz();
|
|
||||||
root["chip_id"] = ESP.getFlashChipId();
|
|
||||||
#if defined(USE_WS2812FX_DMA)
|
|
||||||
#if USE_WS2812FX_DMA == 0
|
|
||||||
root["animation_lib"] = "WS2812FX_DMA";
|
|
||||||
#endif
|
|
||||||
#if USE_WS2812FX_DMA == 1
|
|
||||||
root["animation_lib"] = "WS2812FX_UART1";
|
|
||||||
#endif
|
|
||||||
#if USE_WS2812FX_DMA == 2
|
|
||||||
root["animation_lib"] = "WS2812FX_UART2";
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
root["animation_lib"] = "WS2812FX";
|
|
||||||
#endif
|
|
||||||
root["ws2812_pin"] = Config.pin;
|
|
||||||
root["led_count"] = Config.stripSize;
|
|
||||||
root["rgb_order"] = Config.RGBOrder;
|
|
||||||
if (strstr(Config.RGBOrder, "W") != NULL) {
|
|
||||||
root["rgbw_mode"] = "ON";
|
|
||||||
} else {
|
|
||||||
root["rgbw_mode"] = "OFF";
|
|
||||||
}
|
|
||||||
#if defined(ENABLE_BUTTON)
|
|
||||||
root["button_mode"] = "ON";
|
|
||||||
root["button_pin"] = ENABLE_BUTTON;
|
|
||||||
#else
|
|
||||||
root["button_mode"] = "OFF";
|
|
||||||
#endif
|
|
||||||
#if defined(ENABLE_BUTTON_GY33)
|
|
||||||
root["button_gy33"] = "ON";
|
|
||||||
root["gy33_pin"] = ENABLE_BUTTON_GY33;
|
|
||||||
#else
|
|
||||||
root["button_gy33"] = "OFF";
|
|
||||||
#endif
|
|
||||||
#if defined(ENABLE_REMOTE)
|
|
||||||
root["ir_remote"] = "ON";
|
|
||||||
root["tsop_ir_pin"] = ENABLE_REMOTE;
|
|
||||||
#else
|
|
||||||
root["ir_remote"] = "OFF";
|
|
||||||
#endif
|
|
||||||
#if defined(ENABLE_MQTT)
|
|
||||||
#if ENABLE_MQTT == 0
|
|
||||||
root["mqtt"] = "MQTT";
|
|
||||||
#endif
|
|
||||||
#if ENABLE_MQTT == 1
|
|
||||||
root["mqtt"] = "AMQTT";
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
root["mqtt"] = "OFF";
|
|
||||||
#endif
|
|
||||||
#if defined(ENABLE_HOMEASSISTANT)
|
|
||||||
root["home_assistant"] = "ON";
|
|
||||||
#else
|
|
||||||
root["home_assistant"] = "OFF";
|
|
||||||
#endif
|
|
||||||
#if defined(ENABLE_OTA)
|
|
||||||
#if ENABLE_OTA == 0
|
|
||||||
root["ota"] = "ARDUINO";
|
|
||||||
#endif
|
|
||||||
#if ENABLE_OTA == 1
|
|
||||||
root["ota"] = "HTTP";
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
root["ota"] = "OFF";
|
|
||||||
#endif
|
|
||||||
#if defined(ENABLE_STATE_SAVE)
|
|
||||||
root["state_save"] = "SPIFFS";
|
|
||||||
#else
|
|
||||||
root["state_save"] = "OFF";
|
|
||||||
#endif
|
|
||||||
uint16_t msg_len = measureJson(root) + 1;
|
|
||||||
char * buffer = (char *) malloc(msg_len);
|
|
||||||
serializeJson(root, buffer, msg_len);
|
|
||||||
jsonBuffer.clear();
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
void getESPStateJSON() {
|
|
||||||
char * buffer = listESPStateJSON();
|
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
server.send(200, "application/json", buffer);
|
|
||||||
free (buffer);
|
|
||||||
}
|
|
||||||
@@ -1,258 +1,92 @@
|
|||||||
// Prototypes
|
|
||||||
uint16_t convertSpeed(uint8_t _mcl_speed);
|
|
||||||
uint32_t trans(uint32_t _newcolor, uint32_t _oldcolor, uint8_t _level, uint8_t _steps);
|
|
||||||
// End Prototypes
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Example of adding the example: https://github.com/kitesurfer1404/WS2812FX/blob/master/examples/ws2812fx_custom_FastLED/ws2812fx_custom_FastLED.ino
|
Example of adding the example: https://github.com/kitesurfer1404/WS2812FX/blob/master/examples/ws2812fx_custom_FastLED/ws2812fx_custom_FastLED.ino
|
||||||
as a custom effect
|
as a custom effect
|
||||||
|
|
||||||
More info on how to create custom aniamtions for WS2812FX: https://github.com/kitesurfer1404/WS2812FX/blob/master/extras/WS2812FX%20Users%20Guide.md#custom-effects
|
More info on how to create custom aniamtions for WS2812FX: https://github.com/kitesurfer1404/WS2812FX/blob/master/extras/WS2812FX%20Users%20Guide.md#custom-effects
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint16_t handleSegmentOFF(void) {
|
#include <FastLED.h> //https://github.com/FastLED/FastLED
|
||||||
WS2812FX::Segment* _seg = strip->getSegment();
|
|
||||||
return _seg->speed/(_seg->stop - _seg->start);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
/*
|
||||||
// Function for automatic cycling
|
|
||||||
// ***************************************************************************
|
|
||||||
void handleAutoPlay(uint8_t _seg) {
|
|
||||||
//WS2812FX::Segment* _seg = strip->getSegment();
|
|
||||||
if (autoDelay[_seg] <= millis()) {
|
|
||||||
uint32_t _hex_colors[3] = {};
|
|
||||||
//if (_seg ==
|
|
||||||
_hex_colors[0] = autoParams[autoCount[_seg]][0];
|
|
||||||
_hex_colors[1] = autoParams[autoCount[_seg]][1];
|
|
||||||
_hex_colors[2] = autoParams[autoCount[_seg]][2];
|
|
||||||
//}
|
|
||||||
strip->setColors(_seg, _hex_colors);
|
|
||||||
strip->setSpeed(_seg, convertSpeed((uint16_t)autoParams[autoCount[_seg]][3]));
|
|
||||||
strip->setMode(_seg, (uint8_t)autoParams[autoCount[_seg]][4]);
|
|
||||||
//strip->trigger();
|
|
||||||
autoDelay[_seg] = millis() + (unsigned long)autoParams[autoCount[_seg]][5];
|
|
||||||
DBG_OUTPUT_PORT.printf("autoTick[%d][%d]: {0x%08x, 0x%08x, 0x%08x, %d, %d, %d}\r\n", _seg, autoCount[_seg], autoParams[autoCount[_seg]][0], autoParams[autoCount[_seg]][1], autoParams[autoCount[_seg]][2], autoParams[autoCount[_seg]][3], autoParams[autoCount[_seg]][4], autoParams[autoCount[_seg]][5]);
|
|
||||||
autoCount[_seg]++;
|
|
||||||
if (autoCount[_seg] >= (sizeof(autoParams) / sizeof(autoParams[0]))) autoCount[_seg] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t handleAuto(void) {
|
|
||||||
WS2812FX::Segment* _seg = strip->getSegment();
|
|
||||||
return _seg->speed/(_seg->stop - _seg->start);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t handleCustomWS(void) {
|
|
||||||
WS2812FX::Segment* _seg = strip->getSegment();
|
|
||||||
return _seg->speed/(_seg->stop - _seg->start);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CUSTOM_WS2812FX_ANIMATIONS)
|
|
||||||
// ***************************************************************************
|
|
||||||
// TV mode to be reviewed
|
|
||||||
// ***************************************************************************
|
|
||||||
uint16_t darkTime[10] = {250,250,250,250,250,250,250,250,250,250};
|
|
||||||
uint8_t dipInterval[10] = {10,10,10,10,10,10,10,10,10,10};
|
|
||||||
unsigned long dipStartTime[10] = {};
|
|
||||||
uint8_t ledState[10] = {LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW};
|
|
||||||
unsigned long previousMillis[10]= {0,0,0,0,0,0,0,0,0,0};
|
|
||||||
uint16_t interv[10] = {2000,2000,2000,2000,2000,2000,2000,2000,2000,2000};
|
|
||||||
uint8_t twitch[10]= {50,50,50,50,50,50,50,50,50,50};
|
|
||||||
uint8_t dipCount[10] = {0,0,0,0,0,0,0,0,0,0};
|
|
||||||
bool timeToDip[10] = {false,false,false,false,false,false,false,false,false,false};
|
|
||||||
|
|
||||||
|
|
||||||
void hsb2rgbAN1(uint16_t index, uint8_t sat, uint8_t bright, uint16_t led) {
|
|
||||||
// Source: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/
|
|
||||||
uint8_t temp[5], n = (index >> 8) % 3;
|
|
||||||
temp[0] = temp[3] = (uint8_t)(( (sat ^ 255) * bright) / 255);
|
|
||||||
temp[1] = temp[4] = (uint8_t)((((( (index & 255) * sat) / 255) + (sat ^ 255)) * bright) / 255);
|
|
||||||
temp[2] = (uint8_t)(((((((index & 255) ^ 255) * sat) / 255) + (sat ^ 255)) * bright) / 255);
|
|
||||||
strip->setPixelColor(led, temp[n + 2], temp[n + 1], temp[n], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t handleTV(void) {
|
|
||||||
WS2812FX::Segment* _seg = strip->getSegment();
|
|
||||||
uint8_t _seg_num = strip->getSegmentIndex();
|
|
||||||
if (timeToDip[_seg_num] == false) {
|
|
||||||
if((millis() - previousMillis[_seg_num]) > interv[_seg_num]) {
|
|
||||||
previousMillis[_seg_num] = millis();
|
|
||||||
//interv = random(750,4001);//Adjusts the interval for more/less frequent random light changes
|
|
||||||
interv[_seg_num] = random(800-(512 - (_seg->speed/64)),6001-(2731 - (_seg->speed/24)));
|
|
||||||
twitch[_seg_num] = random(40,100);// Twitch provides motion effect but can be a bit much if too high
|
|
||||||
dipCount[_seg_num]++;
|
|
||||||
}
|
|
||||||
if((millis() - previousMillis[_seg_num]) < twitch[_seg_num]) {
|
|
||||||
uint16_t led=random(_seg->start, _seg->stop);
|
|
||||||
ledState[_seg_num] = ledState[_seg_num] == LOW ? HIGH : LOW; // if the LED is off turn it on and vice-versa:
|
|
||||||
ledstates[led] = ((ledState[_seg_num]) ? 255 : 0);
|
|
||||||
for (uint16_t j=_seg->start; j<=_seg->stop; j++) {
|
|
||||||
uint16_t index = (j%3 == 0) ? 400 : random(0,767);
|
|
||||||
hsb2rgbAN1(index, 200, ledstates[j], j);
|
|
||||||
}
|
|
||||||
if (dipCount[_seg_num] > dipInterval[_seg_num]) {
|
|
||||||
timeToDip[_seg_num] = true;
|
|
||||||
dipCount[_seg_num] = 0;
|
|
||||||
dipStartTime[_seg_num] = millis();
|
|
||||||
darkTime[_seg_num] = random(50,150);
|
|
||||||
dipInterval[_seg_num] = random(5,250);// cycles of flicker
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (millis() - dipStartTime[_seg_num] < darkTime[_seg_num]) {
|
|
||||||
for (uint16_t i = _seg->start; i <= _seg->stop; i++) {
|
|
||||||
ledstates[i] = 0;
|
|
||||||
for (uint16_t j=_seg->start; j<=_seg->stop; j++) {
|
|
||||||
uint16_t index = (j%3 == 0) ? 400 : random(0,767);
|
|
||||||
hsb2rgbAN1(index, 200, ledstates[j], j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
timeToDip[_seg_num] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _seg->speed/(_seg->stop - _seg->start);
|
|
||||||
}
|
|
||||||
// ***************************************************************************
|
|
||||||
// E1.31 mode
|
|
||||||
// ***************************************************************************
|
|
||||||
uint16_t handleE131(void) {
|
|
||||||
WS2812FX::Segment* _seg = strip->getSegment();
|
|
||||||
return _seg->speed/(_seg->stop - _seg->start);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleE131Play(void) {
|
|
||||||
if (!e131->isEmpty()) {
|
|
||||||
e131_packet_t packet;
|
|
||||||
e131->pull(&packet); // Pull packet from ring buffer
|
|
||||||
|
|
||||||
uint16_t universe = htons(packet.universe);
|
|
||||||
uint8_t *data = packet.property_values + 1;
|
|
||||||
|
|
||||||
if (universe < START_UNIVERSE || universe > END_UNIVERSE) return; //async will take care about filling the buffer
|
|
||||||
|
|
||||||
// Serial.printf("Universe %u / %u Channels | Packet#: %u / Errors: %u / CH1: %u\n",
|
|
||||||
// htons(packet.universe), // The Universe for this packet
|
|
||||||
// htons(packet.property_value_count) - 1, // Start code is ignored, we're interested in dimmer data
|
|
||||||
// e131.stats.num_packets, // Packet counter
|
|
||||||
// e131.stats.packet_errors, // Packet error counter
|
|
||||||
// packet.property_values[1]); // Dimmer data for Channel 1
|
|
||||||
/* #if defined(RGBW)
|
|
||||||
uint16_t multipacketOffset = (universe - START_UNIVERSE) * 128; //if more than 128 LEDs * 4 colors = 512 channels, client will send in next higher universe
|
|
||||||
if (Config.stripSize <= multipacketOffset) return _seg->speed/(_seg->stop - _seg->start);
|
|
||||||
uint16_t len = (128 + multipacketOffset > Config.stripSize) ? (Config.stripSize - multipacketOffset) : 128;
|
|
||||||
#else*/
|
|
||||||
uint16_t multipacketOffset = (universe - START_UNIVERSE) * 170; //if more than 170 LEDs * 3 colors = 510 channels, client will send in next higher universe
|
|
||||||
if (Config.stripSize <= multipacketOffset) return;
|
|
||||||
uint16_t len = (170 + multipacketOffset > Config.stripSize) ? (Config.stripSize - multipacketOffset) : 170;
|
|
||||||
/* #endif */
|
|
||||||
for (uint8_t k = 0; k < Config.segments; k++) {
|
|
||||||
if (segState.mode[k] == FX_MODE_CUSTOM_3) {
|
|
||||||
for (uint16_t i = 0; i < len; i++){
|
|
||||||
if ((i >= strip->getSegment(k)->start) && (i <= strip->getSegment(k)->stop)) {
|
|
||||||
uint16_t j = i * 3;
|
|
||||||
/* #if defined(RGBW)
|
|
||||||
strip->setPixelColor(i + multipacketOffset, data[j], data[j + 1], data[j + 2], data[j + 3]);
|
|
||||||
#else */
|
|
||||||
strip->setPixelColor(i + multipacketOffset, data[j], data[j + 1], data[j + 2], 0);
|
|
||||||
/* #endif */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* paste in the Fire2012 code with a small edit at the end which uses the
|
* paste in the Fire2012 code with a small edit at the end which uses the
|
||||||
* setPixelColor() function to copy the color data to the ws2812fx instance.
|
* setPixelColor() function to copy the color data to the ws2812fx instance.
|
||||||
*/
|
*/
|
||||||
#include <FastLED.h> //https://github.com/FastLED/FastLED
|
|
||||||
// Fire2012 by Mark Kriegsman, July 2012
|
// Fire2012 by Mark Kriegsman, July 2012
|
||||||
// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY
|
// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY
|
||||||
////
|
////
|
||||||
// This basic one-dimensional 'fire' simulation works roughly as follows:
|
// This basic one-dimensional 'fire' simulation works roughly as follows:
|
||||||
// There's a underlying array of 'heat' cells, that model the temperature
|
// There's a underlying array of 'heat' cells, that model the temperature
|
||||||
// at each point along the line. Every cycle through the simulation,
|
// at each point along the line. Every cycle through the simulation,
|
||||||
// four steps are performed:
|
// four steps are performed:
|
||||||
// 1) All cells cool down a little bit, losing heat to the air
|
// 1) All cells cool down a little bit, losing heat to the air
|
||||||
// 2) The heat from each cell drifts 'up' and diffuses a little
|
// 2) The heat from each cell drifts 'up' and diffuses a little
|
||||||
// 3) Sometimes randomly new 'sparks' of heat are added at the bottom
|
// 3) Sometimes randomly new 'sparks' of heat are added at the bottom
|
||||||
// 4) The heat from each cell is rendered as a color into the leds array
|
// 4) The heat from each cell is rendered as a color into the leds array
|
||||||
// The heat-to-color mapping uses a black-body radiation approximation.
|
// The heat-to-color mapping uses a black-body radiation approximation.
|
||||||
//
|
//
|
||||||
// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot).
|
// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot).
|
||||||
//
|
//
|
||||||
// This simulation scales it self a bit depending on NUM_LEDS; it should look
|
// This simulation scales it self a bit depending on NUM_LEDS; it should look
|
||||||
// "OK" on anywhere from 20 to 100 LEDs without too much tweaking.
|
// "OK" on anywhere from 20 to 100 LEDs without too much tweaking.
|
||||||
//
|
//
|
||||||
// I recommend running this simulation at anywhere from 30-100 frames per second,
|
// I recommend running this simulation at anywhere from 30-100 frames per second,
|
||||||
// meaning an interframe delay of about 10-35 milliseconds.
|
// meaning an interframe delay of about 10-35 milliseconds.
|
||||||
//
|
//
|
||||||
// Looks best on a high-density LED setup (60+ pixels/meter).
|
// Looks best on a high-density LED setup (60+ pixels/meter).
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// There are two main parameters you can play with to control the look and
|
// There are two main parameters you can play with to control the look and
|
||||||
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
|
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
|
||||||
// in step 3 above).
|
// in step 3 above).
|
||||||
//
|
//
|
||||||
// COOLING: How much does the air cool as it rises?
|
// COOLING: How much does the air cool as it rises?
|
||||||
// Less cooling = taller flames. More cooling = shorter flames.
|
// Less cooling = taller flames. More cooling = shorter flames.
|
||||||
// Default 50, suggested range 20-100
|
// Default 50, suggested range 20-100
|
||||||
#define COOLING 70
|
#define COOLING 70
|
||||||
|
|
||||||
// SPARKING: What chance (out of 255) is there that a new spark will be lit?
|
// SPARKING: What chance (out of 255) is there that a new spark will be lit?
|
||||||
// Higher chance = more roaring fire. Lower chance = more flickery fire.
|
// Higher chance = more roaring fire. Lower chance = more flickery fire.
|
||||||
// Default 120, suggested range 50-200.
|
// Default 120, suggested range 50-200.
|
||||||
#define SPARKING 120
|
#define SPARKING 120
|
||||||
|
|
||||||
uint16_t handleFire2012(void) {
|
bool gReverseDirection = false;
|
||||||
// Array of temperature readings at each simulation cell
|
|
||||||
WS2812FX::Segment* _seg = strip->getSegment();
|
void Fire2012() {
|
||||||
|
// Array of temperature readings at each simulation cell
|
||||||
|
|
||||||
// Step 1. Cool down every cell a little
|
// Step 1. Cool down every cell a little
|
||||||
for( uint16_t i = _seg->start; i <= _seg->stop; i++) {
|
for( uint16_t i = 0; i < WS2812FXStripSettings.stripSize; i++) {
|
||||||
ledstates[i] = qsub8(ledstates[i], random8(0, ((COOLING * 10) / (_seg->stop - _seg->start)+1) + 2));
|
ledstates[i] = qsub8( ledstates[i], random8(0, ((COOLING * 10) / WS2812FXStripSettings.stripSize) + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
||||||
for( uint16_t k= _seg->stop; k >= (_seg->start + 2); k--) {
|
for( uint16_t k= WS2812FXStripSettings.stripSize - 1; k >= 2; k--) {
|
||||||
ledstates[k] = (ledstates[k - 1] + ledstates[k - 2] + ledstates[k - 2]) / 3;
|
ledstates[k] = (ledstates[k - 1] + ledstates[k - 2] + ledstates[k - 2]) / 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
|
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
|
||||||
if( random8() < SPARKING ) {
|
if( random8() < SPARKING ) {
|
||||||
uint8_t y = random8(7) + _seg->start;
|
uint8_t y = random8(7);
|
||||||
ledstates[y] = qadd8(ledstates[y], random8(160,255) );
|
ledstates[y] = qadd8(ledstates[y], random8(160,255) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4. Map from heat cells to LED colors
|
// Step 4. Map from heat cells to LED colors
|
||||||
for( uint16_t j = _seg->start; j <= _seg->stop; j++) {
|
for( uint16_t j = 0; j < WS2812FXStripSettings.stripSize; j++) {
|
||||||
CRGB color = HeatColor(ledstates[j]);
|
CRGB color = HeatColor( ledstates[j]);
|
||||||
uint16_t pixel;
|
uint16_t pixelnumber;
|
||||||
if ((_seg->options & 128) > 0) {
|
if( gReverseDirection ) {
|
||||||
pixel = _seg->stop + (_seg->start - j);
|
pixelnumber = (WS2812FXStripSettings.stripSize - 1) - j;
|
||||||
} else {
|
} else {
|
||||||
pixel = j;
|
pixelnumber = j;
|
||||||
}
|
}
|
||||||
strip->setPixelColor(pixel, color.red, color.green, color.blue, 0);
|
strip->setPixelColor(pixelnumber, color.red, color.green, color.blue, 0);
|
||||||
}
|
|
||||||
return _seg->speed/(_seg->stop - _seg->start);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t handleGradient(void) {
|
uint16_t myCustomEffect0() {
|
||||||
WS2812FX::Segment* _seg = strip->getSegment();
|
Fire2012();
|
||||||
for(uint16_t j = 0; j <= (_seg->stop - _seg->start); j++) {
|
return (strip->getSpeed() / WS2812FXStripSettings.stripSize);
|
||||||
uint16_t pixel;
|
}
|
||||||
if ((_seg->options & 128) > 0) {
|
|
||||||
pixel = _seg->stop - j;
|
|
||||||
} else {
|
|
||||||
pixel = _seg->start + j;
|
|
||||||
}
|
|
||||||
uint32_t color = trans(_seg->colors[1], _seg->colors[0], j, (_seg->stop - _seg->start));
|
|
||||||
strip->setPixelColor(pixel, ((color >> 16) & 0xFF), ((color >> 8) & 0xFF), ((color >> 0) & 0xFF), ((color >> 24) & 0xFF));
|
|
||||||
}
|
|
||||||
return _seg->speed/(_seg->stop - _seg->start);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
// ***************************************************************************
|
||||||
|
// TV mode
|
||||||
|
// ***************************************************************************
|
||||||
|
|
||||||
|
uint8_t dipInterval = 10;
|
||||||
|
uint16_t darkTime = 250;
|
||||||
|
unsigned long currentDipTime;
|
||||||
|
unsigned long dipStartTime;
|
||||||
|
unsigned long currentMillis;
|
||||||
|
uint8_t ledState = LOW;
|
||||||
|
long previousMillis = 0;
|
||||||
|
uint16_t led = 5;
|
||||||
|
uint16_t interv = 2000;
|
||||||
|
uint8_t twitch = 50;
|
||||||
|
uint8_t dipCount = 0;
|
||||||
|
uint8_t analogLevel = 100;
|
||||||
|
boolean timeToDip = false;
|
||||||
|
|
||||||
|
|
||||||
|
void hsb2rgbAN1(uint16_t index, uint8_t sat, uint8_t bright, uint8_t myled) {
|
||||||
|
// Source: https://blog.adafruit.com/2012/03/14/constant-brightness-hsb-to-rgb-algorithm/
|
||||||
|
uint8_t temp[5], n = (index >> 8) % 3;
|
||||||
|
temp[0] = temp[3] = (uint8_t)(( (sat ^ 255) * bright) / 255);
|
||||||
|
temp[1] = temp[4] = (uint8_t)((((( (index & 255) * sat) / 255) + (sat ^ 255)) * bright) / 255);
|
||||||
|
temp[2] = (uint8_t)(((((((index & 255) ^ 255) * sat) / 255) + (sat ^ 255)) * bright) / 255);
|
||||||
|
strip->setPixelColor(myled, temp[n + 2], temp[n + 1], temp[n], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void updateLed (uint16_t led, uint8_t brightness) {
|
||||||
|
ledstates[led] = brightness;
|
||||||
|
for (uint16_t i=0; i<WS2812FXStripSettings.stripSize; i++) {
|
||||||
|
uint16_t index = (i%3 == 0) ? 400 : random(0,767);
|
||||||
|
hsb2rgbAN1(index, 200, ledstates[i], i);
|
||||||
|
}
|
||||||
|
strip->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// See: http://forum.mysensors.org/topic/85/phoneytv-for-vera-is-here/13
|
||||||
|
void handleTV() {
|
||||||
|
if (timeToDip == false) {
|
||||||
|
currentMillis = millis();
|
||||||
|
if(currentMillis-previousMillis > interv) {
|
||||||
|
previousMillis = currentMillis;
|
||||||
|
//interv = random(750,4001);//Adjusts the interval for more/less frequent random light changes
|
||||||
|
interv = random(1000-(ws2812fx_speed*2),5001-(ws2812fx_speed*8));
|
||||||
|
twitch = random(40,100);// Twitch provides motion effect but can be a bit much if too high
|
||||||
|
dipCount = dipCount++;
|
||||||
|
}
|
||||||
|
if(currentMillis-previousMillis<twitch) {
|
||||||
|
led=random(0, WS2812FXStripSettings.stripSize - 1);
|
||||||
|
analogLevel=random(50,255);// set the range of the 3 pwm leds
|
||||||
|
ledState = ledState == LOW ? HIGH: LOW; // if the LED is off turn it on and vice-versa:
|
||||||
|
updateLed(led, (ledState) ? 255 : 0);
|
||||||
|
if (dipCount > dipInterval) {
|
||||||
|
DBG_OUTPUT_PORT.println("dip");
|
||||||
|
timeToDip = true;
|
||||||
|
dipCount = 0;
|
||||||
|
dipStartTime = millis();
|
||||||
|
darkTime = random(50,150);
|
||||||
|
dipInterval = random(5,250);// cycles of flicker
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DBG_OUTPUT_PORT.println("Dip Time");
|
||||||
|
currentDipTime = millis();
|
||||||
|
if (currentDipTime - dipStartTime < darkTime) {
|
||||||
|
for (uint16_t i=3; i<WS2812FXStripSettings.stripSize; i++) {
|
||||||
|
updateLed(i, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
timeToDip = false;
|
||||||
|
}
|
||||||
|
//strip->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
+1078
-494
File diff suppressed because it is too large
Load Diff
+304
-370
@@ -1,24 +1,24 @@
|
|||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Setup: Webserver handler
|
// Setup: Webserver handler
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
//list directory
|
//list directory
|
||||||
server.on("/list", HTTP_GET, handleFileList);
|
server.on("/list", HTTP_GET, handleFileList);
|
||||||
//create file
|
//create file
|
||||||
server.on("/edit", HTTP_PUT, handleFileCreate);
|
server.on("/edit", HTTP_PUT, handleFileCreate);
|
||||||
//delete file
|
//delete file
|
||||||
server.on("/edit", HTTP_DELETE, handleFileDelete);
|
server.on("/edit", HTTP_DELETE, handleFileDelete);
|
||||||
//first callback is called after the request has ended with all parsed arguments
|
//first callback is called after the request has ended with all parsed arguments
|
||||||
//second callback handles file uploads at that location
|
//second callback handles file uploads at that location
|
||||||
server.on("/edit", HTTP_POST, []() {
|
server.on("/edit", HTTP_POST, []() {
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
server.send(200, "text/plain", "");
|
server.send(200, "text/plain", "");
|
||||||
}, handleFileUpload);
|
}, handleFileUpload);
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Setup: SPIFFS Webserver handler
|
// Setup: SPIFFS Webserver handler
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
server.on("/", HTTP_GET, [&](){
|
server.on("/", HTTP_GET, [&](){
|
||||||
#if defined(USE_HTML_MIN_GZ)
|
#if defined(USE_HTML_MIN_GZ)
|
||||||
server.sendHeader("Content-Encoding", "gzip", true);
|
server.sendHeader("Content-Encoding", "gzip", true);
|
||||||
server.send_P(200, PSTR("text/html"), index_htm_gz, index_htm_gz_len);
|
server.send_P(200, PSTR("text/html"), index_htm_gz, index_htm_gz_len);
|
||||||
@@ -26,37 +26,9 @@ server.on("/", HTTP_GET, [&](){
|
|||||||
if (!handleFileRead(server.uri()))
|
if (!handleFileRead(server.uri()))
|
||||||
handleNotFound();
|
handleNotFound();
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/material.woff2", HTTP_GET, [&](){
|
server.on("/edit", HTTP_GET, [&](){
|
||||||
#if defined(USE_HTML_MIN_GZ)
|
|
||||||
server.send_P(200, PSTR("text/plain"), material_icons_woff2, material_icons_woff2_len);
|
|
||||||
#else
|
|
||||||
if (!handleFileRead(server.uri()))
|
|
||||||
handleNotFound();
|
|
||||||
#endif
|
|
||||||
});
|
|
||||||
|
|
||||||
server.on("/favicon.ico", HTTP_GET, [&](){
|
|
||||||
#if defined(USE_HTML_MIN_GZ)
|
|
||||||
server.sendHeader("Content-Encoding", "gzip", true);
|
|
||||||
server.send_P(200, PSTR("text/plain"), fav_icon, fav_icon_len);
|
|
||||||
#else
|
|
||||||
if (!handleFileRead(server.uri()))
|
|
||||||
handleNotFound();
|
|
||||||
#endif
|
|
||||||
});
|
|
||||||
|
|
||||||
server.on("/apple-touch-icon.png", HTTP_GET, [&](){
|
|
||||||
#if defined(USE_HTML_MIN_GZ)
|
|
||||||
server.send_P(200, PSTR("text/plain"), apple_touch_icon_png, apple_touch_icon_png_len);
|
|
||||||
#else
|
|
||||||
if (!handleFileRead(server.uri()))
|
|
||||||
handleNotFound();
|
|
||||||
#endif
|
|
||||||
});
|
|
||||||
|
|
||||||
server.on("/edit", HTTP_GET, [&](){
|
|
||||||
#if defined(USE_HTML_MIN_GZ)
|
#if defined(USE_HTML_MIN_GZ)
|
||||||
server.sendHeader("Content-Encoding", "gzip", true);
|
server.sendHeader("Content-Encoding", "gzip", true);
|
||||||
server.send_P(200, PSTR("text/html"), edit_htm_gz, edit_htm_gz_len);
|
server.send_P(200, PSTR("text/html"), edit_htm_gz, edit_htm_gz_len);
|
||||||
@@ -64,126 +36,234 @@ server.on("/edit", HTTP_GET, [&](){
|
|||||||
if (!handleFileRead("/edit.htm"))
|
if (!handleFileRead("/edit.htm"))
|
||||||
handleNotFound();
|
handleNotFound();
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//called when the url is not defined here
|
//called when the url is not defined here
|
||||||
//use it to load content from SPIFFS
|
//use it to load content from SPIFFS
|
||||||
server.onNotFound([]() {
|
server.onNotFound([]() {
|
||||||
if (!handleFileRead(server.uri()))
|
if (!handleFileRead(server.uri()))
|
||||||
handleNotFound();
|
handleNotFound();
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/upload", handleMinimalUpload);
|
server.on("/upload", handleMinimalUpload);
|
||||||
|
|
||||||
server.on("/esp_status", HTTP_GET, []() { //get heap status, analog input value and all GPIO statuses in one json call
|
server.on("/esp_status", HTTP_GET, []() { //get heap status, analog input value and all GPIO statuses in one json call
|
||||||
getESPStateJSON();
|
const size_t bufferSize = JSON_OBJECT_SIZE(31) + 1500;
|
||||||
});
|
DynamicJsonDocument jsonBuffer(bufferSize);
|
||||||
|
JsonObject root = jsonBuffer.to<JsonObject>();
|
||||||
|
root["HOSTNAME"] = HOSTNAME;
|
||||||
|
root["version"] = SKETCH_VERSION;
|
||||||
|
root["heap"] = ESP.getFreeHeap();
|
||||||
|
root["sketch_size"] = ESP.getSketchSize();
|
||||||
|
root["free_sketch_space"] = ESP.getFreeSketchSpace();
|
||||||
|
root["flash_chip_size"] = ESP.getFlashChipSize();
|
||||||
|
root["flash_chip_real_size"] = ESP.getFlashChipRealSize();
|
||||||
|
root["flash_chip_speed"] = ESP.getFlashChipSpeed();
|
||||||
|
root["sdk_version"] = ESP.getSdkVersion();
|
||||||
|
root["core_version"] = ESP.getCoreVersion();
|
||||||
|
root["cpu_freq"] = ESP.getCpuFreqMHz();
|
||||||
|
root["chip_id"] = ESP.getFlashChipId();
|
||||||
|
#if defined(USE_WS2812FX_DMA)
|
||||||
|
#if USE_WS2812FX_DMA == 0
|
||||||
|
root["animation_lib"] = "WS2812FX_DMA";
|
||||||
|
#endif
|
||||||
|
#if USE_WS2812FX_DMA == 1
|
||||||
|
root["animation_lib"] = "WS2812FX_UART1";
|
||||||
|
#endif
|
||||||
|
#if USE_WS2812FX_DMA == 2
|
||||||
|
root["animation_lib"] = "WS2812FX_UART2";
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
root["animation_lib"] = "WS2812FX";
|
||||||
|
#endif
|
||||||
|
root["ws2812_pin"] = WS2812FXStripSettings.pin;
|
||||||
|
root["led_count"] = WS2812FXStripSettings.stripSize;
|
||||||
|
root["rgb_order"] = WS2812FXStripSettings.RGBOrder;
|
||||||
|
if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) {
|
||||||
|
root["rgbw_mode"] = "ON";
|
||||||
|
} else {
|
||||||
|
root["rgbw_mode"] = "OFF";
|
||||||
|
}
|
||||||
|
#if defined(ENABLE_BUTTON)
|
||||||
|
root["button_mode"] = "ON";
|
||||||
|
root["button_pin"] = ENABLE_BUTTON;
|
||||||
|
#else
|
||||||
|
root["button_mode"] = "OFF";
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_BUTTON_GY33)
|
||||||
|
root["button_gy33"] = "ON";
|
||||||
|
root["gy33_pin"] = ENABLE_BUTTON_GY33;
|
||||||
|
#else
|
||||||
|
root["button_gy33"] = "OFF";
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_REMOTE)
|
||||||
|
root["ir_remote"] = "ON";
|
||||||
|
root["tsop_ir_pin"] = ENABLE_REMOTE;
|
||||||
|
#else
|
||||||
|
root["ir_remote"] = "OFF";
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_MQTT)
|
||||||
|
#if ENABLE_MQTT == 0
|
||||||
|
root["mqtt"] = "MQTT";
|
||||||
|
#endif
|
||||||
|
#if ENABLE_MQTT == 1
|
||||||
|
root["mqtt"] = "AMQTT";
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
root["mqtt"] = "OFF";
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_HOMEASSISTANT)
|
||||||
|
root["home_assistant"] = "ON";
|
||||||
|
#else
|
||||||
|
root["home_assistant"] = "OFF";
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_LEGACY_ANIMATIONS)
|
||||||
|
root["legacy_animations"] = "ON";
|
||||||
|
#else
|
||||||
|
root["legacy_animations"] = "OFF";
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_TV)
|
||||||
|
root["tv_animation"] = "ON";
|
||||||
|
#else
|
||||||
|
root["tv_animation"] = "OFF";
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_E131)
|
||||||
|
root["e131_animations"] = "ON";
|
||||||
|
#else
|
||||||
|
root["e131_animations"] = "OFF";
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_OTA)
|
||||||
|
#if ENABLE_OTA == 0
|
||||||
|
root["ota"] = "ARDUINO";
|
||||||
|
#endif
|
||||||
|
#if ENABLE_OTA == 1
|
||||||
|
root["ota"] = "HTTP";
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
root["ota"] = "OFF";
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_STATE_SAVE)
|
||||||
|
#if ENABLE_STATE_SAVE == 1
|
||||||
|
root["state_save"] = "SPIFFS";
|
||||||
|
#endif
|
||||||
|
#if ENABLE_STATE_SAVE == 0
|
||||||
|
root["state_save"] = "EEPROM";
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
root["state_save"] = "OFF";
|
||||||
|
#endif
|
||||||
|
uint16_t msg_len = measureJson(root) + 1;
|
||||||
|
char * buffer = (char *) malloc(msg_len);
|
||||||
|
serializeJson(root, buffer, msg_len);
|
||||||
|
jsonBuffer.clear();
|
||||||
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
server.send(200, "application/json", buffer);
|
||||||
|
free (buffer);
|
||||||
|
});
|
||||||
|
|
||||||
server.on("/restart", []() {
|
server.on("/restart", []() {
|
||||||
DBG_OUTPUT_PORT.printf("/restart\r\n");
|
DBG_OUTPUT_PORT.printf("/restart\r\n");
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
server.send(200, "text/plain", "restarting..." );
|
server.send(200, "text/plain", "restarting..." );
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/reset_wlan", []() {
|
server.on("/reset_wlan", []() {
|
||||||
DBG_OUTPUT_PORT.printf("/reset_wlan\r\n");
|
DBG_OUTPUT_PORT.printf("/reset_wlan\r\n");
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
server.send(200, "text/plain", "Resetting WLAN and restarting..." );
|
server.send(200, "text/plain", "Resetting WLAN and restarting..." );
|
||||||
WiFiManager wifiManager;
|
WiFiManager wifiManager;
|
||||||
wifiManager.resetSettings();
|
wifiManager.resetSettings();
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/start_config_ap", []() {
|
server.on("/start_config_ap", []() {
|
||||||
DBG_OUTPUT_PORT.printf("/start_config_ap\r\n");
|
DBG_OUTPUT_PORT.printf("/start_config_ap\r\n");
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
server.send(200, "text/plain", "Starting config AP ..." );
|
server.send(200, "text/plain", "Starting config AP ..." );
|
||||||
WiFiManager wifiManager;
|
WiFiManager wifiManager;
|
||||||
wifiManager.startConfigPortal(HOSTNAME);
|
wifiManager.startConfigPortal(HOSTNAME);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/format_spiffs", []() {
|
server.on("/format_spiffs", []() {
|
||||||
DBG_OUTPUT_PORT.printf("/format_spiffs\r\n");
|
DBG_OUTPUT_PORT.printf("/format_spiffs\r\n");
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
server.send(200, "text/plain", "Formatting SPIFFS ..." );
|
server.send(200, "text/plain", "Formatting SPIFFS ..." );
|
||||||
SPIFFS.format();
|
SPIFFS.format();
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/get_brightness", []() {
|
server.on("/set_brightness", []() {
|
||||||
|
mode = SET_BRIGHTNESS;
|
||||||
|
getArgs();
|
||||||
|
getStatusJSON();
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on("/get_brightness", []() {
|
||||||
char str_brightness[4];
|
char str_brightness[4];
|
||||||
snprintf(str_brightness, sizeof(str_brightness), "%i", (int) (State.brightness / 2.55));
|
snprintf(str_brightness, sizeof(str_brightness), "%i", (int) (brightness / 2.55));
|
||||||
str_brightness[sizeof(str_brightness) - 1] = 0x00;
|
str_brightness[sizeof(str_brightness) - 1] = 0x00;
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
server.send(200, "text/plain", str_brightness );
|
server.send(200, "text/plain", str_brightness );
|
||||||
DBG_OUTPUT_PORT.printf("/get_brightness: %i\r\n", (int) (State.brightness / 2.55));
|
DBG_OUTPUT_PORT.printf("/get_brightness: %i\r\n", (int) (brightness / 2.55));
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/get_speed", []() {
|
server.on("/set_speed", []() {
|
||||||
|
mode = SET_SPEED;
|
||||||
|
getArgs();
|
||||||
|
getStatusJSON();
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on("/get_speed", []() {
|
||||||
char str_speed[4];
|
char str_speed[4];
|
||||||
snprintf(str_speed, sizeof(str_speed), "%i", segState.speed[State.segment]);
|
snprintf(str_speed, sizeof(str_speed), "%i", ws2812fx_speed);
|
||||||
str_speed[sizeof(str_speed) - 1] = 0x00;
|
str_speed[sizeof(str_speed) - 1] = 0x00;
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
server.send(200, "text/plain", str_speed );
|
server.send(200, "text/plain", str_speed );
|
||||||
DBG_OUTPUT_PORT.printf("/get_speed: %i\r\n", segState.speed[State.segment]);
|
DBG_OUTPUT_PORT.printf("/get_speed: %i\r\n", ws2812fx_speed);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/get_switch", []() {
|
server.on("/get_switch", []() {
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
server.send(200, "text/plain", (State.mode == OFF) ? "0" : "1" );
|
server.send(200, "text/plain", (mode == OFF) ? "0" : "1" );
|
||||||
DBG_OUTPUT_PORT.printf("/get_switch: %s\r\n", (State.mode == OFF) ? "0" : "1");
|
DBG_OUTPUT_PORT.printf("/get_switch: %s\r\n", (mode == OFF) ? "0" : "1");
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/get_color", []() {
|
server.on("/get_color", []() {
|
||||||
char rgbcolor[7];
|
char rgbcolor[10];
|
||||||
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X", main_color.red, main_color.green, main_color.blue);
|
|
||||||
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
|
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
|
||||||
server.send(200, "text/plain", rgbcolor);
|
|
||||||
DBG_OUTPUT_PORT.print("/get_color: ");
|
|
||||||
DBG_OUTPUT_PORT.println(rgbcolor);
|
|
||||||
});
|
|
||||||
|
|
||||||
server.on("/get_color1", []() {
|
|
||||||
char rgbcolor[9];
|
|
||||||
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", main_color.white, main_color.red, main_color.green, main_color.blue);
|
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", main_color.white, main_color.red, main_color.green, main_color.blue);
|
||||||
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
|
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
server.send(200, "text/plain", rgbcolor );
|
server.send(200, "text/plain", rgbcolor );
|
||||||
DBG_OUTPUT_PORT.print("/get_color1: ");
|
DBG_OUTPUT_PORT.print("/get_color: ");
|
||||||
DBG_OUTPUT_PORT.println(rgbcolor);
|
DBG_OUTPUT_PORT.println(rgbcolor);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/get_color2", []() {
|
server.on("/get_color2", []() {
|
||||||
char rgbcolor[9];
|
char rgbcolor[10];
|
||||||
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", back_color.white, back_color.red, back_color.green, back_color.blue);
|
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", back_color.white, back_color.red, back_color.green, back_color.blue);
|
||||||
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
|
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
server.send(200, "text/plain", rgbcolor );
|
server.send(200, "text/plain", rgbcolor );
|
||||||
DBG_OUTPUT_PORT.print("/get_color2: ");
|
DBG_OUTPUT_PORT.print("/get_color2: ");
|
||||||
DBG_OUTPUT_PORT.println(rgbcolor);
|
DBG_OUTPUT_PORT.println(rgbcolor);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/get_color3", []() {
|
server.on("/get_color3", []() {
|
||||||
char rgbcolor[9];
|
char rgbcolor[10];
|
||||||
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", xtra_color.white, xtra_color.red, xtra_color.green, xtra_color.blue);
|
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", xtra_color.white, xtra_color.red, xtra_color.green, xtra_color.blue);
|
||||||
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
|
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
server.send(200, "text/plain", rgbcolor );
|
server.send(200, "text/plain", rgbcolor );
|
||||||
DBG_OUTPUT_PORT.print("/get_color3: ");
|
DBG_OUTPUT_PORT.print("/get_color3: ");
|
||||||
DBG_OUTPUT_PORT.println(rgbcolor);
|
DBG_OUTPUT_PORT.println(rgbcolor);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/get_modes", []() {
|
|
||||||
getModesJSON();
|
|
||||||
});
|
|
||||||
|
|
||||||
server.on("/status", []() {
|
server.on("/status", []() {
|
||||||
getStateJSON();
|
getStatusJSON();
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/config", []() {
|
server.on("/config", []() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@@ -197,319 +277,173 @@ server.on("/config", []() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
// ToDo do not save if no change
|
|
||||||
bool _updateStrip = false;
|
bool updateStrip = false;
|
||||||
bool _updateConfig = false;
|
bool updateConf = false;
|
||||||
bool _updateState = false;
|
|
||||||
if(server.hasArg("ws_seg")){
|
|
||||||
uint8_t _ws_seg = server.arg("ws_seg").toInt();
|
|
||||||
_ws_seg = constrain(_ws_seg, 1, MAX_NUM_SEGMENTS - 1);
|
|
||||||
if (_ws_seg != Config.segments){
|
|
||||||
Config.segments = _ws_seg;
|
|
||||||
_updateStrip = true;
|
|
||||||
if (State.segment >= Config.segments) {
|
|
||||||
State.segment = Config.segments - 1;
|
|
||||||
_updateState = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(server.hasArg("ws_cnt")){
|
if(server.hasArg("ws_cnt")){
|
||||||
uint16_t _stripSize = server.arg("ws_cnt").toInt();
|
uint16_t pixelCt = server.arg("ws_cnt").toInt();
|
||||||
if (_stripSize > 0) {
|
if (pixelCt > 0) {
|
||||||
_stripSize = constrain(_stripSize, 1, MAXLEDS);
|
WS2812FXStripSettings.stripSize = constrain(pixelCt, 1, MAXLEDS);
|
||||||
if (_stripSize != Config.stripSize) {
|
updateStrip = true;
|
||||||
Config.stripSize = _stripSize;
|
|
||||||
_updateStrip = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(server.hasArg("ws_rgbo")){
|
if(server.hasArg("ws_rgbo")){
|
||||||
char _ws_rgbo[5];
|
char tmp_rgbOrder[5];
|
||||||
snprintf(_ws_rgbo, sizeof(_ws_rgbo), "%s", server.arg("ws_rgbo").c_str());
|
snprintf(tmp_rgbOrder, sizeof(tmp_rgbOrder), "%s", server.arg("ws_rgbo").c_str());
|
||||||
_ws_rgbo[sizeof(_ws_rgbo) - 1] = 0x00;
|
tmp_rgbOrder[sizeof(tmp_rgbOrder) - 1] = 0x00;
|
||||||
checkRGBOrder(_ws_rgbo);
|
checkRGBOrder(tmp_rgbOrder);
|
||||||
_updateStrip = true;
|
updateStrip = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(USE_WS2812FX_DMA)
|
#if !defined(USE_WS2812FX_DMA)
|
||||||
if(server.hasArg("ws_pin")){
|
if(server.hasArg("ws_pin")){
|
||||||
if (checkPin(server.arg("ws_pin").toInt())) {
|
if (checkPin(server.arg("ws_pin").toInt())) {
|
||||||
_updateStrip = true;
|
updateStrip = true;
|
||||||
DBG_OUTPUT_PORT.print("Pin was set to: ");
|
DBG_OUTPUT_PORT.print("Pin was set to: ");
|
||||||
DBG_OUTPUT_PORT.println(Config.pin);
|
DBG_OUTPUT_PORT.println(WS2812FXStripSettings.pin);
|
||||||
} else {
|
} else {
|
||||||
DBG_OUTPUT_PORT.println("invalid input or same value!");
|
DBG_OUTPUT_PORT.println("invalid input!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(_updateStrip) {
|
if(server.hasArg("ws_fxopt")){
|
||||||
initStrip();
|
WS2812FXStripSettings.fxoptions = ((constrain(server.arg("ws_fxopt").toInt(), 0, 255)>>1)<<1);
|
||||||
|
updateStrip = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updateStrip) {
|
||||||
|
mode = INIT_STRIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(server.hasArg("hostname")){
|
if(server.hasArg("hostname")){
|
||||||
char _hostname[sizeof(HOSTNAME)];
|
snprintf(HOSTNAME, sizeof(HOSTNAME), "%s", server.arg("hostname").c_str());
|
||||||
snprintf(_hostname, sizeof(_hostname), "%s", server.arg("hostname").c_str());
|
HOSTNAME[sizeof(HOSTNAME) - 1] = 0x00;
|
||||||
_hostname[sizeof(_hostname) - 1] = 0x00;
|
updateConf = true;
|
||||||
if (strcmp(HOSTNAME, _hostname) != 0) {
|
|
||||||
strcpy(HOSTNAME, _hostname);
|
|
||||||
_updateConfig = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ENABLE_MQTT)
|
#if defined(ENABLE_MQTT)
|
||||||
if(server.hasArg("mqtt_host")){
|
if(server.hasArg("mqtt_host")){
|
||||||
char _mqtt_host[sizeof(mqtt_host)];
|
snprintf(mqtt_host, sizeof(mqtt_host), "%s", server.arg("mqtt_host").c_str());
|
||||||
snprintf(_mqtt_host, sizeof(_mqtt_host), "%s", server.arg("mqtt_host").c_str());
|
mqtt_host[sizeof(mqtt_host) - 1] = 0x00;
|
||||||
_mqtt_host[sizeof(_mqtt_host) - 1] = 0x00;
|
updateConf = true;
|
||||||
if (strcmp(mqtt_host, _mqtt_host) != 0) {
|
|
||||||
strcpy(mqtt_host, _mqtt_host);
|
|
||||||
_updateConfig = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(server.hasArg("mqtt_port")){
|
if(server.hasArg("mqtt_port")){
|
||||||
uint16_t _mqtt_port = constrain(server.arg("mqtt_port").toInt(), 1, 65535);
|
if ((server.arg("mqtt_port").toInt() >= 0) && (server.arg("mqtt_port").toInt() <=65535)) {
|
||||||
if (_mqtt_port != mqtt_port) {
|
mqtt_port = server.arg("mqttport").toInt();
|
||||||
mqtt_port = _mqtt_port;
|
updateConf = true;
|
||||||
_updateConfig = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(server.hasArg("mqtt_user")){
|
if(server.hasArg("mqtt_user")){
|
||||||
char _mqtt_user[sizeof(mqtt_user)];
|
snprintf(mqtt_user, sizeof(mqtt_user), "%s", server.arg("mqtt_user").c_str());
|
||||||
snprintf(_mqtt_user, sizeof(_mqtt_user), "%s", server.arg("mqtt_user").c_str());
|
mqtt_user[sizeof(mqtt_user) - 1] = 0x00;
|
||||||
_mqtt_user[sizeof(mqtt_user) - 1] = 0x00;
|
updateConf = true;
|
||||||
if (strcmp(mqtt_user, _mqtt_user) != 0) {
|
|
||||||
strcpy(mqtt_user, _mqtt_user);
|
|
||||||
_updateConfig = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(server.hasArg("mqtt_pass")){
|
if(server.hasArg("mqtt_pass")){
|
||||||
char _mqtt_pass[sizeof(mqtt_pass)];
|
snprintf(mqtt_pass, sizeof(mqtt_pass), "%s", server.arg("mqtt_pass").c_str());
|
||||||
snprintf(_mqtt_pass, sizeof(_mqtt_pass), "%s", server.arg("mqtt_pass").c_str());
|
mqtt_pass[sizeof(mqtt_pass) - 1] = 0x00;
|
||||||
_mqtt_pass[sizeof(_mqtt_pass) - 1] = 0x00;
|
updateConf = true;
|
||||||
if (strcmp(mqtt_pass, _mqtt_pass) != 0) {
|
|
||||||
strcpy(mqtt_pass, _mqtt_pass);
|
|
||||||
_updateConfig = true;
|
|
||||||
}
|
}
|
||||||
}
|
if (updateConf) {
|
||||||
if (_updateConfig) {
|
|
||||||
initMqtt();
|
initMqtt();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(server.hasArg("trans_effect")){
|
|
||||||
Config.transEffect = server.arg("trans_effect").toInt();
|
|
||||||
_updateConfig = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(ENABLE_STATE_SAVE)
|
#if defined(ENABLE_STATE_SAVE)
|
||||||
if (_updateStrip || _updateConfig) {
|
if (updateStrip || updateConf) {
|
||||||
if(save_conf.active()) save_conf.detach();
|
if(!settings_save_conf.active()) settings_save_conf.once(3, tickerSaveConfig);
|
||||||
save_conf.once(3, tickerSaveConfig);
|
|
||||||
}
|
|
||||||
if (_updateState) {
|
|
||||||
if(save_state.active()) save_state.detach();
|
|
||||||
save_state.once(3, tickerSaveState);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
_updateStrip = false;
|
updateStrip = false;
|
||||||
_updateConfig = false;
|
updateConf = false;
|
||||||
_updateState = false;
|
|
||||||
getConfigJSON();
|
getConfigJSON();
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/off", []() {
|
server.on("/off", []() {
|
||||||
if (State.mode == OFF) { State.mode = SET; } else { State.mode = OFF; };
|
mode = OFF;
|
||||||
getACK("OK");
|
getStatusJSON();
|
||||||
#if defined(ENABLE_STATE_SAVE)
|
});
|
||||||
if(save_state.active()) save_state.detach();
|
|
||||||
save_state.once(3, tickerSaveState);
|
|
||||||
#endif
|
|
||||||
});
|
|
||||||
|
|
||||||
server.on("/on", []() {
|
server.on("/auto", []() {
|
||||||
if (prevmode == OFF) {
|
mode = AUTO;
|
||||||
State.mode = SET;
|
getArgs();
|
||||||
getACK("OK");
|
getStatusJSON();
|
||||||
#if defined(ENABLE_STATE_SAVE)
|
});
|
||||||
if(save_state.active()) save_state.detach();
|
|
||||||
save_state.once(3, tickerSaveState);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
getACK("NOK");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
server.on("/set", []() {
|
server.on("/all", []() {
|
||||||
prevmode = HOLD;
|
prevmode = HOLD;
|
||||||
boolean _updateState = false;
|
ws2812fx_mode = FX_MODE_STATIC;
|
||||||
boolean _updateSegState = false;
|
mode = SET_ALL;
|
||||||
// Segment
|
getArgs();
|
||||||
if ((server.arg("seg") != "") && (server.arg("seg").toInt() >= 0) && (server.arg("seg").toInt() < Config.segments)) {
|
getStatusJSON();
|
||||||
uint8_t _seg = server.arg("seg").toInt();
|
});
|
||||||
if (prevsegment != _seg) {
|
|
||||||
prevsegment = State.segment;
|
|
||||||
State.segment = _seg;
|
|
||||||
getSegmentParams(State.segment);
|
|
||||||
//memcpy(hexcolors_trans, segState.colors[State.segment], sizeof(hexcolors_trans));
|
|
||||||
State.mode = SET;
|
|
||||||
_updateState = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((server.arg("start") != "") && (server.arg("start").toInt() >= 0) && (server.arg("start").toInt() <= segState.stop)) {
|
|
||||||
uint16_t _seg_start = server.arg("start").toInt();
|
|
||||||
_seg_start = constrain(segState.start, 0, Config.stripSize -1);
|
|
||||||
if (_seg_start != segState.start) {
|
|
||||||
segState.start = _seg_start;
|
|
||||||
setSegmentSize();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((server.arg("stop") != "") && (server.arg("stop").toInt() >= segState.start) && (server.arg("stop").toInt() <= Config.stripSize)) {
|
|
||||||
uint16_t _seg_stop = server.arg("stop").toInt();
|
|
||||||
_seg_stop = constrain(_seg_stop, segState.start, Config.stripSize - 1);
|
|
||||||
if (_seg_stop != segState.stop) {
|
|
||||||
segState.stop = _seg_stop;
|
|
||||||
setSegmentSize();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(server.hasArg("fxopt")){
|
#if defined(ENABLE_LEGACY_ANIMATIONS)
|
||||||
uint8_t _fx_options = ((constrain(server.arg("fxopt").toInt(), 0, 255)>>1)<<1);
|
server.on("/wipe", []() {
|
||||||
if (_fx_options != segState.options) {
|
ws2812fx_mode = FX_MODE_COLOR_WIPE;
|
||||||
segState.options = _fx_options;
|
mode = SET_ALL;
|
||||||
strip->setOptions(State.segment, segState.options);
|
getArgs();
|
||||||
_updateSegState = true;
|
getStatusJSON();
|
||||||
}
|
});
|
||||||
}
|
|
||||||
//color wrgb
|
|
||||||
if (server.arg("rgb") != "") {
|
|
||||||
uint32_t rgb = (uint32_t) strtoul(server.arg("rgb").c_str(), NULL, 16);
|
|
||||||
main_color.white = ((rgb >> 24) & 0xFF);
|
|
||||||
main_color.red = ((rgb >> 16) & 0xFF);
|
|
||||||
main_color.green = ((rgb >> 8) & 0xFF);
|
|
||||||
main_color.blue = ((rgb >> 0) & 0xFF);
|
|
||||||
_updateSegState = true;
|
|
||||||
} else {
|
|
||||||
if ((server.arg("r") != "") && (server.arg("r").toInt() >= 0) && (server.arg("r").toInt() <= 255)) {
|
|
||||||
main_color.red = server.arg("r").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
if ((server.arg("g") != "") && (server.arg("g").toInt() >= 0) && (server.arg("g").toInt() <= 255)) {
|
|
||||||
main_color.green = server.arg("g").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
if ((server.arg("b") != "") && (server.arg("b").toInt() >= 0) && (server.arg("b").toInt() <= 255)) {
|
|
||||||
main_color.blue = server.arg("b").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
if ((server.arg("w") != "") && (server.arg("w").toInt() >= 0) && (server.arg("w").toInt() <= 255)){
|
|
||||||
main_color.white = server.arg("w").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (server.arg("rgb2") != "") {
|
|
||||||
uint32_t rgb2 = (uint32_t) strtoul(server.arg("rgb2").c_str(), NULL, 16);
|
|
||||||
back_color.white = ((rgb2 >> 24) & 0xFF);
|
|
||||||
back_color.red = ((rgb2 >> 16) & 0xFF);
|
|
||||||
back_color.green = ((rgb2 >> 8) & 0xFF);
|
|
||||||
back_color.blue = ((rgb2 >> 0) & 0xFF);
|
|
||||||
_updateSegState = true;
|
|
||||||
} else {
|
|
||||||
if ((server.arg("r2") != "") && (server.arg("r2").toInt() >= 0) && (server.arg("r2").toInt() <= 255)) {
|
|
||||||
back_color.red = server.arg("r2").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
if ((server.arg("g2") != "") && (server.arg("g2").toInt() >= 0) && (server.arg("g2").toInt() <= 255)) {
|
|
||||||
back_color.green = server.arg("g2").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
if ((server.arg("b2") != "") && (server.arg("b2").toInt() >= 0) && (server.arg("b2").toInt() <= 255)) {
|
|
||||||
back_color.blue = server.arg("b2").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
if ((server.arg("w2") != "") && (server.arg("w2").toInt() >= 0) && (server.arg("w2").toInt() <= 255)){
|
|
||||||
back_color.white = server.arg("w2").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (server.arg("rgb3") != "") {
|
|
||||||
uint32_t rgb3 = (uint32_t) strtoul(server.arg("rgb3").c_str(), NULL, 16);
|
|
||||||
xtra_color.white = ((rgb3 >> 24) & 0xFF);
|
|
||||||
xtra_color.red = ((rgb3 >> 16) & 0xFF);
|
|
||||||
xtra_color.green = ((rgb3 >> 8) & 0xFF);
|
|
||||||
xtra_color.blue = ((rgb3 >> 0) & 0xFF);
|
|
||||||
_updateSegState = true;
|
|
||||||
} else {
|
|
||||||
if ((server.arg("r3") != "") && (server.arg("r3").toInt() >= 0) && (server.arg("r3").toInt() <= 255)) {
|
|
||||||
xtra_color.red = server.arg("r3").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
if ((server.arg("g3") != "") && (server.arg("g3").toInt() >= 0) && (server.arg("g3").toInt() <= 255)) {
|
|
||||||
xtra_color.green = server.arg("g3").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
if ((server.arg("b3") != "") && (server.arg("b3").toInt() >= 0) && (server.arg("b3").toInt() <= 255)) {
|
|
||||||
xtra_color.blue = server.arg("b3").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
if ((server.arg("w3") != "") && (server.arg("w3").toInt() >= 0) && (server.arg("w3").toInt() <= 255)){
|
|
||||||
xtra_color.white = server.arg("w3").toInt();
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
main_color.red = constrain(main_color.red, 0, 255);
|
|
||||||
main_color.green = constrain(main_color.green, 0, 255);
|
|
||||||
main_color.blue = constrain(main_color.blue, 0, 255);
|
|
||||||
main_color.white = constrain(main_color.white, 0, 255);
|
|
||||||
back_color.red = constrain(back_color.red, 0, 255);
|
|
||||||
back_color.green = constrain(back_color.green, 0, 255);
|
|
||||||
back_color.blue = constrain(back_color.blue, 0, 255);
|
|
||||||
back_color.white = constrain(back_color.white, 0, 255);
|
|
||||||
xtra_color.red = constrain(xtra_color.red, 0, 255);
|
|
||||||
xtra_color.green = constrain(xtra_color.green, 0, 255);
|
|
||||||
xtra_color.blue = constrain(xtra_color.blue, 0, 255);
|
|
||||||
xtra_color.white = constrain(xtra_color.white, 0, 255);
|
|
||||||
|
|
||||||
|
server.on("/rainbow", []() {
|
||||||
|
ws2812fx_mode = FX_MODE_RAINBOW;
|
||||||
|
mode = SET_ALL;
|
||||||
|
getArgs();
|
||||||
|
getStatusJSON();
|
||||||
|
});
|
||||||
|
|
||||||
// Speed
|
server.on("/rainbowcycle", []() {
|
||||||
if ((server.arg("s") != "") && (server.arg("s").toInt() >= 0) && (server.arg("s").toInt() <= 255)) {
|
ws2812fx_mode = FX_MODE_RAINBOW_CYCLE;
|
||||||
segState.speed[State.segment] = constrain(server.arg("s").toInt(), 0, 255);
|
mode = SET_ALL;
|
||||||
_updateSegState = true;
|
getArgs();
|
||||||
}
|
getStatusJSON();
|
||||||
//Mode
|
});
|
||||||
if ((server.arg("m") != "") && (server.arg("m").toInt() >= 0) && (server.arg("m").toInt() <= strip->getModeCount())) {
|
|
||||||
fx_mode = constrain(server.arg("m").toInt(), 0, strip->getModeCount() - 1);
|
|
||||||
if (fx_mode != segState.mode[State.segment]) {
|
|
||||||
_updateSegState = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Brightness
|
server.on("/theaterchase", []() {
|
||||||
if ((server.arg("c") != "") && (server.arg("c").toInt() >= 0) && (server.arg("c").toInt() <= 100)) {
|
ws2812fx_mode = FX_MODE_THEATER_CHASE;
|
||||||
State.brightness = constrain((int) server.arg("c").toInt() * 2.55, 0, 255);
|
mode = SET_ALL;
|
||||||
} else if ((server.arg("p") != "") && (server.arg("p").toInt() >= 0) && (server.arg("p").toInt() <= 255)) {
|
getArgs();
|
||||||
State.brightness = constrain(server.arg("p").toInt(), 0, 255);
|
getStatusJSON();
|
||||||
}
|
});
|
||||||
if (strip->getBrightness() != State.brightness) {
|
|
||||||
State.mode = SET;
|
|
||||||
_updateState = true;
|
|
||||||
}
|
|
||||||
//DBG_OUTPUT_PORT.printf("Get Args: %s\r\n", listStateJSONfull()); //possibly causing heap problems
|
|
||||||
getACK("OK");
|
|
||||||
|
|
||||||
#if defined(ENABLE_STATE_SAVE)
|
server.on("/twinklerandom", []() {
|
||||||
if (_updateState) {
|
ws2812fx_mode = FX_MODE_TWINKLE_RANDOM;
|
||||||
if(save_state.active()) save_state.detach();
|
mode = SET_ALL;
|
||||||
save_state.once(3, tickerSaveState);
|
getArgs();
|
||||||
}
|
getStatusJSON();
|
||||||
if (_updateSegState) {
|
});
|
||||||
State.mode = SET;
|
|
||||||
if(save_seg_state.active()) save_seg_state.detach();
|
server.on("/theaterchaserainbow", []() {
|
||||||
save_seg_state.once(3, tickerSaveSegmentState);
|
ws2812fx_mode = FX_MODE_THEATER_CHASE_RAINBOW;
|
||||||
}
|
mode = SET_ALL;
|
||||||
#endif
|
getArgs();
|
||||||
_updateState = false;
|
getStatusJSON();
|
||||||
_updateSegState = false;
|
});
|
||||||
});
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_E131)
|
||||||
|
server.on("/e131", []() {
|
||||||
|
mode = E131;
|
||||||
|
getArgs();
|
||||||
|
getStatusJSON();
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_TV)
|
||||||
|
server.on("/tv", []() {
|
||||||
|
mode = TV;
|
||||||
|
getArgs();
|
||||||
|
getStatusJSON();
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
server.on("/get_modes", []() {
|
||||||
|
getModesJSON();
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on("/set_mode", []() {
|
||||||
|
mode = SET_MODE;
|
||||||
|
getArgs();
|
||||||
|
getStatusJSON();
|
||||||
|
});
|
||||||
|
|||||||
@@ -70,9 +70,6 @@ bool handleFileRead(String path) {
|
|||||||
path += ".gz";
|
path += ".gz";
|
||||||
File file = SPIFFS.open(path, "r");
|
File file = SPIFFS.open(path, "r");
|
||||||
server.sendHeader("Access-Control-Allow-Origin", "*");
|
server.sendHeader("Access-Control-Allow-Origin", "*");
|
||||||
server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
|
|
||||||
server.sendHeader("Pragma", "no-cache");
|
|
||||||
server.sendHeader("Expires", "-1");
|
|
||||||
size_t sent = server.streamFile(file, contentType);
|
size_t sent = server.streamFile(file, contentType);
|
||||||
file.close();
|
file.close();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#define SKETCH_VERSION "3.1.1"
|
#define SKETCH_VERSION "2.2.8.RU1.rgbw.3c"
|
||||||
|
|||||||
@@ -165,100 +165,12 @@
|
|||||||
* adressed issue: #31
|
* adressed issue: #31
|
||||||
* adressed issue: #32
|
* adressed issue: #32
|
||||||
*
|
*
|
||||||
* 15 September 2019
|
* 09 Oktober 2019
|
||||||
* Version Bump to 2.2.7.BETA1.rgbw.3colors
|
* Version Bump to 2.2.7 rgbw 3colors
|
||||||
* adressed issue: #25 (added Custom Animation 'Gradient' with number 57)
|
* added output to control external power supply
|
||||||
* adressed issue: #30 (Status 'AUTO' is saved now)
|
|
||||||
* adressed issue: https://github.com/toblum/McLighting/issues/403 (Experimental Support of transitions: set transEffect = true in definitions.h)
|
|
||||||
* corrected use of DMA for Neopixelbus by Makuna (Tests for other strips than SK6812 GRBW were not made)
|
|
||||||
*
|
*
|
||||||
* 27 September 2019
|
* 06 December 2019
|
||||||
* Version Bump to 3.0.0.ALPHA1
|
* Version Bump to 2.2.8 rgbw 3colors
|
||||||
* removed LEGACY_ANIMATIONS
|
|
||||||
* removed old Custom Animations from beginning of list.
|
|
||||||
* added Custom Animation 'AutoPlay' with number 56
|
|
||||||
* added Custom Animation 'Custom WS' with number 57
|
|
||||||
* added Custom Animation 'TV' with number 58
|
|
||||||
* added Custom Animation 'E1.31' with number 59
|
|
||||||
* moved Custom Animation 'Fire2012' to number 60
|
|
||||||
* moved Custom Animation 'Gradients' to number 61
|
|
||||||
* REST-API changes (will be documented soon)
|
|
||||||
*
|
|
||||||
* 29 September 2019
|
|
||||||
* Version Bump to 3.0.0.BETA1
|
|
||||||
* further code changes
|
|
||||||
* bugfixes
|
|
||||||
*
|
|
||||||
* 30 September 2019
|
|
||||||
* Version Bump to 3.1.0.ALPHA1
|
|
||||||
* further code changes
|
|
||||||
* removal of saving to EEPROM
|
|
||||||
* first integration of multi segments
|
|
||||||
*
|
|
||||||
* 3 October 2019
|
|
||||||
* Version Bump to 3.1.0.ALPHA2
|
|
||||||
* further code changes
|
|
||||||
* further integration of multi segments
|
|
||||||
* integration of multi segments to GUI
|
|
||||||
*
|
|
||||||
* 5 October 2019
|
|
||||||
* Version Bump to 3.1.0.ALPHA2
|
|
||||||
* further code changes
|
|
||||||
* further integration of multi segments
|
|
||||||
* known problem: as always: AUTOPLAY (as it is not multi segment capable yet)
|
|
||||||
*
|
|
||||||
* 07 October
|
|
||||||
* Version Bump to 3.1.0.BETA1
|
|
||||||
* bugfixes
|
|
||||||
* adressed issue: #39 uncooment //#define ENABLE_MQTT_INCLUDE_IP in defninitions.h
|
|
||||||
*
|
|
||||||
* 09 October
|
|
||||||
* Version Bump to 3.1.0.BETA2
|
|
||||||
* bugfixes
|
|
||||||
* implemented https://github.com/FabLab-Luenen/McLighting/commit/589806d0fda737011426754a6d84c88535ded688
|
|
||||||
*
|
|
||||||
* 20 October
|
|
||||||
* Version Bump to 3.1.0.BETA3
|
|
||||||
* Bugfixes
|
* Bugfixes
|
||||||
* adressed issue: #39
|
|
||||||
*
|
|
||||||
* 25 October
|
|
||||||
* Version Bump to 3.1.0.BETA4
|
|
||||||
* Bugfixes
|
|
||||||
* Made GUI fully offline compatible (included material icons, etc.)
|
|
||||||
* After Timeout (#define WIFIMGR_PORTAL_TIMEOUT 180) in definitions.h Config Portal is closed and MCL is usable over own AP @192.168.4.1
|
|
||||||
* adressed issue: #48
|
|
||||||
* known problems: E1.31 is only working for one segment at the moment
|
|
||||||
*
|
|
||||||
* 26 October
|
|
||||||
* Version Bump to 3.1.0.BETA5
|
|
||||||
* adressed issue: #44
|
|
||||||
* known problems:
|
|
||||||
* Homeassistant will allways use active segment
|
|
||||||
* E1.31 is only working for one segment at the moment
|
|
||||||
*
|
|
||||||
* 09 December
|
|
||||||
* Version Bump to 3.1.0.BETA6
|
|
||||||
* bugfixes for IR remote control
|
|
||||||
* Implemented segments to IR Remote
|
|
||||||
* Power supply update
|
|
||||||
* bugfix for Button definitions as speed and brightness were interchanged
|
|
||||||
* adressed issue #59
|
* adressed issue #59
|
||||||
* known problems:
|
|
||||||
* Homeassistant will allways use active segment
|
|
||||||
* E1.31 is only working for one segment at the moment
|
|
||||||
*
|
|
||||||
* 27 January 2020
|
|
||||||
* Version Bump to 3.1.0.BETA7
|
|
||||||
* small API changes
|
|
||||||
* work to solve heap problems
|
|
||||||
*
|
|
||||||
* 23 February 2020
|
|
||||||
* Version Bump to 3.1.0
|
|
||||||
* bugfixes
|
|
||||||
* E1.31 is now working for multi segments
|
|
||||||
*
|
|
||||||
* 18 April 2020
|
|
||||||
* Version Bump to 3.1.1
|
|
||||||
* bugfixes regarding issue #80
|
|
||||||
*/
|
*/
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# McLighting v3 - The ESP8266 based multi-client lighting gadget
|
# McLighting v2 - The ESP8266 based multi-client lighting gadget
|
||||||
|
|
||||||
[](https://gitter.im/mclighting/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [](https://travis-ci.com/toblum/McLighting) [](https://opensource.org/licenses/MIT) [](https://github.com/FabLab-Luenen/McLighting/blob/master/Arduino/McLighting/version.h)
|
[](https://gitter.im/mclighting/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [](https://travis-ci.com/toblum/McLighting) [](https://opensource.org/licenses/MIT) [](https://github.com/toblum/McLighting/blob/master/Arduino/McLighting/version.h)
|
||||||
|
|
||||||
McLighting (the multi-client lighting gadget) is a very cheap internet-controllable lighting solution based on the famous ESP8266 microcontroller and WS2811/2812 led strips. It features among other things a web-interface, a REST-API and a websocket connector.
|
McLighting (the multi-client lighting gadget) is a very cheap internet-controllable lighting solution based on the famous ESP8266 microcontroller and WS2811/2812 led strips. It features among other things a web-interface, a REST-API and a websocket connector.
|
||||||
|
|
||||||
@@ -33,23 +33,17 @@ again in out wiki: [Software installation](../../wiki/Software-installation)
|
|||||||
|
|
||||||
This project uses libraries and code by different authors:
|
This project uses libraries and code by different authors:
|
||||||
|
|
||||||
- [WiFiManager](https://github.com/tzapu/WiFiManager) by tzapu (tested with version 0.15.0)
|
- [WiFiManager](https://github.com/tzapu/WiFiManager) by tzapu (tested with version 0.12.0)
|
||||||
|
|
||||||
- [WS2812FX](https://github.com/kitesurfer1404/WS2812FX) by kitesurfer1404 (tested with version 1.2.1)
|
- [WS2812FX](https://github.com/kitesurfer1404/WS2812FX) by kitesurfer1404 (tested with version downloaded 2017-02-05)
|
||||||
|
|
||||||
- [WebSockets](https://github.com/Links2004/arduinoWebSockets) by Links2004 (tested with version 2.2.0)
|
- [WebSockets](https://github.com/Links2004/arduinoWebSockets) by Links2004 (tested with version 2.0.6)
|
||||||
|
|
||||||
- [Adafruit NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) by adafruit (tested with 1.4.0)
|
- [Adafruit NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) by adafruit (tested with 1.1.2)
|
||||||
|
|
||||||
- Optional: [PubSubClient](https://github.com/knolleary/pubsubclient/) by knolleary (tested with 2.8.0)
|
- Optional: [PubSubClient](https://github.com/knolleary/pubsubclient/) by knolleary (tested with 2.6.0)
|
||||||
_Only when you have activated MQTT in definitions.h._
|
_Only when you have activated MQTT in definitions.h._
|
||||||
|
|
||||||
- Optional: [Brzo I2C](https://github.com/pasko-zh/brzo_i2c/) by pazko-zh (tested with 1.3.3)
|
|
||||||
_Only when you have activated GY33 in definitions.h._
|
|
||||||
|
|
||||||
- Optional: [FastLed](https://github.com/FastLED/FastLED/) by FastLED (tested with 3.3.3)
|
|
||||||
_Only when you have activated custom animations (Fire2012) in definitions.h._
|
|
||||||
|
|
||||||
The sketch also uses the following built-in library:
|
The sketch also uses the following built-in library:
|
||||||
- Ticker by [@igrr](https://github.com/igrr)
|
- Ticker by [@igrr](https://github.com/igrr)
|
||||||
|
|
||||||
@@ -66,29 +60,21 @@ I hope I didn't miss any sources and mentioned every author. In case I forgot so
|
|||||||
|
|
||||||
|
|
||||||
## Todos
|
## Todos
|
||||||
- [x] Redesign of Code and bump to V3
|
- [ ] Support multiple strips and control them separately or together [Issue](https://github.com/toblum/McLighting/issues/118)
|
||||||
|
- [ ] Remove old / wrong EEPROM settings completely [Issue]
|
||||||
- [ ] Customer profile to define segments of (in)active areas on the strip [Issue](https://github.com/toblum/McLighting/issues/37)
|
- [ ] Customer profile to define segments of (in)active areas on the strip [Issue](https://github.com/toblum/McLighting/issues/37)
|
||||||
- [ ] Additional clients
|
- [ ] Additional clients
|
||||||
- [x] If no wifi, at least enable button mode.
|
- [ ] If no wifi, at least enable button mode.
|
||||||
- [x] Also enable McLighting in Wifi AP mode.
|
- [ ] Also enable McLighting in Wifi AP mode.
|
||||||
- [ ] Search a non-blocking alternative for wifiManager
|
- [ ] Search an non blocking alternative for WifiManager
|
||||||
- [ ] Multiple buttons/GPIO Inputs. [Issue](https://github.com/toblum/McLighting/issues/119)
|
- [ ] Multiple buttons/GPIO Inputs. [Issue](https://github.com/toblum/McLighting/issues/119)
|
||||||
- [ ] Music visualizer / Bring back ArtNet [Issue](https://github.com/toblum/McLighting/issues/111)
|
- [ ] Music visualizer / Bring back ArtNet [Issue](https://github.com/toblum/McLighting/issues/111)
|
||||||
- [ ] Display version and parameters (Number of LEDs, definition settings, ..) in the web UI [Issue](https://github.com/toblum/McLighting/issues/150)
|
- [ ] Display version and parameters (Number of LEDs, definition settings, ..) in the web UI [Issue](https://github.com/toblum/McLighting/issues/150)
|
||||||
- [x] Remove old / wrong EEPROM settings completely [Issue] EEPROM saving discarded
|
- [x] Make number of pixels, MQTT and PIN configurable via front end [Issue](https://github.com/toblum/McLighting/issues/93) and [Issue](https://github.com/toblum/McLighting/issues/93)
|
||||||
- [x] Support multiple strips and control them separately or together [Issue](https://github.com/toblum/McLighting/issues/118)
|
|
||||||
- [x] Support for up to ten segments
|
|
||||||
- [x] Removal of LEGACY_ANIMATIONS
|
|
||||||
- [x] Include ws2812fx library to code due to modifications in library
|
|
||||||
- [x] Add TV, E1.31 and AUTO to CUSTOM_WS2812FX_ANIMATIONS
|
|
||||||
- [x] Save status: Added saving of status 'AUTO'. [Issue](https://github.com/FabLab-Luenen/McLighting/issues/30)
|
|
||||||
- [x] EXPERIMENTAL: Added transition feature on changing values of color brightness and speed. ATTENTION! Does not work properly for all WS2812fx effects. Can be set via UI or REST-API.
|
|
||||||
- [x] Added Custom Animation 'Gradient': [Issue](https://github.com/FabLab-Luenen/McLighting/issues/25)
|
|
||||||
- [x] Make number of pixels, MQTT and PIN configurable via front end [Issue](https://github.com/toblum/McLighting/issues/93) and [Issue](https://github.com/toblum/McLighting/issues/101)
|
|
||||||
- [x] Bundle webpages instead of SPIFFS [Issue](https://github.com/toblum/McLighting/issues/93)
|
- [x] Bundle webpages instead of SPIFFS [Issue](https://github.com/toblum/McLighting/issues/93)
|
||||||
- [x] IR remote support [issue](https://github.com/toblum/McLightingUI/issues/3)
|
- [x] IR remote support [issue](https://github.com/toblum/McLightingUI/issues/3)
|
||||||
- [x] MQTT support
|
- [x] MQTT support
|
||||||
- [x] Save favourite effects? [Issue](https://github.com/toblum/McLighting/issues/35)
|
- [x] Save favourite effects? [Issue](https://github.com/toblum/McLighting/issues/35)(https://github.com/toblum/McLighting/issues/101)
|
||||||
- [x] OTA update [Issue](https://github.com/toblum/McLighting/issues/92)
|
- [x] OTA update [Issue](https://github.com/toblum/McLighting/issues/92)
|
||||||
- [x] Fix issue with websockets connection problems
|
- [x] Fix issue with websockets connection problems
|
||||||
- [x] Switch to the [NeoPixelBus library](https://github.com/Makuna/NeoPixelBus/wiki)
|
- [x] Switch to the [NeoPixelBus library](https://github.com/Makuna/NeoPixelBus/wiki)
|
||||||
|
|||||||
@@ -64,12 +64,7 @@ light:
|
|||||||
- "Bicolor Chase"
|
- "Bicolor Chase"
|
||||||
- "Tricolor Chase"
|
- "Tricolor Chase"
|
||||||
- "ICU"
|
- "ICU"
|
||||||
- "AutoPlay"
|
- "E131"
|
||||||
- "Custom WS"
|
|
||||||
- "TV"
|
|
||||||
- "E1.31"
|
|
||||||
- "Fire(2012)"
|
|
||||||
- "Gradient"
|
|
||||||
brightness: true
|
brightness: true
|
||||||
color_temp: true
|
color_temp: true
|
||||||
rgb: true
|
rgb: true
|
||||||
|
|||||||
@@ -16,18 +16,18 @@
|
|||||||
|
|
||||||
"switch": {
|
"switch": {
|
||||||
"status": "http://<ESP_HOST>/get_switch",
|
"status": "http://<ESP_HOST>/get_switch",
|
||||||
"powerOn": "http://<ESP_HOST>/on",
|
"powerOn": "http://<ESP_HOST>/all?r=255&g=255&b=255",
|
||||||
"powerOff": "http://<ESP_HOST>/off"
|
"powerOff": "http://<ESP_HOST>/off"
|
||||||
},
|
},
|
||||||
|
|
||||||
"brightness": {
|
"brightness": {
|
||||||
"status": "http://<ESP_HOST>/get_brightness",
|
"status": "http://<ESP_HOST>/get_brightness",
|
||||||
"url": "http://<ESP_HOST>/set?c=%s"
|
"url": "http://<ESP_HOST>/set_brightness?c=%s"
|
||||||
},
|
},
|
||||||
|
|
||||||
"color": {
|
"color": {
|
||||||
"status": "http://<ESP_HOST>/get_color",
|
"status": "http://<ESP_HOST>/get_color",
|
||||||
"url": "http://<ESP_HOST>/set?m=0?rgb=00%s",
|
"url": "http://<ESP_HOST>/all?rgb=%s",
|
||||||
"brightness": true
|
"brightness": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,9 +182,7 @@
|
|||||||
var mkfile = document.createElement("button");
|
var mkfile = document.createElement("button");
|
||||||
mkfile.innerHTML = 'MkFile';
|
mkfile.innerHTML = 'MkFile';
|
||||||
document.getElementById(element).appendChild(mkfile);
|
document.getElementById(element).appendChild(mkfile);
|
||||||
var para = document.createElement("text");
|
|
||||||
para.innerHTML = " Press Ctrl-S for save, Ctrl-Z for undo, Ctrl-Shift-Z for redo";
|
|
||||||
document.getElementById(element).appendChild(para);
|
|
||||||
function httpPostProcessRequest(){
|
function httpPostProcessRequest(){
|
||||||
if (xmlHttp.readyState == 4){
|
if (xmlHttp.readyState == 4){
|
||||||
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
|
||||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,4 @@
|
|||||||
|
## Retired, use:
|
||||||
|
McLightingHTML from https://github.com/FabLab-Luenen/McLightingHTML
|
||||||
|
|
||||||
|
or set #define USE_HTML_MIN_GZ in definitions.h to use the integrated!
|
||||||
@@ -0,0 +1,491 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!--Import Google Icon Font-->
|
||||||
|
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
<!--Import materialize.css-->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css" media="screen,projection" />
|
||||||
|
|
||||||
|
<!--Let browser know website is optimized for mobile-->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<title>McLighting (RGBW) v2</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<nav class="blue light-blueXXX lighten-1XXX" role="navigation" id="mc-nav">
|
||||||
|
<div class="nav-wrapper container">
|
||||||
|
<a id="logo-container" href="#" class="brand-logo">McLighting (RGBW) v2</a>
|
||||||
|
|
||||||
|
<ul class="right hide-on-med-and-down">
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul id="nav-mobile" class="side-nav">
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
|
||||||
|
</ul>
|
||||||
|
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container mc_pane" id="pane0">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row" id="mc-wsloader">
|
||||||
|
<div class="col">
|
||||||
|
<div class="preloader-wrapper active">
|
||||||
|
<div class="spinner-layer spinner-blue-only">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row hide" id="mc-wserror">
|
||||||
|
<div class="col">
|
||||||
|
<div>Error on websocket connect.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mc_pane hide" id="pane1">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div style="height: 330px; width: 330px;">
|
||||||
|
<canvas id="myCanvas" width="330" height="330" style="-webkit-user-select: none;-webkit-tap-highlight-color: rgba(0,0,0,0);-moz-user-select:none;"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div class="card-panel" id="status">
|
||||||
|
<div id="status_pos">pick a color</div>
|
||||||
|
<div id="status_color"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div class="right switch">Auto:<br>
|
||||||
|
<label>Off
|
||||||
|
<input id="autoSwitch" type="checkbox"><span class="lever"></span>On
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mc_pane hide" id="pane2">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<form class="col s12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_red">Red</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_red" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_green">Green</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_green" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_blue">Blue</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_blue" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<label for="txt_white">White</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_white" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<label for="txt_delay">Speed</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_delay" min="0" max="255" value="196" class="update_delay" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<label for="txt_delay">Brightness</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_brightness" min="0" max="255" value="196" class="update_brightness" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div id="modes">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
Loading animations...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="page-footer blue">
|
||||||
|
<div class="footer-copyright">
|
||||||
|
<div class="container">© 2017
|
||||||
|
<a class="grey-text text-lighten-4 right" href="https://github.com/toblum/McLighting">Project home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
.btn_grid {
|
||||||
|
margin: 7px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!--Import jQuery before materialize.js-->
|
||||||
|
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
|
||||||
|
<script type="text/javascript">(function($){
|
||||||
|
$(function(){
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
var host = window.location.hostname;
|
||||||
|
//host = "esp8266_02.local";
|
||||||
|
|
||||||
|
var ws_url = 'ws://' + host + ':81';
|
||||||
|
var connection;
|
||||||
|
var ws_waiting = 0;
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Side navigation
|
||||||
|
// ******************************************************************
|
||||||
|
$('.button-collapse').sideNav();
|
||||||
|
|
||||||
|
// Navlinks
|
||||||
|
$('#mc-nav').on('click', '.mc-navlink', function(){
|
||||||
|
console.log("Navigate to pane: ", $(this).data("pane"));
|
||||||
|
showPane($(this).data("pane"));
|
||||||
|
});
|
||||||
|
|
||||||
|
function showPane(pane) {
|
||||||
|
$('.mc_pane').addClass('hide');
|
||||||
|
$('#' + pane).removeClass('hide');
|
||||||
|
$('.button-collapse').sideNav('hide');
|
||||||
|
|
||||||
|
//if (pane == "pane2") {
|
||||||
|
// setMainColor();
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// init()
|
||||||
|
// ******************************************************************
|
||||||
|
function init() {
|
||||||
|
console.log("Connection websockets to:", ws_url);
|
||||||
|
connection = new WebSocket(ws_url, ['arduino']);
|
||||||
|
var mode = 0;
|
||||||
|
var ws2812fx_mode = 0;
|
||||||
|
$.getJSON("http://" + host + "/status", function(data) {
|
||||||
|
console.log("status", data);
|
||||||
|
mode = data.mode;
|
||||||
|
if (mode == "1") {
|
||||||
|
// set autoswitch $("#autoSwitch").val('checked');
|
||||||
|
}
|
||||||
|
ws2812fx_mode = data.ws2812fx_mode;
|
||||||
|
$("#rng_delay").val(data.speed);
|
||||||
|
$("#rng_brightness").val(data.brightness);
|
||||||
|
$("#rng_white").val(data.color[0]);
|
||||||
|
$("#rng_red").val(data.color[1]);
|
||||||
|
$("#rng_green").val(data.color[2]);
|
||||||
|
$("#rng_blue").val(data.color[3]);
|
||||||
|
var statusColor = "#" + componentToHex(data.color[1]) + componentToHex(data.color[2]) + componentToHex(data.color[3]);
|
||||||
|
$('#status').css("backgroundColor", statusColor);
|
||||||
|
$('#status_color').text(statusColor + "- R=" + data.color[1] + ", G=" + data.color[2] + ", B=" + data.color[3]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load modes async
|
||||||
|
// List of all color modes
|
||||||
|
// enum MODE {OFF, AUTO, TV, E131, SET_MODE, HOLD, CUSTOM, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW};
|
||||||
|
$.getJSON("http://" + host + "/get_modes", function(data) {
|
||||||
|
console.log("modes", data);
|
||||||
|
var modes_html = "";
|
||||||
|
data.forEach(function(current_mode){
|
||||||
|
if (current_mode.mode !== undefined) {
|
||||||
|
modes_html += '<div class="col s12 m6 l6 btn_grid">';
|
||||||
|
if ((mode == "5" && current_mode.mode == ws2812fx_mode) || (mode == "0" && current_mode.mode == "off") || (mode == "2" && current_mode.mode == "tv") || (mode == "3" && current_mode.mode == "e131")){
|
||||||
|
modes_html += '<a class="btn waves-effect waves-light btn_mode red" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||||
|
} else {
|
||||||
|
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||||
|
}
|
||||||
|
modes_html += '<i class="material-icons right">send</i>';
|
||||||
|
modes_html += '</a>';
|
||||||
|
modes_html += '</div>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#modes').html(modes_html);
|
||||||
|
});
|
||||||
|
// When the connection is open, send some data to the server
|
||||||
|
connection.onopen = function () {
|
||||||
|
//connection.send('Ping'); // Send the message 'Ping' to the server
|
||||||
|
console.log('WebSocket Open');
|
||||||
|
showPane('pane1');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log errors
|
||||||
|
connection.onerror = function (error) {
|
||||||
|
console.log('WebSocket Error ' + error);
|
||||||
|
$('#mc-wsloader').addClass('hide');
|
||||||
|
$('#mc-wserror').removeClass('hide');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log messages from the server
|
||||||
|
connection.onmessage = function (e) {
|
||||||
|
console.log('WebSocket from server: ' + e.data);
|
||||||
|
ws_waiting = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Modes
|
||||||
|
// ******************************************************************
|
||||||
|
$("#pane2").on("click", ".btn_mode", function() {
|
||||||
|
var mode = $(this).attr("data-mode");
|
||||||
|
last_mode = mode;
|
||||||
|
var btn = $(this);
|
||||||
|
setMode(mode, function() {
|
||||||
|
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
|
||||||
|
btn.removeClass("blue").addClass("red");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("click", ".btn_mode_static", function() {
|
||||||
|
var mode = $(this).attr("data-mode");
|
||||||
|
var btn = $(this);
|
||||||
|
|
||||||
|
wsSendCommand("=" + mode);
|
||||||
|
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
|
||||||
|
btn.removeClass("blue").addClass("red");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_colors", setMainColor);
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_delay", function() {
|
||||||
|
var delay = $("#rng_delay").val();
|
||||||
|
|
||||||
|
wsSendCommand("?" + delay);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_brightness", function() {
|
||||||
|
var brightness = $("#rng_brightness").val();
|
||||||
|
|
||||||
|
wsSendCommand("%" + brightness);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#autoSwitch").on("change", function () {
|
||||||
|
if ($(this).prop('checked')) {
|
||||||
|
wsSendCommand("start");
|
||||||
|
} else {
|
||||||
|
wsSendCommand("stop");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function setMode(mode, finish_funtion) {
|
||||||
|
console.log("Mode: ", mode);
|
||||||
|
|
||||||
|
wsSendCommand("/" + mode);
|
||||||
|
finish_funtion();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMainColor() {
|
||||||
|
var white = $("#rng_white").val();
|
||||||
|
var red = $("#rng_red").val();
|
||||||
|
var green = $("#rng_green").val();
|
||||||
|
var blue = $("#rng_blue").val();
|
||||||
|
|
||||||
|
var hexColor = componentToHex(white) + componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||||
|
var statusColor = "#" + componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||||
|
wsSetMainColor(hexColor);
|
||||||
|
$('#status').css("backgroundColor", statusColor);
|
||||||
|
$('#status_color').text(statusColor + "- R=" + red + ", G=" + green + ", B=" + blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// WebSocket commands
|
||||||
|
// ******************************************************************
|
||||||
|
function wsSendCommand(cmd) {
|
||||||
|
console.log("Send WebSocket command:", cmd);
|
||||||
|
if (ws_waiting == 0) {
|
||||||
|
connection.send(cmd);
|
||||||
|
ws_waiting++;
|
||||||
|
} else {
|
||||||
|
console.log("++++++++ WS call waiting, skip")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function wsSetAll(hexColor) {
|
||||||
|
console.log("wsSetAll() Set all colors to:", hexColor);
|
||||||
|
wsSendCommand("*" + hexColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
function wsSetMainColor(hexColor) {
|
||||||
|
console.log("wsSetMainColor() Set main colors to:", hexColor);
|
||||||
|
wsSendCommand("#" + hexColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Colorwheel
|
||||||
|
// ******************************************************************
|
||||||
|
// this is supposed to work on mobiles (touch) as well as on a desktop (click)
|
||||||
|
// since we couldn't find a decent one .. this try of writing one by myself
|
||||||
|
// + google. swiping would be really nice - I will possibly implement it with
|
||||||
|
// jquery later - or never.
|
||||||
|
|
||||||
|
var canvas = document.getElementById("myCanvas");
|
||||||
|
// FIX: Cancel touch end event and handle click via touchstart
|
||||||
|
// canvas.addEventListener("touchend", function(e) { e.preventDefault(); }, false);
|
||||||
|
canvas.addEventListener("touchmove", doTouch, false);
|
||||||
|
canvas.addEventListener("click", doClick, false);
|
||||||
|
//canvas.addEventListener("mousemove", doClick, false);
|
||||||
|
|
||||||
|
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
var centerX = canvas.width / 2;
|
||||||
|
var centerY = canvas.height / 2;
|
||||||
|
var innerRadius = canvas.width / 4.5;
|
||||||
|
var outerRadius = (canvas.width - 10) / 2
|
||||||
|
|
||||||
|
//outer border
|
||||||
|
context.beginPath();
|
||||||
|
//outer circle
|
||||||
|
context.arc(centerX, centerY, outerRadius, 0, 2 * Math.PI, false);
|
||||||
|
//draw the outer border: (gets drawn around the circle!)
|
||||||
|
context.lineWidth = 4;
|
||||||
|
context.strokeStyle = '#000000';
|
||||||
|
context.stroke();
|
||||||
|
context.closePath();
|
||||||
|
|
||||||
|
//fill with beautiful colors
|
||||||
|
//taken from here: http://stackoverflow.com/questions/18265804/building-a-color-wheel-in-html5
|
||||||
|
for(var angle=0; angle<=360; angle+=1) {
|
||||||
|
var startAngle = (angle-2)*Math.PI/180;
|
||||||
|
var endAngle = angle * Math.PI/180;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(centerX, centerY);
|
||||||
|
context.arc(centerX, centerY, outerRadius, startAngle, endAngle, false);
|
||||||
|
context.closePath();
|
||||||
|
context.fillStyle = 'hsl('+angle+', 100%, 50%)';
|
||||||
|
context.fill();
|
||||||
|
context.closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
//inner border
|
||||||
|
context.beginPath();
|
||||||
|
//context.arc(centerX, centerY, radius, startAngle, endAngle, counterClockwise);
|
||||||
|
context.arc(centerX, centerY, innerRadius, 0, 2 * Math.PI, false);
|
||||||
|
//fill the center
|
||||||
|
var my_gradient=context.createLinearGradient(0,0,170,0);
|
||||||
|
my_gradient.addColorStop(0,"black");
|
||||||
|
my_gradient.addColorStop(1,"white");
|
||||||
|
|
||||||
|
context.fillStyle = my_gradient;
|
||||||
|
context.fillStyle = "white";
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
//draw the inner line
|
||||||
|
context.lineWidth = 2;
|
||||||
|
context.strokeStyle = '#000000';
|
||||||
|
context.stroke();
|
||||||
|
context.closePath();
|
||||||
|
|
||||||
|
//get Mouse x/y canvas position
|
||||||
|
function getMousePos(canvas, evt) {
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: evt.clientX - rect.left,
|
||||||
|
y: evt.clientY - rect.top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//comp to Hex
|
||||||
|
function componentToHex(c) {
|
||||||
|
//var hex = c.toString(16);
|
||||||
|
//return hex.length == 1 ? "0" + hex : hex;
|
||||||
|
return ("0"+(Number(c).toString(16))).slice(-2).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
//rgb/rgba to Hex
|
||||||
|
function rgbToHex(rgb) {
|
||||||
|
return componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//display the touch/click position and color info
|
||||||
|
function updateStatus(pos, color) {
|
||||||
|
//var hexColor = rgbToHex(color);
|
||||||
|
//wsSetAll(hexColor);
|
||||||
|
var hexColor = componentToHex(color[0]) + componentToHex(color[1]) + componentToHex(color[2]);
|
||||||
|
wsSetMainColor(hexColor);
|
||||||
|
hexColor = "#" + hexColor;
|
||||||
|
|
||||||
|
$('#status').css("backgroundColor", hexColor);
|
||||||
|
$('#status_color').text(hexColor + " - R=" + color[0] + ", G=" + color[1] + ", B=" + color[2]);
|
||||||
|
$('#status_pos').text("x: " + pos.x + " - y: " + pos.y);
|
||||||
|
|
||||||
|
$("#rng_white").val(0);
|
||||||
|
$("#rng_red").val(color[0]);
|
||||||
|
$("#rng_green").val(color[1]);
|
||||||
|
$("#rng_blue").val(color[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//handle the touch event
|
||||||
|
function doTouch(event) {
|
||||||
|
//to not also fire on click
|
||||||
|
event.preventDefault();
|
||||||
|
var el = event.target;
|
||||||
|
|
||||||
|
//touch position
|
||||||
|
var pos = {x: Math.round(event.targetTouches[0].pageX - el.offsetLeft),
|
||||||
|
y: Math.round(event.targetTouches[0].pageY - el.offsetTop)};
|
||||||
|
//color
|
||||||
|
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
|
||||||
|
|
||||||
|
updateStatus(pos, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doClick(event) {
|
||||||
|
//click position
|
||||||
|
var pos = getMousePos(canvas, event);
|
||||||
|
//color
|
||||||
|
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
|
||||||
|
|
||||||
|
//console.log("click", pos.x, pos.y, color);
|
||||||
|
updateStatus(pos, color);
|
||||||
|
|
||||||
|
//now do sth with the color rgbToHex(color);
|
||||||
|
//don't do stuff when #000000 (outside circle and lines
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// main
|
||||||
|
// ******************************************************************
|
||||||
|
init();
|
||||||
|
|
||||||
|
}); // end of document ready
|
||||||
|
})(jQuery); // end of jQuery name space</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
var gulp = require('gulp'),
|
||||||
|
request = require('request'),
|
||||||
|
fs = require('fs'),
|
||||||
|
connect = require('gulp-connect'),
|
||||||
|
fileinclude = require('gulp-file-include');
|
||||||
|
|
||||||
|
var src_dir = "src/";
|
||||||
|
var build_dir = "build/";
|
||||||
|
|
||||||
|
|
||||||
|
gulp.task('html', function() {
|
||||||
|
gulp.src(src_dir + '*.htm')
|
||||||
|
.pipe(fileinclude({
|
||||||
|
prefix: '@@',
|
||||||
|
basepath: '@file'
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest('build'))
|
||||||
|
.pipe(connect.reload());
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
gulp.task('connect', function() {
|
||||||
|
connect.server({
|
||||||
|
root: 'build',
|
||||||
|
livereload: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('watch', function() {
|
||||||
|
gulp.watch(src_dir + '*.htm', ['html']);
|
||||||
|
gulp.watch(src_dir + 'js/*.js', ['html']);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
gulp.task('upload', ['html'], function() {
|
||||||
|
var url = 'http://192.168.0.49/edit';
|
||||||
|
var options = {
|
||||||
|
url: url,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var r = request.post(options, function optionalCallback(err, httpResponse, body) {
|
||||||
|
if (err) {
|
||||||
|
return console.error('upload failed:', err);
|
||||||
|
}
|
||||||
|
console.log('Upload successful! Server responded with:', body);
|
||||||
|
});
|
||||||
|
var form = r.form();
|
||||||
|
form.append('data', fs.createReadStream(__dirname + "/" + build_dir + '/index.htm'), {filename: '/index.htm', contentType: "application/octet-stream"});
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('default', ['html']);
|
||||||
|
gulp.task('serve', ['watch', 'connect']);
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "mc_lighting",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"description": "Web client for Mc Lighting",
|
||||||
|
"main": "index.html",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Tobias Blum",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fs": "0.0.2",
|
||||||
|
"gulp": "^3.9.1",
|
||||||
|
"gulp-connect": "^5.0.0",
|
||||||
|
"gulp-file-include": "^1.0.0",
|
||||||
|
"request": "^2.72.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!--Import Google Icon Font-->
|
||||||
|
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
<!--Import materialize.css-->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css" media="screen,projection" />
|
||||||
|
|
||||||
|
<!--Let browser know website is optimized for mobile-->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<title>McLighting (RGBW) v2</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<nav class="blue light-blueXXX lighten-1XXX" role="navigation" id="mc-nav">
|
||||||
|
<div class="nav-wrapper container">
|
||||||
|
<a id="logo-container" href="#" class="brand-logo">McLighting (RGBW) v2</a>
|
||||||
|
|
||||||
|
<ul class="right hide-on-med-and-down">
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul id="nav-mobile" class="side-nav">
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
|
||||||
|
</ul>
|
||||||
|
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container mc_pane" id="pane0">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row" id="mc-wsloader">
|
||||||
|
<div class="col">
|
||||||
|
<div class="preloader-wrapper active">
|
||||||
|
<div class="spinner-layer spinner-blue-only">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row hide" id="mc-wserror">
|
||||||
|
<div class="col">
|
||||||
|
<div>Error on websocket connect.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mc_pane hide" id="pane1">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div style="height: 330px; width: 330px;">
|
||||||
|
<canvas id="myCanvas" width="330" height="330" style="-webkit-user-select: none;-webkit-tap-highlight-color: rgba(0,0,0,0);-moz-user-select:none;"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div class="card-panel" id="status">
|
||||||
|
<div id="status_pos">pick a color</div>
|
||||||
|
<div id="status_color"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div class="right switch">Auto:<br>
|
||||||
|
<label>Off
|
||||||
|
<input id="autoSwitch" type="checkbox"><span class="lever"></span>On
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mc_pane hide" id="pane2">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<form class="col s12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_red">Red</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_red" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_green">Green</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_green" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_blue">Blue</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_blue" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<label for="txt_white">White</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_white" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<label for="txt_delay">Speed</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_delay" min="0" max="255" value="196" class="update_delay" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<label for="txt_delay">Brightness</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_brightness" min="0" max="255" value="196" class="update_brightness" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div id="modes">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
Loading animations...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="page-footer blue">
|
||||||
|
<div class="footer-copyright">
|
||||||
|
<div class="container">© 2017
|
||||||
|
<a class="grey-text text-lighten-4 right" href="https://github.com/toblum/McLighting">Project home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
.btn_grid {
|
||||||
|
margin: 7px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!--Import jQuery before materialize.js-->
|
||||||
|
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
|
||||||
|
<script type="text/javascript">@@include('js/script.js')</script>
|
||||||
|
</body>
|
||||||
|
\ No newline at end of file
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,331 @@
|
|||||||
|
(function($){
|
||||||
|
$(function(){
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
var host = window.location.hostname;
|
||||||
|
//host = "esp8266_02.local";
|
||||||
|
|
||||||
|
var ws_url = 'ws://' + host + ':81';
|
||||||
|
var connection;
|
||||||
|
var ws_waiting = 0;
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Side navigation
|
||||||
|
// ******************************************************************
|
||||||
|
$('.button-collapse').sideNav();
|
||||||
|
|
||||||
|
// Navlinks
|
||||||
|
$('#mc-nav').on('click', '.mc-navlink', function(){
|
||||||
|
console.log("Navigate to pane: ", $(this).data("pane"));
|
||||||
|
showPane($(this).data("pane"));
|
||||||
|
});
|
||||||
|
|
||||||
|
function showPane(pane) {
|
||||||
|
$('.mc_pane').addClass('hide');
|
||||||
|
$('#' + pane).removeClass('hide');
|
||||||
|
$('.button-collapse').sideNav('hide');
|
||||||
|
|
||||||
|
//if (pane == "pane2") {
|
||||||
|
// setMainColor();
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// init()
|
||||||
|
// ******************************************************************
|
||||||
|
function init() {
|
||||||
|
console.log("Connection websockets to:", ws_url);
|
||||||
|
connection = new WebSocket(ws_url, ['arduino']);
|
||||||
|
var mode = 0;
|
||||||
|
var ws2812fx_mode = 0;
|
||||||
|
$.getJSON("http://" + host + "/status", function(data) {
|
||||||
|
console.log("status", data);
|
||||||
|
mode = data.mode;
|
||||||
|
ws2812fx_mode = data.ws2812fx_mode;
|
||||||
|
$("#rng_delay").val(data.speed);
|
||||||
|
$("#rng_brightness").val(data.brightness);
|
||||||
|
$("#rng_white").val(data.color[0]);
|
||||||
|
$("#rng_red").val(data.color[1]);
|
||||||
|
$("#rng_green").val(data.color[2]);
|
||||||
|
$("#rng_blue").val(data.color[3]);
|
||||||
|
var statusColor = "#" + componentToHex(data.color[1]) + componentToHex(data.color[2]) + componentToHex(data.color[3]);
|
||||||
|
$('#status').css("backgroundColor", statusColor);
|
||||||
|
$('#status_color').text(statusColor + "- R=" + data.color[1] + ", G=" + data.color[2] + ", B=" + data.color[3]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load modes async
|
||||||
|
// List of all color modes
|
||||||
|
// enum MODE {OFF, AUTO, TV, E131, SET_MODE, HOLD, CUSTOM, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW};
|
||||||
|
$.getJSON("http://" + host + "/get_modes", function(data) {
|
||||||
|
console.log("modes", data);
|
||||||
|
var modes_html = "";
|
||||||
|
data.forEach(function(current_mode){
|
||||||
|
if (current_mode.mode !== undefined) {
|
||||||
|
modes_html += '<div class="col s12 m6 l6 btn_grid">';
|
||||||
|
if ((mode == "5" && current_mode.mode == ws2812fx_mode) || (mode == "0" && current_mode.mode == "off") || (mode == "2" && current_mode.mode == "tv") || (mode == "3" && current_mode.mode == "e131")){
|
||||||
|
modes_html += '<a class="btn waves-effect waves-light btn_mode red" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||||
|
} else {
|
||||||
|
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||||
|
}
|
||||||
|
modes_html += '<i class="material-icons right">send</i>';
|
||||||
|
modes_html += '</a>';
|
||||||
|
modes_html += '</div>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#modes').html(modes_html);
|
||||||
|
});
|
||||||
|
// When the connection is open, send some data to the server
|
||||||
|
connection.onopen = function () {
|
||||||
|
//connection.send('Ping'); // Send the message 'Ping' to the server
|
||||||
|
console.log('WebSocket Open');
|
||||||
|
showPane('pane1');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log errors
|
||||||
|
connection.onerror = function (error) {
|
||||||
|
console.log('WebSocket Error ' + error);
|
||||||
|
$('#mc-wsloader').addClass('hide');
|
||||||
|
$('#mc-wserror').removeClass('hide');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log messages from the server
|
||||||
|
connection.onmessage = function (e) {
|
||||||
|
console.log('WebSocket from server: ' + e.data);
|
||||||
|
ws_waiting = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Modes
|
||||||
|
// ******************************************************************
|
||||||
|
$("#pane2").on("click", ".btn_mode", function() {
|
||||||
|
var mode = $(this).attr("data-mode");
|
||||||
|
last_mode = mode;
|
||||||
|
var btn = $(this);
|
||||||
|
setMode(mode, function() {
|
||||||
|
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
|
||||||
|
btn.removeClass("blue").addClass("red");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("click", ".btn_mode_static", function() {
|
||||||
|
var mode = $(this).attr("data-mode");
|
||||||
|
var btn = $(this);
|
||||||
|
|
||||||
|
wsSendCommand("=" + mode);
|
||||||
|
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
|
||||||
|
btn.removeClass("blue").addClass("red");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_colors", setMainColor);
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_delay", function() {
|
||||||
|
var delay = $("#rng_delay").val();
|
||||||
|
|
||||||
|
wsSendCommand("?" + delay);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_brightness", function() {
|
||||||
|
var brightness = $("#rng_brightness").val();
|
||||||
|
|
||||||
|
wsSendCommand("%" + brightness);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#autoSwitch").on("change", function () {
|
||||||
|
if ($(this).prop('checked')) {
|
||||||
|
wsSendCommand("start");
|
||||||
|
} else {
|
||||||
|
wsSendCommand("stop");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function setMode(mode, finish_funtion) {
|
||||||
|
console.log("Mode: ", mode);
|
||||||
|
|
||||||
|
wsSendCommand("/" + mode);
|
||||||
|
finish_funtion();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMainColor() {
|
||||||
|
var white = $("#rng_white").val();
|
||||||
|
var red = $("#rng_red").val();
|
||||||
|
var green = $("#rng_green").val();
|
||||||
|
var blue = $("#rng_blue").val();
|
||||||
|
|
||||||
|
var hexColor = componentToHex(white) + componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||||
|
var statusColor = "#" + componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||||
|
wsSetMainColor(hexColor);
|
||||||
|
$('#status').css("backgroundColor", statusColor);
|
||||||
|
$('#status_color').text(statusColor + "- R=" + red + ", G=" + green + ", B=" + blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// WebSocket commands
|
||||||
|
// ******************************************************************
|
||||||
|
function wsSendCommand(cmd) {
|
||||||
|
console.log("Send WebSocket command:", cmd);
|
||||||
|
if (ws_waiting == 0) {
|
||||||
|
connection.send(cmd);
|
||||||
|
ws_waiting++;
|
||||||
|
} else {
|
||||||
|
console.log("++++++++ WS call waiting, skip")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function wsSetAll(hexColor) {
|
||||||
|
console.log("wsSetAll() Set all colors to:", hexColor);
|
||||||
|
wsSendCommand("*" + hexColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
function wsSetMainColor(hexColor) {
|
||||||
|
console.log("wsSetMainColor() Set main colors to:", hexColor);
|
||||||
|
wsSendCommand("#" + hexColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Colorwheel
|
||||||
|
// ******************************************************************
|
||||||
|
// this is supposed to work on mobiles (touch) as well as on a desktop (click)
|
||||||
|
// since we couldn't find a decent one .. this try of writing one by myself
|
||||||
|
// + google. swiping would be really nice - I will possibly implement it with
|
||||||
|
// jquery later - or never.
|
||||||
|
|
||||||
|
var canvas = document.getElementById("myCanvas");
|
||||||
|
// FIX: Cancel touch end event and handle click via touchstart
|
||||||
|
// canvas.addEventListener("touchend", function(e) { e.preventDefault(); }, false);
|
||||||
|
canvas.addEventListener("touchmove", doTouch, false);
|
||||||
|
canvas.addEventListener("click", doClick, false);
|
||||||
|
//canvas.addEventListener("mousemove", doClick, false);
|
||||||
|
|
||||||
|
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
var centerX = canvas.width / 2;
|
||||||
|
var centerY = canvas.height / 2;
|
||||||
|
var innerRadius = canvas.width / 4.5;
|
||||||
|
var outerRadius = (canvas.width - 10) / 2
|
||||||
|
|
||||||
|
//outer border
|
||||||
|
context.beginPath();
|
||||||
|
//outer circle
|
||||||
|
context.arc(centerX, centerY, outerRadius, 0, 2 * Math.PI, false);
|
||||||
|
//draw the outer border: (gets drawn around the circle!)
|
||||||
|
context.lineWidth = 4;
|
||||||
|
context.strokeStyle = '#000000';
|
||||||
|
context.stroke();
|
||||||
|
context.closePath();
|
||||||
|
|
||||||
|
//fill with beautiful colors
|
||||||
|
//taken from here: http://stackoverflow.com/questions/18265804/building-a-color-wheel-in-html5
|
||||||
|
for(var angle=0; angle<=360; angle+=1) {
|
||||||
|
var startAngle = (angle-2)*Math.PI/180;
|
||||||
|
var endAngle = angle * Math.PI/180;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(centerX, centerY);
|
||||||
|
context.arc(centerX, centerY, outerRadius, startAngle, endAngle, false);
|
||||||
|
context.closePath();
|
||||||
|
context.fillStyle = 'hsl('+angle+', 100%, 50%)';
|
||||||
|
context.fill();
|
||||||
|
context.closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
//inner border
|
||||||
|
context.beginPath();
|
||||||
|
//context.arc(centerX, centerY, radius, startAngle, endAngle, counterClockwise);
|
||||||
|
context.arc(centerX, centerY, innerRadius, 0, 2 * Math.PI, false);
|
||||||
|
//fill the center
|
||||||
|
var my_gradient=context.createLinearGradient(0,0,170,0);
|
||||||
|
my_gradient.addColorStop(0,"black");
|
||||||
|
my_gradient.addColorStop(1,"white");
|
||||||
|
|
||||||
|
context.fillStyle = my_gradient;
|
||||||
|
context.fillStyle = "white";
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
//draw the inner line
|
||||||
|
context.lineWidth = 2;
|
||||||
|
context.strokeStyle = '#000000';
|
||||||
|
context.stroke();
|
||||||
|
context.closePath();
|
||||||
|
|
||||||
|
//get Mouse x/y canvas position
|
||||||
|
function getMousePos(canvas, evt) {
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: evt.clientX - rect.left,
|
||||||
|
y: evt.clientY - rect.top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//comp to Hex
|
||||||
|
function componentToHex(c) {
|
||||||
|
//var hex = c.toString(16);
|
||||||
|
//return hex.length == 1 ? "0" + hex : hex;
|
||||||
|
return ("0"+(Number(c).toString(16))).slice(-2).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
//rgb/rgba to Hex
|
||||||
|
function rgbToHex(rgb) {
|
||||||
|
return componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//display the touch/click position and color info
|
||||||
|
function updateStatus(pos, color) {
|
||||||
|
//var hexColor = rgbToHex(color);
|
||||||
|
//wsSetAll(hexColor);
|
||||||
|
var hexColor = componentToHex(color[0]) + componentToHex(color[1]) + componentToHex(color[2]);
|
||||||
|
wsSetMainColor(hexColor);
|
||||||
|
hexColor = "#" + hexColor;
|
||||||
|
|
||||||
|
$('#status').css("backgroundColor", hexColor);
|
||||||
|
$('#status_color').text(hexColor + " - R=" + color[0] + ", G=" + color[1] + ", B=" + color[2]);
|
||||||
|
$('#status_pos').text("x: " + pos.x + " - y: " + pos.y);
|
||||||
|
|
||||||
|
$("#rng_white").val(0);
|
||||||
|
$("#rng_red").val(color[0]);
|
||||||
|
$("#rng_green").val(color[1]);
|
||||||
|
$("#rng_blue").val(color[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//handle the touch event
|
||||||
|
function doTouch(event) {
|
||||||
|
//to not also fire on click
|
||||||
|
event.preventDefault();
|
||||||
|
var el = event.target;
|
||||||
|
|
||||||
|
//touch position
|
||||||
|
var pos = {x: Math.round(event.targetTouches[0].pageX - el.offsetLeft),
|
||||||
|
y: Math.round(event.targetTouches[0].pageY - el.offsetTop)};
|
||||||
|
//color
|
||||||
|
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
|
||||||
|
|
||||||
|
updateStatus(pos, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doClick(event) {
|
||||||
|
//click position
|
||||||
|
var pos = getMousePos(canvas, event);
|
||||||
|
//color
|
||||||
|
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
|
||||||
|
|
||||||
|
//console.log("click", pos.x, pos.y, color);
|
||||||
|
updateStatus(pos, color);
|
||||||
|
|
||||||
|
//now do sth with the color rgbToHex(color);
|
||||||
|
//don't do stuff when #000000 (outside circle and lines
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// main
|
||||||
|
// ******************************************************************
|
||||||
|
init();
|
||||||
|
|
||||||
|
}); // end of document ready
|
||||||
|
})(jQuery); // end of jQuery name space
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
## Retired, use:
|
||||||
|
McLightingHTML from https://github.com/FabLab-Luenen/McLightingHTML
|
||||||
|
|
||||||
|
or set #define USE_HTML_MIN_GZ in definitions.h to use the integrated!
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.4 KiB |
@@ -0,0 +1,466 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!--Import Google Icon Font-->
|
||||||
|
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
<!--Import materialize.css-->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css" media="screen,projection" />
|
||||||
|
|
||||||
|
<!--Let browser know website is optimized for mobile-->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>McLighting v2</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<nav class="blue light-blueXXX lighten-1XXX" role="navigation" id="mc-nav">
|
||||||
|
<div class="nav-wrapper container">
|
||||||
|
<a id="logo-container" href="#" class="brand-logo">Mc Lighting v2</a>
|
||||||
|
|
||||||
|
<ul class="right hide-on-med-and-down">
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul id="nav-mobile" class="side-nav">
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
|
||||||
|
</ul>
|
||||||
|
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container mc_pane" id="pane0">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row" id="mc-wsloader">
|
||||||
|
<div class="col">
|
||||||
|
<div class="preloader-wrapper active">
|
||||||
|
<div class="spinner-layer spinner-blue-only">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row hide" id="mc-wserror">
|
||||||
|
<div class="col">
|
||||||
|
<div>Error on websocket connect.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mc_pane hide" id="pane1">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div style="height: 330px; width: 330px;">
|
||||||
|
<canvas id="myCanvas" width="330" height="330" style="-webkit-user-select: none;-webkit-tap-highlight-color: rgba(0,0,0,0);-moz-user-select:none;"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div class="card-panel" id="status">
|
||||||
|
<div id="status_pos">pick a color</div>
|
||||||
|
<div id="status_color"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div class="right switch">Auto:<br>
|
||||||
|
<label>Off
|
||||||
|
<input id="autoSwitch" type="checkbox"><span class="lever"></span>On
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mc_pane hide" id="pane2">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<form class="col s12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_red">Red</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_red" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_green">Green</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_green" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_blue">Blue</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_blue" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<label for="txt_delay">Speed</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_delay" min="0" max="255" value="196" class="update_delay" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<label for="txt_delay">Brightness</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_brightness" min="0" max="255" value="196" class="update_brightness" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 m6 l6 btn_grid">
|
||||||
|
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="off">OFF
|
||||||
|
<i class="material-icons right">send</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col s12 m6 l6 btn_grid">
|
||||||
|
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="tv">TV
|
||||||
|
<i class="material-icons right">send</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="modes">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
Loading animations...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="page-footer blue">
|
||||||
|
<div class="footer-copyright">
|
||||||
|
<div class="container">© 2017
|
||||||
|
<a class="grey-text text-lighten-4 right" href="https://github.com/toblum/McLighting">Project home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
.btn_grid {
|
||||||
|
margin: 7px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!--Import jQuery before materialize.js-->
|
||||||
|
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
|
||||||
|
<script type="text/javascript">(function($){
|
||||||
|
$(function(){
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
var host = window.location.hostname;
|
||||||
|
//host = "esp8266_02.local";
|
||||||
|
|
||||||
|
var ws_url = 'ws://' + host + ':81';
|
||||||
|
var connection;
|
||||||
|
var ws_waiting = 0;
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Side navigation
|
||||||
|
// ******************************************************************
|
||||||
|
$('.button-collapse').sideNav();
|
||||||
|
|
||||||
|
// Navlinks
|
||||||
|
$('#mc-nav').on('click', '.mc-navlink', function(){
|
||||||
|
console.log("Navigate to pane: ", $(this).data("pane"));
|
||||||
|
showPane($(this).data("pane"));
|
||||||
|
});
|
||||||
|
|
||||||
|
function showPane(pane) {
|
||||||
|
$('.mc_pane').addClass('hide');
|
||||||
|
$('#' + pane).removeClass('hide');
|
||||||
|
$('.button-collapse').sideNav('hide');
|
||||||
|
|
||||||
|
if (pane == "pane2") {
|
||||||
|
setMainColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// init()
|
||||||
|
// ******************************************************************
|
||||||
|
function init() {
|
||||||
|
console.log("Connection websockets to:", ws_url);
|
||||||
|
connection = new WebSocket(ws_url, ['arduino']);
|
||||||
|
|
||||||
|
// Load modes async
|
||||||
|
$.getJSON("http://" + host + "/get_modes", function(data) {
|
||||||
|
//console.log("modes", data);
|
||||||
|
|
||||||
|
var modes_html = "";
|
||||||
|
data.forEach(function(current_mode){
|
||||||
|
if (current_mode.mode !== undefined) {
|
||||||
|
modes_html += '<div class="col s12 m6 l6 btn_grid">';
|
||||||
|
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||||
|
modes_html += '<i class="material-icons right">send</i>';
|
||||||
|
modes_html += '</a>';
|
||||||
|
modes_html += '</div>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#modes').html(modes_html);
|
||||||
|
});
|
||||||
|
|
||||||
|
// When the connection is open, send some data to the server
|
||||||
|
connection.onopen = function () {
|
||||||
|
//connection.send('Ping'); // Send the message 'Ping' to the server
|
||||||
|
console.log('WebSocket Open');
|
||||||
|
showPane('pane1');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log errors
|
||||||
|
connection.onerror = function (error) {
|
||||||
|
console.log('WebSocket Error ' + error);
|
||||||
|
$('#mc-wsloader').addClass('hide');
|
||||||
|
$('#mc-wserror').removeClass('hide');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log messages from the server
|
||||||
|
connection.onmessage = function (e) {
|
||||||
|
console.log('WebSocket from server: ' + e.data);
|
||||||
|
ws_waiting = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Modes
|
||||||
|
// ******************************************************************
|
||||||
|
$("#pane2").on("click", ".btn_mode", function() {
|
||||||
|
var mode = $(this).attr("data-mode");
|
||||||
|
last_mode = mode;
|
||||||
|
var btn = $(this);
|
||||||
|
setMode(mode, function() {
|
||||||
|
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
|
||||||
|
btn.removeClass("blue").addClass("red");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("click", ".btn_mode_static", function() {
|
||||||
|
var mode = $(this).attr("data-mode");
|
||||||
|
var btn = $(this);
|
||||||
|
|
||||||
|
wsSendCommand("=" + mode);
|
||||||
|
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
|
||||||
|
btn.removeClass("blue").addClass("red");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_colors", setMainColor);
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_delay", function() {
|
||||||
|
var delay = $("#rng_delay").val();
|
||||||
|
|
||||||
|
wsSendCommand("?" + delay);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_brightness", function() {
|
||||||
|
var brightness = $("#rng_brightness").val();
|
||||||
|
|
||||||
|
wsSendCommand("%" + brightness);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#autoSwitch").on("change", function () {
|
||||||
|
if ($(this).prop('checked')) {
|
||||||
|
wsSendCommand("start");
|
||||||
|
} else {
|
||||||
|
wsSendCommand("stop");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function setMode(mode, finish_funtion) {
|
||||||
|
console.log("Mode: ", mode);
|
||||||
|
|
||||||
|
wsSendCommand("/" + mode);
|
||||||
|
finish_funtion();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMainColor() {
|
||||||
|
var red = $("#rng_red").val();
|
||||||
|
var green = $("#rng_green").val();
|
||||||
|
var blue = $("#rng_blue").val();
|
||||||
|
|
||||||
|
var mainColorHex = componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||||
|
wsSetMainColor(mainColorHex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// WebSocket commands
|
||||||
|
// ******************************************************************
|
||||||
|
function wsSendCommand(cmd) {
|
||||||
|
console.log("Send WebSocket command:", cmd);
|
||||||
|
if (ws_waiting == 0) {
|
||||||
|
connection.send(cmd);
|
||||||
|
ws_waiting++;
|
||||||
|
} else {
|
||||||
|
console.log("++++++++ WS call waiting, skip")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function wsSetAll(hexColor) {
|
||||||
|
console.log("wsSetAll() Set all colors to:", hexColor);
|
||||||
|
wsSendCommand("*" + hexColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
function wsSetMainColor(hexColor) {
|
||||||
|
console.log("wsSetMainColor() Set main colors to:", hexColor);
|
||||||
|
wsSendCommand("#" + hexColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Colorwheel
|
||||||
|
// ******************************************************************
|
||||||
|
// this is supposed to work on mobiles (touch) as well as on a desktop (click)
|
||||||
|
// since we couldn't find a decent one .. this try of writing one by myself
|
||||||
|
// + google. swiping would be really nice - I will possibly implement it with
|
||||||
|
// jquery later - or never.
|
||||||
|
|
||||||
|
var canvas = document.getElementById("myCanvas");
|
||||||
|
// FIX: Cancel touch end event and handle click via touchstart
|
||||||
|
// canvas.addEventListener("touchend", function(e) { e.preventDefault(); }, false);
|
||||||
|
canvas.addEventListener("touchmove", doTouch, false);
|
||||||
|
canvas.addEventListener("click", doClick, false);
|
||||||
|
//canvas.addEventListener("mousemove", doClick, false);
|
||||||
|
|
||||||
|
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
var centerX = canvas.width / 2;
|
||||||
|
var centerY = canvas.height / 2;
|
||||||
|
var innerRadius = canvas.width / 4.5;
|
||||||
|
var outerRadius = (canvas.width - 10) / 2
|
||||||
|
|
||||||
|
//outer border
|
||||||
|
context.beginPath();
|
||||||
|
//outer circle
|
||||||
|
context.arc(centerX, centerY, outerRadius, 0, 2 * Math.PI, false);
|
||||||
|
//draw the outer border: (gets drawn around the circle!)
|
||||||
|
context.lineWidth = 4;
|
||||||
|
context.strokeStyle = '#000000';
|
||||||
|
context.stroke();
|
||||||
|
context.closePath();
|
||||||
|
|
||||||
|
//fill with beautiful colors
|
||||||
|
//taken from here: http://stackoverflow.com/questions/18265804/building-a-color-wheel-in-html5
|
||||||
|
for(var angle=0; angle<=360; angle+=1) {
|
||||||
|
var startAngle = (angle-2)*Math.PI/180;
|
||||||
|
var endAngle = angle * Math.PI/180;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(centerX, centerY);
|
||||||
|
context.arc(centerX, centerY, outerRadius, startAngle, endAngle, false);
|
||||||
|
context.closePath();
|
||||||
|
context.fillStyle = 'hsl('+angle+', 100%, 50%)';
|
||||||
|
context.fill();
|
||||||
|
context.closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
//inner border
|
||||||
|
context.beginPath();
|
||||||
|
//context.arc(centerX, centerY, radius, startAngle, endAngle, counterClockwise);
|
||||||
|
context.arc(centerX, centerY, innerRadius, 0, 2 * Math.PI, false);
|
||||||
|
//fill the center
|
||||||
|
var my_gradient=context.createLinearGradient(0,0,170,0);
|
||||||
|
my_gradient.addColorStop(0,"black");
|
||||||
|
my_gradient.addColorStop(1,"white");
|
||||||
|
|
||||||
|
context.fillStyle = my_gradient;
|
||||||
|
context.fillStyle = "white";
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
//draw the inner line
|
||||||
|
context.lineWidth = 2;
|
||||||
|
context.strokeStyle = '#000000';
|
||||||
|
context.stroke();
|
||||||
|
context.closePath();
|
||||||
|
|
||||||
|
//get Mouse x/y canvas position
|
||||||
|
function getMousePos(canvas, evt) {
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: evt.clientX - rect.left,
|
||||||
|
y: evt.clientY - rect.top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//comp to Hex
|
||||||
|
function componentToHex(c) {
|
||||||
|
//var hex = c.toString(16);
|
||||||
|
//return hex.length == 1 ? "0" + hex : hex;
|
||||||
|
return ("0"+(Number(c).toString(16))).slice(-2).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
//rgb/rgba to Hex
|
||||||
|
function rgbToHex(rgb) {
|
||||||
|
return componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//display the touch/click position and color info
|
||||||
|
function updateStatus(pos, color) {
|
||||||
|
var hexColor = rgbToHex(color);
|
||||||
|
wsSetAll(hexColor);
|
||||||
|
|
||||||
|
hexColor = "#" + hexColor;
|
||||||
|
|
||||||
|
$('#status').css("backgroundColor", hexColor);
|
||||||
|
$('#status_color').text(hexColor + " - R=" + color[0] + ", G=" + color[1] + ", B=" + color[2]);
|
||||||
|
$('#status_pos').text("x: " + pos.x + " - y: " + pos.y);
|
||||||
|
|
||||||
|
$("#rng_red").val(color[0]);
|
||||||
|
$("#rng_green").val(color[1]);
|
||||||
|
$("#rng_blue").val(color[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//handle the touch event
|
||||||
|
function doTouch(event) {
|
||||||
|
//to not also fire on click
|
||||||
|
event.preventDefault();
|
||||||
|
var el = event.target;
|
||||||
|
|
||||||
|
//touch position
|
||||||
|
var pos = {x: Math.round(event.targetTouches[0].pageX - el.offsetLeft),
|
||||||
|
y: Math.round(event.targetTouches[0].pageY - el.offsetTop)};
|
||||||
|
//color
|
||||||
|
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
|
||||||
|
|
||||||
|
updateStatus(pos, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doClick(event) {
|
||||||
|
//click position
|
||||||
|
var pos = getMousePos(canvas, event);
|
||||||
|
//color
|
||||||
|
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
|
||||||
|
|
||||||
|
//console.log("click", pos.x, pos.y, color);
|
||||||
|
updateStatus(pos, color);
|
||||||
|
|
||||||
|
//now do sth with the color rgbToHex(color);
|
||||||
|
//don't do stuff when #000000 (outside circle and lines
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// main
|
||||||
|
// ******************************************************************
|
||||||
|
init();
|
||||||
|
|
||||||
|
}); // end of document ready
|
||||||
|
})(jQuery); // end of jQuery name space</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 34 KiB |
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,55 @@
|
|||||||
|
var gulp = require('gulp'),
|
||||||
|
request = require('request'),
|
||||||
|
fs = require('fs'),
|
||||||
|
connect = require('gulp-connect'),
|
||||||
|
fileinclude = require('gulp-file-include');
|
||||||
|
|
||||||
|
var src_dir = "src/";
|
||||||
|
var build_dir = "build/";
|
||||||
|
|
||||||
|
|
||||||
|
gulp.task('html', function() {
|
||||||
|
gulp.src(src_dir + '*.htm')
|
||||||
|
.pipe(fileinclude({
|
||||||
|
prefix: '@@',
|
||||||
|
basepath: '@file'
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest('build'))
|
||||||
|
.pipe(connect.reload());
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
gulp.task('connect', function() {
|
||||||
|
connect.server({
|
||||||
|
root: 'build',
|
||||||
|
livereload: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('watch', function() {
|
||||||
|
gulp.watch(src_dir + '*.htm', ['html']);
|
||||||
|
gulp.watch(src_dir + 'js/*.js', ['html']);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
gulp.task('upload', ['html'], function() {
|
||||||
|
var url = 'http://192.168.0.49/edit';
|
||||||
|
var options = {
|
||||||
|
url: url,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var r = request.post(options, function optionalCallback(err, httpResponse, body) {
|
||||||
|
if (err) {
|
||||||
|
return console.error('upload failed:', err);
|
||||||
|
}
|
||||||
|
console.log('Upload successful! Server responded with:', body);
|
||||||
|
});
|
||||||
|
var form = r.form();
|
||||||
|
form.append('data', fs.createReadStream(__dirname + "/" + build_dir + '/index.htm'), {filename: '/index.htm', contentType: "application/octet-stream"});
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('default', ['html']);
|
||||||
|
gulp.task('serve', ['watch', 'connect']);
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "mc_lighting",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"description": "Web client for Mc Lighting",
|
||||||
|
"main": "index.html",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Tobias Blum",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fs": "0.0.2",
|
||||||
|
"gulp": "^3.9.1",
|
||||||
|
"gulp-connect": "^5.0.0",
|
||||||
|
"gulp-file-include": "^1.0.0",
|
||||||
|
"request": "^2.72.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!--Import Google Icon Font-->
|
||||||
|
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
<!--Import materialize.css-->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css" media="screen,projection" />
|
||||||
|
|
||||||
|
<!--Let browser know website is optimized for mobile-->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>McLighting v2</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<nav class="blue light-blueXXX lighten-1XXX" role="navigation" id="mc-nav">
|
||||||
|
<div class="nav-wrapper container">
|
||||||
|
<a id="logo-container" href="#" class="brand-logo">Mc Lighting v2</a>
|
||||||
|
|
||||||
|
<ul class="right hide-on-med-and-down">
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul id="nav-mobile" class="side-nav">
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane1">Wheel</a></li>
|
||||||
|
<li><a href="#" class="mc-navlink" data-pane="pane2">Modes</a></li>
|
||||||
|
</ul>
|
||||||
|
<a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container mc_pane" id="pane0">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row" id="mc-wsloader">
|
||||||
|
<div class="col">
|
||||||
|
<div class="preloader-wrapper active">
|
||||||
|
<div class="spinner-layer spinner-blue-only">
|
||||||
|
<div class="circle-clipper left">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="gap-patch">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="circle-clipper right">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row hide" id="mc-wserror">
|
||||||
|
<div class="col">
|
||||||
|
<div>Error on websocket connect.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mc_pane hide" id="pane1">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div style="height: 330px; width: 330px;">
|
||||||
|
<canvas id="myCanvas" width="330" height="330" style="-webkit-user-select: none;-webkit-tap-highlight-color: rgba(0,0,0,0);-moz-user-select:none;"></canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div class="card-panel" id="status">
|
||||||
|
<div id="status_pos">pick a color</div>
|
||||||
|
<div id="status_color"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m6">
|
||||||
|
<div class="right switch">Auto:<br>
|
||||||
|
<label>Off
|
||||||
|
<input id="autoSwitch" type="checkbox"><span class="lever"></span>On
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container mc_pane hide" id="pane2">
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<form class="col s12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_red">Red</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_red" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_green">Green</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_green" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
<div class="input-field col s12 l4">
|
||||||
|
<label for="txt_blue">Blue</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_blue" min="0" max="255" class="update_colors" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<label for="txt_delay">Speed</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_delay" min="0" max="255" value="196" class="update_delay" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<label for="txt_delay">Brightness</label><br/>
|
||||||
|
<p class="range-field"><input type="range" id="rng_brightness" min="0" max="255" value="196" class="update_brightness" /></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 m6 l6 btn_grid">
|
||||||
|
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="off">OFF
|
||||||
|
<i class="material-icons right">send</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col s12 m6 l6 btn_grid">
|
||||||
|
<a class="btn waves-effect waves-light btn_mode_static blue" name="action" data-mode="tv">TV
|
||||||
|
<i class="material-icons right">send</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="modes">
|
||||||
|
<div class="input-field col s12">
|
||||||
|
Loading animations...
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="page-footer blue">
|
||||||
|
<div class="footer-copyright">
|
||||||
|
<div class="container">© 2017
|
||||||
|
<a class="grey-text text-lighten-4 right" href="https://github.com/toblum/McLighting">Project home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
.btn_grid {
|
||||||
|
margin: 7px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!--Import jQuery before materialize.js-->
|
||||||
|
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
|
||||||
|
<script type="text/javascript">@@include('js/script.js')</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,305 @@
|
|||||||
|
(function($){
|
||||||
|
$(function(){
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
var host = window.location.hostname;
|
||||||
|
//host = "esp8266_02.local";
|
||||||
|
|
||||||
|
var ws_url = 'ws://' + host + ':81';
|
||||||
|
var connection;
|
||||||
|
var ws_waiting = 0;
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Side navigation
|
||||||
|
// ******************************************************************
|
||||||
|
$('.button-collapse').sideNav();
|
||||||
|
|
||||||
|
// Navlinks
|
||||||
|
$('#mc-nav').on('click', '.mc-navlink', function(){
|
||||||
|
console.log("Navigate to pane: ", $(this).data("pane"));
|
||||||
|
showPane($(this).data("pane"));
|
||||||
|
});
|
||||||
|
|
||||||
|
function showPane(pane) {
|
||||||
|
$('.mc_pane').addClass('hide');
|
||||||
|
$('#' + pane).removeClass('hide');
|
||||||
|
$('.button-collapse').sideNav('hide');
|
||||||
|
|
||||||
|
if (pane == "pane2") {
|
||||||
|
setMainColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// init()
|
||||||
|
// ******************************************************************
|
||||||
|
function init() {
|
||||||
|
console.log("Connection websockets to:", ws_url);
|
||||||
|
connection = new WebSocket(ws_url, ['arduino']);
|
||||||
|
|
||||||
|
// Load modes async
|
||||||
|
$.getJSON("http://" + host + "/get_modes", function(data) {
|
||||||
|
//console.log("modes", data);
|
||||||
|
|
||||||
|
var modes_html = "";
|
||||||
|
data.forEach(function(current_mode){
|
||||||
|
if (current_mode.mode !== undefined) {
|
||||||
|
modes_html += '<div class="col s12 m6 l6 btn_grid">';
|
||||||
|
modes_html += '<a class="btn waves-effect waves-light btn_mode blue" name="action" data-mode="' + current_mode.mode + '">(' + current_mode.mode +') '+ current_mode.name;
|
||||||
|
modes_html += '<i class="material-icons right">send</i>';
|
||||||
|
modes_html += '</a>';
|
||||||
|
modes_html += '</div>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#modes').html(modes_html);
|
||||||
|
});
|
||||||
|
|
||||||
|
// When the connection is open, send some data to the server
|
||||||
|
connection.onopen = function () {
|
||||||
|
//connection.send('Ping'); // Send the message 'Ping' to the server
|
||||||
|
console.log('WebSocket Open');
|
||||||
|
showPane('pane1');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log errors
|
||||||
|
connection.onerror = function (error) {
|
||||||
|
console.log('WebSocket Error ' + error);
|
||||||
|
$('#mc-wsloader').addClass('hide');
|
||||||
|
$('#mc-wserror').removeClass('hide');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log messages from the server
|
||||||
|
connection.onmessage = function (e) {
|
||||||
|
console.log('WebSocket from server: ' + e.data);
|
||||||
|
ws_waiting = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Modes
|
||||||
|
// ******************************************************************
|
||||||
|
$("#pane2").on("click", ".btn_mode", function() {
|
||||||
|
var mode = $(this).attr("data-mode");
|
||||||
|
last_mode = mode;
|
||||||
|
var btn = $(this);
|
||||||
|
setMode(mode, function() {
|
||||||
|
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
|
||||||
|
btn.removeClass("blue").addClass("red");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("click", ".btn_mode_static", function() {
|
||||||
|
var mode = $(this).attr("data-mode");
|
||||||
|
var btn = $(this);
|
||||||
|
|
||||||
|
wsSendCommand("=" + mode);
|
||||||
|
$(".btn_mode, .btn_mode_static").removeClass("red").addClass("blue");
|
||||||
|
btn.removeClass("blue").addClass("red");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_colors", setMainColor);
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_delay", function() {
|
||||||
|
var delay = $("#rng_delay").val();
|
||||||
|
|
||||||
|
wsSendCommand("?" + delay);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#pane2").on("change", ".update_brightness", function() {
|
||||||
|
var brightness = $("#rng_brightness").val();
|
||||||
|
|
||||||
|
wsSendCommand("%" + brightness);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#autoSwitch").on("change", function () {
|
||||||
|
if ($(this).prop('checked')) {
|
||||||
|
wsSendCommand("start");
|
||||||
|
} else {
|
||||||
|
wsSendCommand("stop");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function setMode(mode, finish_funtion) {
|
||||||
|
console.log("Mode: ", mode);
|
||||||
|
|
||||||
|
wsSendCommand("/" + mode);
|
||||||
|
finish_funtion();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMainColor() {
|
||||||
|
var red = $("#rng_red").val();
|
||||||
|
var green = $("#rng_green").val();
|
||||||
|
var blue = $("#rng_blue").val();
|
||||||
|
|
||||||
|
var mainColorHex = componentToHex(red) + componentToHex(green) + componentToHex(blue);
|
||||||
|
wsSetMainColor(mainColorHex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// WebSocket commands
|
||||||
|
// ******************************************************************
|
||||||
|
function wsSendCommand(cmd) {
|
||||||
|
console.log("Send WebSocket command:", cmd);
|
||||||
|
if (ws_waiting == 0) {
|
||||||
|
connection.send(cmd);
|
||||||
|
ws_waiting++;
|
||||||
|
} else {
|
||||||
|
console.log("++++++++ WS call waiting, skip")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function wsSetAll(hexColor) {
|
||||||
|
console.log("wsSetAll() Set all colors to:", hexColor);
|
||||||
|
wsSendCommand("*" + hexColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
function wsSetMainColor(hexColor) {
|
||||||
|
console.log("wsSetMainColor() Set main colors to:", hexColor);
|
||||||
|
wsSendCommand("#" + hexColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// Colorwheel
|
||||||
|
// ******************************************************************
|
||||||
|
// this is supposed to work on mobiles (touch) as well as on a desktop (click)
|
||||||
|
// since we couldn't find a decent one .. this try of writing one by myself
|
||||||
|
// + google. swiping would be really nice - I will possibly implement it with
|
||||||
|
// jquery later - or never.
|
||||||
|
|
||||||
|
var canvas = document.getElementById("myCanvas");
|
||||||
|
// FIX: Cancel touch end event and handle click via touchstart
|
||||||
|
// canvas.addEventListener("touchend", function(e) { e.preventDefault(); }, false);
|
||||||
|
canvas.addEventListener("touchmove", doTouch, false);
|
||||||
|
canvas.addEventListener("click", doClick, false);
|
||||||
|
//canvas.addEventListener("mousemove", doClick, false);
|
||||||
|
|
||||||
|
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
var centerX = canvas.width / 2;
|
||||||
|
var centerY = canvas.height / 2;
|
||||||
|
var innerRadius = canvas.width / 4.5;
|
||||||
|
var outerRadius = (canvas.width - 10) / 2
|
||||||
|
|
||||||
|
//outer border
|
||||||
|
context.beginPath();
|
||||||
|
//outer circle
|
||||||
|
context.arc(centerX, centerY, outerRadius, 0, 2 * Math.PI, false);
|
||||||
|
//draw the outer border: (gets drawn around the circle!)
|
||||||
|
context.lineWidth = 4;
|
||||||
|
context.strokeStyle = '#000000';
|
||||||
|
context.stroke();
|
||||||
|
context.closePath();
|
||||||
|
|
||||||
|
//fill with beautiful colors
|
||||||
|
//taken from here: http://stackoverflow.com/questions/18265804/building-a-color-wheel-in-html5
|
||||||
|
for(var angle=0; angle<=360; angle+=1) {
|
||||||
|
var startAngle = (angle-2)*Math.PI/180;
|
||||||
|
var endAngle = angle * Math.PI/180;
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(centerX, centerY);
|
||||||
|
context.arc(centerX, centerY, outerRadius, startAngle, endAngle, false);
|
||||||
|
context.closePath();
|
||||||
|
context.fillStyle = 'hsl('+angle+', 100%, 50%)';
|
||||||
|
context.fill();
|
||||||
|
context.closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
//inner border
|
||||||
|
context.beginPath();
|
||||||
|
//context.arc(centerX, centerY, radius, startAngle, endAngle, counterClockwise);
|
||||||
|
context.arc(centerX, centerY, innerRadius, 0, 2 * Math.PI, false);
|
||||||
|
//fill the center
|
||||||
|
var my_gradient=context.createLinearGradient(0,0,170,0);
|
||||||
|
my_gradient.addColorStop(0,"black");
|
||||||
|
my_gradient.addColorStop(1,"white");
|
||||||
|
|
||||||
|
context.fillStyle = my_gradient;
|
||||||
|
context.fillStyle = "white";
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
//draw the inner line
|
||||||
|
context.lineWidth = 2;
|
||||||
|
context.strokeStyle = '#000000';
|
||||||
|
context.stroke();
|
||||||
|
context.closePath();
|
||||||
|
|
||||||
|
//get Mouse x/y canvas position
|
||||||
|
function getMousePos(canvas, evt) {
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: evt.clientX - rect.left,
|
||||||
|
y: evt.clientY - rect.top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//comp to Hex
|
||||||
|
function componentToHex(c) {
|
||||||
|
//var hex = c.toString(16);
|
||||||
|
//return hex.length == 1 ? "0" + hex : hex;
|
||||||
|
return ("0"+(Number(c).toString(16))).slice(-2).toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
//rgb/rgba to Hex
|
||||||
|
function rgbToHex(rgb) {
|
||||||
|
return componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//display the touch/click position and color info
|
||||||
|
function updateStatus(pos, color) {
|
||||||
|
var hexColor = rgbToHex(color);
|
||||||
|
wsSetAll(hexColor);
|
||||||
|
|
||||||
|
hexColor = "#" + hexColor;
|
||||||
|
|
||||||
|
$('#status').css("backgroundColor", hexColor);
|
||||||
|
$('#status_color').text(hexColor + " - R=" + color[0] + ", G=" + color[1] + ", B=" + color[2]);
|
||||||
|
$('#status_pos').text("x: " + pos.x + " - y: " + pos.y);
|
||||||
|
|
||||||
|
$("#rng_red").val(color[0]);
|
||||||
|
$("#rng_green").val(color[1]);
|
||||||
|
$("#rng_blue").val(color[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//handle the touch event
|
||||||
|
function doTouch(event) {
|
||||||
|
//to not also fire on click
|
||||||
|
event.preventDefault();
|
||||||
|
var el = event.target;
|
||||||
|
|
||||||
|
//touch position
|
||||||
|
var pos = {x: Math.round(event.targetTouches[0].pageX - el.offsetLeft),
|
||||||
|
y: Math.round(event.targetTouches[0].pageY - el.offsetTop)};
|
||||||
|
//color
|
||||||
|
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
|
||||||
|
|
||||||
|
updateStatus(pos, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doClick(event) {
|
||||||
|
//click position
|
||||||
|
var pos = getMousePos(canvas, event);
|
||||||
|
//color
|
||||||
|
var color = context.getImageData(pos.x, pos.y, 1, 1).data;
|
||||||
|
|
||||||
|
//console.log("click", pos.x, pos.y, color);
|
||||||
|
updateStatus(pos, color);
|
||||||
|
|
||||||
|
//now do sth with the color rgbToHex(color);
|
||||||
|
//don't do stuff when #000000 (outside circle and lines
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ******************************************************************
|
||||||
|
// main
|
||||||
|
// ******************************************************************
|
||||||
|
init();
|
||||||
|
|
||||||
|
}); // end of document ready
|
||||||
|
})(jQuery); // end of jQuery name space
|
||||||
+1
-1
@@ -46,7 +46,7 @@ arduino_core_stage = https://github.com/platformio/platform-espressif8266.git#fe
|
|||||||
|
|
||||||
framework = arduino
|
framework = arduino
|
||||||
;platform = ${common.arduino_core_2_4_2}
|
;platform = ${common.arduino_core_2_4_2}
|
||||||
platform = ${common.arduino_core_2_6_3}
|
platform = ${common.arduino_core_2_5_2}
|
||||||
build_flags =
|
build_flags =
|
||||||
-DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
|
-DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
|
||||||
-DMQTT_MAX_PACKET_SIZE=512 ; PubSubClient Specific flags
|
-DMQTT_MAX_PACKET_SIZE=512 ; PubSubClient Specific flags
|
||||||
|
|||||||
Reference in New Issue
Block a user