mirror of
https://github.com/wled/WLED.git
synced 2025-08-29 04:29:25 +00:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d09a97f230 | ||
![]() |
89afdd2b17 | ||
![]() |
8d7a066680 | ||
![]() |
c93b185f54 | ||
![]() |
3ef4a2b9d2 | ||
![]() |
37f91c4d50 | ||
![]() |
bbb27dd70b | ||
![]() |
e7e11b8bd2 | ||
![]() |
1b0d735e50 | ||
![]() |
9aebaa78fa |
@@ -3,22 +3,25 @@
|
||||
WLED is a fast and (relatively) secure implementation of an ESP8266 webserver to control NeoPixel (WS2812B) LEDs!
|
||||
Now also with experimental ESP32 support.
|
||||
|
||||
### Features: (V0.5.0)
|
||||
### Features: (V0.6.0)
|
||||
- RGB, HSB, and brightness sliders
|
||||
- Settings page - configuration over network
|
||||
- Access Point and station mode - automatic failsafe AP
|
||||
- WS2812FX library integrated for over 50 special effects!
|
||||
- Secondary color support lets you use even more effect combinations
|
||||
- Alexa smart home device server (including dimming)
|
||||
- Beta syncronization to Philips hue lights
|
||||
- Support for RGBW strips
|
||||
- 25 user presets! Save your favorite colors and effects and apply them easily!
|
||||
- HTTP request API for simple integration
|
||||
- Macro functions to automatically execute API calls
|
||||
- Nightlight function (gradually dims down)
|
||||
- Notifier function (multiple ESPs sync color via UDP broadcast)
|
||||
- Support for power pushbutton
|
||||
- Custom Theater Chase
|
||||
- Full OTA software update capability (HTTP and ArduinoOTA)
|
||||
- Password protected OTA page for added security (OTA lock)
|
||||
- Alexa smart home device server (including dimming)
|
||||
- NTP and experimental analog clock function
|
||||
- NTP and configurable analog clock function
|
||||
- Support for the Cronixie Clock kit by Diamex
|
||||
- Realtime UDP Packet Control (WARLS) possible
|
||||
- Client HTML UI controlled, customizable themes
|
||||
|
@@ -73,7 +73,7 @@ void WS2812FX::stop() {
|
||||
strip_off();
|
||||
}
|
||||
|
||||
void WS2812FX::setMode(uint8_t m) {
|
||||
void WS2812FX::setMode(byte m) {
|
||||
_counter_mode_call = 0;
|
||||
_counter_mode_step = 0;
|
||||
_mode_last_call_time = 0;
|
||||
@@ -83,7 +83,7 @@ void WS2812FX::setMode(uint8_t m) {
|
||||
strip_off_respectLock();
|
||||
}
|
||||
|
||||
void WS2812FX::setSpeed(uint8_t s) {
|
||||
void WS2812FX::setSpeed(byte s) {
|
||||
_counter_mode_call = 0;
|
||||
_counter_mode_step = 0;
|
||||
_mode_last_call_time = 0;
|
||||
@@ -91,35 +91,35 @@ void WS2812FX::setSpeed(uint8_t s) {
|
||||
strip_off_respectLock();
|
||||
}
|
||||
|
||||
void WS2812FX::increaseSpeed(uint8_t s) {
|
||||
void WS2812FX::increaseSpeed(byte s) {
|
||||
s = constrain(_speed + s, SPEED_MIN, SPEED_MAX);
|
||||
setSpeed(s);
|
||||
}
|
||||
|
||||
void WS2812FX::decreaseSpeed(uint8_t s) {
|
||||
void WS2812FX::decreaseSpeed(byte s) {
|
||||
s = constrain(_speed - s, SPEED_MIN, SPEED_MAX);
|
||||
setSpeed(s);
|
||||
}
|
||||
|
||||
void WS2812FX::setIntensity(uint8_t in) {
|
||||
void WS2812FX::setIntensity(byte in) {
|
||||
_intensity=in;
|
||||
}
|
||||
|
||||
void WS2812FX::setColor(uint8_t r, uint8_t g, uint8_t b) {
|
||||
void WS2812FX::setColor(byte r, byte g, byte b) {
|
||||
setColor(((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
|
||||
}
|
||||
|
||||
|
||||
void WS2812FX::setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||
void WS2812FX::setColor(byte r, byte g, byte b, byte w) {
|
||||
setColor(((uint32_t)w << 24)|((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
|
||||
}
|
||||
|
||||
void WS2812FX::setSecondaryColor(uint8_t r, uint8_t g, uint8_t b) {
|
||||
void WS2812FX::setSecondaryColor(byte r, byte g, byte b) {
|
||||
setSecondaryColor(((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
|
||||
}
|
||||
|
||||
|
||||
void WS2812FX::setSecondaryColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
|
||||
void WS2812FX::setSecondaryColor(byte r, byte g, byte b, byte w) {
|
||||
setSecondaryColor(((uint32_t)w << 24)|((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
|
||||
}
|
||||
|
||||
@@ -136,33 +136,33 @@ void WS2812FX::setSecondaryColor(uint32_t c) {
|
||||
setBrightness(_brightness);
|
||||
}
|
||||
|
||||
void WS2812FX::increaseBrightness(uint8_t s) {
|
||||
void WS2812FX::increaseBrightness(byte s) {
|
||||
s = constrain(_brightness + s, BRIGHTNESS_MIN, BRIGHTNESS_MAX);
|
||||
setBrightness(s);
|
||||
}
|
||||
|
||||
void WS2812FX::decreaseBrightness(uint8_t s) {
|
||||
void WS2812FX::decreaseBrightness(byte s) {
|
||||
s = constrain(_brightness - s, BRIGHTNESS_MIN, BRIGHTNESS_MAX);
|
||||
setBrightness(s);
|
||||
}
|
||||
|
||||
boolean WS2812FX::isRunning() {
|
||||
bool WS2812FX::isRunning() {
|
||||
return _running;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getMode(void) {
|
||||
byte WS2812FX::getMode(void) {
|
||||
return _mode_index;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getSpeed(void) {
|
||||
byte WS2812FX::getSpeed(void) {
|
||||
return _speed;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getBrightness(void) {
|
||||
byte WS2812FX::getBrightness(void) {
|
||||
return _brightness;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::getModeCount(void) {
|
||||
byte WS2812FX::getModeCount(void) {
|
||||
return MODE_COUNT;
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ void WS2812FX::strip_off_respectLock() {
|
||||
* The colours are a transition r -> g -> b -> back to r
|
||||
* Inspired by the Adafruit examples.
|
||||
*/
|
||||
uint32_t WS2812FX::color_wheel(uint8_t pos) {
|
||||
uint32_t WS2812FX::color_wheel(byte pos) {
|
||||
pos = 255 - pos;
|
||||
if(pos < 85) {
|
||||
return ((uint32_t)(255 - pos * 3) << 16) | ((uint32_t)(0) << 8) | (pos * 3);
|
||||
@@ -215,11 +215,11 @@ uint32_t WS2812FX::color_wheel(uint8_t pos) {
|
||||
/*
|
||||
* Returns a new, random wheel index with a minimum distance of 42 from pos.
|
||||
*/
|
||||
uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) {
|
||||
uint8_t r = 0;
|
||||
uint8_t x = 0;
|
||||
uint8_t y = 0;
|
||||
uint8_t d = 0;
|
||||
byte WS2812FX::get_random_wheel_index(byte pos) {
|
||||
byte r = 0;
|
||||
byte x = 0;
|
||||
byte y = 0;
|
||||
byte d = 0;
|
||||
|
||||
while(d < 42) {
|
||||
r = random(256);
|
||||
@@ -360,13 +360,13 @@ void WS2812FX::mode_multi_dynamic(void) {
|
||||
void WS2812FX::mode_breath(void) {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // step
|
||||
uint16_t breath_delay_steps[] = { 7, 9, 13, 15, 16, 17, 18, 930, 19, 18, 15, 13, 9, 7, 4, 5, 10 }; // magic numbers for breathing LED
|
||||
uint8_t breath_brightness_steps[] = { 150, 125, 100, 75, 50, 25, 16, 15, 16, 25, 50, 75, 100, 125, 150, 220, 255 }; // even more magic numbers!
|
||||
byte breath_brightness_steps[] = { 150, 125, 100, 75, 50, 25, 16, 15, 16, 25, 50, 75, 100, 125, 150, 220, 255 }; // even more magic numbers!
|
||||
|
||||
if(_counter_mode_call == 0) {
|
||||
_mode_color = breath_brightness_steps[0] + 1;
|
||||
}
|
||||
|
||||
uint8_t breath_brightness = _mode_color; // we use _mode_color to store the brightness
|
||||
byte breath_brightness = _mode_color; // we use _mode_color to store the brightness
|
||||
|
||||
if(_counter_mode_step < 8) {
|
||||
breath_brightness--;
|
||||
@@ -376,7 +376,7 @@ void WS2812FX::mode_breath(void) {
|
||||
|
||||
// update index of current delay when target brightness is reached, start over after the last step
|
||||
if(breath_brightness == breath_brightness_steps[_counter_mode_step]) {
|
||||
_counter_mode_step = (_counter_mode_step + 1) % (sizeof(breath_brightness_steps)/sizeof(uint8_t));
|
||||
_counter_mode_step = (_counter_mode_step + 1) % (sizeof(breath_brightness_steps)/sizeof(byte));
|
||||
}
|
||||
|
||||
for(uint16_t i=0; i < _led_count; i++) {
|
||||
@@ -400,10 +400,10 @@ void WS2812FX::mode_fade(void) {
|
||||
int y = _counter_mode_step - 127;
|
||||
y = 256 - (abs(y) * 2);
|
||||
double z = (double)y/256;
|
||||
uint8_t w = ((_color >> 24) & 0xFF), ws = ((_color_sec >> 24) & 0xFF);
|
||||
uint8_t r = ((_color >> 16) & 0xFF), rs = ((_color_sec >> 16) & 0xFF);
|
||||
uint8_t g = ((_color >> 8) & 0xFF), gs = ((_color_sec >> 8) & 0xFF);
|
||||
uint8_t b = (_color & 0xFF), bs = (_color_sec & 0xFF);
|
||||
byte w = ((_color >> 24) & 0xFF), ws = ((_color_sec >> 24) & 0xFF);
|
||||
byte r = ((_color >> 16) & 0xFF), rs = ((_color_sec >> 16) & 0xFF);
|
||||
byte g = ((_color >> 8) & 0xFF), gs = ((_color_sec >> 8) & 0xFF);
|
||||
byte b = (_color & 0xFF), bs = (_color_sec & 0xFF);
|
||||
w = w+((ws - w)*z);
|
||||
r = r+((rs - r)*z);
|
||||
g = g+((gs - g)*z);
|
||||
@@ -506,7 +506,7 @@ void WS2812FX::mode_rainbow_cycle(void) {
|
||||
* Inspired by the Adafruit examples.
|
||||
*/
|
||||
void WS2812FX::mode_theater_chase(void) {
|
||||
uint8_t j = _counter_mode_call % 6;
|
||||
byte j = _counter_mode_call % 6;
|
||||
if(j % 2 == 0) {
|
||||
for(uint16_t i=0; i < _led_count; i=i+3) {
|
||||
if (!_locked[i+(j/2)])
|
||||
@@ -529,7 +529,7 @@ void WS2812FX::mode_theater_chase(void) {
|
||||
* Inspired by the Adafruit examples.
|
||||
*/
|
||||
void WS2812FX::mode_theater_chase_rainbow(void) {
|
||||
uint8_t j = _counter_mode_call % 6;
|
||||
byte j = _counter_mode_call % 6;
|
||||
if(j % 2 == 0) {
|
||||
for(uint16_t i=0; i < _led_count; i=i+3) {
|
||||
if (!_locked[i+(j/2)])
|
||||
@@ -552,10 +552,10 @@ void WS2812FX::mode_theater_chase_rainbow(void) {
|
||||
* Running lights effect with smooth sine transition.
|
||||
*/
|
||||
void WS2812FX::mode_running_lights(void) {
|
||||
uint8_t w = ((_color >> 24) & 0xFF);
|
||||
uint8_t r = ((_color >> 16) & 0xFF);
|
||||
uint8_t g = ((_color >> 8) & 0xFF);
|
||||
uint8_t b = (_color & 0xFF);
|
||||
byte w = ((_color >> 24) & 0xFF);
|
||||
byte r = ((_color >> 16) & 0xFF);
|
||||
byte g = ((_color >> 8) & 0xFF);
|
||||
byte b = (_color & 0xFF);
|
||||
|
||||
for(uint16_t i=0; i < _led_count; i++) {
|
||||
int s = (sin(i+_counter_mode_call) * 127) + 128;
|
||||
@@ -900,8 +900,8 @@ void WS2812FX::mode_chase_rainbow(void) {
|
||||
* _color_sec flashes running on _color.
|
||||
*/
|
||||
void WS2812FX::mode_chase_flash(void) {
|
||||
const static uint8_t flash_count = 4;
|
||||
uint8_t flash_step = _counter_mode_call % ((flash_count * 2) + 1);
|
||||
const static byte flash_count = 4;
|
||||
byte flash_step = _counter_mode_call % ((flash_count * 2) + 1);
|
||||
|
||||
for(uint16_t i=0; i < _led_count; i++) {
|
||||
if (!_locked[i])
|
||||
@@ -933,8 +933,8 @@ void WS2812FX::mode_chase_flash(void) {
|
||||
* _color_sec flashes running, followed by random color.
|
||||
*/
|
||||
void WS2812FX::mode_chase_flash_random(void) {
|
||||
const static uint8_t flash_count = 4;
|
||||
uint8_t flash_step = _counter_mode_call % ((flash_count * 2) + 1);
|
||||
const static byte flash_count = 4;
|
||||
byte flash_step = _counter_mode_call % ((flash_count * 2) + 1);
|
||||
|
||||
for(uint16_t i=0; i < _counter_mode_step; i++) {
|
||||
if (!_locked[i])
|
||||
@@ -1606,13 +1606,13 @@ void WS2812FX::mode_cc_core()
|
||||
for (int i = 0; i < _cc_num1; i++)
|
||||
{
|
||||
int num = 0;
|
||||
num = ((k + i + _counter_cc_step) % _cc_i2) +_cc_i1;
|
||||
num = ((k + i + _counter_ccStep) % _cc_i2) +_cc_i1;
|
||||
if (_cc_fs) setPixelColor(num, _color);
|
||||
if (_cc_fe) setPixelColor(_cc_i2 - num, _color);
|
||||
}
|
||||
}
|
||||
show();
|
||||
_counter_cc_step = (_counter_cc_step + _cc_step) % (_cc_i2 - _cc_i1);
|
||||
_counter_ccStep = (_counter_ccStep + _ccStep) % (_cc_i2 - _cc_i1);
|
||||
_mode_delay = 10 + ((250 * (uint32_t)(SPEED_MAX - _speed)) / SPEED_MAX);
|
||||
}
|
||||
|
||||
@@ -1816,6 +1816,11 @@ void WS2812FX::setFastUpdateMode(bool y)
|
||||
if (_mode_index == 0) _mode_delay = 20;
|
||||
}
|
||||
|
||||
void WS2812FX::setReverseMode(bool b)
|
||||
{
|
||||
_reverseMode = b;
|
||||
}
|
||||
|
||||
void WS2812FX::driverModeCronixie(bool b)
|
||||
{
|
||||
_cronixieMode = b;
|
||||
@@ -1826,7 +1831,7 @@ void WS2812FX::setCronixieBacklight(bool b)
|
||||
_cronixieBacklightEnabled = b;
|
||||
}
|
||||
|
||||
void WS2812FX::setCronixieDigits(uint8_t d[])
|
||||
void WS2812FX::setCronixieDigits(byte d[])
|
||||
{
|
||||
for (int i = 0; i<6; i++)
|
||||
{
|
||||
@@ -1834,7 +1839,7 @@ void WS2812FX::setCronixieDigits(uint8_t d[])
|
||||
}
|
||||
}
|
||||
|
||||
double WS2812FX::getPowerEstimate(uint8_t leds, uint32_t c, uint8_t b)
|
||||
double WS2812FX::getPowerEstimate(byte leds, uint32_t c, byte b)
|
||||
{
|
||||
double _mARequired = 100; //ESP power
|
||||
double _mul = (double)b/255;
|
||||
@@ -1854,7 +1859,7 @@ double WS2812FX::getPowerEstimate(uint8_t leds, uint32_t c, uint8_t b)
|
||||
//It is NOT guaranteed to stay within the safeAmps margin.
|
||||
//Stay safe with high amperage and have a reasonable safety margin!
|
||||
//I am NOT to be held liable for burned down garages!
|
||||
double WS2812FX::getSafePowerMultiplier(double safeMilliAmps, uint8_t leds, uint32_t c, uint8_t b)
|
||||
double WS2812FX::getSafePowerMultiplier(double safeMilliAmps, byte leds, uint32_t c, byte b)
|
||||
{
|
||||
double _mARequired = getPowerEstimate(leds,c,b);
|
||||
if (_mARequired > safeMilliAmps)
|
||||
@@ -1864,72 +1869,72 @@ double WS2812FX::getSafePowerMultiplier(double safeMilliAmps, uint8_t leds, uint
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
void WS2812FX::setCCIndex1(uint8_t i1)
|
||||
void WS2812FX::setCCIndex1(byte i1)
|
||||
{
|
||||
if (i1 < _led_count-1) _cc_i1 = i1;
|
||||
if (_cc_i2 <= i1) _cc_i2 = i1+1;
|
||||
_counter_cc_step = 0;
|
||||
_counter_ccStep = 0;
|
||||
}
|
||||
|
||||
void WS2812FX::setCCIndex2(uint8_t i2)
|
||||
void WS2812FX::setCCIndex2(byte i2)
|
||||
{
|
||||
if (i2 > _cc_i1) _cc_i2 = i2;
|
||||
if (_cc_i2 >= _led_count) _cc_i2 = _led_count-1;
|
||||
_counter_cc_step = 0;
|
||||
_counter_ccStep = 0;
|
||||
}
|
||||
|
||||
void WS2812FX::setCCStart(uint8_t is)
|
||||
void WS2812FX::setCCStart(byte is)
|
||||
{
|
||||
_cc_is = (is < _cc_i1 || is > _cc_i2) ? _cc_i1 : is;
|
||||
_counter_cc_step = 0;
|
||||
_counter_ccStep = 0;
|
||||
}
|
||||
|
||||
void WS2812FX::setCCNum1(uint8_t np)
|
||||
void WS2812FX::setCCNum1(byte np)
|
||||
{
|
||||
_cc_num1 = np;
|
||||
_counter_cc_step = 0;
|
||||
_counter_ccStep = 0;
|
||||
}
|
||||
|
||||
void WS2812FX::setCCNum2(uint8_t ns)
|
||||
void WS2812FX::setCCNum2(byte ns)
|
||||
{
|
||||
_cc_num2 = ns;
|
||||
_counter_cc_step = 0;
|
||||
_counter_ccStep = 0;
|
||||
}
|
||||
|
||||
void WS2812FX::setCCStep(uint8_t stp)
|
||||
void WS2812FX::setCCStep(byte stp)
|
||||
{
|
||||
_cc_step = stp;
|
||||
_counter_cc_step = 0;
|
||||
_ccStep = stp;
|
||||
_counter_ccStep = 0;
|
||||
}
|
||||
|
||||
void WS2812FX::setCCFS(bool fs)
|
||||
{
|
||||
_cc_fs = fs;
|
||||
_cc_fe = (fs) ? _cc_fe : true;
|
||||
_counter_cc_step = 0;
|
||||
_counter_ccStep = 0;
|
||||
}
|
||||
|
||||
void WS2812FX::setCCFE(bool fe)
|
||||
{
|
||||
_cc_fe = fe;
|
||||
_cc_fs = (fe) ? _cc_fs : true;
|
||||
_counter_cc_step = 0;
|
||||
_counter_ccStep = 0;
|
||||
}
|
||||
|
||||
void WS2812FX::setCustomChase(uint8_t i1, uint8_t i2, uint8_t is, uint8_t np, uint8_t ns, uint8_t stp, bool fs, bool fe)
|
||||
void WS2812FX::setCustomChase(byte i1, byte i2, byte is, byte np, byte ns, byte stp, bool fs, bool fe)
|
||||
{
|
||||
setCCIndex1(i1);
|
||||
setCCIndex2(i2);
|
||||
setCCStart(is);
|
||||
_cc_num1 = np;
|
||||
_cc_num2 = ns;
|
||||
_cc_step = stp;
|
||||
_ccStep = stp;
|
||||
setCCFS(fs);
|
||||
setCCFE(fe);
|
||||
}
|
||||
|
||||
//Added for quick NeoPixelBus compatibility with Adafruit syntax
|
||||
void WS2812FX::setPixelColorRaw(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uint8_t w)
|
||||
void WS2812FX::setPixelColorRaw(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
{
|
||||
#ifdef RGBW
|
||||
NeoPixelBrightnessBus::SetPixelColor(i, RgbwColor(r,g,b,w));
|
||||
@@ -1938,8 +1943,9 @@ void WS2812FX::setPixelColorRaw(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uin
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::setPixelColor(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uint8_t w)
|
||||
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||
{
|
||||
if (_reverseMode) i = _led_count - 1 -i;
|
||||
if (!_cronixieMode)
|
||||
{
|
||||
#ifdef RGBW
|
||||
@@ -1949,13 +1955,13 @@ void WS2812FX::setPixelColor(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uint8_
|
||||
#endif
|
||||
} else {
|
||||
if(i>6)return;
|
||||
uint8_t o = 10*i;
|
||||
byte o = 10*i;
|
||||
if (_cronixieBacklightEnabled && _cronixieDigits[i] <11)
|
||||
{
|
||||
uint8_t rCorr = (int)(((double)((_color_sec>>16) & 0xFF))*_cronixieSecMultiplier);
|
||||
uint8_t gCorr = (int)(((double)((_color_sec>>8) & 0xFF))*_cronixieSecMultiplier);
|
||||
uint8_t bCorr = (int)(((double)((_color_sec) & 0xFF))*_cronixieSecMultiplier);
|
||||
uint8_t wCorr = (int)(((double)((_color_sec>>24) & 0xFF))*_cronixieSecMultiplier);
|
||||
byte rCorr = (int)(((double)((_color_sec>>16) & 0xFF))*_cronixieSecMultiplier);
|
||||
byte gCorr = (int)(((double)((_color_sec>>8) & 0xFF))*_cronixieSecMultiplier);
|
||||
byte bCorr = (int)(((double)((_color_sec) & 0xFF))*_cronixieSecMultiplier);
|
||||
byte wCorr = (int)(((double)((_color_sec>>24) & 0xFF))*_cronixieSecMultiplier);
|
||||
for (int j=o; j< o+19; j++)
|
||||
{
|
||||
setPixelColorRaw(j,rCorr,gCorr,bCorr,wCorr);
|
||||
@@ -1984,7 +1990,7 @@ void WS2812FX::setPixelColor(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uint8_
|
||||
}
|
||||
}
|
||||
|
||||
void WS2812FX::setPixelColor(uint16_t i, uint8_t r, uint8_t g, uint8_t b)
|
||||
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b)
|
||||
{
|
||||
setPixelColor(i,r,g,b,0);
|
||||
}
|
||||
@@ -1999,7 +2005,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
|
||||
if (_cronixieMode)
|
||||
{
|
||||
if(i>6)return 0;
|
||||
uint8_t o = 10*i;
|
||||
byte o = 10*i;
|
||||
switch(_cronixieDigits[i])
|
||||
{
|
||||
case 0: i=o+5; break;
|
||||
@@ -2024,7 +2030,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
|
||||
#endif
|
||||
}
|
||||
|
||||
void WS2812FX::setBrightness(uint8_t b)
|
||||
void WS2812FX::setBrightness(byte b)
|
||||
{
|
||||
_brightness = constrain(b, BRIGHTNESS_MIN, BRIGHTNESS_MAX);
|
||||
NeoPixelBrightnessBus::SetBrightness(_brightness);
|
||||
@@ -2034,12 +2040,17 @@ void WS2812FX::setBrightness(uint8_t b)
|
||||
void WS2812FX::show()
|
||||
{
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#ifdef WORKAROUND_ESP32_BITBANG
|
||||
delay(1);
|
||||
portDISABLE_INTERRUPTS(); //this is a workaround to prevent flickering (see https://github.com/adafruit/Adafruit_NeoPixel/issues/139)
|
||||
#endif
|
||||
#endif
|
||||
NeoPixelBrightnessBus::Show();
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#ifdef WORKAROUND_ESP32_BITBANG
|
||||
portENABLE_INTERRUPTS();
|
||||
#else
|
||||
NeoPixelBrightnessBus::Show();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2059,13 +2070,13 @@ void WS2812FX::begin()
|
||||
|
||||
//For some reason min and max are not declared here
|
||||
|
||||
uint8_t WS2812FX::minval (uint8_t v, uint8_t w)
|
||||
byte WS2812FX::minval (byte v, byte w)
|
||||
{
|
||||
if (w > v) return v;
|
||||
return w;
|
||||
}
|
||||
|
||||
uint8_t WS2812FX::maxval (uint8_t v, uint8_t w)
|
||||
byte WS2812FX::maxval (byte v, byte w)
|
||||
{
|
||||
if (w > v) return w;
|
||||
return v;
|
||||
|
@@ -1,10 +1,16 @@
|
||||
//#define RGBW
|
||||
#define PIN 2 //strip pin. Only change for ESP32
|
||||
#define WORKAROUND_ESP32_BITBANG
|
||||
//see https://github.com/Aircoookie/WLED/issues/2 for flicker free ESP32 support
|
||||
|
||||
//automatically uses the right driver method for each platform
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#ifdef WORKAROUND_ESP32_BITBANG
|
||||
#define PIXELMETHOD NeoEsp32BitBangWs2813Method
|
||||
#else
|
||||
#define PIXELMETHOD NeoEsp32RmtWS2813_V3Method
|
||||
#endif
|
||||
#else
|
||||
#define PIXELMETHOD NeoEsp8266Uart800KbpsMethod
|
||||
#endif
|
||||
|
||||
@@ -208,47 +214,49 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
_cc_i2 = n-1;
|
||||
_cc_num1 = 5;
|
||||
_cc_num2 = 5;
|
||||
_cc_step = 1;
|
||||
_ccStep = 1;
|
||||
_counter_mode_call = 0;
|
||||
_counter_mode_step = 0;
|
||||
_counter_cc_step = 0;
|
||||
_counter_ccStep = 0;
|
||||
_fastStandard = false;
|
||||
_locked = new boolean[n];
|
||||
_cronixieDigits = new uint8_t[6];
|
||||
_reverseMode = false;
|
||||
_locked = new bool[n];
|
||||
_cronixieDigits = new byte[6];
|
||||
}
|
||||
|
||||
void
|
||||
show(void),
|
||||
setPixelColor(uint16_t i, uint8_t r, uint8_t g, uint8_t b),
|
||||
setPixelColor(uint16_t i, byte r, byte g, byte b),
|
||||
init(void),
|
||||
service(void),
|
||||
start(void),
|
||||
stop(void),
|
||||
setMode(uint8_t m),
|
||||
setCustomChase(uint8_t i1, uint8_t i2, uint8_t is, uint8_t np, uint8_t ns, uint8_t stp, bool fs, bool fe),
|
||||
setCCIndex1(uint8_t i1),
|
||||
setCCIndex2(uint8_t i2),
|
||||
setCCStart(uint8_t is),
|
||||
setCCNum1(uint8_t np),
|
||||
setCCNum2(uint8_t ns),
|
||||
setCCStep(uint8_t stp),
|
||||
setMode(byte m),
|
||||
setCustomChase(byte i1, byte i2, byte is, byte np, byte ns, byte stp, bool fs, bool fe),
|
||||
setCCIndex1(byte i1),
|
||||
setCCIndex2(byte i2),
|
||||
setCCStart(byte is),
|
||||
setCCNum1(byte np),
|
||||
setCCNum2(byte ns),
|
||||
setCCStep(byte stp),
|
||||
setCCFS(bool fs),
|
||||
setCCFE(bool fe),
|
||||
setSpeed(uint8_t s),
|
||||
setIntensity(uint8_t in),
|
||||
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),
|
||||
setSpeed(byte s),
|
||||
setIntensity(byte in),
|
||||
increaseSpeed(byte s),
|
||||
decreaseSpeed(byte s),
|
||||
setColor(byte r, byte g, byte b),
|
||||
setColor(byte r, byte g, byte b, byte w),
|
||||
setColor(uint32_t c),
|
||||
setSecondaryColor(uint8_t r, uint8_t g, uint8_t b),
|
||||
setSecondaryColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w),
|
||||
setSecondaryColor(byte r, byte g, byte b),
|
||||
setSecondaryColor(byte r, byte g, byte b, byte w),
|
||||
setSecondaryColor(uint32_t c),
|
||||
setBrightness(uint8_t b),
|
||||
increaseBrightness(uint8_t s),
|
||||
decreaseBrightness(uint8_t s),
|
||||
setBrightness(byte b),
|
||||
increaseBrightness(byte s),
|
||||
decreaseBrightness(byte s),
|
||||
setReverseMode(bool b),
|
||||
driverModeCronixie(bool b),
|
||||
setCronixieDigits(uint8_t* d),
|
||||
setCronixieDigits(byte* d),
|
||||
setCronixieBacklight(bool b),
|
||||
setIndividual(int i),
|
||||
setIndividual(int i, uint32_t col),
|
||||
@@ -265,12 +273,12 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
setLedCount(uint16_t i),
|
||||
setFade(int sp);
|
||||
|
||||
boolean
|
||||
bool
|
||||
isRunning(void),
|
||||
isLocked(int i);
|
||||
|
||||
uint8_t
|
||||
get_random_wheel_index(uint8_t),
|
||||
byte
|
||||
get_random_wheel_index(byte),
|
||||
getMode(void),
|
||||
getSpeed(void),
|
||||
getIntensity(void),
|
||||
@@ -278,12 +286,12 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
getModeCount(void);
|
||||
|
||||
uint32_t
|
||||
color_wheel(uint8_t),
|
||||
color_wheel(byte),
|
||||
getColor(void);
|
||||
|
||||
double
|
||||
getPowerEstimate(uint8_t leds, uint32_t c, uint8_t b),
|
||||
getSafePowerMultiplier(double safeMilliAmps, uint8_t leds, uint32_t c, uint8_t b);
|
||||
getPowerEstimate(byte leds, uint32_t c, byte b),
|
||||
getSafePowerMultiplier(double safeMilliAmps, byte leds, uint32_t c, byte b);
|
||||
|
||||
private:
|
||||
|
||||
@@ -291,8 +299,8 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
begin(void),
|
||||
clear(void),
|
||||
setPixelColor(uint16_t i, uint32_t c),
|
||||
setPixelColor(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uint8_t w),
|
||||
setPixelColorRaw(uint16_t i, uint8_t r, uint8_t g, uint8_t b, uint8_t w),
|
||||
setPixelColor(uint16_t i, byte r, byte g, byte b, byte w),
|
||||
setPixelColorRaw(uint16_t i, byte r, byte g, byte b, byte w),
|
||||
dofade(void),
|
||||
strip_off(void),
|
||||
strip_off_respectLock(void),
|
||||
@@ -357,21 +365,22 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
mode_cc_blink(void),
|
||||
mode_cc_random(void);
|
||||
|
||||
boolean
|
||||
bool
|
||||
_triggered,
|
||||
_fastStandard,
|
||||
_reverseMode,
|
||||
_cronixieMode,
|
||||
_cronixieBacklightEnabled,
|
||||
_cc_fs,
|
||||
_cc_fe,
|
||||
_running;
|
||||
|
||||
boolean*
|
||||
bool*
|
||||
_locked;
|
||||
|
||||
uint8_t
|
||||
minval(uint8_t v, uint8_t w),
|
||||
maxval(uint8_t v, uint8_t w),
|
||||
byte
|
||||
minval(byte v, byte w),
|
||||
maxval(byte v, byte w),
|
||||
_mode_index,
|
||||
_speed,
|
||||
_intensity,
|
||||
@@ -380,10 +389,10 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
_cc_is,
|
||||
_cc_num1,
|
||||
_cc_num2,
|
||||
_cc_step,
|
||||
_ccStep,
|
||||
_brightness;
|
||||
|
||||
uint8_t*
|
||||
byte*
|
||||
_cronixieDigits;
|
||||
|
||||
uint16_t
|
||||
@@ -395,7 +404,7 @@ class WS2812FX : public NeoPixelBrightnessBus<PIXELFEATURE, PIXELMETHOD> {
|
||||
_color_sec,
|
||||
_counter_mode_call,
|
||||
_counter_mode_step,
|
||||
_counter_cc_step,
|
||||
_counter_ccStep,
|
||||
_mode_color,
|
||||
_mode_color_sec,
|
||||
_mode_delay;
|
||||
|
@@ -46,7 +46,7 @@
|
||||
if (this.readyState == 4) {
|
||||
if (this.status == 200) {
|
||||
if (this.responseXML != null) {
|
||||
d.Cf.SA.value = this.responseXML.getElementsByTagName('act')[0].childNodes[0].nodeValue;
|
||||
d.Cf.SA.value = this.responseXML.getElementsByTagName('ac')[0].childNodes[0].nodeValue;
|
||||
d.Cf.SR.value = this.responseXML.getElementsByTagName('cl')[0].childNodes[0].nodeValue;
|
||||
d.Cf.SG.value = this.responseXML.getElementsByTagName('cl')[1].childNodes[0].nodeValue;
|
||||
d.Cf.SB.value = this.responseXML.getElementsByTagName('cl')[2].childNodes[0].nodeValue;
|
||||
@@ -69,7 +69,7 @@
|
||||
nState = 0;
|
||||
nState = (this.responseXML.getElementsByTagName('nr')[0].innerHTML)!=0?1:0;
|
||||
nState += (this.responseXML.getElementsByTagName('ns')[0].innerHTML)!=0?2:0;
|
||||
d.getElementsByClassName("desc")[0].innerHTML = this.responseXML.getElementsByTagName('desc')[0].innerHTML;
|
||||
d.getElementsByClassName("desc")[0].innerHTML = this.responseXML.getElementsByTagName('ds')[0].innerHTML;
|
||||
UV();
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
344
wled00/htmls01.h
344
wled00/htmls01.h
@@ -37,37 +37,37 @@ const char PAGE_settings_wifi1[] PROGMEM = R"=====(
|
||||
<body onload="GetV()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save & Reboot</button><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button><hr>
|
||||
<h2>WiFi setup</h2>
|
||||
<h3>Connect to existing network</h3>
|
||||
Network name (SSID, empty to not connect): <br><input name="CSSID" maxlength="32"> <br>
|
||||
Network password: <br> <input type="password" name="CPASS" maxlength="63"> <br>
|
||||
Static IP (leave at 0.0.0.0 for DHCP): <br>
|
||||
<input name="CSIP0" type="number" min="0" max="255" required> .
|
||||
<input name="CSIP1" type="number" min="0" max="255" required> .
|
||||
<input name="CSIP2" type="number" min="0" max="255" required> .
|
||||
<input name="CSIP3" type="number" min="0" max="255" required> <br>
|
||||
Static gateway: <br>
|
||||
<input name="CSGW0" type="number" min="0" max="255" required> .
|
||||
<input name="CSGW1" type="number" min="0" max="255" required> .
|
||||
<input name="CSGW2" type="number" min="0" max="255" required> .
|
||||
<input name="CSGW3" type="number" min="0" max="255" required> <br>
|
||||
Static subnet mask: <br>
|
||||
<input name="CSSN0" type="number" min="0" max="255" required> .
|
||||
<input name="CSSN1" type="number" min="0" max="255" required> .
|
||||
<input name="CSSN2" type="number" min="0" max="255" required> .
|
||||
<input name="CSSN3" type="number" min="0" max="255" required> <br>
|
||||
mDNS address (leave empty for no mDNS): <br/>
|
||||
http:// <input name="CMDNS" maxlength="32"> .local <br>
|
||||
Try connecting before opening AP for: <input name="APWTM" type="number" min="0" max="255" required> s <br>
|
||||
Client IP: <span class="sip"> Not connected </span> <br>
|
||||
Network name (SSID, empty to not connect): <br><input name="CS" maxlength="32"><br>
|
||||
Network password: <br> <input type="password" name="CP" maxlength="63"><br>
|
||||
Static IP (leave at 0.0.0.0 for DHCP):<br>
|
||||
<input name="I0" type="number" min="0" max="255" required> .
|
||||
<input name="I1" type="number" min="0" max="255" required> .
|
||||
<input name="I2" type="number" min="0" max="255" required> .
|
||||
<input name="I3" type="number" min="0" max="255" required><br>
|
||||
Static gateway:<br>
|
||||
<input name="G0" type="number" min="0" max="255" required> .
|
||||
<input name="G1" type="number" min="0" max="255" required> .
|
||||
<input name="G2" type="number" min="0" max="255" required> .
|
||||
<input name="G3" type="number" min="0" max="255" required><br>
|
||||
Static subnet mask:<br>
|
||||
<input name="S0" type="number" min="0" max="255" required> .
|
||||
<input name="S1" type="number" min="0" max="255" required> .
|
||||
<input name="S2" type="number" min="0" max="255" required> .
|
||||
<input name="S3" type="number" min="0" max="255" required><br>
|
||||
mDNS address (leave empty for no mDNS):<br/>
|
||||
http:// <input name="CM" maxlength="32"> .local<br>
|
||||
Try connecting before opening AP for: <input name="AT" type="number" min="0" max="255" required> s <br>
|
||||
Client IP: <span class="sip"> Not connected </span><br>
|
||||
<h3>Configure Access Point</h3>
|
||||
AP SSID (leave empty for no AP): <br> <input name="APSSID" maxlength="32"> <br>
|
||||
Hide AP name: <input type="checkbox" name="APHSSID"> <br>
|
||||
AP password (leave empty for open): <br> <input type="password" name="APPASS" maxlength="63"> <br>
|
||||
Access Point WiFi channel: <input name="APCHAN" type="number" min="1" max="13" required> <br>
|
||||
AP IP: <span class="sip"> Not active </span> <hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save & Reboot</button>
|
||||
AP SSID (leave empty for no AP):<br> <input name="AS" maxlength="32"><br>
|
||||
Hide AP name: <input type="checkbox" name="AH"><br>
|
||||
AP password (leave empty for open):<br> <input type="password" name="AP" maxlength="63"> <br>
|
||||
Access Point WiFi channel: <input name="AC" type="number" min="1" max="13" required><br>
|
||||
AP IP: <span class="sip"> Not active </span><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -83,46 +83,46 @@ const char PAGE_settings_leds1[] PROGMEM = R"=====(
|
||||
<body onload="GetV()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save</button><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||
<h2>LED setup</h2>
|
||||
LED count (max. 255): <input name="LEDCN" type="number" min="1" max="255" required> <br>
|
||||
LED count (max. 255): <input name="LC" type="number" min="1" max="255" required><br>
|
||||
<i>The default boot color is always saved in preset slot 0.</i><br>
|
||||
Alternatively, apply preset <input name="BOOTP" type="number" min="0" max="25" required> at boot<br>
|
||||
Alternatively, apply preset <input name="BP" type="number" min="0" max="25" required> at boot<br>
|
||||
Default RGB color:
|
||||
<input name="CLDFR" type="number" min="0" max="255" required>
|
||||
<input name="CLDFG" type="number" min="0" max="255" required>
|
||||
<input name="CLDFB" type="number" min="0" max="255" required> <br>
|
||||
Default brightness: <input name="CLDFA" type="number" min="0" max="255" required> (0-255) <br>
|
||||
Default white value (only RGBW, -1 to disable): <input name="CLDFW" type="number" min="-1" max="255" required> <br>
|
||||
Default effect ID: <input name="FXDEF" type="number" min="0" max="57" required> <br>
|
||||
Default effect speed: <input name="SXDEF" type="number" min="0" max="255" required> <br>
|
||||
Default effect intensity: <input name="IXDEF" type="number" min="0" max="255" required> <br>
|
||||
<input name="CR" type="number" min="0" max="255" required>
|
||||
<input name="CG" type="number" min="0" max="255" required>
|
||||
<input name="CB" type="number" min="0" max="255" required><br>
|
||||
Default brightness: <input name="CA" type="number" min="0" max="255" required> (0-255)<br>
|
||||
Default white value (only RGBW, -1 to disable): <input name="CW" type="number" min="-1" max="255" required><br>
|
||||
Default effect ID: <input name="FX" type="number" min="0" max="57" required> <br>
|
||||
Default effect speed: <input name="SX" type="number" min="0" max="255" required> <br>
|
||||
Default effect intensity: <input name="IX" type="number" min="0" max="255" required> <br>
|
||||
Default secondary RGB(W):<br>
|
||||
<input name="CSECR" type="number" min="0" max="255" required>
|
||||
<input name="CSECG" type="number" min="0" max="255" required>
|
||||
<input name="CSECB" type="number" min="0" max="255" required>
|
||||
<input name="CSECW" type="number" min="0" max="255" required><br>
|
||||
Ignore and use current color, brightness and effects: <input type="checkbox" name="CBEOR"> <br>
|
||||
Turn on after power up/reset: <input type="checkbox" name="BOOTN"> <br>
|
||||
Use Gamma correction for brightness: <input type="checkbox" name="GCBRI"> <br>
|
||||
Use Gamma correction for color: <input type="checkbox" name="GCRGB"> <br>
|
||||
Brightness factor: <input name="NRBRI" type="number" min="0" max="255" required> %
|
||||
<input name="SR" type="number" min="0" max="255" required>
|
||||
<input name="SG" type="number" min="0" max="255" required>
|
||||
<input name="SB" type="number" min="0" max="255" required>
|
||||
<input name="SW" type="number" min="0" max="255" required><br>
|
||||
Ignore and use current color, brightness and effects: <input type="checkbox" name="IS"><br>
|
||||
Turn on after power up/reset: <input type="checkbox" name="BO"><br>
|
||||
Use Gamma correction for brightness: <input type="checkbox" name="GB"><br>
|
||||
Use Gamma correction for color: <input type="checkbox" name="GC"><br>
|
||||
Brightness factor: <input name="BF" type="number" min="0" max="255" required> %
|
||||
<h3>Transitions</h3>
|
||||
Fade: <input type="checkbox" name="TFADE"><br>
|
||||
Sweep: <input type="checkbox" name="TSWEE"> Invert direction: <input type="checkbox" name="TSDIR"><br>
|
||||
Transition Delay: <input name="TDLAY" maxlength="5" size="2"> ms
|
||||
Fade: <input type="checkbox" name="TF"><br>
|
||||
Sweep: <input type="checkbox" name="TS"> Invert direction: <input type="checkbox" name="TI"><br>
|
||||
Transition Delay: <input name="TD" maxlength="5" size="2"> ms
|
||||
<h3>Timed light</h3>
|
||||
Default Duration: <input name="TLDUR" type="number" min="1" max="255" required> min<br>
|
||||
Default Target brightness: <input name="TLBRI" type="number" min="0" max="255" required><br>
|
||||
Fade down: <input type="checkbox" name="TLFDE"><br>
|
||||
Default Duration: <input name="TL" type="number" min="1" max="255" required> min<br>
|
||||
Default Target brightness: <input name="TB" type="number" min="0" max="255" required><br>
|
||||
Fade down: <input type="checkbox" name="TW"><br>
|
||||
<h3>Advanced</h3>
|
||||
Default overlay ID: <input name="OLDEF" type="number" min="0" max="255" required> <br>
|
||||
WARLS offset: <input name="WOFFS" type="number" min="-255" max="255" required><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save</button>
|
||||
Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br>
|
||||
Init LEDs after WiFi: <input type="checkbox" name="EI"><br>
|
||||
WARLS offset: <input name="WO" type="number" min="-255" max="255" required><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
)=====";
|
||||
|
||||
const char PAGE_settings_ui0[] PROGMEM = R"=====(
|
||||
@@ -137,12 +137,12 @@ const char PAGE_settings_ui1[] PROGMEM = R"=====(
|
||||
<body onload="S()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save</button><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||
<h2>Web Setup</h2>
|
||||
Server description: <input name="DESC" maxlength="32"><br>
|
||||
Use HSB sliders instead of RGB by default: <input type="checkbox" name="COLMD"><br>
|
||||
Server description: <input name="DS" maxlength="32"><br>
|
||||
Use HSB sliders instead of RGB by default: <input type="checkbox" name="MD"><br>
|
||||
Color Theme:
|
||||
<select name="THEME" onchange="Ct()">
|
||||
<select name="TH" onchange="Ct()">
|
||||
<option value="0" selected>Night</option>
|
||||
<option value="1">Modern</option>
|
||||
<option value="2">Bright</option>
|
||||
@@ -154,7 +154,7 @@ Color Theme:
|
||||
<option value="8">Air</option>
|
||||
<option value="9">Nixie</option>
|
||||
<option value="10">Terminal</option>
|
||||
<option value="11">Placeholder</option>
|
||||
<option value="11">C64</option>
|
||||
<option value="12">Placeholder</option>
|
||||
<option value="13">Placeholder</option>
|
||||
<option value="14">The End</option>
|
||||
@@ -162,15 +162,15 @@ Color Theme:
|
||||
</select><br>
|
||||
<div id="cth">
|
||||
Please specify your custom hex colors (e.g. FF0000 for red)<br>
|
||||
Custom accent color: <input maxlength=9 name="CCOL0"><br>
|
||||
Custom background: <input maxlength=9 name="CCOL1"><br>
|
||||
Custom panel color: <input maxlength=9 name="CCOL2"><br>
|
||||
Custom icon color: <input maxlength=9 name="CCOL3"><br>
|
||||
Custom shadow: <input maxlength=9 name="CCOL4"><br>
|
||||
Custom text color: <input maxlength=9 name="CCOL5"><br></div>
|
||||
Use font: <input maxlength=32 name="CFONT"><br>
|
||||
Custom accent color: <input maxlength=9 name="C0"><br>
|
||||
Custom background: <input maxlength=9 name="C1"><br>
|
||||
Custom panel color: <input maxlength=9 name="C2"><br>
|
||||
Custom icon color: <input maxlength=9 name="C3"><br>
|
||||
Custom shadow: <input maxlength=9 name="C4"><br>
|
||||
Custom text color: <input maxlength=9 name="C5"><br></div>
|
||||
Use font: <input maxlength=32 name="CF"><br>
|
||||
Make sure the font you use is installed on your system!<br>
|
||||
<hr><button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save</button>
|
||||
<hr><button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -186,39 +186,34 @@ const char PAGE_settings_sync1[] PROGMEM = R"=====(
|
||||
<body onload="GetV()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save</button><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||
<h2>Sync setup</h2>
|
||||
<h3>Button setup</h3>
|
||||
On/Off button enabled: <input type="checkbox" name="BTNON">
|
||||
On/Off button enabled: <input type="checkbox" name="BT">
|
||||
<h3>WLED Broadcast</h3>
|
||||
UDP Port: <input name="NUDPP" maxlength="5" size="4"><br>
|
||||
Receive <input type="checkbox" name="NRCBR">Brightness, <input type="checkbox" name="NRCCL">Color, and <input type="checkbox" name="NRCFX">Effects<br>
|
||||
Send notifications on direct change: <input type="checkbox" name="NSDIR"> <br>
|
||||
Send notifications on button press: <input type="checkbox" name="NSBTN"> <br>
|
||||
Send Alexa notifications: <input type="checkbox" name="NSALX"> <br>
|
||||
<!--Send Philips Hue change notifications: <input type="checkbox" name="NSHUE">-->
|
||||
UDP Port: <input name="UP" maxlength="5" size="4"><br>
|
||||
Receive <input type="checkbox" name="RB">Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox" name="RX">Effects<br>
|
||||
Send notifications on direct change: <input type="checkbox" name="SD"><br>
|
||||
Send notifications on button press: <input type="checkbox" name="SB"><br>
|
||||
Send Alexa notifications: <input type="checkbox" name="SA"><br>
|
||||
Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
||||
Send notifications twice: <input type="checkbox" name="S2">
|
||||
<h3>Alexa Voice Assistant</h3>
|
||||
Emulate Alexa device: <input type="checkbox" name="ALEXA"> <br>
|
||||
Alexa invocation name: <input name="AINVN" maxlength="32"><br>
|
||||
Emulate Alexa device: <input type="checkbox" name="AL"><br>
|
||||
Alexa invocation name: <input name="AI" maxlength="32"><br>
|
||||
<h3>Philips Hue</h3>
|
||||
Coming soon! Not yet implemented!
|
||||
<!--<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
||||
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
||||
Hue Bridge IP:<br>
|
||||
<input name="HUIP0" type="number" min="0" max="255" required> .
|
||||
<input name="HUIP1" type="number" min="0" max="255" required> .
|
||||
<input name="HUIP2" type="number" min="0" max="255" required> .
|
||||
<input name="HUIP3" type="number" min="0" max="255" required> <br>
|
||||
<b>For successful pairing, press the pushlink button on the bridge, then save this page!</b><br>
|
||||
<input name="H0" type="number" min="0" max="255" required> .
|
||||
<input name="H1" type="number" min="0" max="255" required> .
|
||||
<input name="H2" type="number" min="0" max="255" required> .
|
||||
<input name="H3" type="number" min="0" max="255" required><br>
|
||||
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
|
||||
(when first connecting)<br>
|
||||
<i> Use 0 for group and light to turn off sending/receiving </i><br>
|
||||
Update Hue group <input name="HUEGR" type="number" min="0" max="99" required> <br>
|
||||
Send <input type="checkbox" name="HUEIO"> On/Off, <input type="checkbox" name="HUEBR"> Brightness, and <input type="checkbox" name="HUECL"> Color<br>
|
||||
Poll Hue light <input name="HUELI" type="number" min="0" max="99" required> every <input name="HUEPL" type="number" min="100" max="62000" required> ms<br>
|
||||
Then, receive <input type="checkbox" name="HURIO"> On/Off, <input type="checkbox" name="HURBR"> Brightness, and <input type="checkbox" name="HURCL"> Color<br>
|
||||
After device color update, ignore Hue updates for <input name="HUELI" type="number" min="0" max="255" required> minutes<br>
|
||||
Hue status: <span class="hms"> Internal ESP error! </span>-->
|
||||
<hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save</button>
|
||||
Poll Hue light <input name="HL" type="number" min="1" max="99" required> every <input name="HI" type="number" min="100" max="65000" required> ms: <input type="checkbox" name="HP"><br>
|
||||
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
|
||||
Hue status: <span class="hms"> Internal ESP Error! </span><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -227,77 +222,84 @@ Hue status: <span class="hms"> Internal ESP error! </span>-->
|
||||
const char PAGE_settings_time0[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html><head><title>Time Settings</title>
|
||||
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings");}function B(){window.open("/settings","_self");}function GetV(){var d = document;
|
||||
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings");}function B(){window.open("/settings","_self");}function S(){GetV();Cs();}function gId(s){return document.getElementById(s);}function Cs(){gId("cac").style.display="none";gId("coc").style.display="block";gId("ccc").style.display="none";if (gId("ca").selected){gId("cac").style.display="block";}if (gId("cc").selected){gId("coc").style.display="none";gId("ccc").style.display="block";}if (gId("cn").selected){gId("coc").style.display="none";}}function GetV(){var d = document;
|
||||
)=====";
|
||||
const char PAGE_settings_time1[] PROGMEM = R"=====(
|
||||
</head>
|
||||
<body onload="GetV()">
|
||||
<body onload="S()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save</button><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
|
||||
<h2>Time setup</h2>
|
||||
Get time from NTP server: <input type="checkbox" name="NTPON"><br>
|
||||
<!--NTP server: <input name="NTPSR" maxlength="32"><br>
|
||||
Get time from NTP server: <input type="checkbox" name="NT"><br>
|
||||
Use 24h format: <input type="checkbox" name="CF"><br>
|
||||
Time zone:
|
||||
<select name="TZONE">
|
||||
<option value="1" selected>GMT(UTC)</option>
|
||||
<option value="2">GMT/BST</option>
|
||||
<option value="3">CET/CEST</option>
|
||||
<option value="4">EET/EEST</option>
|
||||
<option value="5">US-EST/EDT</option>
|
||||
<option value="6">US-CST/CDT</option>
|
||||
<option value="7">US-MST/MDT</option>
|
||||
<option value="8">US-AZ</option>
|
||||
<option value="9">US-PST/PDT</option>
|
||||
<option value="10">CST(AWST)</option>
|
||||
<option value="11">JST(KST)</option>
|
||||
<option value="12">AEST/AEDT</option>
|
||||
<option value="13">NZST/NZDT</option>
|
||||
<select name="TZ">
|
||||
<option value="0" selected>GMT(UTC)</option>
|
||||
<option value="1">GMT/BST</option>
|
||||
<option value="2">CET/CEST</option>
|
||||
<option value="3">EET/EEST</option>
|
||||
<option value="4">US-EST/EDT</option>
|
||||
<option value="5">US-CST/CDT</option>
|
||||
<option value="6">US-MST/MDT</option>
|
||||
<option value="7">US-AZ</option>
|
||||
<option value="8">US-PST/PDT</option>
|
||||
<option value="9">CST(AWST)</option>
|
||||
<option value="10">JST(KST)</option>
|
||||
<option value="11">AEST/AEDT</option>
|
||||
<option value="12">NZST/NZDT</option>
|
||||
</select><br>
|
||||
Hour/Min offset: <input name="TOFSH" type="number" min="-255" max="255" required> <input name="TOFSM" type="number" min="-255" max="255" required><br>-->
|
||||
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
|
||||
Current local time is <span class="times">unknown</span>.
|
||||
<h3>Weather</h3>
|
||||
Coming soon! Not yet implemented!
|
||||
<!--Get yours on open weather API.<br>
|
||||
City code: <input name="WCITY" maxlength="32"><br>
|
||||
Change color depending on weather: <input type="checkbox" name="WCCOL"><br>
|
||||
Daylight Emulation: <input type="checkbox" name="WDAYL"><br>
|
||||
Reverse (turns on at sunset): <input type="checkbox" name="WREVL"><br>
|
||||
Fade duration: <input name="WSDUR" type="number" min="0" max="255" required><br>
|
||||
Sunrise/Sunset Offset: <input name="WSOFS" type="number" min="-255" max="255" required>-->
|
||||
<h3>Clock</h3>
|
||||
Clock Overlay:
|
||||
<select name="OL" onchange="Cs()">
|
||||
<option value="0" id="cn" selected>None</option>
|
||||
<option value="1">Static color</option>
|
||||
<option value="2" id="ca">Analog Clock</option>
|
||||
<option value="3">Single Digit Clock</option>
|
||||
<option value="4" id="cc">Cronixie Clock</option>
|
||||
</select><br>
|
||||
<div id="coc">
|
||||
First LED: <input name="O1" type="number" min="0" max="255" required> Last LED: <input name="O2" type="number" min="0" max="255" required><br>
|
||||
<div id="cac">
|
||||
12h LED: <input name="OM" type="number" min="0" max="255" required><br>
|
||||
Show 5min marks: <input type="checkbox" name="O5"><br></div>
|
||||
Seconds (as trail): <input type="checkbox" name="OS"><br>
|
||||
</div>
|
||||
<div id="ccc">
|
||||
Cronixie Display: <input name="CX" maxlength="6"><br>
|
||||
Cronixie Backlight: <input type="checkbox" name="CB"><br>
|
||||
</div>
|
||||
Countdown Mode: <input type="checkbox" name="CE"><br>
|
||||
Countdown Goal: Year: 20 <input name="CY" type="number" min="0" max="99" required> Month: <input name="CI" type="number" min="1" max="12" required> Day: <input name="CD" type="number" min="1" max="31" required><br>
|
||||
Hour: <input name="CH" type="number" min="0" max="23" required> Minute: <input name="CM" type="number" min="0" max="59" required> Second: <input name="CS" type="number" min="0" max="59" required><br>
|
||||
<h3>Advanced Macros</h3>
|
||||
Coming soon! Not yet implemented!
|
||||
<!--Define API macros here:<br>
|
||||
0: <input name="MCR00" maxlength="64"><br>
|
||||
1: <input name="MCR01" maxlength="64"><br>
|
||||
2: <input name="MCR02" maxlength="64"><br>
|
||||
3: <input name="MCR03" maxlength="64"><br>
|
||||
4: <input name="MCR04" maxlength="64"><br>
|
||||
5: <input name="MCR05" maxlength="64"><br>
|
||||
6: <input name="MCR06" maxlength="64"><br>
|
||||
7: <input name="MCR07" maxlength="64"><br>
|
||||
8: <input name="MCR08" maxlength="64"><br>
|
||||
9: <input name="MCR09" maxlength="64"><br>
|
||||
10: <input name="MCR10" maxlength="64"><br>
|
||||
11: <input name="MCR11" maxlength="64"><br>
|
||||
12: <input name="MCR12" maxlength="64"><br>
|
||||
13: <input name="MCR13" maxlength="64"><br>
|
||||
14: <input name="MCR14" maxlength="64"><br>
|
||||
15: <input name="MCR15" maxlength="64"><br>
|
||||
<br>
|
||||
<i>Use -1 to use the default action instead of a macro</i><br>
|
||||
<--1st Time-Controlled Macro:
|
||||
Alexa On/Off Macros: <input name="MCA0I" type="number" min="-1" max="15" required> <input name="MCA0O" type="number" min="-1" max="15" required><br>
|
||||
<--Emulate 2nd Alexa device:
|
||||
|
||||
Emulate 3rd Alexa device:
|
||||
Button Macro: <input name="MCBT0" type="number" min="-1" max="15" required><br>
|
||||
Button Long Press Macro: <input name="MCBT1" type="number" min="-1" max="15" required><br>
|
||||
<--Sunrise Macro
|
||||
Sunset Macro
|
||||
Countdown-Over Macro: <input name="MCNTD" type="number" min="-1" max="15" required><br>-->
|
||||
<hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save</button>
|
||||
Define API macros here:<br>
|
||||
1: <input name="M1" maxlength="64"><br>
|
||||
2: <input name="M2" maxlength="64"><br>
|
||||
3: <input name="M3" maxlength="64"><br>
|
||||
4: <input name="M4" maxlength="64"><br>
|
||||
5: <input name="M5" maxlength="64"><br>
|
||||
6: <input name="M6" maxlength="64"><br>
|
||||
7: <input name="M7" maxlength="64"><br>
|
||||
8: <input name="M8" maxlength="64"><br>
|
||||
9: <input name="M9" maxlength="64"><br>
|
||||
10: <input name="M10" maxlength="64"><br>
|
||||
11: <input name="M11" maxlength="64"><br>
|
||||
12: <input name="M12" maxlength="64"><br>
|
||||
13: <input name="M13" maxlength="64"><br>
|
||||
14: <input name="M14" maxlength="64"><br>
|
||||
15: <input name="M15" maxlength="64"><br>
|
||||
16: <input name="M16" maxlength="64"><br><br>
|
||||
<i>Use 0 for the default action instead of a macro</i><br>
|
||||
Time controlled macros coming soon!<br>
|
||||
Boot Macro: <input name="MB" type="number" min="0" max="16" required><br>
|
||||
Alexa On/Off Macros: <input name="A0" type="number" min="0" max="16" required> <input name="A1" type="number" min="0" max="16" required><br>
|
||||
Button Macro: <input name="MP" type="number" min="0" max="16" required> Long Press: <input name="ML" type="number" min="0" max="16" required><br>
|
||||
Countdown-Over Macro: <input name="MC" type="number" min="0" max="16" required><br>
|
||||
Timed-Light-Over Macro: <input name="MN" type="number" min="0" max="16" required><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -314,26 +316,26 @@ const char PAGE_settings_sec1[] PROGMEM = R"=====(
|
||||
<body onload="GetV()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
<div class="helpB"><button type="button" onclick="H()">?</button></div>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save & Reboot</button><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button><hr>
|
||||
<h2>Security & Update setup</h2>
|
||||
Enable OTA lock: <input type="checkbox" name="NOOTA"><br>
|
||||
Passphrase: <input type="password" name="OPASS" maxlength="32"><br>
|
||||
Enable OTA lock: <input type="checkbox" name="NO"><br>
|
||||
Passphrase: <input type="password" name="OP" maxlength="32"><br>
|
||||
To enable OTA, for security reasons you need to also enter the correct password!<br>
|
||||
The password may/should be changed when OTA is enabled.<br>
|
||||
<b>Disable OTA when not in use, otherwise an attacker could reflash device software!</b><br>
|
||||
The password should be changed when OTA is enabled.<br>
|
||||
<b>Disable OTA when not in use, otherwise an attacker can reflash device software!</b><br>
|
||||
<i>Settings on this page are only changable if OTA lock is disabled!</i><br>
|
||||
Deny access to WiFi settings if locked: <input type="checkbox" name="OWIFI"><br><br>
|
||||
Disable recovery AP: <input type="checkbox" name="NORAP"><br>
|
||||
In case of a connection error there will be no wireless recovery possible!<br>
|
||||
Deny access to WiFi settings if locked: <input type="checkbox" name="OW"><br><br>
|
||||
Disable recovery AP: <input type="checkbox" name="NA"><br>
|
||||
In case of an error there will be no wireless recovery possible!<br>
|
||||
Completely disables all Access Point functions.<br><br>
|
||||
Factory reset: <input type="checkbox" name="RESET"><br>
|
||||
Factory reset: <input type="checkbox" name="RS"><br>
|
||||
All EEPROM content (settings) will be erased.<br><br>
|
||||
HTTP traffic is not encrypted. An attacker in the same network could intercept form data!
|
||||
HTTP traffic is unencrypted. An attacker in the same network can intercept form data!
|
||||
<h3>Software Update</h3>
|
||||
<button type="button" onclick="U()">Manual OTA Update</button><br>
|
||||
Enable ArduinoOTA: <input type="checkbox" name="AROTA"><br>
|
||||
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
|
||||
<h3>About</h3>
|
||||
<a href="https://github.com/Aircoookie/WLED">WLED</a> version 0.5.0<br>
|
||||
<a href="https://github.com/Aircoookie/WLED">WLED</a> version 0.6.0<br>
|
||||
(c) 2016-2018 Christian Schwinne <br>
|
||||
<i>Licensed under the MIT license</i><br><br>
|
||||
<i>Uses libraries:</i><br>
|
||||
@@ -344,7 +346,7 @@ Enable ArduinoOTA: <input type="checkbox" name="AROTA"><br>
|
||||
<i><a href="https://github.com/Aircoookie/Espalexa">Espalexa</a> by Aircoookie (modified)</i><br><br>
|
||||
<i>UI icons by <a href="https://linearicons.com">Linearicons</a> created by <a href="https://perxis.com">Perxis</a>! (CC-BY-SA 4.0)</i> <br><br>
|
||||
Server message: <span class="msg"> Response error! </span><hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit" name="SUBM">Save & Reboot</button>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -281,9 +281,9 @@ void setTime(time_t t) {
|
||||
nextSyncTime = (uint32_t)t + syncInterval;
|
||||
Status = timeSet;
|
||||
prevMillis = millis(); // restart counting from now (thanks to Korman for this fix)
|
||||
}
|
||||
}
|
||||
|
||||
void setTime(int hr,int min,int sec,int dy, int mnth, int yr){
|
||||
time_t getUnixTime(int hr,int min,int sec,int dy, int mnth, int yr){
|
||||
// year can be given as full four digit year or two digts (2010 or 10 for 2010);
|
||||
//it is converted to years since 1970
|
||||
if( yr > 99)
|
||||
@@ -296,7 +296,11 @@ void setTime(int hr,int min,int sec,int dy, int mnth, int yr){
|
||||
tm.Hour = hr;
|
||||
tm.Minute = min;
|
||||
tm.Second = sec;
|
||||
setTime(makeTime(tm));
|
||||
return makeTime(tm);
|
||||
}
|
||||
|
||||
void setTime(int hr,int min,int sec,int dy, int mnth, int yr){
|
||||
setTime(getUnixTime(hr,min,sec,dy,mnth,yr));
|
||||
}
|
||||
|
||||
void adjustTime(long adjustment) {
|
||||
|
@@ -120,6 +120,7 @@ int year(time_t t); // the year for the given time
|
||||
time_t now(); // return the current time as seconds since Jan 1 1970
|
||||
void setTime(time_t t);
|
||||
void setTime(int hr,int min,int sec,int day, int month, int yr);
|
||||
time_t getUnixTime(int hr,int min,int sec,int day, int month, int yr); //added by Aircoookie to get epoch time
|
||||
void adjustTime(long adjustment);
|
||||
|
||||
/* date strings */
|
||||
|
@@ -27,12 +27,11 @@ enum month_t {Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
|
||||
//or when standard time begins.
|
||||
struct TimeChangeRule
|
||||
{
|
||||
char abbrev[6]; //five chars max
|
||||
uint8_t week; //First, Second, Third, Fourth, or Last week of the month
|
||||
uint8_t dow; //day of week, 1=Sun, 2=Mon, ... 7=Sat
|
||||
uint8_t month; //1=Jan, 2=Feb, ... 12=Dec
|
||||
uint8_t hour; //0-23
|
||||
int offset; //offset from UTC in minutes
|
||||
int16_t offset; //offset from UTC in minutes
|
||||
};
|
||||
|
||||
class Timezone
|
||||
|
@@ -15,7 +15,7 @@ const char* ESP8266HTTPUpdateServer::_serverIndex =
|
||||
R"(<html><head><script>function B(){window.history.back()}</script></head><body><h2>WLED Software Update</h2><br>Get the latest binaries on the <a href="https://github.com/Aircoookie/WLED/tree/master/bin">project GitHub page</a>!<br>
|
||||
<i>Unsure which binary is correct? Go to the <a href="./build">/build subpage</a> for the details of this version.</i><br>
|
||||
<b>Be sure to upload a valid .bin file for your ESP! Otherwise you'll need USB recovery!</b><br>
|
||||
<br><br><button onclick="B()\">Back</button><br><br>
|
||||
<br><br><button onclick='B()'>Back</button><br><br>
|
||||
<form method='POST' action='' enctype='multipart/form-data'>
|
||||
<input type='file' name='update'>
|
||||
<input type='submit' value='Update!'>
|
||||
|
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
/*
|
||||
* @title WLED project sketch
|
||||
* @version 0.5.0
|
||||
* @version 0.6.0
|
||||
* @author Christian Schwinne
|
||||
*/
|
||||
|
||||
@@ -12,14 +12,17 @@
|
||||
#include <WiFi.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include "src/dependencies/webserver/WebServer.h"
|
||||
#include <HTTPClient.h>
|
||||
#else
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266HTTPClient.h>
|
||||
#endif
|
||||
#include <EEPROM.h>
|
||||
#include <ArduinoOTA.h>
|
||||
#include <WiFiUDP.h>
|
||||
#include <DNSServer.h>
|
||||
#include "src/dependencies/webserver/ESP8266HTTPUpdateServer.h"
|
||||
#include "src/dependencies/time/Time.h"
|
||||
#include "src/dependencies/time/TimeLib.h"
|
||||
@@ -30,203 +33,191 @@
|
||||
#include "WS2812FX.h"
|
||||
|
||||
//version in format yymmddb (b = daily build)
|
||||
#define VERSION 1802222
|
||||
const String versionString = "0.5.0";
|
||||
#define VERSION 1803151
|
||||
const String versionString = "0.6.0";
|
||||
|
||||
//AP and OTA default passwords (change them!)
|
||||
String appass = "wled1234";
|
||||
String otapass = "wledota";
|
||||
String apPass = "wled1234";
|
||||
String otaPass = "wledota";
|
||||
|
||||
//If you have an RGBW strip, also uncomment first line in WS2812FX.h!
|
||||
bool useRGBW = false;
|
||||
|
||||
//overlays, needed for clocks etc.
|
||||
#define USEOVERLAYS
|
||||
|
||||
//support for the CRONIXIE clock by Diamex (disable overlays!)
|
||||
//#define CRONIXIE
|
||||
|
||||
//spiffs FS only useful for debug (only ESP8266)
|
||||
//#define USEFS
|
||||
|
||||
//to toggle usb serial debug (un)comment following line
|
||||
//to toggle usb serial debug (un)comment following line(s)
|
||||
//#define DEBUG
|
||||
|
||||
//Hardware-settings (only changeble via code)
|
||||
#define LEDCOUNT 255 //maximum, exact count set-able via settings
|
||||
uint8_t buttonPin = 0; //needs pull-up
|
||||
uint8_t auxPin = 15; //use e.g. for external relay
|
||||
uint8_t auxDefaultState = 0; //0: input 1: high 2: low
|
||||
uint8_t auxTriggeredState = 0; //0: input 1: high 2: low
|
||||
|
||||
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; //Central European Summer Time
|
||||
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; //Central European Standard Time
|
||||
Timezone TZ(CEST, CET);
|
||||
TimeChangeRule *tcr; //pointer to the time change rule, use to get the TZ abbrev
|
||||
time_t local;
|
||||
|
||||
//cronixie defaults
|
||||
#ifdef CRONIXIE
|
||||
#undef LEDCOUNT
|
||||
#define LEDCOUNT 60
|
||||
uint8_t ledcount = 6;
|
||||
String apssid = "CRONIXIE-AP";
|
||||
String alexaInvocationName = "Clock";
|
||||
char cronixieDefault[] = "HHMMSS";
|
||||
long cronixieRefreshMs = 497;
|
||||
unsigned long cronixieRefreshedTime;
|
||||
byte dP[]{0,0,0,0,0,0};
|
||||
bool cronixieUseAMPM = false;
|
||||
bool cronixieBacklight = true;
|
||||
bool cronixieCountdown = false;
|
||||
bool ntpEnabled = true;
|
||||
#endif
|
||||
byte buttonPin = 0; //needs pull-up
|
||||
byte auxPin = 15; //use e.g. for external relay
|
||||
byte auxDefaultState = 0; //0: input 1: high 2: low
|
||||
byte auxTriggeredState = 0; //0: input 1: high 2: low
|
||||
|
||||
//Default CONFIG
|
||||
String serverDescription = versionString;
|
||||
uint8_t currentTheme = 0;
|
||||
String clientssid = "Your_Network_Here";
|
||||
String clientpass = "Dummy_Pass";
|
||||
String cmdns = "led";
|
||||
#ifndef CRONIXIE
|
||||
uint8_t ledcount = 100;
|
||||
String apssid = "WLED-AP";
|
||||
#endif
|
||||
uint8_t apchannel = 1;
|
||||
uint8_t aphide = 0;
|
||||
uint8_t apWaitTimeSecs = 32;
|
||||
boolean recoveryAPDisabled = false;
|
||||
IPAddress staticip(0, 0, 0, 0);
|
||||
IPAddress staticgateway(0, 0, 0, 0);
|
||||
IPAddress staticsubnet(255, 255, 255, 0);
|
||||
IPAddress staticdns(8, 8, 8, 8); //only for NTP
|
||||
byte currentTheme = 0;
|
||||
String clientSSID = "Your_Network";
|
||||
String clientPass = "";
|
||||
String cmDNS = "led";
|
||||
byte ledCount = 10; //lowered to prevent accidental overcurrent
|
||||
String apSSID = ""; //AP off by default (unless setup)
|
||||
byte apChannel = 1;
|
||||
byte apHide = 0;
|
||||
byte apWaitTimeSecs = 32;
|
||||
bool recoveryAPDisabled = false;
|
||||
IPAddress staticIP(0, 0, 0, 0);
|
||||
IPAddress staticGateway(0, 0, 0, 0);
|
||||
IPAddress staticSubnet(255, 255, 255, 0);
|
||||
IPAddress staticDNS(8, 8, 8, 8); //only for NTP
|
||||
bool useHSB = false, useHSBDefault = false;
|
||||
bool turnOnAtBoot = true;
|
||||
uint8_t bootPreset = 0;
|
||||
byte col_s[]{255, 159, 0};
|
||||
byte col_sec_s[]{0, 0, 0};
|
||||
byte white_s = 0;
|
||||
byte white_sec_s = 0;
|
||||
byte bri_s = 127;
|
||||
uint8_t nightlightTargetBri = 0, bri_nl_t;
|
||||
bool initLedsLast = false;
|
||||
byte bootPreset = 0;
|
||||
byte colS[]{255, 159, 0};
|
||||
byte colSecS[]{0, 0, 0};
|
||||
byte whiteS = 0;
|
||||
byte whiteSecS = 0;
|
||||
byte briS = 127;
|
||||
byte nightlightTargetBri = 0;
|
||||
bool fadeTransition = true;
|
||||
bool sweepTransition = false, sweepDirection = true;
|
||||
uint16_t transitionDelay = 1200;
|
||||
bool reverseMode = false;
|
||||
bool otaLock = false, wifiLock = false;
|
||||
bool aOtaEnabled = true;
|
||||
bool onlyAP = false;
|
||||
bool buttonEnabled = true;
|
||||
bool notifyDirect = true, notifyButton = true, notifyDirectDefault = true, alexaNotify = false, macroNotify = false;
|
||||
bool notifyDirect = true, notifyButton = true, notifyDirectDefault = true, alexaNotify = false, macroNotify = false, notifyTwice = false;
|
||||
bool receiveNotifications = true, receiveNotificationBrightness = true, receiveNotificationColor = true, receiveNotificationEffects = true;
|
||||
uint8_t briMultiplier = 100;
|
||||
uint8_t nightlightDelayMins = 60;
|
||||
byte briMultiplier = 100;
|
||||
byte nightlightDelayMins = 60;
|
||||
bool nightlightFade = true;
|
||||
uint16_t udpPort = 21324;
|
||||
uint8_t effectDefault = 0;
|
||||
uint8_t effectSpeedDefault = 75;
|
||||
uint8_t effectIntensityDefault = 128;
|
||||
byte effectDefault = 0;
|
||||
byte effectSpeedDefault = 75;
|
||||
byte effectIntensityDefault = 128;
|
||||
//NTP stuff
|
||||
#ifndef CRONIXIE
|
||||
boolean ntpEnabled = false;
|
||||
#endif
|
||||
IPAddress ntpServerIP;
|
||||
const char* ntpServerName = "pool.ntp.org";
|
||||
bool ntpEnabled = false;
|
||||
String ntpServerName = "0.wled.pool.ntp.org";
|
||||
//custom chase
|
||||
uint8_t cc_numPrimary = 2;
|
||||
uint8_t cc_numSecondary = 4;
|
||||
uint8_t cc_index1 = 0;
|
||||
uint8_t cc_index2 = ledcount -1;
|
||||
bool cc_fromStart = true, cc_fromEnd = false;
|
||||
uint8_t cc_step = 1;
|
||||
uint8_t cc_start = 0;
|
||||
byte ccNumPrimary = 2;
|
||||
byte ccNumSecondary = 4;
|
||||
byte ccIndex1 = 0;
|
||||
byte ccIndex2 = ledCount -1;
|
||||
bool ccFromStart = true, ccFromEnd = false;
|
||||
byte ccStep = 1;
|
||||
byte ccStart = 0;
|
||||
|
||||
//alexa
|
||||
boolean alexaEnabled = true;
|
||||
#ifndef CRONIXIE
|
||||
bool alexaEnabled = true;
|
||||
String alexaInvocationName = "Light";
|
||||
#endif
|
||||
uint8_t alexaOnMacro = 255, alexaOffMacro = 255;
|
||||
uint8_t buttonMacro = 255, countdownMacro = 255;
|
||||
|
||||
byte macroBoot = 0, macroNl = 0;
|
||||
byte macroAlexaOn = 0, macroAlexaOff = 0;
|
||||
byte macroButton = 0, macroCountdown = 0, macroLongPress = 0;
|
||||
|
||||
unsigned long countdownTime = 1514764800L;
|
||||
|
||||
double transitionResolution = 0.011;
|
||||
|
||||
//hue
|
||||
bool huePollingEnabled = false, hueAttempt = false;
|
||||
uint16_t huePollIntervalMs = 2500;
|
||||
String hueApiKey = "api";
|
||||
byte huePollLightId = 1;
|
||||
IPAddress hueIP = (0,0,0,0);
|
||||
bool notifyHue = true;
|
||||
bool hueApplyOnOff = true, hueApplyBri = true, hueApplyColor = true;
|
||||
|
||||
//Internal vars
|
||||
byte col[]{0, 0, 0};
|
||||
byte col_old[]{0, 0, 0};
|
||||
byte col_t[]{0, 0, 0};
|
||||
byte col_it[]{0, 0, 0};
|
||||
byte col_sec[]{0, 0, 0};
|
||||
byte col_sec_it[]{0, 0, 0};
|
||||
byte white, white_old, white_t, white_it;
|
||||
byte white_sec, white_sec_it;
|
||||
uint8_t lastRandomIndex = 0;
|
||||
byte colOld[]{0, 0, 0};
|
||||
byte colT[]{0, 0, 0};
|
||||
byte colIT[]{0, 0, 0};
|
||||
byte colSec[]{0, 0, 0};
|
||||
byte colSecIT[]{0, 0, 0};
|
||||
byte white, whiteOld, whiteT, whiteIT;
|
||||
byte whiteSec, whiteSecIT;
|
||||
byte lastRandomIndex = 0;
|
||||
uint16_t transitionDelayTemp = transitionDelay;
|
||||
unsigned long transitionStartTime;
|
||||
unsigned long nightlightStartTime;
|
||||
float tper_last = 0;
|
||||
float tperLast = 0;
|
||||
byte bri = 0;
|
||||
byte bri_old = 0;
|
||||
byte bri_t = 0;
|
||||
byte bri_it = 0;
|
||||
byte bri_last = 127;
|
||||
boolean transitionActive = false;
|
||||
boolean buttonPressedBefore = false;
|
||||
long buttonPressedTime = 0;
|
||||
boolean nightlightActive = false;
|
||||
boolean nightlightActive_old = false;
|
||||
int nightlightDelayMs;
|
||||
uint8_t effectCurrent = 0;
|
||||
uint8_t effectSpeed = 75;
|
||||
uint8_t effectIntensity = 128;
|
||||
boolean udpConnected = false;
|
||||
byte udpIn[1026];
|
||||
byte briOld = 0;
|
||||
byte briT = 0;
|
||||
byte briIT = 0;
|
||||
byte briLast = 127;
|
||||
bool transitionActive = false;
|
||||
bool buttonPressedBefore = false;
|
||||
unsigned long buttonPressedTime = 0;
|
||||
unsigned long notificationSentTime = 0;
|
||||
byte notificationSentCallMode = 0;
|
||||
bool notificationTwoRequired = false;
|
||||
bool nightlightActive = false;
|
||||
bool nightlightActiveOld = false;
|
||||
uint32_t nightlightDelayMs;
|
||||
byte briNlT;
|
||||
byte effectCurrent = 0;
|
||||
byte effectSpeed = 75;
|
||||
byte effectIntensity = 128;
|
||||
bool onlyAP = false;
|
||||
bool udpConnected = false;
|
||||
String cssCol[]={"","","","","",""};
|
||||
String cssFont="Verdana";
|
||||
String cssColorString="";
|
||||
//NTP stuff
|
||||
boolean ntpConnected = false;
|
||||
unsigned int ntpLocalPort = 2390;
|
||||
const int NTP_PACKET_SIZE = 48;
|
||||
byte ntpPacketBuffer[NTP_PACKET_SIZE];
|
||||
unsigned long ntpLastSyncTime = 999000000L;
|
||||
unsigned long ntpPacketSentTime = 999000000L;
|
||||
const unsigned long seventyYears = 2208988800UL;
|
||||
bool ntpConnected = false;
|
||||
byte currentTimezone = 0;
|
||||
time_t local;
|
||||
int utcOffsetSecs = 0;
|
||||
|
||||
//hue
|
||||
String hueError = "Inactive";
|
||||
uint16_t hueFailCount = 0;
|
||||
float hueXLast=0, hueYLast=0;
|
||||
uint16_t hueHueLast=0, hueCtLast=0;
|
||||
byte hueSatLast=0, hueBriLast=0;
|
||||
long hueLastRequestSent = 0;
|
||||
uint32_t huePollIntervalMsTemp = huePollIntervalMs;
|
||||
|
||||
//overlay stuff
|
||||
uint8_t overlayDefault = 0;
|
||||
uint8_t overlayCurrent = 0;
|
||||
#ifdef USEOVERLAYS
|
||||
int overlayMin = 0, overlayMax = 79; //bb: 35, 46, t: 0, 79
|
||||
int analogClock12pixel = 25; //bb: 41, t: 25
|
||||
bool overlayDimBg = true;
|
||||
boolean analogClockSecondsTrail = false;
|
||||
boolean analogClock5MinuteMarks = false;
|
||||
boolean nixieClockDisplaySeconds = false;
|
||||
boolean nixieClock12HourFormat = false;
|
||||
boolean overlayReverse = true;
|
||||
uint8_t overlaySpeed = 200;
|
||||
long overlayRefreshMs = 200;
|
||||
byte overlayDefault = 0;
|
||||
byte overlayCurrent = 0;
|
||||
byte overlayMin = 0, overlayMax = ledCount-1;
|
||||
byte analogClock12pixel = 0;
|
||||
bool analogClockSecondsTrail = false;
|
||||
bool analogClock5MinuteMarks = false;
|
||||
byte overlaySpeed = 200;
|
||||
unsigned long overlayRefreshMs = 200;
|
||||
unsigned long overlayRefreshedTime;
|
||||
int overlayArr[6];
|
||||
int overlayDur[6];
|
||||
int overlayPauseDur[6];
|
||||
uint16_t overlayDur[6];
|
||||
uint16_t overlayPauseDur[6];
|
||||
int nixieClockI = -1;
|
||||
boolean nixiePause;
|
||||
#endif
|
||||
bool nixiePause;
|
||||
byte countdownYear=19, countdownMonth=1, countdownDay=1, countdownHour=0, countdownMin=0, countdownSec=0; //year is actual year -2000
|
||||
bool countdownOverTriggered = true;
|
||||
//cronixie
|
||||
String cronixieDisplay = "HHMMSS";
|
||||
byte dP[]{0,0,0,0,0,0};
|
||||
bool useAMPM = false;
|
||||
bool cronixieBacklight = true;
|
||||
bool countdownMode = false;
|
||||
bool cronixieInit = false;
|
||||
|
||||
int arlsTimeoutMillis = 2500;
|
||||
boolean arlsTimeout = false;
|
||||
long arlsTimeoutTime;
|
||||
boolean arlsSign = true;
|
||||
uint8_t auxTime = 0;
|
||||
uint32_t arlsTimeoutMillis = 2500;
|
||||
bool arlsTimeout = false;
|
||||
unsigned long arlsTimeoutTime;
|
||||
byte auxTime = 0;
|
||||
unsigned long auxStartTime;
|
||||
boolean auxActive, auxActiveBefore;
|
||||
boolean showWelcomePage = false;
|
||||
bool auxActive, auxActiveBefore;
|
||||
bool showWelcomePage = false;
|
||||
|
||||
boolean useGammaCorrectionBri = false;
|
||||
boolean useGammaCorrectionRGB = true;
|
||||
bool useGammaCorrectionBri = false;
|
||||
bool useGammaCorrectionRGB = true;
|
||||
int arlsOffset = -22; //10: -22 assuming arls52
|
||||
|
||||
//alexa udp
|
||||
@@ -236,25 +227,28 @@ unsigned int portMulti = 1900;
|
||||
char packetBuffer[255];
|
||||
String escapedMac;
|
||||
|
||||
//dns server
|
||||
DNSServer dnsServer;
|
||||
bool dnsActive = false;
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
WebServer server(80);
|
||||
#else
|
||||
ESP8266WebServer server(80);
|
||||
#endif
|
||||
HTTPClient hueClient;
|
||||
ESP8266HTTPUpdateServer httpUpdater;
|
||||
WiFiUDP notifierUdp;
|
||||
WiFiUDP ntpUdp;
|
||||
IPAddress ntpServerIP;
|
||||
unsigned int ntpLocalPort = 2390;
|
||||
const uint16_t NTP_PACKET_SIZE = 48;
|
||||
byte ntpPacketBuffer[NTP_PACKET_SIZE];
|
||||
unsigned long ntpLastSyncTime = 999000000L;
|
||||
unsigned long ntpPacketSentTime = 999000000L;
|
||||
|
||||
WS2812FX strip = WS2812FX(LEDCOUNT);
|
||||
|
||||
//eeprom Version code, enables default settings instead of 0 init on update
|
||||
#define EEPVER 4
|
||||
//0 -> old version, default
|
||||
//1 -> 0.4p 1711272 and up
|
||||
//2 -> 0.4p 1711302 and up
|
||||
//3 -> 0.4 1712121 and up
|
||||
//4 -> 0.5.0 and up
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_PRINT(x) Serial.print (x)
|
||||
#define DEBUG_PRINTLN(x) Serial.println (x)
|
||||
@@ -276,7 +270,7 @@ int lastWifiState = 3;
|
||||
long wifiStateChangedTime = 0;
|
||||
#endif
|
||||
|
||||
const uint8_t gamma8[] = {
|
||||
const byte gamma8[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
|
||||
@@ -300,7 +294,7 @@ void serveMessage(int,String,String,int=255);
|
||||
|
||||
void down()
|
||||
{
|
||||
bri_t = 0;
|
||||
briT = 0;
|
||||
setAllLeds();
|
||||
DEBUG_PRINTLN("MODULE TERMINATED");
|
||||
while (1) {delay(1000);}
|
||||
@@ -308,7 +302,7 @@ void down()
|
||||
|
||||
void reset()
|
||||
{
|
||||
bri_t = 0;
|
||||
briT = 0;
|
||||
setAllLeds();
|
||||
DEBUG_PRINTLN("MODULE RESET");
|
||||
ESP.restart();
|
||||
@@ -322,21 +316,19 @@ void loop() {
|
||||
server.handleClient();
|
||||
handleNotifications();
|
||||
handleTransitions();
|
||||
userLoop();
|
||||
yield();
|
||||
handleButton();
|
||||
handleNetworkTime();
|
||||
if (!otaLock && aOtaEnabled) ArduinoOTA.handle();
|
||||
#ifdef CRONIXIE
|
||||
handleCronixie();
|
||||
#endif
|
||||
handleAlexa();
|
||||
handleOverlays();
|
||||
if (!arlsTimeout) //block stuff if WARLS is enabled
|
||||
{
|
||||
if (dnsActive) dnsServer.processNextRequest();
|
||||
handleHue();
|
||||
handleNightlight();
|
||||
#ifdef USEOVERLAYS
|
||||
handleOverlays();
|
||||
#endif
|
||||
if (bri_t) strip.service(); //do not update strip if off, prevents flicker on ESP32
|
||||
if (briT) strip.service(); //do not update strip if off, prevents flicker on ESP32
|
||||
}
|
||||
|
||||
//DEBUG
|
||||
|
@@ -1,9 +1,21 @@
|
||||
/*
|
||||
* Methods to handle saving and loading to non-volatile memory
|
||||
* EEPROM Map: https://github.com/Aircoookie/WLED/wiki/EEPROM-Map
|
||||
*/
|
||||
|
||||
#define EEPSIZE 2048
|
||||
#define EEPSIZE 3072
|
||||
|
||||
//eeprom Version code, enables default settings instead of 0 init on update
|
||||
#define EEPVER 6
|
||||
//0 -> old version, default
|
||||
//1 -> 0.4p 1711272 and up
|
||||
//2 -> 0.4p 1711302 and up
|
||||
//3 -> 0.4 1712121 and up
|
||||
//4 -> 0.5.0 and up
|
||||
//5 -> 0.5.1 and up
|
||||
//6 -> 0.6.0 and up
|
||||
|
||||
//todo add settings
|
||||
void clearEEPROM()
|
||||
{
|
||||
for (int i = 0; i < EEPSIZE; i++)
|
||||
@@ -26,59 +38,60 @@ void saveSettingsToEEPROM()
|
||||
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
EEPROM.write(i, clientssid.charAt(i));
|
||||
EEPROM.write(i, clientSSID.charAt(i));
|
||||
}
|
||||
for (int i = 32; i < 96; ++i)
|
||||
{
|
||||
EEPROM.write(i, clientpass.charAt(i-32));
|
||||
EEPROM.write(i, clientPass.charAt(i-32));
|
||||
}
|
||||
for (int i = 96; i < 128; ++i)
|
||||
{
|
||||
EEPROM.write(i, cmdns.charAt(i-96));
|
||||
EEPROM.write(i, cmDNS.charAt(i-96));
|
||||
}
|
||||
for (int i = 128; i < 160; ++i)
|
||||
{
|
||||
EEPROM.write(i, apssid.charAt(i-128));
|
||||
EEPROM.write(i, apSSID.charAt(i-128));
|
||||
}
|
||||
for (int i = 160; i < 224; ++i)
|
||||
{
|
||||
EEPROM.write(i, appass.charAt(i-160));
|
||||
EEPROM.write(i, apPass.charAt(i-160));
|
||||
}
|
||||
EEPROM.write(224, nightlightDelayMins);
|
||||
EEPROM.write(225, nightlightFade);
|
||||
EEPROM.write(226, notifyDirectDefault);
|
||||
EEPROM.write(227, apchannel);
|
||||
EEPROM.write(228, aphide);
|
||||
EEPROM.write(229, ledcount);
|
||||
EEPROM.write(227, apChannel);
|
||||
EEPROM.write(228, apHide);
|
||||
EEPROM.write(229, ledCount);
|
||||
EEPROM.write(230, notifyButton);
|
||||
//231 was notifyNightlight
|
||||
EEPROM.write(231, notifyTwice);
|
||||
EEPROM.write(232, buttonEnabled);
|
||||
//233 reserved for first boot flag
|
||||
EEPROM.write(234, staticip[0]);
|
||||
EEPROM.write(235, staticip[1]);
|
||||
EEPROM.write(236, staticip[2]);
|
||||
EEPROM.write(237, staticip[3]);
|
||||
EEPROM.write(238, staticgateway[0]);
|
||||
EEPROM.write(239, staticgateway[1]);
|
||||
EEPROM.write(240, staticgateway[2]);
|
||||
EEPROM.write(241, staticgateway[3]);
|
||||
EEPROM.write(242, staticsubnet[0]);
|
||||
EEPROM.write(243, staticsubnet[1]);
|
||||
EEPROM.write(244, staticsubnet[2]);
|
||||
EEPROM.write(245, staticsubnet[3]);
|
||||
EEPROM.write(246, col_s[0]);
|
||||
EEPROM.write(247, col_s[1]);
|
||||
EEPROM.write(248, col_s[2]);
|
||||
EEPROM.write(249, bri_s);
|
||||
EEPROM.write(234, staticIP[0]);
|
||||
EEPROM.write(235, staticIP[1]);
|
||||
EEPROM.write(236, staticIP[2]);
|
||||
EEPROM.write(237, staticIP[3]);
|
||||
EEPROM.write(238, staticGateway[0]);
|
||||
EEPROM.write(239, staticGateway[1]);
|
||||
EEPROM.write(240, staticGateway[2]);
|
||||
EEPROM.write(241, staticGateway[3]);
|
||||
EEPROM.write(242, staticSubnet[0]);
|
||||
EEPROM.write(243, staticSubnet[1]);
|
||||
EEPROM.write(244, staticSubnet[2]);
|
||||
EEPROM.write(245, staticSubnet[3]);
|
||||
EEPROM.write(246, colS[0]);
|
||||
EEPROM.write(247, colS[1]);
|
||||
EEPROM.write(248, colS[2]);
|
||||
EEPROM.write(249, briS);
|
||||
EEPROM.write(250, receiveNotificationBrightness);
|
||||
EEPROM.write(251, fadeTransition);
|
||||
EEPROM.write(252, reverseMode);
|
||||
EEPROM.write(253, (transitionDelay >> 0) & 0xFF);
|
||||
EEPROM.write(254, (transitionDelay >> 8) & 0xFF);
|
||||
EEPROM.write(255, briMultiplier);
|
||||
//255,250,231,230,226 notifier bytes
|
||||
for (int i = 256; i < 288; ++i)
|
||||
{
|
||||
EEPROM.write(i, otapass.charAt(i-256));
|
||||
EEPROM.write(i, otaPass.charAt(i-256));
|
||||
}
|
||||
EEPROM.write(288, nightlightTargetBri);
|
||||
EEPROM.write(289, otaLock);
|
||||
@@ -92,8 +105,8 @@ void saveSettingsToEEPROM()
|
||||
EEPROM.write(325, effectSpeedDefault);
|
||||
EEPROM.write(326, effectIntensityDefault);
|
||||
EEPROM.write(327, ntpEnabled);
|
||||
//328 reserved for timezone setting
|
||||
//329 reserved for dst setting
|
||||
EEPROM.write(328, currentTimezone);
|
||||
EEPROM.write(329, useAMPM);
|
||||
EEPROM.write(330, useGammaCorrectionBri);
|
||||
EEPROM.write(331, useGammaCorrectionRGB);
|
||||
EEPROM.write(332, overlayDefault);
|
||||
@@ -103,33 +116,37 @@ void saveSettingsToEEPROM()
|
||||
EEPROM.write(i, alexaInvocationName.charAt(i-334));
|
||||
}
|
||||
EEPROM.write(366, alexaNotify);
|
||||
EEPROM.write(367, arlsSign);
|
||||
EEPROM.write(367, (arlsOffset>=0));
|
||||
EEPROM.write(368, abs(arlsOffset));
|
||||
EEPROM.write(369, turnOnAtBoot);
|
||||
EEPROM.write(370, useHSBDefault);
|
||||
EEPROM.write(371, white_s);
|
||||
EEPROM.write(371, whiteS);
|
||||
EEPROM.write(372, useRGBW);
|
||||
EEPROM.write(373, sweepTransition);
|
||||
EEPROM.write(374, sweepDirection);
|
||||
EEPROM.write(375, apWaitTimeSecs);
|
||||
EEPROM.write(376, recoveryAPDisabled);
|
||||
EEPROM.write(377, EEPVER); //eeprom was updated to latest
|
||||
EEPROM.write(378, col_sec_s[0]);
|
||||
EEPROM.write(379, col_sec_s[1]);
|
||||
EEPROM.write(380, col_sec_s[2]);
|
||||
EEPROM.write(381, white_sec_s);
|
||||
EEPROM.write(382, cc_index1);
|
||||
EEPROM.write(383, cc_index2);
|
||||
EEPROM.write(384, cc_numPrimary);
|
||||
EEPROM.write(385, cc_numSecondary);
|
||||
EEPROM.write(386, cc_fromStart);
|
||||
EEPROM.write(387, cc_fromEnd);
|
||||
EEPROM.write(388, cc_step);
|
||||
EEPROM.write(378, colSecS[0]);
|
||||
EEPROM.write(379, colSecS[1]);
|
||||
EEPROM.write(380, colSecS[2]);
|
||||
EEPROM.write(381, whiteSecS);
|
||||
EEPROM.write(382, ccIndex1);
|
||||
EEPROM.write(383, ccIndex2);
|
||||
EEPROM.write(384, ccNumPrimary);
|
||||
EEPROM.write(385, ccNumSecondary);
|
||||
EEPROM.write(386, ccFromStart);
|
||||
EEPROM.write(387, ccFromEnd);
|
||||
EEPROM.write(388, ccStep);
|
||||
EEPROM.write(389, bootPreset);
|
||||
EEPROM.write(390, aOtaEnabled);
|
||||
EEPROM.write(391, receiveNotificationColor);
|
||||
EEPROM.write(392, receiveNotificationEffects);
|
||||
EEPROM.write(393, wifiLock);
|
||||
EEPROM.write(394, (abs(utcOffsetSecs) >> 0) & 0xFF);
|
||||
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
|
||||
EEPROM.write(396, (utcOffsetSecs<0)); //is negative
|
||||
EEPROM.write(397, initLedsLast);
|
||||
|
||||
for (int k=0;k<6;k++){
|
||||
int in = 900+k*8;
|
||||
@@ -143,6 +160,53 @@ void saveSettingsToEEPROM()
|
||||
{
|
||||
EEPROM.write(i, cssFont.charAt(i-950));
|
||||
}
|
||||
|
||||
EEPROM.write(2048, huePollingEnabled);
|
||||
//EEPROM.write(2049, hueUpdatingEnabled);
|
||||
for (int i = 2050; i < 2054; ++i)
|
||||
{
|
||||
EEPROM.write(i, hueIP[i-2050]);
|
||||
}
|
||||
for (int i = 2054; i < 2100; ++i)
|
||||
{
|
||||
EEPROM.write(i, hueApiKey.charAt(i-2054));
|
||||
}
|
||||
EEPROM.write(2100, (huePollIntervalMs >> 0) & 0xFF);
|
||||
EEPROM.write(2101, (huePollIntervalMs >> 8) & 0xFF);
|
||||
EEPROM.write(2102, notifyHue);
|
||||
EEPROM.write(2103, hueApplyOnOff);
|
||||
EEPROM.write(2104, hueApplyBri);
|
||||
EEPROM.write(2105, hueApplyColor);
|
||||
EEPROM.write(2106, huePollLightId);
|
||||
|
||||
EEPROM.write(2150, overlayMin);
|
||||
EEPROM.write(2151, overlayMax);
|
||||
EEPROM.write(2152, analogClock12pixel);
|
||||
EEPROM.write(2153, analogClock5MinuteMarks);
|
||||
EEPROM.write(2154, analogClockSecondsTrail);
|
||||
EEPROM.write(2155, countdownMode);
|
||||
EEPROM.write(2156, countdownYear);
|
||||
EEPROM.write(2157, countdownMonth);
|
||||
EEPROM.write(2158, countdownDay);
|
||||
EEPROM.write(2159, countdownHour);
|
||||
EEPROM.write(2160, countdownMin);
|
||||
EEPROM.write(2161, countdownSec);
|
||||
setCountdown();
|
||||
|
||||
for (int i = 2165; i < 2171; ++i)
|
||||
{
|
||||
EEPROM.write(i, cronixieDisplay.charAt(i-2165));
|
||||
}
|
||||
EEPROM.write(2171, cronixieBacklight);
|
||||
setCronixie();
|
||||
|
||||
EEPROM.write(2175, macroBoot);
|
||||
EEPROM.write(2176, macroAlexaOn);
|
||||
EEPROM.write(2177, macroAlexaOff);
|
||||
EEPROM.write(2178, macroButton);
|
||||
EEPROM.write(2179, macroLongPress);
|
||||
EEPROM.write(2180, macroCountdown);
|
||||
EEPROM.write(2181, macroNl);
|
||||
|
||||
EEPROM.commit();
|
||||
}
|
||||
@@ -157,77 +221,78 @@ void loadSettingsFromEEPROM(bool first)
|
||||
}
|
||||
int lastEEPROMversion = EEPROM.read(377); //last EEPROM version before update
|
||||
|
||||
clientssid = "";
|
||||
clientSSID = "";
|
||||
for (int i = 0; i < 32; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
clientssid += char(EEPROM.read(i));
|
||||
clientSSID += char(EEPROM.read(i));
|
||||
}
|
||||
clientpass = "";
|
||||
clientPass = "";
|
||||
for (int i = 32; i < 96; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
clientpass += char(EEPROM.read(i));
|
||||
clientPass += char(EEPROM.read(i));
|
||||
}
|
||||
cmdns = "";
|
||||
cmDNS = "";
|
||||
for (int i = 96; i < 128; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
cmdns += char(EEPROM.read(i));
|
||||
cmDNS += char(EEPROM.read(i));
|
||||
}
|
||||
apssid = "";
|
||||
apSSID = "";
|
||||
for (int i = 128; i < 160; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
apssid += char(EEPROM.read(i));
|
||||
apSSID += char(EEPROM.read(i));
|
||||
}
|
||||
appass = "";
|
||||
apPass = "";
|
||||
for (int i = 160; i < 224; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
appass += char(EEPROM.read(i));
|
||||
apPass += char(EEPROM.read(i));
|
||||
}
|
||||
nightlightDelayMins = EEPROM.read(224);
|
||||
nightlightFade = EEPROM.read(225);
|
||||
notifyDirectDefault = EEPROM.read(226);
|
||||
notifyDirect = notifyDirectDefault;
|
||||
apchannel = EEPROM.read(227);
|
||||
if (apchannel > 13 || apchannel < 1) apchannel = 1;
|
||||
aphide = EEPROM.read(228);
|
||||
if (aphide > 1) aphide = 1;
|
||||
ledcount = EEPROM.read(229); if (ledcount > LEDCOUNT) ledcount = LEDCOUNT;
|
||||
apChannel = EEPROM.read(227);
|
||||
if (apChannel > 13 || apChannel < 1) apChannel = 1;
|
||||
apHide = EEPROM.read(228);
|
||||
if (apHide > 1) apHide = 1;
|
||||
ledCount = EEPROM.read(229); if (ledCount > LEDCOUNT) ledCount = LEDCOUNT;
|
||||
notifyButton = EEPROM.read(230);
|
||||
//231 was notifyNightlight
|
||||
notifyTwice = EEPROM.read(231);
|
||||
buttonEnabled = EEPROM.read(232);
|
||||
staticip[0] = EEPROM.read(234);
|
||||
staticip[1] = EEPROM.read(235);
|
||||
staticip[2] = EEPROM.read(236);
|
||||
staticip[3] = EEPROM.read(237);
|
||||
staticgateway[0] = EEPROM.read(238);
|
||||
staticgateway[1] = EEPROM.read(239);
|
||||
staticgateway[2] = EEPROM.read(240);
|
||||
staticgateway[3] = EEPROM.read(241);
|
||||
staticsubnet[0] = EEPROM.read(242);
|
||||
staticsubnet[1] = EEPROM.read(243);
|
||||
staticsubnet[2] = EEPROM.read(244);
|
||||
staticsubnet[3] = EEPROM.read(245);
|
||||
col_s[0] = EEPROM.read(246); col[0] = col_s[0];
|
||||
col_s[1] = EEPROM.read(247); col[1] = col_s[1];
|
||||
col_s[2] = EEPROM.read(248); col[2] = col_s[2];
|
||||
bri_s = EEPROM.read(249); bri = bri_s;
|
||||
staticIP[0] = EEPROM.read(234);
|
||||
staticIP[1] = EEPROM.read(235);
|
||||
staticIP[2] = EEPROM.read(236);
|
||||
staticIP[3] = EEPROM.read(237);
|
||||
staticGateway[0] = EEPROM.read(238);
|
||||
staticGateway[1] = EEPROM.read(239);
|
||||
staticGateway[2] = EEPROM.read(240);
|
||||
staticGateway[3] = EEPROM.read(241);
|
||||
staticSubnet[0] = EEPROM.read(242);
|
||||
staticSubnet[1] = EEPROM.read(243);
|
||||
staticSubnet[2] = EEPROM.read(244);
|
||||
staticSubnet[3] = EEPROM.read(245);
|
||||
colS[0] = EEPROM.read(246); col[0] = colS[0];
|
||||
colS[1] = EEPROM.read(247); col[1] = colS[1];
|
||||
colS[2] = EEPROM.read(248); col[2] = colS[2];
|
||||
briS = EEPROM.read(249); bri = briS;
|
||||
if (!EEPROM.read(369) && first)
|
||||
{
|
||||
bri = 0; bri_last = bri_s;
|
||||
bri = 0; briLast = briS;
|
||||
}
|
||||
receiveNotificationBrightness = EEPROM.read(250);
|
||||
fadeTransition = EEPROM.read(251);
|
||||
reverseMode = EEPROM.read(252);
|
||||
transitionDelay = ((EEPROM.read(253) << 0) & 0xFF) + ((EEPROM.read(254) << 8) & 0xFF00);
|
||||
briMultiplier = EEPROM.read(255);
|
||||
otapass = "";
|
||||
otaPass = "";
|
||||
for (int i = 256; i < 288; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
otapass += char(EEPROM.read(i));
|
||||
otaPass += char(EEPROM.read(i));
|
||||
}
|
||||
nightlightTargetBri = EEPROM.read(288);
|
||||
otaLock = EEPROM.read(289);
|
||||
@@ -241,6 +306,8 @@ void loadSettingsFromEEPROM(bool first)
|
||||
effectDefault = EEPROM.read(324); effectCurrent = effectDefault;
|
||||
effectSpeedDefault = EEPROM.read(325); effectSpeed = effectSpeedDefault;
|
||||
ntpEnabled = EEPROM.read(327);
|
||||
currentTimezone = EEPROM.read(328);
|
||||
useAMPM = EEPROM.read(329);
|
||||
useGammaCorrectionBri = EEPROM.read(330);
|
||||
useGammaCorrectionRGB = EEPROM.read(331);
|
||||
overlayDefault = EEPROM.read(332);
|
||||
@@ -252,12 +319,11 @@ void loadSettingsFromEEPROM(bool first)
|
||||
alexaInvocationName += char(EEPROM.read(i));
|
||||
}
|
||||
alexaNotify = EEPROM.read(366);
|
||||
arlsSign = EEPROM.read(367);
|
||||
arlsOffset = EEPROM.read(368);
|
||||
if (!arlsSign) arlsOffset = -arlsOffset;
|
||||
if (!EEPROM.read(367)) arlsOffset = -arlsOffset;
|
||||
turnOnAtBoot = EEPROM.read(369);
|
||||
useHSBDefault = EEPROM.read(370);
|
||||
white_s = EEPROM.read(371); white = white_s;
|
||||
whiteS = EEPROM.read(371); white = whiteS;
|
||||
useRGBW = EEPROM.read(372);
|
||||
sweepTransition = EEPROM.read(373);
|
||||
sweepDirection = EEPROM.read(374);
|
||||
@@ -267,18 +333,18 @@ void loadSettingsFromEEPROM(bool first)
|
||||
}
|
||||
//377 = lastEEPROMversion
|
||||
if (lastEEPROMversion > 1) {
|
||||
col_sec_s[0] = EEPROM.read(378); col_sec[0] = col_sec_s[0];
|
||||
col_sec_s[1] = EEPROM.read(379); col_sec[1] = col_sec_s[1];
|
||||
col_sec_s[2] = EEPROM.read(380); col_sec[2] = col_sec_s[2];
|
||||
white_sec_s = EEPROM.read(381); white_sec = white_sec_s;
|
||||
cc_index1 = EEPROM.read(382);
|
||||
cc_index2 = EEPROM.read(383);
|
||||
cc_numPrimary = EEPROM.read(384);
|
||||
cc_numSecondary = EEPROM.read(385);
|
||||
cc_fromStart = EEPROM.read(386);
|
||||
cc_fromEnd = EEPROM.read(387);
|
||||
cc_step = EEPROM.read(388);
|
||||
strip.setCustomChase(cc_index1, cc_index2, cc_start, cc_numPrimary, cc_numSecondary, cc_step, cc_fromStart, cc_fromEnd);
|
||||
colSecS[0] = EEPROM.read(378); colSec[0] = colSecS[0];
|
||||
colSecS[1] = EEPROM.read(379); colSec[1] = colSecS[1];
|
||||
colSecS[2] = EEPROM.read(380); colSec[2] = colSecS[2];
|
||||
whiteSecS = EEPROM.read(381); whiteSec = whiteSecS;
|
||||
ccIndex1 = EEPROM.read(382);
|
||||
ccIndex2 = EEPROM.read(383);
|
||||
ccNumPrimary = EEPROM.read(384);
|
||||
ccNumSecondary = EEPROM.read(385);
|
||||
ccFromStart = EEPROM.read(386);
|
||||
ccFromEnd = EEPROM.read(387);
|
||||
ccStep = EEPROM.read(388);
|
||||
strip.setCustomChase(ccIndex1, ccIndex2, ccStart, ccNumPrimary, ccNumSecondary, ccStep, ccFromStart, ccFromEnd);
|
||||
}
|
||||
if (lastEEPROMversion > 3) {
|
||||
effectIntensityDefault = EEPROM.read(326); effectIntensity = effectIntensityDefault;
|
||||
@@ -291,11 +357,69 @@ void loadSettingsFromEEPROM(bool first)
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
cssFont += char(EEPROM.read(i));
|
||||
}
|
||||
} else //keep receiving notification behavior from pre0.5.0 after update
|
||||
{
|
||||
receiveNotificationColor = receiveNotificationBrightness;
|
||||
receiveNotificationEffects = receiveNotificationBrightness;
|
||||
}
|
||||
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
||||
if (lastEEPROMversion > 4) {
|
||||
huePollingEnabled = EEPROM.read(2048);
|
||||
//hueUpdatingEnabled = EEPROM.read(2049);
|
||||
for (int i = 2050; i < 2054; ++i)
|
||||
{
|
||||
hueIP[i-2050] = EEPROM.read(i);
|
||||
}
|
||||
hueApiKey = "";
|
||||
for (int i = 2054; i < 2100; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
hueApiKey += char(EEPROM.read(i));
|
||||
}
|
||||
huePollIntervalMs = ((EEPROM.read(2100) << 0) & 0xFF) + ((EEPROM.read(2101) << 8) & 0xFF00);
|
||||
notifyHue = EEPROM.read(2102);
|
||||
hueApplyOnOff = EEPROM.read(2103);
|
||||
hueApplyBri = EEPROM.read(2104);
|
||||
hueApplyColor = EEPROM.read(2105);
|
||||
huePollLightId = EEPROM.read(2106);
|
||||
}
|
||||
if (lastEEPROMversion > 5) {
|
||||
overlayMin = EEPROM.read(2150);
|
||||
overlayMax = EEPROM.read(2151);
|
||||
analogClock12pixel = EEPROM.read(2152);
|
||||
analogClock5MinuteMarks = EEPROM.read(2153);
|
||||
analogClockSecondsTrail = EEPROM.read(2154);
|
||||
countdownMode = EEPROM.read(2155);
|
||||
countdownYear = EEPROM.read(2156);
|
||||
countdownMonth = EEPROM.read(2157);
|
||||
countdownDay = EEPROM.read(2158);
|
||||
countdownHour = EEPROM.read(2159);
|
||||
countdownMin = EEPROM.read(2160);
|
||||
countdownSec = EEPROM.read(2161);
|
||||
setCountdown();
|
||||
|
||||
cronixieDisplay = "";
|
||||
for (int i = 2165; i < 2171; ++i)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
cronixieDisplay += char(EEPROM.read(i));
|
||||
}
|
||||
cronixieBacklight = EEPROM.read(2171);
|
||||
|
||||
macroBoot = EEPROM.read(2175);
|
||||
macroAlexaOn = EEPROM.read(2176);
|
||||
macroAlexaOff = EEPROM.read(2177);
|
||||
macroButton = EEPROM.read(2178);
|
||||
macroLongPress = EEPROM.read(2179);
|
||||
macroCountdown = EEPROM.read(2180);
|
||||
macroNl = EEPROM.read(2181);
|
||||
}
|
||||
|
||||
bootPreset = EEPROM.read(389);
|
||||
wifiLock = EEPROM.read(393);
|
||||
utcOffsetSecs = ((EEPROM.read(394) << 0) & 0xFF) + ((EEPROM.read(395) << 8) & 0xFF00);
|
||||
if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative
|
||||
initLedsLast = EEPROM.read(397);
|
||||
|
||||
//favorite setting memory (25 slots/ each 20byte)
|
||||
//400 - 899 reserved
|
||||
@@ -311,6 +435,9 @@ void loadSettingsFromEEPROM(bool first)
|
||||
|
||||
//custom macro memory (16 slots/ each 64byte)
|
||||
//1024-2047 reserved
|
||||
|
||||
//user MOD memory
|
||||
//2944 - 3071 reserved
|
||||
|
||||
useHSB = useHSBDefault;
|
||||
|
||||
@@ -324,7 +451,7 @@ void loadSettingsFromEEPROM(bool first)
|
||||
//0: preset purpose byte 0:invalid 1:valid preset 1.0
|
||||
//1:a 2:r 3:g 4:b 5:w 6:er 7:eg 8:eb 9:ew 10:fx 11:sx | custom chase 12:numP 13:numS 14:(0:fs 1:both 2:fe) 15:step 16:ix 17-19:Zeros
|
||||
|
||||
void applyPreset(uint8_t index, bool loadBri, bool loadCol, bool loadFX)
|
||||
void applyPreset(byte index, bool loadBri, bool loadCol, bool loadFX)
|
||||
{
|
||||
if (index == 255 || index == 0) loadSettingsFromEEPROM(false);//load boot defaults
|
||||
if (index > 25 || index < 1) return;
|
||||
@@ -337,29 +464,29 @@ void applyPreset(uint8_t index, bool loadBri, bool loadCol, bool loadFX)
|
||||
col[1] = EEPROM.read(i+3);
|
||||
col[2] = EEPROM.read(i+4);
|
||||
white = EEPROM.read(i+5);
|
||||
col_sec[0] = EEPROM.read(i+6);
|
||||
col_sec[1] = EEPROM.read(i+7);
|
||||
col_sec[2] = EEPROM.read(i+8);
|
||||
white_sec = EEPROM.read(i+9);
|
||||
colSec[0] = EEPROM.read(i+6);
|
||||
colSec[1] = EEPROM.read(i+7);
|
||||
colSec[2] = EEPROM.read(i+8);
|
||||
whiteSec = EEPROM.read(i+9);
|
||||
}
|
||||
if (loadFX)
|
||||
{
|
||||
effectCurrent = EEPROM.read(i+10);
|
||||
effectSpeed = EEPROM.read(i+11);
|
||||
effectIntensity = EEPROM.read(i+16);
|
||||
cc_numPrimary = EEPROM.read(i+12);
|
||||
cc_numSecondary = EEPROM.read(i+13);
|
||||
cc_fromEnd = EEPROM.read(i+14);
|
||||
cc_fromStart = (EEPROM.read(i+14)<2);
|
||||
cc_step = EEPROM.read(i+15);
|
||||
strip.setCustomChase(cc_index1, cc_index2, cc_start, cc_numPrimary, cc_numSecondary, cc_step, cc_fromStart, cc_fromEnd);
|
||||
ccNumPrimary = EEPROM.read(i+12);
|
||||
ccNumSecondary = EEPROM.read(i+13);
|
||||
ccFromEnd = EEPROM.read(i+14);
|
||||
ccFromStart = (EEPROM.read(i+14)<2);
|
||||
ccStep = EEPROM.read(i+15);
|
||||
strip.setCustomChase(ccIndex1, ccIndex2, ccStart, ccNumPrimary, ccNumSecondary, ccStep, ccFromStart, ccFromEnd);
|
||||
strip.setMode(effectCurrent);
|
||||
strip.setSpeed(effectSpeed);
|
||||
strip.setIntensity(effectIntensity);
|
||||
}
|
||||
}
|
||||
|
||||
void savePreset(uint8_t index)
|
||||
void savePreset(byte index)
|
||||
{
|
||||
if (index > 25) return;
|
||||
if (index < 1) {saveSettingsToEEPROM();return;}
|
||||
@@ -370,32 +497,43 @@ void savePreset(uint8_t index)
|
||||
EEPROM.write(i+3, col[1]);
|
||||
EEPROM.write(i+4, col[2]);
|
||||
EEPROM.write(i+5, white);
|
||||
EEPROM.write(i+6, col_sec[0]);
|
||||
EEPROM.write(i+7, col_sec[1]);
|
||||
EEPROM.write(i+8, col_sec[2]);
|
||||
EEPROM.write(i+9, white_sec);
|
||||
EEPROM.write(i+6, colSec[0]);
|
||||
EEPROM.write(i+7, colSec[1]);
|
||||
EEPROM.write(i+8, colSec[2]);
|
||||
EEPROM.write(i+9, whiteSec);
|
||||
EEPROM.write(i+10, effectCurrent);
|
||||
EEPROM.write(i+11, effectSpeed);
|
||||
EEPROM.write(i+12, cc_numPrimary);
|
||||
EEPROM.write(i+13, cc_numSecondary);
|
||||
uint8_t m = 1;
|
||||
if (!cc_fromStart) m = 2;
|
||||
if (!cc_fromEnd) m = 0;
|
||||
EEPROM.write(i+12, ccNumPrimary);
|
||||
EEPROM.write(i+13, ccNumSecondary);
|
||||
byte m = 1;
|
||||
if (!ccFromStart) m = 2;
|
||||
if (!ccFromEnd) m = 0;
|
||||
EEPROM.write(i+14, m);
|
||||
EEPROM.write(i+15, cc_step);
|
||||
EEPROM.write(i+15, ccStep);
|
||||
EEPROM.write(i+16, effectIntensity);
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
void applyMacro(uint8_t index)
|
||||
String loadMacro(byte index)
|
||||
{
|
||||
if (index > 15) return;
|
||||
String mc="win&";
|
||||
index-=1;
|
||||
String m="";
|
||||
if (index > 15) return m;
|
||||
for (int i = 1024+64*index; i < 1088+64*index; i++)
|
||||
{
|
||||
if (EEPROM.read(i) == 0) break;
|
||||
mc += char(EEPROM.read(i));
|
||||
m += char(EEPROM.read(i));
|
||||
}
|
||||
if (m.charAt(0) < 65 || m.charAt(0) > 90) return ""; //do simple check if macro is valid (capital first letter)
|
||||
return m;
|
||||
}
|
||||
|
||||
void applyMacro(byte index)
|
||||
{
|
||||
index-=1;
|
||||
if (index > 15) return;
|
||||
String mc="win&";
|
||||
mc += loadMacro(index+1);
|
||||
mc += "&IN"; //internal, no XML response
|
||||
if (!macroNotify) mc += "&NN";
|
||||
String forbidden = "&M="; //dont apply if called by the macro itself to prevent loop
|
||||
@@ -408,14 +546,15 @@ void applyMacro(uint8_t index)
|
||||
handleSet(mc);
|
||||
}
|
||||
|
||||
void saveMacro(uint8_t index, String mc)
|
||||
void saveMacro(byte index, String mc, bool sing=true) //only commit on single save, not in settings
|
||||
{
|
||||
index-=1;
|
||||
if (index > 15) return;
|
||||
int s = 1024+index*64;
|
||||
for (int i = s; i < s+64; i++)
|
||||
{
|
||||
EEPROM.write(i, mc.charAt(i-s));
|
||||
}
|
||||
EEPROM.commit();
|
||||
if (sing) EEPROM.commit();
|
||||
}
|
||||
|
||||
|
@@ -7,15 +7,15 @@ void XML_response()
|
||||
String resp;
|
||||
resp = resp + "<?xml version = \"1.0\" ?>";
|
||||
resp = resp + "<vs>";
|
||||
resp = resp + "<act>";
|
||||
resp = resp + "<ac>";
|
||||
if (nightlightActive && nightlightFade)
|
||||
{
|
||||
resp = resp + bri_t;
|
||||
resp = resp + briT;
|
||||
} else
|
||||
{
|
||||
resp = resp + bri;
|
||||
}
|
||||
resp = resp + "</act>";
|
||||
resp = resp + "</ac>";
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
@@ -49,14 +49,14 @@ void XML_response()
|
||||
}
|
||||
resp = resp + "</wv><md>";
|
||||
resp = resp + useHSB;
|
||||
resp = resp + "</md><desc>";
|
||||
resp = resp + "</md><ds>";
|
||||
resp = resp + serverDescription;
|
||||
resp = resp + "</desc>";
|
||||
resp = resp + "</ds>";
|
||||
resp = resp + "</vs>";
|
||||
server.send(200, "text/xml", resp);
|
||||
}
|
||||
|
||||
String getSettings(uint8_t subPage)
|
||||
String getSettings(byte subPage)
|
||||
{
|
||||
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec
|
||||
DEBUG_PRINT("settings resp");
|
||||
@@ -70,38 +70,39 @@ String getSettings(uint8_t subPage)
|
||||
String v = ".value=";
|
||||
String c = ".checked=";
|
||||
String ih = ".innerHTML=";
|
||||
String si = ".selectedIndex=";
|
||||
|
||||
if (subPage == 1) {
|
||||
resp += ds + "CSSID" + v + "\"" + clientssid + "\";";
|
||||
resp += ds + "CPASS" + v + "\"";
|
||||
for (int i = 0; i < clientpass.length(); i++)
|
||||
resp += ds + "CS" + v + "\"" + clientSSID + "\";";
|
||||
resp += ds + "CP" + v + "\"";
|
||||
for (int i = 0; i < clientPass.length(); i++)
|
||||
{
|
||||
resp += "*";
|
||||
}
|
||||
resp += "\";";
|
||||
resp += ds + "CSIP0" + v + staticip[0] +";";
|
||||
resp += ds + "CSIP1" + v + staticip[1] +";";
|
||||
resp += ds + "CSIP2" + v + staticip[2] +";";
|
||||
resp += ds + "CSIP3" + v + staticip[3] +";";
|
||||
resp += ds + "CSGW0" + v + staticgateway[0] +";";
|
||||
resp += ds + "CSGW1" + v + staticgateway[1] +";";
|
||||
resp += ds + "CSGW2" + v + staticgateway[2] +";";
|
||||
resp += ds + "CSGW3" + v + staticgateway[3] +";";
|
||||
resp += ds + "CSSN0" + v + staticsubnet[0] +";";
|
||||
resp += ds + "CSSN1" + v + staticsubnet[1] +";";
|
||||
resp += ds + "CSSN2" + v + staticsubnet[2] +";";
|
||||
resp += ds + "CSSN3" + v + staticsubnet[3] +";";
|
||||
resp += ds + "CMDNS" + v + "\"" + cmdns + "\";";
|
||||
resp += ds + "APWTM" + v + apWaitTimeSecs +";";
|
||||
resp += ds + "APSSID" + v + "\"" + apssid + "\";";
|
||||
resp += ds + "APHSSID" + c + aphide + ";";
|
||||
resp += ds + "APPASS" + v + "\"";
|
||||
for (int i = 0; i < clientpass.length(); i++)
|
||||
resp += ds + "I0" + v + staticIP[0] +";";
|
||||
resp += ds + "I1" + v + staticIP[1] +";";
|
||||
resp += ds + "I2" + v + staticIP[2] +";";
|
||||
resp += ds + "I3" + v + staticIP[3] +";";
|
||||
resp += ds + "G0" + v + staticGateway[0] +";";
|
||||
resp += ds + "G1" + v + staticGateway[1] +";";
|
||||
resp += ds + "G2" + v + staticGateway[2] +";";
|
||||
resp += ds + "G3" + v + staticGateway[3] +";";
|
||||
resp += ds + "S0" + v + staticSubnet[0] +";";
|
||||
resp += ds + "S1" + v + staticSubnet[1] +";";
|
||||
resp += ds + "S2" + v + staticSubnet[2] +";";
|
||||
resp += ds + "S3" + v + staticSubnet[3] +";";
|
||||
resp += ds + "CM" + v + "\"" + cmDNS + "\";";
|
||||
resp += ds + "AT" + v + apWaitTimeSecs +";";
|
||||
resp += ds + "AS" + v + "\"" + apSSID + "\";";
|
||||
resp += ds + "AH" + c + apHide + ";";
|
||||
resp += ds + "AP" + v + "\"";
|
||||
for (int i = 0; i < apPass.length(); i++)
|
||||
{
|
||||
resp += "*";
|
||||
}
|
||||
resp += "\";";
|
||||
resp += ds + "APCHAN" + v + apchannel +";";
|
||||
resp += ds + "AC" + v + apChannel +";";
|
||||
resp += dg + "(\"sip\")[0]" + ih + "\"";
|
||||
if (!WiFi.localIP()[0] == 0)
|
||||
{
|
||||
@@ -135,75 +136,118 @@ String getSettings(uint8_t subPage)
|
||||
}
|
||||
|
||||
if (subPage == 2) {
|
||||
resp += ds + "LEDCN" + v + ledcount +";";
|
||||
resp += ds + "CLDFR" + v + col_s[0] +";";
|
||||
resp += ds + "CLDFG" + v + col_s[1] +";";
|
||||
resp += ds + "CLDFB" + v + col_s[2] +";";
|
||||
resp += ds + "CLDFA" + v + bri_s +";";
|
||||
resp += ds + "LC" + v + ledCount +";";
|
||||
resp += ds + "CR" + v + colS[0] +";";
|
||||
resp += ds + "CG" + v + colS[1] +";";
|
||||
resp += ds + "CB" + v + colS[2] +";";
|
||||
resp += ds + "CA" + v + briS +";";
|
||||
if (useRGBW) {
|
||||
resp += ds + "CLDFW" + v + white_s +";";
|
||||
resp += ds + "CW" + v + whiteS +";";
|
||||
} else {
|
||||
resp += ds + "CLDFW" + v + "-1;";
|
||||
resp += ds + "CW" + v + "-1;";
|
||||
}
|
||||
resp += ds + "CSECR" + v + col_sec_s[0] +";";
|
||||
resp += ds + "CSECG" + v + col_sec_s[1] +";";
|
||||
resp += ds + "CSECB" + v + col_sec_s[2] +";";
|
||||
resp += ds + "CSECW" + v + white_s +";";
|
||||
resp += ds + "BOOTN" + c + turnOnAtBoot +";";
|
||||
resp += ds + "BOOTP" + v + bootPreset +";";
|
||||
resp += ds + "FXDEF" + v + effectDefault +";";
|
||||
resp += ds + "SXDEF" + v + effectSpeedDefault +";";
|
||||
resp += ds + "IXDEF" + v + effectIntensityDefault +";";
|
||||
resp += ds + "GCBRI" + c + useGammaCorrectionBri +";";
|
||||
resp += ds + "GCRGB" + c + useGammaCorrectionRGB +";";
|
||||
resp += ds + "TFADE" + c + fadeTransition +";";
|
||||
resp += ds + "TSWEE" + c + sweepTransition +";";
|
||||
resp += ds + "TSDIR" + c + !sweepDirection +";";
|
||||
resp += ds + "TDLAY" + v + transitionDelay +";";
|
||||
resp += ds + "NRBRI" + v + briMultiplier +";";
|
||||
resp += ds + "TLBRI" + v + nightlightTargetBri +";";
|
||||
resp += ds + "TLDUR" + v + nightlightDelayMins +";";
|
||||
resp += ds + "TLFDE" + c + nightlightFade +";";
|
||||
resp += ds + "OLDEF" + v + overlayDefault +";";
|
||||
resp += ds + "WOFFS" + v + arlsOffset +";";
|
||||
resp += ds + "SR" + v + colSecS[0] +";";
|
||||
resp += ds + "SG" + v + colSecS[1] +";";
|
||||
resp += ds + "SB" + v + colSecS[2] +";";
|
||||
resp += ds + "SW" + v + whiteSecS +";";
|
||||
resp += ds + "BO" + c + turnOnAtBoot +";";
|
||||
resp += ds + "BP" + v + bootPreset +";";
|
||||
resp += ds + "FX" + v + effectDefault +";";
|
||||
resp += ds + "SX" + v + effectSpeedDefault +";";
|
||||
resp += ds + "IX" + v + effectIntensityDefault +";";
|
||||
resp += ds + "GB" + c + useGammaCorrectionBri +";";
|
||||
resp += ds + "GC" + c + useGammaCorrectionRGB +";";
|
||||
resp += ds + "TF" + c + fadeTransition +";";
|
||||
resp += ds + "TS" + c + sweepTransition +";";
|
||||
resp += ds + "TI" + c + !sweepDirection +";";
|
||||
resp += ds + "TD" + v + transitionDelay +";";
|
||||
resp += ds + "BF" + v + briMultiplier +";";
|
||||
resp += ds + "TB" + v + nightlightTargetBri +";";
|
||||
resp += ds + "TL" + v + nightlightDelayMins +";";
|
||||
resp += ds + "TW" + c + nightlightFade +";";
|
||||
resp += ds + "RV" + c + reverseMode +";";
|
||||
resp += ds + "EI" + c + initLedsLast +";";
|
||||
resp += ds + "WO" + v + arlsOffset +";";
|
||||
}
|
||||
|
||||
if (subPage == 3)
|
||||
{
|
||||
resp += ds + "DESC" + v + "\"" + serverDescription + "\";";
|
||||
resp += ds + "COLMD" + c + useHSBDefault + ";";
|
||||
resp += ds + "THEME.selectedIndex=" + String(currentTheme) + ";";
|
||||
resp += ds + "DS" + v + "\"" + serverDescription + "\";";
|
||||
resp += ds + "MD" + c + useHSBDefault + ";";
|
||||
resp += ds + "TH" + si + String(currentTheme) + ";";
|
||||
for(int i=0;i<6;i++)
|
||||
resp += ds + "CCOL" + i + v + "\"" + cssCol[i] + "\";";
|
||||
resp += ds + "CFONT" + v + "\"" + cssFont + "\";";
|
||||
resp += ds + "C" + i + v + "\"" + cssCol[i] + "\";";
|
||||
resp += ds + "CF" + v + "\"" + cssFont + "\";";
|
||||
}
|
||||
|
||||
if (subPage == 4)
|
||||
{
|
||||
resp += ds + "BTNON" + c + buttonEnabled +";";
|
||||
resp += ds + "NUDPP" + v + udpPort +";";
|
||||
resp += ds + "NRCBR" + c + receiveNotificationBrightness +";";
|
||||
resp += ds + "NRCCL" + c + receiveNotificationColor +";";
|
||||
resp += ds + "NRCFX" + c + receiveNotificationEffects +";";
|
||||
resp += ds + "NSDIR" + c + notifyDirectDefault +";";
|
||||
resp += ds + "NSBTN" + c + notifyButton +";";
|
||||
resp += ds + "ALEXA" + c + alexaEnabled +";";
|
||||
resp += ds + "AINVN" + v + "\"" + alexaInvocationName + "\";";
|
||||
resp += ds + "NSALX" + c + alexaNotify +";";
|
||||
resp += ds + "BT" + c + buttonEnabled +";";
|
||||
resp += ds + "UP" + v + udpPort +";";
|
||||
resp += ds + "RB" + c + receiveNotificationBrightness +";";
|
||||
resp += ds + "RC" + c + receiveNotificationColor +";";
|
||||
resp += ds + "RX" + c + receiveNotificationEffects +";";
|
||||
resp += ds + "SD" + c + notifyDirectDefault +";";
|
||||
resp += ds + "SB" + c + notifyButton +";";
|
||||
resp += ds + "SH" + c + notifyHue +";";
|
||||
resp += ds + "S2" + c + notifyTwice +";";
|
||||
resp += ds + "AL" + c + alexaEnabled +";";
|
||||
resp += ds + "AI" + v + "\"" + alexaInvocationName + "\";";
|
||||
resp += ds + "SA" + c + alexaNotify +";";
|
||||
resp += ds + "H0" + v + hueIP[0] +";";
|
||||
resp += ds + "H1" + v + hueIP[1] +";";
|
||||
resp += ds + "H2" + v + hueIP[2] +";";
|
||||
resp += ds + "H3" + v + hueIP[3] +";";
|
||||
resp += ds + "HL" + v + huePollLightId +";";
|
||||
resp += ds + "HI" + v + huePollIntervalMs +";";
|
||||
resp += ds + "HP" + c + huePollingEnabled +";";
|
||||
resp += ds + "HO" + c + hueApplyOnOff +";";
|
||||
resp += ds + "HB" + c + hueApplyBri +";";
|
||||
resp += ds + "HC" + c + hueApplyColor +";";
|
||||
resp += dg + "(\"hms\")[0]" + ih + "\"" + hueError + "\";";
|
||||
}
|
||||
|
||||
if (subPage == 5)
|
||||
{
|
||||
resp += ds + "NTPON" + c + ntpEnabled +";";
|
||||
resp += ds + "NT" + c + ntpEnabled +";";
|
||||
resp += ds + "CF" + c + !useAMPM +";";
|
||||
resp += ds + "TZ" + si + String(currentTimezone) + ";";
|
||||
resp += ds + "UO" + v + utcOffsetSecs +";";
|
||||
resp += dg + "(\"times\")[0]" + ih + "\"" + getTimeString() + "\";";
|
||||
resp += ds + "OL" + si + String(overlayCurrent) + ";";
|
||||
resp += ds + "O1" + v + overlayMin +";";
|
||||
resp += ds + "O2" + v + overlayMax +";";
|
||||
resp += ds + "OM" + v + analogClock12pixel +";";
|
||||
resp += ds + "OS" + c + analogClockSecondsTrail +";";
|
||||
resp += ds + "O5" + c + analogClock5MinuteMarks +";";
|
||||
resp += ds + "CX" + v + "\"" + cronixieDisplay + "\";";
|
||||
resp += ds + "CB" + c + cronixieBacklight +";";
|
||||
resp += ds + "CE" + c + countdownMode +";";
|
||||
resp += ds + "CY" + v + countdownYear +";";
|
||||
resp += ds + "CI" + v + countdownMonth +";";
|
||||
resp += ds + "CD" + v + countdownDay +";";
|
||||
resp += ds + "CH" + v + countdownHour +";";
|
||||
resp += ds + "CM" + v + countdownMin +";";
|
||||
resp += ds + "CS" + v + countdownSec +";";
|
||||
for (int i=1;i<17;i++)
|
||||
{
|
||||
resp += ds + "M" + String(i) + v + "\"" + loadMacro(i) + "\";";
|
||||
}
|
||||
resp += ds + "MB" + v + macroBoot +";";
|
||||
resp += ds + "A0" + v + macroAlexaOn +";";
|
||||
resp += ds + "A1" + v + macroAlexaOff +";";
|
||||
resp += ds + "MP" + v + macroButton +";";
|
||||
resp += ds + "ML" + v + macroLongPress +";";
|
||||
resp += ds + "MC" + v + macroCountdown +";";
|
||||
resp += ds + "MN" + v + macroNl +";";
|
||||
}
|
||||
|
||||
if (subPage == 6)
|
||||
{
|
||||
resp += ds + "NOOTA" + c + otaLock +";";
|
||||
resp += ds + "OWIFI" + c + wifiLock +";";
|
||||
resp += ds + "AROTA" + c + aOtaEnabled +";";
|
||||
resp += ds + "NORAP" + c + recoveryAPDisabled +";";
|
||||
resp += ds + "NO" + c + otaLock +";";
|
||||
resp += ds + "OW" + c + wifiLock +";";
|
||||
resp += ds + "AO" + c + aOtaEnabled +";";
|
||||
resp += ds + "NA" + c + recoveryAPDisabled +";";
|
||||
resp += dg + "(\"msg\")[0]" + ih + "\"WLED "+ versionString +" (build " + VERSION + ") OK\";";
|
||||
}
|
||||
resp += "}</script>";
|
||||
|
@@ -2,24 +2,18 @@
|
||||
* Receives client input
|
||||
*/
|
||||
|
||||
void _setRandomColor(bool _sec)
|
||||
void _setRandomColor(bool _sec,bool fromButton=false)
|
||||
{
|
||||
lastRandomIndex = strip.get_random_wheel_index(lastRandomIndex);
|
||||
uint32_t _color = strip.color_wheel(lastRandomIndex);
|
||||
if (_sec){
|
||||
white_sec = ((_color >> 24) & 0xFF);
|
||||
col_sec[0] = ((_color >> 16) & 0xFF);
|
||||
col_sec[1] = ((_color >> 8) & 0xFF);
|
||||
col_sec[2] = (_color & 0xFF);
|
||||
colorHStoRGB(lastRandomIndex*256,255,colSec);
|
||||
} else {
|
||||
white = ((_color >> 24) & 0xFF);
|
||||
col[0] = ((_color >> 16) & 0xFF);
|
||||
col[1] = ((_color >> 8) & 0xFF);
|
||||
col[2] = (_color & 0xFF);
|
||||
colorHStoRGB(lastRandomIndex*256,255,col);
|
||||
}
|
||||
if (fromButton) colorUpdated(2);
|
||||
}
|
||||
|
||||
void handleSettingsSet(uint8_t subPage)
|
||||
void handleSettingsSet(byte subPage)
|
||||
{
|
||||
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec
|
||||
if (subPage <1 || subPage >6) return;
|
||||
@@ -27,223 +21,220 @@ void handleSettingsSet(uint8_t subPage)
|
||||
//WIFI SETTINGS
|
||||
if (subPage == 1)
|
||||
{
|
||||
if (server.hasArg("CSSID")) clientssid = server.arg("CSSID");
|
||||
if (server.hasArg("CPASS"))
|
||||
if (server.hasArg("CS")) clientSSID = server.arg("CS");
|
||||
if (server.hasArg("CP"))
|
||||
{
|
||||
if (!server.arg("CPASS").indexOf('*') == 0)
|
||||
if (!server.arg("CP").indexOf('*') == 0)
|
||||
{
|
||||
DEBUG_PRINTLN("Setting pass");
|
||||
clientpass = server.arg("CPASS");
|
||||
clientPass = server.arg("CP");
|
||||
}
|
||||
}
|
||||
if (server.hasArg("CMDNS")) cmdns = server.arg("CMDNS");
|
||||
if (server.hasArg("APWTM"))
|
||||
if (server.hasArg("CM")) cmDNS = server.arg("CM");
|
||||
if (server.hasArg("AT"))
|
||||
{
|
||||
int i = server.arg("APWTM").toInt();
|
||||
int i = server.arg("AT").toInt();
|
||||
if (i >= 0 && i <= 255) apWaitTimeSecs = i;
|
||||
}
|
||||
if (server.hasArg("APSSID")) apssid = server.arg("APSSID");
|
||||
aphide = server.hasArg("APHSSID");
|
||||
if (server.hasArg("APPASS"))
|
||||
if (server.hasArg("AS")) apSSID = server.arg("AS");
|
||||
apHide = server.hasArg("AH");
|
||||
if (server.hasArg("AP"))
|
||||
{
|
||||
if (!server.arg("APPASS").indexOf('*') == 0) appass = server.arg("APPASS");
|
||||
if (!server.arg("AP").indexOf('*') == 0) apPass = server.arg("AP");
|
||||
}
|
||||
if (server.hasArg("APCHAN"))
|
||||
if (server.hasArg("AC"))
|
||||
{
|
||||
int chan = server.arg("APCHAN").toInt();
|
||||
if (chan > 0 && chan < 14) apchannel = chan;
|
||||
int chan = server.arg("AC").toInt();
|
||||
if (chan > 0 && chan < 14) apChannel = chan;
|
||||
}
|
||||
if (server.hasArg("CSIP0"))
|
||||
if (server.hasArg("I0"))
|
||||
{
|
||||
int i = server.arg("CSIP0").toInt();
|
||||
if (i >= 0 && i <= 255) staticip[0] = i;
|
||||
int i = server.arg("I0").toInt();
|
||||
if (i >= 0 && i <= 255) staticIP[0] = i;
|
||||
}
|
||||
if (server.hasArg("CSIP1"))
|
||||
if (server.hasArg("I1"))
|
||||
{
|
||||
int i = server.arg("CSIP1").toInt();
|
||||
if (i >= 0 && i <= 255) staticip[1] = i;
|
||||
int i = server.arg("I1").toInt();
|
||||
if (i >= 0 && i <= 255) staticIP[1] = i;
|
||||
}
|
||||
if (server.hasArg("CSIP2"))
|
||||
if (server.hasArg("I2"))
|
||||
{
|
||||
int i = server.arg("CSIP2").toInt();
|
||||
if (i >= 0 && i <= 255) staticip[2] = i;
|
||||
int i = server.arg("I2").toInt();
|
||||
if (i >= 0 && i <= 255) staticIP[2] = i;
|
||||
}
|
||||
if (server.hasArg("CSIP3"))
|
||||
if (server.hasArg("I3"))
|
||||
{
|
||||
int i = server.arg("CSIP3").toInt();
|
||||
if (i >= 0 && i <= 255) staticip[3] = i;
|
||||
int i = server.arg("I3").toInt();
|
||||
if (i >= 0 && i <= 255) staticIP[3] = i;
|
||||
}
|
||||
if (server.hasArg("CSGW0"))
|
||||
if (server.hasArg("G0"))
|
||||
{
|
||||
int i = server.arg("CSGW0").toInt();
|
||||
if (i >= 0 && i <= 255) staticgateway[0] = i;
|
||||
int i = server.arg("G0").toInt();
|
||||
if (i >= 0 && i <= 255) staticGateway[0] = i;
|
||||
}
|
||||
if (server.hasArg("CSGW1"))
|
||||
if (server.hasArg("G1"))
|
||||
{
|
||||
int i = server.arg("CSGW1").toInt();
|
||||
if (i >= 0 && i <= 255) staticgateway[1] = i;
|
||||
int i = server.arg("G1").toInt();
|
||||
if (i >= 0 && i <= 255) staticGateway[1] = i;
|
||||
}
|
||||
if (server.hasArg("CSGW2"))
|
||||
if (server.hasArg("G2"))
|
||||
{
|
||||
int i = server.arg("CSGW2").toInt();
|
||||
if (i >= 0 && i <= 255) staticgateway[2] = i;
|
||||
int i = server.arg("G2").toInt();
|
||||
if (i >= 0 && i <= 255) staticGateway[2] = i;
|
||||
}
|
||||
if (server.hasArg("CSGW3"))
|
||||
if (server.hasArg("G3"))
|
||||
{
|
||||
int i = server.arg("CSGW3").toInt();
|
||||
if (i >= 0 && i <= 255) staticgateway[3] = i;
|
||||
int i = server.arg("G3").toInt();
|
||||
if (i >= 0 && i <= 255) staticGateway[3] = i;
|
||||
}
|
||||
if (server.hasArg("CSSN0"))
|
||||
if (server.hasArg("S0"))
|
||||
{
|
||||
int i = server.arg("CSSN0").toInt();
|
||||
if (i >= 0 && i <= 255) staticsubnet[0] = i;
|
||||
int i = server.arg("S0").toInt();
|
||||
if (i >= 0 && i <= 255) staticSubnet[0] = i;
|
||||
}
|
||||
if (server.hasArg("CSSN1"))
|
||||
if (server.hasArg("S1"))
|
||||
{
|
||||
int i = server.arg("CSSN1").toInt();
|
||||
if (i >= 0 && i <= 255) staticsubnet[1] = i;
|
||||
int i = server.arg("S1").toInt();
|
||||
if (i >= 0 && i <= 255) staticSubnet[1] = i;
|
||||
}
|
||||
if (server.hasArg("CSSN2"))
|
||||
if (server.hasArg("S2"))
|
||||
{
|
||||
int i = server.arg("CSSN2").toInt();
|
||||
if (i >= 0 && i <= 255) staticsubnet[2] = i;
|
||||
int i = server.arg("S2").toInt();
|
||||
if (i >= 0 && i <= 255) staticSubnet[2] = i;
|
||||
}
|
||||
if (server.hasArg("CSSN3"))
|
||||
if (server.hasArg("S3"))
|
||||
{
|
||||
int i = server.arg("CSSN3").toInt();
|
||||
if (i >= 0 && i <= 255) staticsubnet[3] = i;
|
||||
int i = server.arg("S3").toInt();
|
||||
if (i >= 0 && i <= 255) staticSubnet[3] = i;
|
||||
}
|
||||
}
|
||||
|
||||
//LED SETTINGS
|
||||
if (subPage == 2)
|
||||
{
|
||||
if (server.hasArg("LEDCN"))
|
||||
if (server.hasArg("LC"))
|
||||
{
|
||||
int i = server.arg("LEDCN").toInt();
|
||||
if (i >= 0 && i <= LEDCOUNT) ledcount = i;
|
||||
strip.setLedCount(ledcount);
|
||||
int i = server.arg("LC").toInt();
|
||||
if (i >= 0 && i <= LEDCOUNT) ledCount = i;
|
||||
strip.setLedCount(ledCount);
|
||||
}
|
||||
if (server.hasArg("CBEOR")) //ignore settings and save current brightness, colors and fx as default
|
||||
if (server.hasArg("IS")) //ignore settings and save current brightness, colors and fx as default
|
||||
{
|
||||
col_s[0] = col[0];
|
||||
col_s[1] = col[1];
|
||||
col_s[2] = col[2];
|
||||
if (useRGBW) white_s = white;
|
||||
bri_s = bri;
|
||||
colS[0] = col[0];
|
||||
colS[1] = col[1];
|
||||
colS[2] = col[2];
|
||||
if (useRGBW) whiteS = white;
|
||||
briS = bri;
|
||||
effectDefault = effectCurrent;
|
||||
effectSpeedDefault = effectSpeed;
|
||||
} else {
|
||||
if (server.hasArg("CLDFR"))
|
||||
if (server.hasArg("CR"))
|
||||
{
|
||||
int i = server.arg("CLDFR").toInt();
|
||||
if (i >= 0 && i <= 255) col_s[0] = i;
|
||||
int i = server.arg("CR").toInt();
|
||||
if (i >= 0 && i <= 255) colS[0] = i;
|
||||
}
|
||||
if (server.hasArg("CLDFG"))
|
||||
if (server.hasArg("CG"))
|
||||
{
|
||||
int i = server.arg("CLDFG").toInt();
|
||||
if (i >= 0 && i <= 255) col_s[1] = i;
|
||||
int i = server.arg("CG").toInt();
|
||||
if (i >= 0 && i <= 255) colS[1] = i;
|
||||
}
|
||||
if (server.hasArg("CLDFB"))
|
||||
if (server.hasArg("CB"))
|
||||
{
|
||||
int i = server.arg("CLDFB").toInt();
|
||||
if (i >= 0 && i <= 255) col_s[2] = i;
|
||||
int i = server.arg("CB").toInt();
|
||||
if (i >= 0 && i <= 255) colS[2] = i;
|
||||
}
|
||||
if (server.hasArg("CSECR"))
|
||||
if (server.hasArg("SR"))
|
||||
{
|
||||
int i = server.arg("CSECR").toInt();
|
||||
if (i >= 0 && i <= 255) col_sec_s[0] = i;
|
||||
int i = server.arg("SR").toInt();
|
||||
if (i >= 0 && i <= 255) colSecS[0] = i;
|
||||
}
|
||||
if (server.hasArg("CSECG"))
|
||||
if (server.hasArg("SG"))
|
||||
{
|
||||
int i = server.arg("CSECG").toInt();
|
||||
if (i >= 0 && i <= 255) col_sec_s[1] = i;
|
||||
int i = server.arg("SG").toInt();
|
||||
if (i >= 0 && i <= 255) colSecS[1] = i;
|
||||
}
|
||||
if (server.hasArg("CSECB"))
|
||||
if (server.hasArg("SB"))
|
||||
{
|
||||
int i = server.arg("CSECB").toInt();
|
||||
if (i >= 0 && i <= 255) col_sec_s[2] = i;
|
||||
int i = server.arg("SB").toInt();
|
||||
if (i >= 0 && i <= 255) colSecS[2] = i;
|
||||
}
|
||||
if (server.hasArg("CSECW"))
|
||||
if (server.hasArg("SW"))
|
||||
{
|
||||
int i = server.arg("CSECW").toInt();
|
||||
if (i >= 0 && i <= 255) white_sec_s = i;
|
||||
int i = server.arg("SW").toInt();
|
||||
if (i >= 0 && i <= 255) whiteSecS = i;
|
||||
}
|
||||
if (server.hasArg("CLDFW"))
|
||||
if (server.hasArg("CW"))
|
||||
{
|
||||
int i = server.arg("CLDFW").toInt();
|
||||
int i = server.arg("CW").toInt();
|
||||
if (i >= 0 && i <= 255)
|
||||
{
|
||||
useRGBW = true;
|
||||
white_s = i;
|
||||
whiteS = i;
|
||||
} else {
|
||||
useRGBW = false;
|
||||
white_s = 0;
|
||||
whiteS = 0;
|
||||
}
|
||||
}
|
||||
if (server.hasArg("CLDFA"))
|
||||
if (server.hasArg("CA"))
|
||||
{
|
||||
int i = server.arg("CLDFA").toInt();
|
||||
if (i >= 0 && i <= 255) bri_s = i;
|
||||
int i = server.arg("CA").toInt();
|
||||
if (i >= 0 && i <= 255) briS = i;
|
||||
}
|
||||
if (server.hasArg("FXDEF"))
|
||||
if (server.hasArg("FX"))
|
||||
{
|
||||
int i = server.arg("FXDEF").toInt();
|
||||
int i = server.arg("FX").toInt();
|
||||
if (i >= 0 && i <= 255) effectDefault = i;
|
||||
}
|
||||
if (server.hasArg("SXDEF"))
|
||||
if (server.hasArg("SX"))
|
||||
{
|
||||
int i = server.arg("SXDEF").toInt();
|
||||
int i = server.arg("SX").toInt();
|
||||
if (i >= 0 && i <= 255) effectSpeedDefault = i;
|
||||
}
|
||||
if (server.hasArg("IXDEF"))
|
||||
if (server.hasArg("IX"))
|
||||
{
|
||||
int i = server.arg("IXDEF").toInt();
|
||||
int i = server.arg("IX").toInt();
|
||||
if (i >= 0 && i <= 255) effectIntensityDefault = i;
|
||||
}
|
||||
}
|
||||
turnOnAtBoot = server.hasArg("BOOTN");
|
||||
if (server.hasArg("BOOTP"))
|
||||
turnOnAtBoot = server.hasArg("BO");
|
||||
if (server.hasArg("BP"))
|
||||
{
|
||||
int i = server.arg("BOOTP").toInt();
|
||||
int i = server.arg("BP").toInt();
|
||||
if (i >= 0 && i <= 25) bootPreset = i;
|
||||
}
|
||||
useGammaCorrectionBri = server.hasArg("GCBRI");
|
||||
useGammaCorrectionRGB = server.hasArg("GCRGB");
|
||||
fadeTransition = server.hasArg("TFADE");
|
||||
sweepTransition = server.hasArg("TSWEE");
|
||||
sweepDirection = !server.hasArg("TSDIR");
|
||||
if (server.hasArg("TDLAY"))
|
||||
useGammaCorrectionBri = server.hasArg("GB");
|
||||
useGammaCorrectionRGB = server.hasArg("GC");
|
||||
fadeTransition = server.hasArg("TF");
|
||||
sweepTransition = server.hasArg("TS");
|
||||
sweepDirection = !server.hasArg("TI");
|
||||
if (server.hasArg("TD"))
|
||||
{
|
||||
int i = server.arg("TDLAY").toInt();
|
||||
int i = server.arg("TD").toInt();
|
||||
if (i > 0){
|
||||
transitionDelay = i;
|
||||
}
|
||||
}
|
||||
if (server.hasArg("TLBRI"))
|
||||
if (server.hasArg("TB"))
|
||||
{
|
||||
nightlightTargetBri = server.arg("TLBRI").toInt();
|
||||
nightlightTargetBri = server.arg("TB").toInt();
|
||||
}
|
||||
if (server.hasArg("TLDUR"))
|
||||
if (server.hasArg("TL"))
|
||||
{
|
||||
int i = server.arg("TLDUR").toInt();
|
||||
int i = server.arg("TL").toInt();
|
||||
if (i > 0) nightlightDelayMins = i;
|
||||
}
|
||||
nightlightFade = server.hasArg("TLFDE");
|
||||
if (server.hasArg("OLDEF"))
|
||||
nightlightFade = server.hasArg("TW");
|
||||
reverseMode = server.hasArg("RV");
|
||||
initLedsLast = server.hasArg("EI");
|
||||
strip.setReverseMode(reverseMode);
|
||||
if (server.hasArg("WO"))
|
||||
{
|
||||
int i = server.arg("OLDEF").toInt();
|
||||
if (i >= 0 && i <= 255) overlayDefault = i;
|
||||
}
|
||||
if (server.hasArg("WOFFS"))
|
||||
{
|
||||
int i = server.arg("WOFFS").toInt();
|
||||
int i = server.arg("WO").toInt();
|
||||
if (i >= -255 && i <= 255) arlsOffset = i;
|
||||
arlsSign = (i>=0)?true:false;
|
||||
}
|
||||
if (server.hasArg("NRBRI"))
|
||||
if (server.hasArg("BF"))
|
||||
{
|
||||
int i = server.arg("NRBRI").toInt();
|
||||
int i = server.arg("BF").toInt();
|
||||
if (i > 0) briMultiplier = i;
|
||||
}
|
||||
}
|
||||
@@ -251,49 +242,120 @@ void handleSettingsSet(uint8_t subPage)
|
||||
//UI
|
||||
if (subPage == 3)
|
||||
{
|
||||
if (server.hasArg("DESC")) serverDescription = server.arg("DESC");
|
||||
useHSBDefault = server.hasArg("COLMD");
|
||||
if (server.hasArg("DS")) serverDescription = server.arg("DS");
|
||||
useHSBDefault = server.hasArg("MD");
|
||||
useHSB = useHSBDefault;
|
||||
if (server.hasArg("THEME")) currentTheme = server.arg("THEME").toInt();
|
||||
if (server.hasArg("TH")) currentTheme = server.arg("TH").toInt();
|
||||
for(int i=0;i<6;i++)
|
||||
{
|
||||
if (server.hasArg("CCOL"+String(i))) cssCol[i] = server.arg("CCOL"+String(i));
|
||||
if (server.hasArg("C"+String(i))) cssCol[i] = server.arg("C"+String(i));
|
||||
}
|
||||
if (server.hasArg("CFONT")) cssFont = server.arg("CFONT");
|
||||
if (server.hasArg("CF")) cssFont = server.arg("CF");
|
||||
buildCssColorString();
|
||||
}
|
||||
|
||||
//SYNC
|
||||
if (subPage == 4)
|
||||
{
|
||||
buttonEnabled = server.hasArg("BTNON");
|
||||
if (server.hasArg("NUDPP"))
|
||||
buttonEnabled = server.hasArg("BT");
|
||||
if (server.hasArg("UP"))
|
||||
{
|
||||
udpPort = server.arg("NUDPP").toInt();
|
||||
udpPort = server.arg("UP").toInt();
|
||||
}
|
||||
receiveNotificationBrightness = server.hasArg("NRCBR");
|
||||
receiveNotificationColor = server.hasArg("NRCCL");
|
||||
receiveNotificationEffects = server.hasArg("NRCFX");
|
||||
receiveNotificationBrightness = server.hasArg("RB");
|
||||
receiveNotificationColor = server.hasArg("RC");
|
||||
receiveNotificationEffects = server.hasArg("RX");
|
||||
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
||||
notifyDirectDefault = server.hasArg("NSDIR");
|
||||
notifyDirectDefault = server.hasArg("SD");
|
||||
notifyDirect = notifyDirectDefault;
|
||||
notifyButton = server.hasArg("NSBTN");
|
||||
alexaEnabled = server.hasArg("ALEXA");
|
||||
if (server.hasArg("AINVN")) alexaInvocationName = server.arg("AINVN");
|
||||
alexaNotify = server.hasArg("NSALX");
|
||||
notifyButton = server.hasArg("SB");
|
||||
notifyTwice = server.hasArg("S2");
|
||||
alexaEnabled = server.hasArg("AL");
|
||||
if (server.hasArg("AI")) alexaInvocationName = server.arg("AI");
|
||||
alexaNotify = server.hasArg("SA");
|
||||
notifyHue = server.hasArg("SH");
|
||||
for (int i=0;i<4;i++){
|
||||
String a = "H"+String(i);
|
||||
if (server.hasArg(a))
|
||||
hueIP[i] = server.arg(a).toInt();
|
||||
}
|
||||
if (server.hasArg("HL"))
|
||||
{
|
||||
int i = server.arg("HL").toInt();
|
||||
if (i > 0) huePollLightId = i;
|
||||
}
|
||||
if (server.hasArg("HI"))
|
||||
{
|
||||
int i = server.arg("HI").toInt();
|
||||
if (i > 50) huePollIntervalMs = i;
|
||||
}
|
||||
hueApplyOnOff = server.hasArg("HO");
|
||||
hueApplyBri = server.hasArg("HB");
|
||||
hueApplyColor = server.hasArg("HC");
|
||||
if (server.hasArg("HP"))
|
||||
{
|
||||
if (!huePollingEnabled) hueAttempt = true;
|
||||
if (!setupHue()) hueAttempt = true;
|
||||
} else
|
||||
{
|
||||
huePollingEnabled = false;
|
||||
hueError = "Inactive";
|
||||
}
|
||||
}
|
||||
|
||||
//TIME
|
||||
if (subPage == 5)
|
||||
{
|
||||
ntpEnabled = server.hasArg("NTPON");
|
||||
ntpEnabled = server.hasArg("NT");
|
||||
useAMPM = !server.hasArg("CF");
|
||||
if (server.hasArg("TZ")) currentTimezone = server.arg("TZ").toInt();
|
||||
if (server.hasArg("UO")) utcOffsetSecs = server.arg("UO").toInt();
|
||||
if (ntpEnabled && WiFi.status() == WL_CONNECTED && !ntpConnected) ntpConnected = ntpUdp.begin(ntpLocalPort); //start if not already connected
|
||||
|
||||
if (server.hasArg("OL")){
|
||||
overlayDefault = server.arg("OL").toInt();
|
||||
overlayCurrent = overlayDefault;
|
||||
strip.unlockAll();
|
||||
}
|
||||
if (server.hasArg("O1")) overlayMin = server.arg("O1").toInt();
|
||||
if (server.hasArg("O2")) overlayMax = server.arg("O2").toInt();
|
||||
if (server.hasArg("OM")) analogClock12pixel = server.arg("OM").toInt();
|
||||
analogClock5MinuteMarks = server.hasArg("O5");
|
||||
analogClockSecondsTrail = server.hasArg("OS");
|
||||
|
||||
if (server.hasArg("CX")) cronixieDisplay = server.arg("CX");
|
||||
bool cbOld = cronixieBacklight;
|
||||
cronixieBacklight = server.hasArg("CB");
|
||||
if (cbOld != cronixieBacklight && overlayCurrent == 4)
|
||||
{
|
||||
strip.setCronixieBacklight(cronixieBacklight); overlayRefreshedTime = 0;
|
||||
}
|
||||
countdownMode = server.hasArg("CE");
|
||||
if (server.hasArg("CY")) countdownYear = server.arg("CY").toInt();
|
||||
if (server.hasArg("CI")) countdownMonth = server.arg("CI").toInt();
|
||||
if (server.hasArg("CD")) countdownDay = server.arg("CD").toInt();
|
||||
if (server.hasArg("CH")) countdownHour = server.arg("CH").toInt();
|
||||
if (server.hasArg("CM")) countdownMin = server.arg("CM").toInt();
|
||||
if (server.hasArg("CS")) countdownSec = server.arg("CS").toInt();
|
||||
|
||||
for (int i=1;i<17;i++)
|
||||
{
|
||||
String a = "M"+String(i);
|
||||
if (server.hasArg(a)) saveMacro(i,server.arg(a),false);
|
||||
}
|
||||
if (server.hasArg("MB")) macroBoot = server.arg("MB").toInt();
|
||||
if (server.hasArg("A0")) macroAlexaOn = server.arg("A0").toInt();
|
||||
if (server.hasArg("A1")) macroAlexaOff = server.arg("A1").toInt();
|
||||
if (server.hasArg("MP")) macroButton = server.arg("MP").toInt();
|
||||
if (server.hasArg("ML")) macroLongPress = server.arg("ML").toInt();
|
||||
if (server.hasArg("MC")) macroCountdown = server.arg("MC").toInt();
|
||||
if (server.hasArg("MN")) macroNl = server.arg("MN").toInt();
|
||||
}
|
||||
|
||||
//SECURITY
|
||||
if (subPage == 6)
|
||||
{
|
||||
if (server.hasArg("RESET"))
|
||||
if (server.hasArg("RS"))
|
||||
{
|
||||
clearEEPROM();
|
||||
serveMessage(200, "All Settings erased.", "Connect to WLED-AP to setup again...",255);
|
||||
@@ -301,33 +363,33 @@ void handleSettingsSet(uint8_t subPage)
|
||||
}
|
||||
|
||||
bool pwdCorrect = !otaLock; //always allow access if ota not locked
|
||||
if (server.hasArg("OPASS"))
|
||||
if (server.hasArg("OP"))
|
||||
{
|
||||
if (otaLock && otapass.equals(server.arg("OPASS")))
|
||||
if (otaLock && otaPass.equals(server.arg("OP")))
|
||||
{
|
||||
pwdCorrect = true;
|
||||
}
|
||||
if (!otaLock && server.arg("OPASS").length() > 0)
|
||||
if (!otaLock && server.arg("OP").length() > 0)
|
||||
{
|
||||
otapass = server.arg("OPASS");
|
||||
otaPass = server.arg("OP");
|
||||
}
|
||||
}
|
||||
|
||||
if (pwdCorrect) //allow changes if correct pwd or no ota active
|
||||
{
|
||||
otaLock = server.hasArg("NOOTA");
|
||||
wifiLock = server.hasArg("OWIFI");
|
||||
recoveryAPDisabled = server.hasArg("NORAP");
|
||||
aOtaEnabled = server.hasArg("AROTA");
|
||||
otaLock = server.hasArg("NO");
|
||||
wifiLock = server.hasArg("OW");
|
||||
recoveryAPDisabled = server.hasArg("NA");
|
||||
aOtaEnabled = server.hasArg("AO");
|
||||
}
|
||||
}
|
||||
|
||||
saveSettingsToEEPROM();
|
||||
}
|
||||
|
||||
boolean handleSet(String req)
|
||||
bool handleSet(String req)
|
||||
{
|
||||
boolean effectUpdated = false;
|
||||
bool effectUpdated = false;
|
||||
if (!(req.indexOf("win") >= 0)) {
|
||||
return false;
|
||||
}
|
||||
@@ -358,6 +420,19 @@ boolean handleSet(String req)
|
||||
if (pos > 0) {
|
||||
bri = req.substring(pos + 3).toInt();
|
||||
}
|
||||
|
||||
//set hue
|
||||
pos = req.indexOf("HU=");
|
||||
if (pos > 0) {
|
||||
uint16_t temphue = req.substring(pos + 3).toInt();
|
||||
byte tempsat = 255;
|
||||
pos = req.indexOf("SA=");
|
||||
if (pos > 0) {
|
||||
tempsat = req.substring(pos + 3).toInt();
|
||||
}
|
||||
colorHStoRGB(temphue,tempsat,(req.indexOf("H2")>0)? colSec:col);
|
||||
}
|
||||
|
||||
//set red value
|
||||
pos = req.indexOf("&R=");
|
||||
if (pos > 0) {
|
||||
@@ -382,45 +457,45 @@ boolean handleSet(String req)
|
||||
//set 2nd red value
|
||||
pos = req.indexOf("R2=");
|
||||
if (pos > 0) {
|
||||
col_sec[0] = req.substring(pos + 3).toInt();
|
||||
colSec[0] = req.substring(pos + 3).toInt();
|
||||
}
|
||||
//set 2nd green value
|
||||
pos = req.indexOf("G2=");
|
||||
if (pos > 0) {
|
||||
col_sec[1] = req.substring(pos + 3).toInt();
|
||||
colSec[1] = req.substring(pos + 3).toInt();
|
||||
}
|
||||
//set 2nd blue value
|
||||
pos = req.indexOf("B2=");
|
||||
if (pos > 0) {
|
||||
col_sec[2] = req.substring(pos + 3).toInt();
|
||||
colSec[2] = req.substring(pos + 3).toInt();
|
||||
}
|
||||
//set 2nd white value
|
||||
pos = req.indexOf("W2=");
|
||||
if (pos > 0) {
|
||||
white_sec = req.substring(pos + 3).toInt();
|
||||
whiteSec = req.substring(pos + 3).toInt();
|
||||
}
|
||||
|
||||
//set 2nd to white
|
||||
pos = req.indexOf("SW");
|
||||
if (pos > 0) {
|
||||
if(useRGBW) {
|
||||
white_sec = 255;
|
||||
col_sec[0] = 0;
|
||||
col_sec[1] = 0;
|
||||
col_sec[2] = 0;
|
||||
whiteSec = 255;
|
||||
colSec[0] = 0;
|
||||
colSec[1] = 0;
|
||||
colSec[2] = 0;
|
||||
} else {
|
||||
col_sec[0] = 255;
|
||||
col_sec[1] = 255;
|
||||
col_sec[2] = 255;
|
||||
colSec[0] = 255;
|
||||
colSec[1] = 255;
|
||||
colSec[2] = 255;
|
||||
}
|
||||
}
|
||||
//set 2nd to black
|
||||
pos = req.indexOf("SB");
|
||||
if (pos > 0) {
|
||||
white_sec = 0;
|
||||
col_sec[0] = 0;
|
||||
col_sec[1] = 0;
|
||||
col_sec[2] = 0;
|
||||
whiteSec = 0;
|
||||
colSec[0] = 0;
|
||||
colSec[1] = 0;
|
||||
colSec[2] = 0;
|
||||
}
|
||||
//set to random hue SR=0->1st SR=1->2nd
|
||||
pos = req.indexOf("SR");
|
||||
@@ -430,24 +505,24 @@ boolean handleSet(String req)
|
||||
//set 2nd to 1st
|
||||
pos = req.indexOf("SP");
|
||||
if (pos > 0) {
|
||||
col_sec[0] = col[0];
|
||||
col_sec[1] = col[1];
|
||||
col_sec[2] = col[2];
|
||||
white_sec = white;
|
||||
colSec[0] = col[0];
|
||||
colSec[1] = col[1];
|
||||
colSec[2] = col[2];
|
||||
whiteSec = white;
|
||||
}
|
||||
//swap 2nd & 1st
|
||||
pos = req.indexOf("SC");
|
||||
if (pos > 0) {
|
||||
uint8_t _temp[4];
|
||||
byte _temp[4];
|
||||
for (int i = 0; i<3; i++)
|
||||
{
|
||||
_temp[i] = col[i];
|
||||
col[i] = col_sec[i];
|
||||
col_sec[i] = _temp[i];
|
||||
col[i] = colSec[i];
|
||||
colSec[i] = _temp[i];
|
||||
}
|
||||
_temp[3] = white;
|
||||
white = white_sec;
|
||||
white_sec = _temp[3];
|
||||
white = whiteSec;
|
||||
whiteSec = _temp[3];
|
||||
}
|
||||
|
||||
//set current effect index
|
||||
@@ -480,6 +555,19 @@ boolean handleSet(String req)
|
||||
effectUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
//set hue polling light: 0 -off
|
||||
pos = req.indexOf("HP=");
|
||||
if (pos > 0) {
|
||||
int id = req.substring(pos + 3).toInt();
|
||||
if (id > 0)
|
||||
{
|
||||
if (id < 100) huePollLightId = id;
|
||||
setupHue();
|
||||
} else {
|
||||
huePollingEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
//set default control mode (0 - RGB, 1 - HSB)
|
||||
pos = req.indexOf("MD=");
|
||||
@@ -560,7 +648,7 @@ boolean handleSet(String req)
|
||||
if (req.indexOf("NL=0") > 0)
|
||||
{
|
||||
nightlightActive = false;
|
||||
bri = bri_t;
|
||||
bri = briT;
|
||||
} else {
|
||||
nightlightActive = true;
|
||||
nightlightDelayMins = req.substring(pos + 3).toInt();
|
||||
@@ -571,7 +659,7 @@ boolean handleSet(String req)
|
||||
pos = req.indexOf("NT=");
|
||||
if (pos > 0) {
|
||||
nightlightTargetBri = req.substring(pos + 3).toInt();
|
||||
nightlightActive_old = false; //re-init
|
||||
nightlightActiveOld = false; //re-init
|
||||
}
|
||||
//toggle nightlight fade
|
||||
if (req.indexOf("NF=") > 0)
|
||||
@@ -582,7 +670,7 @@ boolean handleSet(String req)
|
||||
} else {
|
||||
nightlightFade = true;
|
||||
}
|
||||
nightlightActive_old = false; //re-init
|
||||
nightlightActiveOld = false; //re-init
|
||||
}
|
||||
//toggle general purpose output
|
||||
pos = req.indexOf("AX=");
|
||||
@@ -596,14 +684,14 @@ boolean handleSet(String req)
|
||||
if (pos > 0) {
|
||||
switch (req.substring(pos + 3).toInt())
|
||||
{
|
||||
case 0: if (bri != 0){bri_last = bri; bri = 0;} break; //off
|
||||
case 1: bri = bri_last; break; //on
|
||||
case 0: if (bri != 0){briLast = bri; bri = 0;} break; //off
|
||||
case 1: bri = briLast; break; //on
|
||||
default: if (bri == 0) //toggle
|
||||
{
|
||||
bri = bri_last;
|
||||
bri = briLast;
|
||||
} else
|
||||
{
|
||||
bri_last = bri;
|
||||
briLast = bri;
|
||||
bri = 0;
|
||||
}
|
||||
}
|
||||
@@ -622,15 +710,15 @@ boolean handleSet(String req)
|
||||
|
||||
//set custom chase data
|
||||
bool _cc_updated = false;
|
||||
pos = req.indexOf("C0="); if (pos > 0) {cc_start = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("C1="); if (pos > 0) {cc_index1 = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("C2="); if (pos > 0) {cc_index2 = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("CP="); if (pos > 0) {cc_numPrimary = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("CS="); if (pos > 0) {cc_numSecondary = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("CM="); if (pos > 0) {cc_step = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("CF="); if (pos > 0) {cc_fromStart = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("CE="); if (pos > 0) {cc_fromEnd = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
if (_cc_updated) strip.setCustomChase(cc_index1, cc_index2, cc_start, cc_numPrimary, cc_numSecondary, cc_step, cc_fromStart, cc_fromEnd);
|
||||
pos = req.indexOf("C0="); if (pos > 0) {ccStart = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("C1="); if (pos > 0) {ccIndex1 = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("C2="); if (pos > 0) {ccIndex2 = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("CP="); if (pos > 0) {ccNumPrimary = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("CS="); if (pos > 0) {ccNumSecondary = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("CM="); if (pos > 0) {ccStep = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("CF="); if (pos > 0) {ccFromStart = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
pos = req.indexOf("CE="); if (pos > 0) {ccFromEnd = (req.substring(pos + 3).toInt()); _cc_updated = true;}
|
||||
if (_cc_updated) strip.setCustomChase(ccIndex1, ccIndex2, ccStart, ccNumPrimary, ccNumSecondary, ccStep, ccFromStart, ccFromEnd);
|
||||
|
||||
//set presets
|
||||
pos = req.indexOf("PS="); //saves current in preset
|
||||
@@ -655,17 +743,19 @@ boolean handleSet(String req)
|
||||
applyPreset(req.substring(pos + 3).toInt(), false, false, true);
|
||||
effectUpdated = true;
|
||||
}
|
||||
#ifdef CRONIXIE
|
||||
|
||||
//cronixie
|
||||
pos = req.indexOf("NX="); //sets digits to code
|
||||
if (pos > 0) {
|
||||
setCronixie(req.substring(pos + 3, pos + 9).c_str());
|
||||
cronixieDisplay = req.substring(pos + 3, pos + 9);
|
||||
setCronixie();
|
||||
}
|
||||
pos = req.indexOf("NM="); //mode, 1 countdown
|
||||
if (pos > 0) {
|
||||
cronixieCountdown = true;
|
||||
countdownMode = true;
|
||||
if (req.indexOf("NM=0") > 0)
|
||||
{
|
||||
cronixieCountdown = false;
|
||||
countdownMode = false;
|
||||
}
|
||||
}
|
||||
if (req.indexOf("NB=") > 0) //sets backlight
|
||||
@@ -675,10 +765,10 @@ boolean handleSet(String req)
|
||||
{
|
||||
cronixieBacklight = false;
|
||||
}
|
||||
strip.setCronixieBacklight(cronixieBacklight);
|
||||
cronixieRefreshedTime = 0;
|
||||
if (overlayCurrent == 4) strip.setCronixieBacklight(cronixieBacklight);
|
||||
overlayRefreshedTime = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
//internal call, does not send XML response
|
||||
pos = req.indexOf("IN");
|
||||
if (pos < 1) XML_response();
|
||||
|
@@ -4,44 +4,37 @@
|
||||
|
||||
void wledInit()
|
||||
{
|
||||
EEPROM.begin(EEPSIZE);
|
||||
if (!EEPROM.read(397)) strip.init(); //quick init
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
|
||||
#ifdef USEFS
|
||||
SPIFFS.begin();
|
||||
{
|
||||
Dir dir = SPIFFS.openDir("/");
|
||||
while (dir.next()) {
|
||||
String fileName = dir.fileName();
|
||||
size_t fileSize = dir.fileSize();
|
||||
#ifdef DEBUG
|
||||
Serial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
|
||||
#endif
|
||||
}
|
||||
DEBUG_PRINTF("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
DEBUG_PRINTLN("Init EEPROM");
|
||||
EEPROM.begin(EEPSIZE);
|
||||
DEBUG_PRINTLN("Load EEPROM");
|
||||
loadSettingsFromEEPROM(true);
|
||||
DEBUG_PRINT("CC: SSID: ");
|
||||
DEBUG_PRINT(clientssid);
|
||||
if (!initLedsLast) initStrip();
|
||||
DEBUG_PRINT("C-SSID: ");
|
||||
DEBUG_PRINT(clientSSID);
|
||||
buildCssColorString();
|
||||
userBeginPreConnection();
|
||||
|
||||
WiFi.disconnect(); //close old connections
|
||||
|
||||
if (staticip[0] != 0)
|
||||
if (staticIP[0] != 0)
|
||||
{
|
||||
WiFi.config(staticip, staticgateway, staticsubnet, staticdns);
|
||||
WiFi.config(staticIP, staticGateway, staticSubnet, staticDNS);
|
||||
} else
|
||||
{
|
||||
WiFi.config(0U, 0U, 0U);
|
||||
}
|
||||
|
||||
if (apssid.length()>0)
|
||||
if (apSSID.length()>0)
|
||||
{
|
||||
DEBUG_PRINT("USING AP");
|
||||
DEBUG_PRINTLN(apssid.length());
|
||||
DEBUG_PRINTLN(apSSID.length());
|
||||
initAP();
|
||||
} else
|
||||
{
|
||||
@@ -54,9 +47,16 @@ void wledInit()
|
||||
DEBUG_PRINTLN("");
|
||||
DEBUG_PRINT("Connected! IP address: ");
|
||||
DEBUG_PRINTLN(WiFi.localIP());
|
||||
|
||||
if (hueIP[0] == 0)
|
||||
{
|
||||
hueIP[0] = WiFi.localIP()[0];
|
||||
hueIP[1] = WiFi.localIP()[1];
|
||||
hueIP[2] = WiFi.localIP()[2];
|
||||
}
|
||||
|
||||
// Set up mDNS responder:
|
||||
if (cmdns != NULL && !onlyAP && !MDNS.begin(cmdns.c_str())) {
|
||||
if (cmDNS != NULL && !onlyAP && !MDNS.begin(cmDNS.c_str())) {
|
||||
DEBUG_PRINTLN("Error setting up MDNS responder!");
|
||||
down();
|
||||
}
|
||||
@@ -69,6 +69,14 @@ void wledInit()
|
||||
if (ntpEnabled && WiFi.status() == WL_CONNECTED)
|
||||
ntpConnected = ntpUdp.begin(ntpLocalPort);
|
||||
|
||||
//start captive portal
|
||||
if (onlyAP || apSSID.length() > 0)
|
||||
{
|
||||
dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
|
||||
dnsServer.start(53, "*", WiFi.softAPIP());
|
||||
dnsActive = true;
|
||||
}
|
||||
|
||||
//SERVER INIT
|
||||
//settings page
|
||||
server.on("/settings", HTTP_GET, [](){
|
||||
@@ -106,15 +114,15 @@ void wledInit()
|
||||
});
|
||||
|
||||
server.on("/", HTTP_GET, [](){
|
||||
if (!showWelcomePage){
|
||||
if(!handleFileRead("/index.htm")) {
|
||||
serveIndex();
|
||||
}
|
||||
}else{
|
||||
if(!handleFileRead("/welcome.htm")) {
|
||||
serveSettings(255);
|
||||
}
|
||||
}
|
||||
serveIndexOrWelcome();
|
||||
});
|
||||
|
||||
server.on("/generate_204", HTTP_GET, [](){
|
||||
serveIndexOrWelcome();
|
||||
});
|
||||
|
||||
server.on("/fwlink", HTTP_GET, [](){
|
||||
serveIndexOrWelcome();
|
||||
});
|
||||
|
||||
server.on("/sliders", HTTP_GET, serveIndex);
|
||||
@@ -124,7 +132,7 @@ void wledInit()
|
||||
});
|
||||
|
||||
server.on("/reset", HTTP_GET, [](){
|
||||
serveMessage(200,"Rebooting now...","(takes ~20 seconds, wait for auto-redirect)",139);
|
||||
serveMessage(200,"Rebooting now...","(takes ~20 seconds, wait for auto-redirect)",79);
|
||||
reset();
|
||||
});
|
||||
|
||||
@@ -146,7 +154,13 @@ void wledInit()
|
||||
|
||||
server.on("/settings/sync", HTTP_POST, [](){
|
||||
handleSettingsSet(4);
|
||||
serveMessage(200,"Sync settings saved.","Redirecting...",1);
|
||||
if (hueAttempt)
|
||||
{
|
||||
serveMessage(200,"Hue setup result",hueError,253);
|
||||
} else {
|
||||
serveMessage(200,"Sync settings saved.","Redirecting...",1);
|
||||
}
|
||||
hueAttempt = false;
|
||||
});
|
||||
|
||||
server.on("/settings/time", HTTP_POST, [](){
|
||||
@@ -173,7 +187,7 @@ void wledInit()
|
||||
});
|
||||
|
||||
server.on("/power", HTTP_GET, [](){
|
||||
String val = (String)(int)strip.getPowerEstimate(ledcount,strip.getColor(),strip.getBrightness());
|
||||
String val = (String)(int)strip.getPowerEstimate(ledCount,strip.getColor(),strip.getBrightness());
|
||||
val += "mA currently";
|
||||
serveMessage(200,val,"This is just an estimate (does not take into account several factors like effects and wire resistance). It is NOT an accurate measurement!",254);
|
||||
});
|
||||
@@ -198,16 +212,6 @@ void wledInit()
|
||||
info += "rgbw: false\r\n";
|
||||
#endif
|
||||
info += "max-leds: " + (String)LEDCOUNT + "\r\n";
|
||||
#ifdef USEOVERLAYS
|
||||
info += "overlays: true\r\n";
|
||||
#else
|
||||
info += "overlays: false\r\n";
|
||||
#endif
|
||||
#ifdef CRONIXIE
|
||||
info += "cronixie: true\r\n";
|
||||
#else
|
||||
info += "cronixie: false\r\n";
|
||||
#endif
|
||||
#ifdef USEFS
|
||||
info += "spiffs: true\r\n";
|
||||
#else
|
||||
@@ -289,51 +293,66 @@ void wledInit()
|
||||
ArduinoOTA.begin();
|
||||
}
|
||||
|
||||
// Initialize NeoPixel Strip
|
||||
strip.init();
|
||||
strip.setLedCount(ledcount);
|
||||
if (initLedsLast) initStrip();
|
||||
userBegin();
|
||||
if (macroBoot>0) applyMacro(macroBoot);
|
||||
}
|
||||
|
||||
void initStrip()
|
||||
{
|
||||
// Initialize NeoPixel Strip and button
|
||||
if (initLedsLast) strip.init();
|
||||
strip.setLedCount(ledCount);
|
||||
strip.setReverseMode(reverseMode);
|
||||
strip.setColor(0);
|
||||
strip.setBrightness(255);
|
||||
strip.start();
|
||||
|
||||
pinMode(buttonPin, INPUT_PULLUP);
|
||||
#ifdef CRONIXIE
|
||||
strip.driverModeCronixie(true);
|
||||
strip.setCronixieBacklight(cronixieBacklight);
|
||||
setCronixie(cronixieDefault);
|
||||
#endif
|
||||
|
||||
if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true);
|
||||
colorUpdated(0);
|
||||
if(digitalRead(buttonPin) == LOW) buttonEnabled = false; //disable button if it is "pressed" unintentionally
|
||||
}
|
||||
|
||||
void initAP(){
|
||||
String save = apssid;
|
||||
#ifdef CRONIXIE
|
||||
if (apssid.length() <1) apssid = "CRONIXIE-AP";
|
||||
#else
|
||||
if (apssid.length() <1) apssid = "WLED-AP";
|
||||
#endif
|
||||
WiFi.softAP(apssid.c_str(), appass.c_str(), apchannel, aphide);
|
||||
apssid = save;
|
||||
String save = apSSID;
|
||||
if (apSSID.length() <1) apSSID = "WLED-AP";
|
||||
WiFi.softAP(apSSID.c_str(), apPass.c_str(), apChannel, apHide);
|
||||
apSSID = save;
|
||||
}
|
||||
|
||||
void initCon()
|
||||
{
|
||||
int fail_count = 0;
|
||||
if (clientssid.length() <1 || clientssid.equals("Your_Network_Here")) fail_count = apWaitTimeSecs*2;
|
||||
WiFi.begin(clientssid.c_str(), clientpass.c_str());
|
||||
while(WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
DEBUG_PRINTLN("C_NC");
|
||||
fail_count++;
|
||||
if (!recoveryAPDisabled && fail_count > apWaitTimeSecs*2)
|
||||
if (clientSSID.length() <1 || clientSSID.equals("Your_Network")) fail_count = apWaitTimeSecs*2;
|
||||
WiFi.begin(clientSSID.c_str(), clientPass.c_str());
|
||||
unsigned long lastTry = 0;
|
||||
bool con = false;
|
||||
while(!con)
|
||||
{
|
||||
yield();
|
||||
if (!initLedsLast)
|
||||
{
|
||||
WiFi.disconnect();
|
||||
DEBUG_PRINTLN("Can't connect. Opening AP...");
|
||||
onlyAP = true;
|
||||
initAP();
|
||||
return;
|
||||
handleTransitions();
|
||||
handleButton();
|
||||
handleOverlays();
|
||||
if (briT) strip.service();
|
||||
}
|
||||
if (millis()-lastTry > 499) {
|
||||
con = (WiFi.status() == WL_CONNECTED);
|
||||
if (con) DEBUG_PRINTLN("rofl");
|
||||
lastTry = millis();
|
||||
DEBUG_PRINTLN("C_NC");
|
||||
if (!recoveryAPDisabled && fail_count > apWaitTimeSecs*2)
|
||||
{
|
||||
WiFi.disconnect();
|
||||
DEBUG_PRINTLN("Can't connect. Opening AP...");
|
||||
onlyAP = true;
|
||||
initAP();
|
||||
return;
|
||||
}
|
||||
fail_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,6 +373,7 @@ void buildCssColorString()
|
||||
case 8: cs[0]="0ac"; cs[1]="124"; cs[2]="224"; cs[3]="003eff"; cs[4]="003eff"; cs[5]="003eff"; break;//air
|
||||
case 9: cs[0]="f70"; cs[1]="421"; cs[2]="221"; cs[3]="a50"; cs[4]="f70"; cs[5]="f70"; break;//nixie
|
||||
case 10: cs[0]="2d2"; cs[1]="010"; cs[2]="121"; cs[3]="060"; cs[4]="040"; cs[5]="3f3"; break; //terminal
|
||||
case 11: cs[0]="867ADE"; cs[1]="4033A3"; cs[2]="483AAA"; cs[3]="483AAA"; cs[4]=""; cs[5]="867ADE"; break; //c64
|
||||
case 14: cs[0]="fc7"; cs[1]="49274a"; cs[2]="94618e"; cs[3]="f4decb"; cs[4]="0008"; cs[5]="f4decb"; break; //end
|
||||
case 15: for (int i=0;i<6;i++)cs[i]=cssCol[i];//custom
|
||||
}
|
||||
@@ -374,6 +394,19 @@ void buildCssColorString()
|
||||
cssColorString+=";}";
|
||||
}
|
||||
|
||||
void serveIndexOrWelcome()
|
||||
{
|
||||
if (!showWelcomePage){
|
||||
if(!handleFileRead("/index.htm")) {
|
||||
serveIndex();
|
||||
}
|
||||
}else{
|
||||
if(!handleFileRead("/welcome.htm")) {
|
||||
serveSettings(255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void serveIndex()
|
||||
{
|
||||
if (!arlsTimeout) //do not serve while receiving realtime
|
||||
@@ -421,7 +454,7 @@ void serveMessage(int code, String headl, String subl="", int optionType)
|
||||
server.sendContent(messageBody);
|
||||
}
|
||||
|
||||
void serveSettings(uint8_t subPage)
|
||||
void serveSettings(byte subPage)
|
||||
{
|
||||
//0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec 255: welcomepage
|
||||
if (!arlsTimeout) //do not serve while receiving realtime
|
||||
|
@@ -1,6 +0,0 @@
|
||||
/*
|
||||
* foo
|
||||
*/
|
||||
|
||||
String readFromFS(String filename){return "N";};
|
||||
void writeToFS(String filename, String file) {};
|
21
wled00/wled06_usermod.ino
Normal file
21
wled00/wled06_usermod.ino
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* This file allows you to add own functionality to WLED more easily
|
||||
* See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality
|
||||
* EEPROM bytes 2944 to 3071 are reserved for your custom use case.
|
||||
*/
|
||||
|
||||
void userBeginPreConnection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void userBegin()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void userLoop()
|
||||
{
|
||||
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
#define WLEDPACKETSIZE 24
|
||||
|
||||
void notify(uint8_t callMode)
|
||||
void notify(byte callMode, bool followUp=false)
|
||||
{
|
||||
if (!udpConnected) return;
|
||||
switch (callMode)
|
||||
@@ -13,6 +13,7 @@ void notify(uint8_t callMode)
|
||||
case 2: if (!notifyButton) return; break;
|
||||
case 4: if (!notifyDirect) return; break;
|
||||
case 6: if (!notifyDirect) return; break; //fx change
|
||||
case 7: if (!notifyHue) return; break;
|
||||
default: return;
|
||||
}
|
||||
byte udpOut[WLEDPACKETSIZE];
|
||||
@@ -27,12 +28,14 @@ void notify(uint8_t callMode)
|
||||
udpOut[8] = effectCurrent;
|
||||
udpOut[9] = effectSpeed;
|
||||
udpOut[10] = white;
|
||||
udpOut[11] = 3; //compatibilityVersionByte: 0: old 1: supports white 2: supports secondary color 3: supports FX intensity, 24 byte packet
|
||||
udpOut[12] = col_sec[0];
|
||||
udpOut[13] = col_sec[1];
|
||||
udpOut[14] = col_sec[2];
|
||||
udpOut[15] = white_sec;
|
||||
udpOut[11] = 4; //compatibilityVersionByte: 0: old 1: supports white 2: supports secondary color 3: supports FX intensity, 24 byte packet 4: supports transitionDelay
|
||||
udpOut[12] = colSec[0];
|
||||
udpOut[13] = colSec[1];
|
||||
udpOut[14] = colSec[2];
|
||||
udpOut[15] = whiteSec;
|
||||
udpOut[16] = effectIntensity;
|
||||
udpOut[17] = (transitionDelay >> 0) & 0xFF;
|
||||
udpOut[18] = (transitionDelay >> 8) & 0xFF;
|
||||
|
||||
IPAddress broadcastIp;
|
||||
broadcastIp = ~WiFi.subnetMask() | WiFi.gatewayIP();
|
||||
@@ -40,14 +43,23 @@ void notify(uint8_t callMode)
|
||||
notifierUdp.beginPacket(broadcastIp, udpPort);
|
||||
notifierUdp.write(udpOut, WLEDPACKETSIZE);
|
||||
notifierUdp.endPacket();
|
||||
notificationSentCallMode = callMode;
|
||||
notificationSentTime = millis();
|
||||
notificationTwoRequired = (followUp)? false:notifyTwice;
|
||||
}
|
||||
|
||||
void handleNotifications()
|
||||
{
|
||||
if(udpConnected && notificationTwoRequired && millis()-notificationSentTime > 250){
|
||||
notify(notificationSentCallMode,true);
|
||||
}
|
||||
|
||||
if(udpConnected && receiveNotifications){
|
||||
int packetSize = notifierUdp.parsePacket();
|
||||
uint16_t packetSize = notifierUdp.parsePacket();
|
||||
if (packetSize > 1026) return;
|
||||
if(packetSize && notifierUdp.remoteIP() != WiFi.localIP()) //don't process broadcasts we send ourselves
|
||||
{
|
||||
byte udpIn[packetSize];
|
||||
notifierUdp.read(udpIn, packetSize);
|
||||
if (udpIn[0] == 0 && !arlsTimeout) //wled notifier, block if realtime packets active
|
||||
{
|
||||
@@ -62,10 +74,10 @@ void handleNotifications()
|
||||
white = udpIn[10];
|
||||
if (udpIn[11] > 1 )
|
||||
{
|
||||
col_sec[0] = udpIn[12];
|
||||
col_sec[1] = udpIn[13];
|
||||
col_sec[2] = udpIn[14];
|
||||
white_sec = udpIn[15];
|
||||
colSec[0] = udpIn[12];
|
||||
colSec[1] = udpIn[13];
|
||||
colSec[2] = udpIn[14];
|
||||
whiteSec = udpIn[15];
|
||||
}
|
||||
}
|
||||
if (udpIn[8] != effectCurrent && receiveNotificationEffects)
|
||||
@@ -83,6 +95,10 @@ void handleNotifications()
|
||||
effectIntensity = udpIn[16];
|
||||
strip.setIntensity(effectIntensity);
|
||||
}
|
||||
if (udpIn[11] > 3)
|
||||
{
|
||||
transitionDelayTemp = ((udpIn[17] << 0) & 0xFF) + ((udpIn[18] << 8) & 0xFF00);
|
||||
}
|
||||
nightlightActive = udpIn[6];
|
||||
if (!nightlightActive)
|
||||
{
|
||||
@@ -97,7 +113,7 @@ void handleNotifications()
|
||||
arlsTimeout = false;
|
||||
} else {
|
||||
if (!arlsTimeout){
|
||||
strip.setRange(0, ledcount-1, 0);
|
||||
strip.setRange(0, ledCount-1, 0);
|
||||
strip.setMode(0);
|
||||
}
|
||||
arlsTimeout = true;
|
||||
@@ -105,7 +121,7 @@ void handleNotifications()
|
||||
}
|
||||
for (int i = 2; i < packetSize -3; i += 4)
|
||||
{
|
||||
if (udpIn[i] + arlsOffset < ledcount && udpIn[i] + arlsOffset >= 0)
|
||||
if (udpIn[i] + arlsOffset < ledCount && udpIn[i] + arlsOffset >= 0)
|
||||
if (useGammaCorrectionRGB)
|
||||
{
|
||||
strip.setPixelColor(udpIn[i] + arlsOffset, gamma8[udpIn[i+1]], gamma8[udpIn[i+2]], gamma8[udpIn[i+3]]);
|
||||
|
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
void setAllLeds() {
|
||||
double d = bri_t*briMultiplier;
|
||||
double d = briT*briMultiplier;
|
||||
int val = d/100;
|
||||
if (val > 255) val = 255;
|
||||
if (useGammaCorrectionBri)
|
||||
@@ -14,26 +14,26 @@ void setAllLeds() {
|
||||
}
|
||||
if (useGammaCorrectionRGB)
|
||||
{
|
||||
strip.setColor(gamma8[col_t[0]], gamma8[col_t[1]], gamma8[col_t[2]], gamma8[white_t]);
|
||||
strip.setSecondaryColor(gamma8[col_sec[0]], gamma8[col_sec[1]], gamma8[col_sec[2]], gamma8[white_sec]);
|
||||
strip.setColor(gamma8[colT[0]], gamma8[colT[1]], gamma8[colT[2]], gamma8[whiteT]);
|
||||
strip.setSecondaryColor(gamma8[colSec[0]], gamma8[colSec[1]], gamma8[colSec[2]], gamma8[whiteSec]);
|
||||
} else {
|
||||
strip.setColor(col_t[0], col_t[1], col_t[2], white_t);
|
||||
strip.setSecondaryColor(col_sec[0], col_sec[1], col_sec[2], white_sec);
|
||||
strip.setColor(colT[0], colT[1], colT[2], whiteT);
|
||||
strip.setSecondaryColor(colSec[0], colSec[1], colSec[2], whiteSec);
|
||||
}
|
||||
}
|
||||
|
||||
void setLedsStandard()
|
||||
{
|
||||
col_old[0] = col[0];
|
||||
col_old[1] = col[1];
|
||||
col_old[2] = col[2];
|
||||
white_old = white;
|
||||
bri_old = bri;
|
||||
col_t[0] = col[0];
|
||||
col_t[1] = col[1];
|
||||
col_t[2] = col[2];
|
||||
white_t = white;
|
||||
bri_t = bri;
|
||||
colOld[0] = col[0];
|
||||
colOld[1] = col[1];
|
||||
colOld[2] = col[2];
|
||||
whiteOld = white;
|
||||
briOld = bri;
|
||||
colT[0] = col[0];
|
||||
colT[1] = col[1];
|
||||
colT[2] = col[2];
|
||||
whiteT = white;
|
||||
briT = bri;
|
||||
setAllLeds();
|
||||
}
|
||||
|
||||
@@ -41,17 +41,17 @@ bool colorChanged()
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (col[i] != col_it[i]) return true;
|
||||
if (col_sec[i] != col_sec_it[i]) return true;
|
||||
if (col[i] != colIT[i]) return true;
|
||||
if (colSec[i] != colSecIT[i]) return true;
|
||||
}
|
||||
if (white != white_it || white_sec != white_sec_it) return true;
|
||||
if (bri != bri_it) return true;
|
||||
if (white != whiteIT || whiteSec != whiteSecIT) return true;
|
||||
if (bri != briIT) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void colorUpdated(int callMode)
|
||||
{
|
||||
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (no not.) (NN)6: fx changed
|
||||
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (NN)6: fx changed 7: hue
|
||||
if (!colorChanged())
|
||||
{
|
||||
if (callMode == 6) notify(6);
|
||||
@@ -59,31 +59,34 @@ void colorUpdated(int callMode)
|
||||
}
|
||||
if (callMode != 5 && nightlightActive && nightlightFade)
|
||||
{
|
||||
bri_nl_t = bri;
|
||||
briNlT = bri;
|
||||
nightlightDelayMs -= (millis() - nightlightStartTime);
|
||||
nightlightStartTime = millis();
|
||||
}
|
||||
col_it[0] = col[0];
|
||||
col_it[1] = col[1];
|
||||
col_it[2] = col[2];
|
||||
col_sec_it[0] = col_sec[0];
|
||||
col_sec_it[1] = col_sec[1];
|
||||
col_sec_it[2] = col_sec[2];
|
||||
white_it = white;
|
||||
white_sec_it = white_sec;
|
||||
bri_it = bri;
|
||||
if (bri > 0) bri_last = bri;
|
||||
colIT[0] = col[0];
|
||||
colIT[1] = col[1];
|
||||
colIT[2] = col[2];
|
||||
colSecIT[0] = colSec[0];
|
||||
colSecIT[1] = colSec[1];
|
||||
colSecIT[2] = colSec[2];
|
||||
whiteIT = white;
|
||||
whiteSecIT = whiteSec;
|
||||
briIT = bri;
|
||||
if (bri > 0) briLast = bri;
|
||||
notify(callMode);
|
||||
if (fadeTransition || sweepTransition)
|
||||
{
|
||||
//set correct delay if not using notification delay
|
||||
if (callMode != 3) transitionDelayTemp = transitionDelay;
|
||||
|
||||
if (transitionActive)
|
||||
{
|
||||
col_old[0] = col_t[0];
|
||||
col_old[1] = col_t[1];
|
||||
col_old[2] = col_t[2];
|
||||
white_old = white_t;
|
||||
bri_old = bri_t;
|
||||
tper_last = 0;
|
||||
colOld[0] = colT[0];
|
||||
colOld[1] = colT[1];
|
||||
colOld[2] = colT[2];
|
||||
whiteOld = whiteT;
|
||||
briOld = briT;
|
||||
tperLast = 0;
|
||||
}
|
||||
transitionActive = true;
|
||||
transitionStartTime = millis();
|
||||
@@ -97,40 +100,40 @@ void colorUpdated(int callMode)
|
||||
|
||||
void handleTransitions()
|
||||
{
|
||||
if (transitionActive && transitionDelay > 0)
|
||||
if (transitionActive && transitionDelayTemp > 0)
|
||||
{
|
||||
float tper = (millis() - transitionStartTime)/(float)transitionDelay;
|
||||
float tper = (millis() - transitionStartTime)/(float)transitionDelayTemp;
|
||||
if (tper >= 1.0)
|
||||
{
|
||||
transitionActive = false;
|
||||
tper_last = 0;
|
||||
tperLast = 0;
|
||||
if (sweepTransition) strip.unlockAll();
|
||||
setLedsStandard();
|
||||
strip.setFastUpdateMode(false);
|
||||
return;
|
||||
}
|
||||
if (tper - tper_last < transitionResolution)
|
||||
if (tper - tperLast < transitionResolution)
|
||||
{
|
||||
return;
|
||||
}
|
||||
tper_last = tper;
|
||||
tperLast = tper;
|
||||
if (fadeTransition)
|
||||
{
|
||||
col_t[0] = col_old[0]+((col[0] - col_old[0])*tper);
|
||||
col_t[1] = col_old[1]+((col[1] - col_old[1])*tper);
|
||||
col_t[2] = col_old[2]+((col[2] - col_old[2])*tper);
|
||||
white_t = white_old +((white - white_old )*tper);
|
||||
bri_t = bri_old +((bri - bri_old )*tper);
|
||||
colT[0] = colOld[0]+((col[0] - colOld[0])*tper);
|
||||
colT[1] = colOld[1]+((col[1] - colOld[1])*tper);
|
||||
colT[2] = colOld[2]+((col[2] - colOld[2])*tper);
|
||||
whiteT = whiteOld +((white - whiteOld )*tper);
|
||||
briT = briOld +((bri - briOld )*tper);
|
||||
}
|
||||
if (sweepTransition)
|
||||
{
|
||||
strip.lockAll();
|
||||
if (sweepDirection)
|
||||
{
|
||||
strip.unlockRange(0, (int)(tper*(double)ledcount));
|
||||
strip.unlockRange(0, (int)(tper*(double)ledCount));
|
||||
} else
|
||||
{
|
||||
strip.unlockRange(ledcount - (int)(tper*(double)ledcount), ledcount);
|
||||
strip.unlockRange(ledCount - (int)(tper*(double)ledCount), ledCount);
|
||||
}
|
||||
if (!fadeTransition)
|
||||
{
|
||||
@@ -145,18 +148,18 @@ void handleNightlight()
|
||||
{
|
||||
if (nightlightActive)
|
||||
{
|
||||
if (!nightlightActive_old) //init
|
||||
if (!nightlightActiveOld) //init
|
||||
{
|
||||
nightlightStartTime = millis();
|
||||
notify(4);
|
||||
nightlightDelayMs = (int)(nightlightDelayMins*60000);
|
||||
nightlightActive_old = true;
|
||||
bri_nl_t = bri;
|
||||
nightlightActiveOld = true;
|
||||
briNlT = bri;
|
||||
}
|
||||
float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs);
|
||||
if (nightlightFade)
|
||||
{
|
||||
bri = bri_nl_t+((nightlightTargetBri - bri_nl_t)*nper);
|
||||
bri = briNlT+((nightlightTargetBri - briNlT)*nper);
|
||||
colorUpdated(5);
|
||||
}
|
||||
if (nper >= 1)
|
||||
@@ -167,10 +170,10 @@ void handleNightlight()
|
||||
bri = nightlightTargetBri;
|
||||
colorUpdated(5);
|
||||
}
|
||||
if (bri == 0) bri_last = bri_nl_t;
|
||||
if (bri == 0) briLast = briNlT;
|
||||
}
|
||||
} else if (nightlightActive_old) //early de-init
|
||||
} else if (nightlightActiveOld) //early de-init
|
||||
{
|
||||
nightlightActive_old = false;
|
||||
nightlightActiveOld = false;
|
||||
}
|
||||
}
|
||||
|
@@ -10,27 +10,34 @@ void handleButton()
|
||||
{
|
||||
buttonPressedTime = millis();
|
||||
buttonPressedBefore = true;
|
||||
if (buttonMacro == 255)
|
||||
{
|
||||
if (bri == 0)
|
||||
{
|
||||
bri = bri_last;
|
||||
} else
|
||||
{
|
||||
bri_last = bri;
|
||||
bri = 0;
|
||||
}
|
||||
colorUpdated(2);
|
||||
} else {
|
||||
applyMacro(buttonMacro);
|
||||
}
|
||||
}
|
||||
else if (digitalRead(buttonPin) == HIGH && buttonPressedBefore)
|
||||
{
|
||||
delay(15); //debounce
|
||||
if (digitalRead(buttonPin) == HIGH)
|
||||
{
|
||||
if (millis() - buttonPressedTime > 7000) initAP();
|
||||
if (millis() - buttonPressedTime > 7000) {initAP();}
|
||||
else if (millis() - buttonPressedTime > 700)
|
||||
{
|
||||
if (macroLongPress != 0) {applyMacro(macroLongPress);}
|
||||
else _setRandomColor(false,true);
|
||||
}
|
||||
else {
|
||||
if (macroButton == 0)
|
||||
{
|
||||
if (bri == 0)
|
||||
{
|
||||
bri = briLast;
|
||||
} else
|
||||
{
|
||||
briLast = bri;
|
||||
bri = 0;
|
||||
}
|
||||
colorUpdated(2);
|
||||
} else {
|
||||
applyMacro(macroButton);
|
||||
}
|
||||
}
|
||||
buttonPressedBefore = false;
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,55 @@
|
||||
* Acquires time from NTP server
|
||||
*/
|
||||
|
||||
TimeChangeRule UTCr = {Last, Sun, Mar, 1, 0}; // UTC
|
||||
Timezone tzUTC(UTCr, UTCr);
|
||||
|
||||
TimeChangeRule BST = {Last, Sun, Mar, 1, 60}; // British Summer Time
|
||||
TimeChangeRule GMT = {Last, Sun, Oct, 2, 0}; // Standard Time
|
||||
Timezone tzUK(BST, GMT);
|
||||
|
||||
TimeChangeRule CEST = {Last, Sun, Mar, 2, 120}; //Central European Summer Time
|
||||
TimeChangeRule CET = {Last, Sun, Oct, 3, 60}; //Central European Standard Time
|
||||
Timezone tzEUCentral(CEST, CET);
|
||||
|
||||
TimeChangeRule EEST = {Last, Sun, Mar, 3, 180}; //Central European Summer Time
|
||||
TimeChangeRule EET = {Last, Sun, Oct, 4, 120}; //Central European Standard Time
|
||||
Timezone tzEUEastern(EEST, EET);
|
||||
|
||||
TimeChangeRule EDT = {Second, Sun, Mar, 2, -240 }; //Daylight time = UTC - 4 hours
|
||||
TimeChangeRule EST = {First, Sun, Nov, 2, -300 }; //Standard time = UTC - 5 hours
|
||||
Timezone tzUSEastern(EDT, EST);
|
||||
|
||||
TimeChangeRule CDT = {Second, Sun, Mar, 2, -300 }; //Daylight time = UTC - 5 hours
|
||||
TimeChangeRule CST = {First, Sun, Nov, 2, -360 }; //Standard time = UTC - 6 hours
|
||||
Timezone tzUSCentral(CDT, CST);
|
||||
|
||||
TimeChangeRule MDT = {Second, Sun, Mar, 2, -360 }; //Daylight time = UTC - 6 hours
|
||||
TimeChangeRule MST = {First, Sun, Nov, 2, -420 }; //Standard time = UTC - 7 hours
|
||||
Timezone tzUSMountain(MDT, MST);
|
||||
|
||||
Timezone tzUSArizona(MST, MST); //Mountain without DST
|
||||
|
||||
TimeChangeRule PDT = {Second, Sun, Mar, 2, -420 }; //Daylight time = UTC - 7 hours
|
||||
TimeChangeRule PST = {First, Sun, Nov, 2, -480 }; //Standard time = UTC - 8 hours
|
||||
Timezone tzUSPacific(PDT, PST);
|
||||
|
||||
TimeChangeRule ChST = {Last, Sun, Mar, 1, 480}; // China Standard Time = UTC + 8 hours
|
||||
Timezone tzChina(ChST, ChST);
|
||||
|
||||
TimeChangeRule JST = {Last, Sun, Mar, 1, 540}; // Japan Standard Time = UTC + 9 hours
|
||||
Timezone tzJapan(JST, JST);
|
||||
|
||||
TimeChangeRule AEDT = {Second, Sun, Oct, 2, 660 }; //Daylight time = UTC + 11 hours
|
||||
TimeChangeRule AEST = {First, Sun, Apr, 3, 600 }; //Standard time = UTC + 10 hours
|
||||
Timezone tzAUEastern(AEDT, AEST);
|
||||
|
||||
TimeChangeRule NZDT = {Second, Sun, Sep, 2, 780 }; //Daylight time = UTC + 13 hours
|
||||
TimeChangeRule NZST = {First, Sun, Apr, 3, 720 }; //Standard time = UTC + 12 hours
|
||||
Timezone tzNZ(NZDT, NZST);
|
||||
|
||||
Timezone* timezones[] = { &tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ};
|
||||
|
||||
void handleNetworkTime()
|
||||
{
|
||||
if (ntpEnabled && ntpConnected && millis() - ntpLastSyncTime > 50000000L && WiFi.status() == WL_CONNECTED)
|
||||
@@ -20,7 +69,8 @@ void handleNetworkTime()
|
||||
|
||||
void sendNTPPacket()
|
||||
{
|
||||
WiFi.hostByName(ntpServerName, ntpServerIP);
|
||||
const char* ntpsrv = ntpServerName.c_str();
|
||||
WiFi.hostByName(ntpsrv, ntpServerIP);
|
||||
DEBUG_PRINTLN("send NTP packet");
|
||||
|
||||
memset(ntpPacketBuffer, 0, NTP_PACKET_SIZE);
|
||||
@@ -40,7 +90,7 @@ void sendNTPPacket()
|
||||
ntpUdp.endPacket();
|
||||
}
|
||||
|
||||
boolean checkNTPResponse()
|
||||
bool checkNTPResponse()
|
||||
{
|
||||
int cb = ntpUdp.parsePacket();
|
||||
if (cb) {
|
||||
@@ -56,7 +106,7 @@ boolean checkNTPResponse()
|
||||
unsigned long secsSince1900 = highWord << 16 | lowWord;
|
||||
|
||||
DEBUG_PRINT("Unix time = ");
|
||||
unsigned long epoch = secsSince1900 - seventyYears;
|
||||
unsigned long epoch = secsSince1900 - 2208988800UL; //subtract 70 years
|
||||
setTime(epoch);
|
||||
DEBUG_PRINTLN(epoch);
|
||||
if (countdownTime - now() > 0) countdownOverTriggered = false;
|
||||
@@ -65,33 +115,49 @@ boolean checkNTPResponse()
|
||||
return false;
|
||||
}
|
||||
|
||||
void updateLocalTime()
|
||||
{
|
||||
unsigned long tmc = now()+ utcOffsetSecs;
|
||||
local = timezones[currentTimezone]->toLocal(tmc);
|
||||
}
|
||||
|
||||
String getTimeString()
|
||||
{
|
||||
local = TZ.toLocal(now(), &tcr);
|
||||
updateLocalTime();
|
||||
String ret = monthStr(month(local));
|
||||
ret = ret + " ";
|
||||
ret = ret + day(local);
|
||||
ret = ret + " ";
|
||||
ret = ret + year(local);
|
||||
ret = ret + ", ";
|
||||
ret = ret + hour(local);
|
||||
ret += (useAMPM)? hour(local)%12:hour(local);
|
||||
ret = ret + ":";
|
||||
if (minute(local) < 10) ret = ret + "0";
|
||||
ret = ret + minute(local);
|
||||
ret = ret + ":";
|
||||
if (second(local) < 10) ret = ret + "0";
|
||||
ret = ret + second(local);
|
||||
if (useAMPM)
|
||||
{
|
||||
ret += (hour(local) > 11)? " PM":" AM";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void setCountdown()
|
||||
{
|
||||
countdownTime = timezones[currentTimezone]->toUTC(getUnixTime(countdownHour, countdownMin, countdownSec, countdownDay, countdownMonth, countdownYear));
|
||||
if (countdownTime - now() > 0) countdownOverTriggered = false;
|
||||
}
|
||||
|
||||
//returns true if countdown just over
|
||||
bool checkCountdown()
|
||||
{
|
||||
long diff = countdownTime - local;
|
||||
long diff = countdownTime - now();
|
||||
local = abs(diff);
|
||||
if (diff <0 && !countdownOverTriggered)
|
||||
{
|
||||
applyMacro(countdownMacro);
|
||||
if (macroCountdown != 0) applyMacro(macroCountdown);
|
||||
countdownOverTriggered = true;
|
||||
return true;
|
||||
}
|
||||
|
@@ -1,13 +1,27 @@
|
||||
/*
|
||||
* The Overlay function is over a year old, largely untested and not configurable during runtime. Consider it as deprecated for now, it might get either removed/simplified/reworked.
|
||||
* Used to draw clock overlays over the strip
|
||||
*/
|
||||
#ifdef USEOVERLAYS
|
||||
void _nixieDisplay(int num[], int dur[], int pausedur[], int cnt)
|
||||
void initCronixie()
|
||||
{
|
||||
if (overlayCurrent == 4 && !cronixieInit)
|
||||
{
|
||||
strip.driverModeCronixie(true);
|
||||
strip.setCronixieBacklight(cronixieBacklight);
|
||||
setCronixie();
|
||||
cronixieInit = true;
|
||||
} else if (cronixieInit && overlayCurrent != 4)
|
||||
{
|
||||
strip.driverModeCronixie(false);
|
||||
cronixieInit = false;
|
||||
}
|
||||
}
|
||||
|
||||
void _nixieDisplay(int num[], uint16_t dur[], uint16_t pausedur[], byte cnt)
|
||||
{
|
||||
strip.setRange(overlayMin, overlayMax, 0);
|
||||
if (num[nixieClockI] >= 0 && !nixiePause)
|
||||
{
|
||||
strip.setIndividual(num[nixieClockI],((uint32_t)white << 24)| ((uint32_t)col_t[0] << 16) | ((uint32_t)col_t[1] << 8) | col_t[2]);
|
||||
strip.setIndividual(num[nixieClockI],((uint32_t)white << 24)| ((uint32_t)colT[0] << 16) | ((uint32_t)colT[1] << 8) | colT[2]);
|
||||
strip.unlock(num[nixieClockI]);
|
||||
}
|
||||
if (!nixiePause)
|
||||
@@ -84,8 +98,6 @@ void _nixieNumber(int number, int dur)
|
||||
if (overlayArr[i] != -1)
|
||||
{
|
||||
overlayArr[i] = overlayArr[i] + overlayMin;
|
||||
if (overlayReverse)
|
||||
overlayArr[i] = overlayMax - overlayArr[i];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i <6; i++)
|
||||
@@ -106,38 +118,40 @@ void _nixieNumber(int number, int dur)
|
||||
|
||||
void handleOverlays()
|
||||
{
|
||||
//properties: range, (color)
|
||||
//0 no overlay
|
||||
//1 solid color (NI)
|
||||
//2 analog clock
|
||||
//3 digital nixie-style clock one digit
|
||||
//4 just static hour (NI)
|
||||
//5 analog countdown
|
||||
//6 digital one digit countdown
|
||||
if (millis() - overlayRefreshedTime > overlayRefreshMs)
|
||||
{
|
||||
overlayRefreshedTime = millis();
|
||||
initCronixie();
|
||||
updateLocalTime();
|
||||
switch (overlayCurrent)
|
||||
{
|
||||
case 0: break;//no overlay
|
||||
case 1: _overlaySolid(); break;//solid secondary color
|
||||
case 2: _overlayAnalogClock(); break;//2 analog clock
|
||||
case 3: _overlayNixieClock(); break;//nixie 1-digit
|
||||
case 5: _overlayAnalogCountdown(); break;//a.countdown
|
||||
case 6: _overlayNixieCountdown(); break;//d.
|
||||
case 4: _overlayCronixie();//Diamex cronixie clock kit
|
||||
}
|
||||
if (!countdownMode || overlayCurrent < 2) checkCountdown(); //countdown macro activation must work
|
||||
overlayRefreshedTime = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void _overlaySolid()
|
||||
{
|
||||
strip.unlockAll();
|
||||
uint32_t cls = (useGammaCorrectionRGB)? gamma8[whiteSec*16777216] + gamma8[colSec[0]]*65536 + gamma8[colSec[1]]*256 + gamma8[colSec[2]]:whiteSec*16777216 + colSec[0]*65536 + colSec[1]*256 + colSec[2];
|
||||
strip.setRange(overlayMin,overlayMax,cls);
|
||||
overlayRefreshMs = 1902;
|
||||
}
|
||||
|
||||
void _overlayAnalogClock()
|
||||
{
|
||||
int overlaySize = overlayMax - overlayMin +1;
|
||||
strip.unlockAll();
|
||||
if (overlayDimBg)
|
||||
if (countdownMode)
|
||||
{
|
||||
uint32_t ct = (white>>1)*16777216 + (col[0]>>1)*65536 + (col[1]>>1)*256 + (col[2]>>1);
|
||||
if (useGammaCorrectionRGB) ct = (gamma8[white]>>1)*16777216 + (gamma8[col[0]]>>1)*65536 + (gamma8[col[1]]>>1)*256 + (gamma8[col[2]]>>1);
|
||||
strip.setRange(overlayMin, overlayMax, ct);
|
||||
_overlayAnalogCountdown(); return;
|
||||
}
|
||||
local = TZ.toLocal(now(), &tcr);
|
||||
_overlaySolid();
|
||||
double hourP = ((double)(hour(local)%12))/12;
|
||||
double minuteP = ((double)minute(local))/60;
|
||||
hourP = hourP + minuteP/12;
|
||||
@@ -148,6 +162,17 @@ void _overlayAnalogClock()
|
||||
if (minutePixel > overlayMax) minutePixel = overlayMin -1 + minutePixel - overlayMax;
|
||||
int secondPixel = floor(analogClock12pixel + overlaySize*secondP);
|
||||
if (secondPixel > overlayMax) secondPixel = overlayMin -1 + secondPixel - overlayMax;
|
||||
if (analogClockSecondsTrail)
|
||||
{
|
||||
if (secondPixel < analogClock12pixel)
|
||||
{
|
||||
strip.setRange(analogClock12pixel, overlayMax, 0xFF0000);
|
||||
strip.setRange(overlayMin, secondPixel, 0xFF0000);
|
||||
} else
|
||||
{
|
||||
strip.setRange(analogClock12pixel, secondPixel, 0xFF0000);
|
||||
}
|
||||
}
|
||||
if (analogClock5MinuteMarks)
|
||||
{
|
||||
int pix;
|
||||
@@ -155,16 +180,10 @@ void _overlayAnalogClock()
|
||||
{
|
||||
pix = overlayMin + analogClock12pixel + (overlaySize/12)*i;
|
||||
if (pix > overlayMax) pix = pix - overlayMax;
|
||||
strip.setIndividual(pix, 0xAAAAAA);
|
||||
strip.setIndividual(pix,0x00FFAA);
|
||||
}
|
||||
}
|
||||
if (analogClockSecondsTrail)
|
||||
{
|
||||
strip.setRange(analogClock12pixel, secondPixel, 0xFF0000);
|
||||
} else
|
||||
{
|
||||
strip.setIndividual(secondPixel, 0xFF0000);
|
||||
}
|
||||
if (!analogClockSecondsTrail) strip.setIndividual(secondPixel, 0xFF0000);
|
||||
strip.setIndividual(minutePixel, 0x00FF00);
|
||||
strip.setIndividual(hourPixel, 0x0000FF);
|
||||
overlayRefreshMs = 998;
|
||||
@@ -172,14 +191,14 @@ void _overlayAnalogClock()
|
||||
|
||||
void _overlayNixieClock()
|
||||
{
|
||||
if (countdownMode)
|
||||
{
|
||||
_overlayNixieCountdown(); return;
|
||||
}
|
||||
if (nixieClockI < 0)
|
||||
{
|
||||
local = TZ.toLocal(now(), &tcr);
|
||||
overlayArr[0] = hour(local);
|
||||
if (nixieClock12HourFormat && overlayArr[0] > 12)
|
||||
{
|
||||
overlayArr[0] = overlayArr[0]%12;
|
||||
}
|
||||
if (useAMPM) overlayArr[0] = overlayArr[0]%12;
|
||||
overlayArr[1] = -1;
|
||||
if (overlayArr[0] > 9)
|
||||
{
|
||||
@@ -191,7 +210,7 @@ void _overlayNixieClock()
|
||||
overlayArr[2] = overlayArr[2]/10;
|
||||
overlayArr[4] = -1;
|
||||
overlayArr[5] = -1;
|
||||
if (nixieClockDisplaySeconds)
|
||||
if (analogClockSecondsTrail)
|
||||
{
|
||||
overlayArr[4] = second(local);
|
||||
overlayArr[5] = overlayArr[4]%10;
|
||||
@@ -202,8 +221,6 @@ void _overlayNixieClock()
|
||||
if (overlayArr[i] != -1)
|
||||
{
|
||||
overlayArr[i] = overlayArr[i] + overlayMin;
|
||||
if (overlayReverse)
|
||||
overlayArr[i] = overlayMax - overlayArr[i];
|
||||
}
|
||||
}
|
||||
overlayDur[0] = 12 + 12*(255 - overlaySpeed);
|
||||
@@ -292,14 +309,14 @@ void _overlayAnalogCountdown()
|
||||
int overlaySize = overlayMax - overlayMin +1;
|
||||
double perc = (pval-(double)diff)/pval;
|
||||
if (perc > 1.0) perc = 1.0;
|
||||
uint8_t pixelCnt = perc*overlaySize;
|
||||
byte pixelCnt = perc*overlaySize;
|
||||
if (analogClock12pixel + pixelCnt > overlayMax)
|
||||
{
|
||||
strip.setRange(analogClock12pixel, overlayMax, ((uint32_t)white_sec << 24)| ((uint32_t)col_sec[0] << 16) | ((uint32_t)col_sec[1] << 8) | col_sec[2]);
|
||||
strip.setRange(overlayMin, overlayMin +pixelCnt -(1+ overlayMax -analogClock12pixel), ((uint32_t)white_sec << 24)| ((uint32_t)col_sec[0] << 16) | ((uint32_t)col_sec[1] << 8) | col_sec[2]);
|
||||
strip.setRange(analogClock12pixel, overlayMax, ((uint32_t)whiteSec << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
|
||||
strip.setRange(overlayMin, overlayMin +pixelCnt -(1+ overlayMax -analogClock12pixel), ((uint32_t)whiteSec << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
|
||||
} else
|
||||
{
|
||||
strip.setRange(analogClock12pixel, analogClock12pixel + pixelCnt, ((uint32_t)white_sec << 24)| ((uint32_t)col_sec[0] << 16) | ((uint32_t)col_sec[1] << 8) | col_sec[2]);
|
||||
strip.setRange(analogClock12pixel, analogClock12pixel + pixelCnt, ((uint32_t)whiteSec << 24)| ((uint32_t)colSec[0] << 16) | ((uint32_t)colSec[1] << 8) | colSec[2]);
|
||||
}
|
||||
}
|
||||
overlayRefreshMs = 998;
|
||||
@@ -331,5 +348,5 @@ void _overlayNixieCountdown()
|
||||
}
|
||||
_nixieNumber(diff, 800);
|
||||
}
|
||||
overlayRefreshMs = 998;
|
||||
}
|
||||
#endif
|
||||
|
@@ -46,12 +46,12 @@ void handleAlexa()
|
||||
|
||||
void alexaOn()
|
||||
{
|
||||
if (alexaOnMacro == 255)
|
||||
if (macroAlexaOn == 0)
|
||||
{
|
||||
handleSet((alexaNotify)?"win&T=1&IN":"win&T=1&NN&IN");
|
||||
} else
|
||||
{
|
||||
applyMacro(alexaOnMacro);
|
||||
applyMacro(macroAlexaOn);
|
||||
}
|
||||
|
||||
String body = "[{\"success\":{\"/lights/1/state/on\":true}}]";
|
||||
@@ -64,12 +64,12 @@ void alexaOn()
|
||||
|
||||
void alexaOff()
|
||||
{
|
||||
if (alexaOffMacro == 255)
|
||||
if (macroAlexaOff == 0)
|
||||
{
|
||||
handleSet((alexaNotify)?"win&T=0&IN":"win&T=0&NN&IN");
|
||||
} else
|
||||
{
|
||||
applyMacro(alexaOffMacro);
|
||||
applyMacro(macroAlexaOff);
|
||||
}
|
||||
|
||||
String body = "[{\"success\":{\"/lights/1/state/on\":false}}]";
|
||||
@@ -80,7 +80,7 @@ void alexaOff()
|
||||
DEBUG_PRINTLN(body);
|
||||
}
|
||||
|
||||
void alexaDim(uint8_t briL)
|
||||
void alexaDim(byte briL)
|
||||
{
|
||||
String body = "[{\"success\":{\"/lights/1/state/bri\":"+ String(briL) +"}}]";
|
||||
|
||||
@@ -127,7 +127,7 @@ void respondToSearch() {
|
||||
|
||||
UDP.beginPacket(UDP.remoteIP(), UDP.remotePort());
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
UDP.write((uint8_t*)response.c_str(), response.length());
|
||||
UDP.write((byte*)response.c_str(), response.length());
|
||||
#else
|
||||
UDP.write(response.c_str());
|
||||
#endif
|
||||
@@ -223,7 +223,7 @@ String briForHue(int realBri)
|
||||
return String(realBri);
|
||||
}
|
||||
|
||||
boolean handleAlexaApiCall(String req, String body) //basic implementation of Philips hue api functions needed for basic Alexa control
|
||||
bool handleAlexaApiCall(String req, String body) //basic implementation of Philips hue api functions needed for basic Alexa control
|
||||
{
|
||||
DEBUG_PRINTLN("AlexaApiCall");
|
||||
if (req.indexOf("api") <0) return false;
|
||||
@@ -262,8 +262,8 @@ boolean handleAlexaApiCall(String req, String body) //basic implementation of Ph
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean connectUDP(){
|
||||
boolean state = false;
|
||||
bool connectUDP(){
|
||||
bool state = false;
|
||||
|
||||
DEBUG_PRINTLN("");
|
||||
DEBUG_PRINTLN("Con UDP");
|
||||
|
@@ -1,10 +1,9 @@
|
||||
/*
|
||||
* Support for the Cronixie clock
|
||||
*/
|
||||
#ifdef CRONIXIE
|
||||
uint8_t getSameCodeLength(char code, int index, char const digits[])
|
||||
byte getSameCodeLength(char code, int index, char const digits[])
|
||||
{
|
||||
uint8_t counter = 0;
|
||||
byte counter = 0;
|
||||
|
||||
for (int i = index+1; i < 6; i++)
|
||||
{
|
||||
@@ -18,8 +17,9 @@ uint8_t getSameCodeLength(char code, int index, char const digits[])
|
||||
return counter;
|
||||
}
|
||||
|
||||
void setCronixie(char const digits[])
|
||||
void setCronixie()
|
||||
{
|
||||
char digits[6]; for (int a=0;a<6;a++) digits[a]=cronixieDisplay.charAt(a);
|
||||
/*
|
||||
* digit purpose index
|
||||
* 0-9 | 0-9 (incl. random)
|
||||
@@ -86,7 +86,7 @@ void setCronixie(char const digits[])
|
||||
DEBUG_PRINT("cset ");
|
||||
DEBUG_PRINTLN(digits);
|
||||
|
||||
cronixieRefreshMs = 1997; //Only refresh every 2secs if no seconds are displayed
|
||||
overlayRefreshMs = 1997; //Only refresh every 2secs if no seconds are displayed
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
@@ -107,8 +107,8 @@ void setCronixie(char const digits[])
|
||||
case 'a': dP[i] = 58; i++; break;
|
||||
case 'm': dP[i] = 74 + getSameCodeLength('m',i,digits); i = i+dP[i]-74; break;
|
||||
case 'M': dP[i] = 24 + getSameCodeLength('M',i,digits); i = i+dP[i]-24; break;
|
||||
case 's': dP[i] = 80 + getSameCodeLength('s',i,digits); i = i+dP[i]-80; cronixieRefreshMs = 497; break; //refresh more often bc. of secs
|
||||
case 'S': dP[i] = 30 + getSameCodeLength('S',i,digits); i = i+dP[i]-30; cronixieRefreshMs = 497; break;
|
||||
case 's': dP[i] = 80 + getSameCodeLength('s',i,digits); i = i+dP[i]-80; overlayRefreshMs = 497; break; //refresh more often bc. of secs
|
||||
case 'S': dP[i] = 30 + getSameCodeLength('S',i,digits); i = i+dP[i]-30; overlayRefreshMs = 497; break;
|
||||
case 'Y': dP[i] = 36 + getSameCodeLength('Y',i,digits); i = i+dP[i]-36; break;
|
||||
case 'y': dP[i] = 86 + getSameCodeLength('y',i,digits); i = i+dP[i]-86; break;
|
||||
case 'I': dP[i] = 39 + getSameCodeLength('I',i,digits); i = i+dP[i]-39; break; //Month. Don't ask me why month and minute both start with M.
|
||||
@@ -139,27 +139,23 @@ void setCronixie(char const digits[])
|
||||
}
|
||||
DEBUG_PRINTLN((int)dP[5]);
|
||||
|
||||
cronixieRefreshedTime = 0; //refresh immediately
|
||||
_overlayCronixie(); //refresh
|
||||
}
|
||||
|
||||
void handleCronixie()
|
||||
void _overlayCronixie()
|
||||
{
|
||||
if (millis() - cronixieRefreshedTime > cronixieRefreshMs)
|
||||
{
|
||||
cronixieRefreshedTime = millis();
|
||||
local = TZ.toLocal(now(), &tcr);
|
||||
if (cronixieCountdown) checkCountdown();
|
||||
uint8_t h = hour(local);
|
||||
uint8_t h0 = h;
|
||||
uint8_t m = minute(local);
|
||||
uint8_t s = second(local);
|
||||
uint8_t d = day(local);
|
||||
uint8_t mi = month(local);
|
||||
if (countdownMode) checkCountdown();
|
||||
byte h = hour(local);
|
||||
byte h0 = h;
|
||||
byte m = minute(local);
|
||||
byte s = second(local);
|
||||
byte d = day(local);
|
||||
byte mi = month(local);
|
||||
int y = year(local);
|
||||
//this has to be changed in time for 22nd century
|
||||
y -= 2000; if (y<0) y += 30; //makes countdown work
|
||||
|
||||
if (cronixieUseAMPM && !cronixieCountdown)
|
||||
if (useAMPM && !countdownMode)
|
||||
{
|
||||
if (h>12) h-=12;
|
||||
else if (h==0) h+=12;
|
||||
@@ -213,6 +209,4 @@ void handleCronixie()
|
||||
}
|
||||
strip.setCronixieDigits(_digitOut);
|
||||
//strip.trigger(); //this has a drawback, no effects slower than RefreshMs. advantage: Quick update, not dependant on effect time
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@@ -1,27 +1,139 @@
|
||||
/*
|
||||
* Color conversion methods
|
||||
*/
|
||||
void colorCTtoRGB(uint16_t mired, uint8_t* rgb) //white spectrum to rgb
|
||||
void colorCTtoRGB(uint16_t mired, byte* rgb) //white spectrum to rgb
|
||||
{
|
||||
|
||||
//this is only an approximation using WS2812B with gamma correction enabled
|
||||
if (mired > 475)
|
||||
{
|
||||
rgb[0]=255;rgb[1]=199;rgb[2]=92;//500
|
||||
} else if (mired > 425)
|
||||
{
|
||||
rgb[0]=255;rgb[1]=213;rgb[2]=118;//450
|
||||
} else if (mired > 375)
|
||||
{
|
||||
rgb[0]=255;rgb[1]=216;rgb[2]=118;//400
|
||||
} else if (mired > 325)
|
||||
{
|
||||
rgb[0]=255;rgb[1]=234;rgb[2]=140;//350
|
||||
} else if (mired > 275)
|
||||
{
|
||||
rgb[0]=255;rgb[1]=243;rgb[2]=160;//300
|
||||
} else if (mired > 225)
|
||||
{
|
||||
rgb[0]=250;rgb[1]=255;rgb[2]=188;//250
|
||||
} else if (mired > 175)
|
||||
{
|
||||
rgb[0]=247;rgb[1]=255;rgb[2]=215;//200
|
||||
} else
|
||||
{
|
||||
rgb[0]=237;rgb[1]=255;rgb[2]=239;//150
|
||||
}
|
||||
}
|
||||
|
||||
void colorHSBtoRGB(uint16_t hue, uint8_t sat, uint8_t bri, uint8_t* rgb) //hue, sat, bri to rgb
|
||||
void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb
|
||||
{
|
||||
|
||||
float h = ((float)hue)/65535.0;
|
||||
float s = ((float)sat)/255.0;
|
||||
byte i = floor(h*6);
|
||||
float f = h * 6-i;
|
||||
float p = 255 * (1-s);
|
||||
float q = 255 * (1-f*s);
|
||||
float t = 255 * (1-(1-f)*s);
|
||||
switch (i%6) {
|
||||
case 0: rgb[0]=255,rgb[1]=t,rgb[2]=p;break;
|
||||
case 1: rgb[0]=q,rgb[1]=255,rgb[2]=p;break;
|
||||
case 2: rgb[0]=p,rgb[1]=255,rgb[2]=t;break;
|
||||
case 3: rgb[0]=p,rgb[1]=q,rgb[2]=255;break;
|
||||
case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break;
|
||||
case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q;
|
||||
}
|
||||
}
|
||||
|
||||
void colorXYtoRGB(float x, float y, uint8_t* rgb) //coordinates to rgb (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
|
||||
void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
|
||||
{
|
||||
float z = 1.0f - x - y;
|
||||
//float Y = 1.0f; // Brightness, we handle this separately
|
||||
float X = (1.0f / y) * x;
|
||||
float Z = (1.0f / y) * z;
|
||||
rgb[0] = (int)(X * 1.656492f - 0.354851f - Z * 0.255038f);
|
||||
rgb[1] = (int)(-X * 0.707196f + 1.655397f + Z * 0.036152f);
|
||||
rgb[2] = (int)(X * 0.051713f - 0.121364f + Z * 1.011530f);
|
||||
float r = (int)255*(X * 1.656492f - 0.354851f - Z * 0.255038f);
|
||||
float g = (int)255*(-X * 0.707196f + 1.655397f + Z * 0.036152f);
|
||||
float b = (int)255*(X * 0.051713f - 0.121364f + Z * 1.011530f);
|
||||
if (r > b && r > g && r > 1.0f) {
|
||||
// red is too big
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0f;
|
||||
} else if (g > b && g > r && g > 1.0f) {
|
||||
// green is too big
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0f;
|
||||
} else if (b > r && b > g && b > 1.0f) {
|
||||
// blue is too big
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0f;
|
||||
}
|
||||
// Apply gamma correction
|
||||
r = r <= 0.0031308f ? 12.92f * r : (1.0f + 0.055f) * pow(r, (1.0f / 2.4f)) - 0.055f;
|
||||
g = g <= 0.0031308f ? 12.92f * g : (1.0f + 0.055f) * pow(g, (1.0f / 2.4f)) - 0.055f;
|
||||
b = b <= 0.0031308f ? 12.92f * b : (1.0f + 0.055f) * pow(b, (1.0f / 2.4f)) - 0.055f;
|
||||
|
||||
if (r > b && r > g) {
|
||||
// red is biggest
|
||||
if (r > 1.0f) {
|
||||
g = g / r;
|
||||
b = b / r;
|
||||
r = 1.0f;
|
||||
}
|
||||
} else if (g > b && g > r) {
|
||||
// green is biggest
|
||||
if (g > 1.0f) {
|
||||
r = r / g;
|
||||
b = b / g;
|
||||
g = 1.0f;
|
||||
}
|
||||
} else if (b > r && b > g) {
|
||||
// blue is biggest
|
||||
if (b > 1.0f) {
|
||||
r = r / b;
|
||||
g = g / b;
|
||||
b = 1.0f;
|
||||
}
|
||||
}
|
||||
rgb[0] = 255.0*r;
|
||||
rgb[1] = 255.0*g;
|
||||
rgb[2] = 255.0*b;
|
||||
}
|
||||
|
||||
void colorRGBtoXY(uint8_t* rgb, float* xy){} //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
|
||||
void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
|
||||
{
|
||||
float X = rgb[0] * 0.664511f + rgb[1] * 0.154324f + rgb[2] * 0.162028f;
|
||||
float Y = rgb[0] * 0.283881f + rgb[1] * 0.668433f + rgb[2] * 0.047685f;
|
||||
float Z = rgb[0] * 0.000088f + rgb[1] * 0.072310f + rgb[2] * 0.986039f;
|
||||
xy[0] = X / (X + Y + Z);
|
||||
xy[1] = Y / (X + Y + Z);
|
||||
}
|
||||
|
||||
/*//For some reason min and max are not declared here
|
||||
|
||||
float minf (float v, float w)
|
||||
{
|
||||
if (w > v) return v;
|
||||
return w;
|
||||
}
|
||||
|
||||
float maxf (float v, float w)
|
||||
{
|
||||
if (w > v) return w;
|
||||
return v;
|
||||
}
|
||||
|
||||
void colorRGBtoRGBW(byte* rgb, byte* wht) //rgb to rgbw, untested and currently unused
|
||||
{
|
||||
*wht = (float)minf(rgb[0],minf(rgb[1],rgb[2]))*0.95;
|
||||
rgb[0]-=wht;
|
||||
rgb[1]-=wht;
|
||||
rgb[2]-=wht;
|
||||
}*/
|
||||
|
||||
void colorRGBtoRGBW(uint8_t* rgb, uint8_t* rgbw){} //rgb to rgbw, not imlemented yet
|
||||
|
@@ -1,4 +1,207 @@
|
||||
/*
|
||||
* Sync to Philips hue lights
|
||||
*/
|
||||
void foo(){}
|
||||
|
||||
void handleHue()
|
||||
{
|
||||
if (huePollingEnabled && WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
if (millis() - hueLastRequestSent > huePollIntervalMsTemp)
|
||||
{
|
||||
sendHuePoll(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool setupHue()
|
||||
{
|
||||
if (WiFi.status() == WL_CONNECTED) //setup needed
|
||||
{
|
||||
if (hueApiKey.length()>20) //api key is probably ok
|
||||
{
|
||||
if (sendHuePoll(false))
|
||||
{
|
||||
huePollingEnabled = true;
|
||||
return true;
|
||||
}
|
||||
if (hueError.charAt(0) == 'R' || hueError.charAt(0) == 'I') return false; //can't connect
|
||||
delay(20);
|
||||
}
|
||||
sendHuePoll(true); //new API key
|
||||
if (hueError.charAt(0) != 'C') return false; //still some error
|
||||
delay(20);
|
||||
if (sendHuePoll(false))
|
||||
{
|
||||
huePollingEnabled = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sendHuePoll(bool sAuth)
|
||||
{
|
||||
bool st;
|
||||
hueClient.setReuse(true);
|
||||
hueClient.setTimeout(450);
|
||||
String hueURL = "http://";
|
||||
hueURL += hueIP.toString();
|
||||
hueURL += "/api/";
|
||||
if (!sAuth) {
|
||||
hueURL += hueApiKey;
|
||||
hueURL += "/lights/" + String(huePollLightId);
|
||||
}
|
||||
hueClient.begin(hueURL);
|
||||
int httpCode = (sAuth)? hueClient.POST("{\"devicetype\":\"wled#esp\"}"):hueClient.GET();
|
||||
//TODO this request may block operation for ages
|
||||
|
||||
if (httpCode>0){
|
||||
st = handleHueResponse(hueClient.getString(),sAuth);
|
||||
} else {
|
||||
hueError = "Request timed out";
|
||||
st = false;
|
||||
}
|
||||
if (!st){ //error
|
||||
if (huePollIntervalMsTemp<300000) huePollIntervalMsTemp*=2; // only poll every ~5min when unable to connect
|
||||
hueFailCount++;
|
||||
if (hueFailCount > 150) huePollingEnabled = false; //disable after many hours offline
|
||||
}
|
||||
hueLastRequestSent = millis();
|
||||
return st;
|
||||
}
|
||||
|
||||
bool handleHueResponse(String hueResp, bool isAuth)
|
||||
{
|
||||
DEBUG_PRINTLN(hueApiKey);
|
||||
DEBUG_PRINTLN(hueResp);
|
||||
if (hueResp.indexOf("error")>0)//hue bridge returned error
|
||||
{
|
||||
int hueErrorCode = getJsonValue(&hueResp,"type").toInt();
|
||||
switch (hueErrorCode)
|
||||
{
|
||||
case 1: hueError = "Unauthorized"; break;
|
||||
case 3: hueError = "Invalid light ID"; break;
|
||||
case 101: hueError = "Link button not pressed"; break;
|
||||
default: hueError = "Bridge Error " + String(hueErrorCode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isAuth)
|
||||
{
|
||||
String tempApi = getJsonValue(&hueResp,"username");
|
||||
if (tempApi.length()>0)
|
||||
{
|
||||
hueApiKey = tempApi;
|
||||
return true;
|
||||
}
|
||||
hueError = "Invalid response";
|
||||
return false;
|
||||
}
|
||||
|
||||
float hueX=0, hueY=0;
|
||||
uint16_t hueHue=0, hueCt=0;
|
||||
byte hueBri=0, hueSat=0, hueColormode=0;
|
||||
|
||||
if (getJsonValue(&hueResp,"on").charAt(0) == 't')
|
||||
{
|
||||
String tempV = getJsonValue(&hueResp,"bri");
|
||||
if (tempV.length()>0) //Dimmable device
|
||||
{
|
||||
hueBri = (tempV.toInt())+1;
|
||||
tempV = getJsonValue(&hueResp,"colormode");
|
||||
if (hueApplyColor && tempV.length()>0) //Color device
|
||||
{
|
||||
if (tempV.charAt(0) == 'x') //xy mode
|
||||
{
|
||||
tempV = getJsonValue(&hueResp,"xy");
|
||||
if (tempV.length()>0) //valid
|
||||
{
|
||||
hueColormode = 1;
|
||||
hueX = tempV.toFloat();
|
||||
tempV = tempV.substring(tempV.indexOf(',')+1);
|
||||
hueY = tempV.toFloat();
|
||||
}
|
||||
} else if (tempV.charAt(0) == 'h') //hs mode
|
||||
{
|
||||
tempV = getJsonValue(&hueResp,"hue");
|
||||
if (tempV.length()>0) //valid
|
||||
{
|
||||
hueColormode = 2;
|
||||
hueHue = tempV.toInt();
|
||||
tempV = getJsonValue(&hueResp,"sat");
|
||||
if (tempV.length()>0) //valid
|
||||
{
|
||||
hueSat = tempV.toInt();
|
||||
}
|
||||
}
|
||||
} else //ct mode
|
||||
{
|
||||
tempV = getJsonValue(&hueResp,"\"ct"); //dirty hack to not get effect value instead
|
||||
if (tempV.length()>0) //valid
|
||||
{
|
||||
hueColormode = 3;
|
||||
hueCt = tempV.toInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else //On/Off device
|
||||
{
|
||||
hueBri = briLast;
|
||||
}
|
||||
} else
|
||||
{
|
||||
hueBri = 0;
|
||||
}
|
||||
hueFailCount = 0;
|
||||
huePollIntervalMsTemp = huePollIntervalMs;
|
||||
hueError = "Connected";
|
||||
//applying vals
|
||||
if (hueBri != hueBriLast)
|
||||
{
|
||||
bri = hueBri;
|
||||
if (hueApplyOnOff)
|
||||
{
|
||||
if (hueBri==0) {bri = 0;}
|
||||
else if (bri==0 && hueBri>0) bri = briLast;
|
||||
}
|
||||
if (hueApplyBri)
|
||||
{
|
||||
if (hueBri>0) bri = hueBri;
|
||||
}
|
||||
hueBriLast = hueBri;
|
||||
}
|
||||
if (hueApplyColor)
|
||||
{
|
||||
switch(hueColormode)
|
||||
{
|
||||
case 1: if (hueX != hueXLast || hueY != hueYLast) colorXYtoRGB(hueX,hueY,col); hueXLast = hueX; hueYLast = hueY; break;
|
||||
case 2: if (hueHue != hueHueLast || hueSat != hueSatLast) colorHStoRGB(hueHue,hueSat,col); hueHueLast = hueHue; hueSatLast = hueSat; break;
|
||||
case 3: if (hueCt != hueCtLast) colorCTtoRGB(hueCt,col); hueCtLast = hueCt; break;
|
||||
}
|
||||
}
|
||||
colorUpdated(7);
|
||||
return true;
|
||||
}
|
||||
|
||||
String getJsonValue(String* req, String key)
|
||||
{
|
||||
//TODO may replace with ArduinoJSON if too complex
|
||||
//this is horribly inefficient and designed to work only in this case
|
||||
uint16_t pos = req->indexOf(key);
|
||||
String b = req->substring(pos + key.length()+2);
|
||||
if (b.charAt(0)=='\"') //is string
|
||||
{
|
||||
return b.substring(1,b.substring(1).indexOf('\"')+1);
|
||||
} else if (b.charAt(0)=='[') //is array
|
||||
{
|
||||
return b.substring(1,b.indexOf(']'));
|
||||
} else //is primitive type
|
||||
{
|
||||
return b.substring(0,b.indexOf(',')); //this works only if value not last
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user