Added MQTT

Updated readme for 0.8.0
Fixed custom theme bug
Bumped version codes to 0.8.0
This commit is contained in:
cschwinne 2018-10-04 16:50:12 +02:00
parent 473991638c
commit eeb17b417c
15 changed files with 153 additions and 58 deletions

View File

@ -1,17 +1,20 @@
![WLED logo](https://raw.githubusercontent.com/Aircoookie/WLED/master/wled_logo.png)
## Welcome to my project WLED!
WLED is a fast and (relatively) secure implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B) LEDs!
WLED is a fast, advanced and (relatively) secure implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B) LEDs!
### Features: (V0.7.1)
### Features: (v0.8.0)
- RGB, HSB, and brightness sliders
- All new, mobile-friendly web UI!
- Settings page - configuration over network
- Access Point and station mode - automatic failsafe AP
- Support of Blynk IoT cloud
- WS2812FX library integrated for over 50 special effects (+Custom Theater Chase)!
- Support of Blynk IoT cloud and MQTT
- WS2812FX library integrated for over 70 special effects (with FastLED palettes)!
- Secondary color support lets you use even more effect combinations
- Alexa smart home device server (including dimming)
- Beta syncronization to Philips hue lights
- Realtime UDP Packet Control (E1.31, Hyperion, WARLS, DRGB, DRGBW)
- Support for RGBW strips
- 25 user presets! Save colors and effects and apply them easily! Supports cycling through them.
- HTTP request API for simple integration
@ -24,7 +27,6 @@ WLED is a fast and (relatively) secure implementation of an ESP8266/ESP32 webser
- Password protected OTA page for added security (OTA lock)
- NTP and configurable analog clock function
- Support for the Cronixie Clock kit by Diamex
- Realtime UDP Packet Control (E1.31, Hyperion, WARLS, DRGB, DRGBW)
### Quick start guide and documentation:
@ -32,16 +34,14 @@ See the [wiki](https://github.com/Aircoookie/WLED/wiki)!
### Other
Licensed under the MIT license
Uses libraries:
ESP8266/ESP32 Arduino Core
NeoPixelBus by Makuna
[WS2812FX](https://github.com/kitesurfer1404/WS2812FX) by kitesurfer1404 (Aircoookie fork)
Time library
Timezone library by JChristensen
Alexa code based on arduino-esp8266-alexa-multiple-wemo-switch by kakopappa
Licensed under the MIT license
Credits in About page!
Uses Linearicons by Perxis! (link in settings page)
Uses Linearicons by Perxis!
Join the Discord [server](https://discord.gg/KuqP7NE) to discuss everything about WLED!
You can also send me mails to [dev.aircoookie@gmail.com](mailto:dev.aircoookie@gmail.com).
If you insist that you just love WLED too much, you can [send me a gift](https://paypal.me/aircoookie)

View File

@ -2,7 +2,7 @@
<html>
<head><meta charset="utf-8"><meta name="theme-color" content="#fff">
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico'/>
<title>WLED 0.8.0-a</title>
<title>WLED 0.8.0</title>
<script>
var d=document;
var w=window.getComputedStyle(d.querySelector("html"));

View File

@ -7,7 +7,7 @@
<meta name="theme-color" content="#333333">
<meta content="yes" name="apple-mobile-web-app-capable">
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAGACGAAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAE1JREFUOI1j/P//PwOxgNGeAUMxE9G6cQCKDWAhpADZ2f8PMjBS3QW08QK20KaZC2gfC9hCnqouoNgARgY7zMxAyNlUdQHlXiAlO2MDAD63EVqNHAe0AAAAAElFTkSuQmCC"/>
<title>WLED 0.8.0-a</title>
<title>WLED 0.8.0</title>
<style>
*{transition-duration: 0.5s;}
body {

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -250,6 +250,11 @@ Alexa invocation name: <input name="AI" maxlength="32">
<h3>Blynk</h3>
Device Auth token: <input name="BK" maxlength="33"><br>
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
<h3>MQTT</h3>
Broker: <input name="MS" maxlength="32"><br>
Device Topic: <input name="MD" maxlength="32"><br>
Group Topic: <input name="MG" maxlength="32"><br>
<i>Reboot required to apply changes. </i><a href="https://github.com/Aircoookie/WLED/wiki/MQTT" target="_blank">MQTT info</a>
<h3>Philips Hue</h3>
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
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>
@ -406,7 +411,7 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
<button type="button" onclick="U()">Manual OTA Update</button><br>
Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
<h3>About</h3>
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.8.0-a<br><br>
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.8.0<br><br>
<b>Contributors:</b><br>
StormPie <i>(Mobile HTML UI)</i><br><br>
Thank you so much!<br><br>
@ -421,6 +426,7 @@ Thank you so much!<br><br>
<i><a href="https://github.com/JChristensen/Timezone" target="_blank">Timezone</a> library by JChristensen</i><br>
<i><a href="https://github.com/blynkkk/blynk-library" target="_blank">Blynk</a> library (compacted)</i><br>
<i><a href="https://github.com/forkineye/E131" target="_blank">E1.31</a> library by forkineye (modified)</i><br>
<i><a href="https://github.com/knolleary/pubsubclient" target="_blank">PubSubClient</a> by knolleary (modified)</i><br>
<i><a href="https://github.com/Aircoookie/Espalexa" target="_blank">Espalexa</a> by Aircoookie (modified)</i><br><br>
<i>UI icons by <a href="https://linearicons.com" target="_blank">Linearicons</a> created by <a href="https://perxis.com" target="_blank">Perxis</a>! (CC-BY-SA 4.0)</i> <br><br>
Server message: <span class="msg"> Response error! </span><hr>

View File

@ -3,7 +3,7 @@
*/
/*
* @title WLED project sketch
* @version 0.8.0-a
* @version 0.8.0
* @author Christian Schwinne
*/
@ -45,8 +45,8 @@
//version code in format yymmddb (b = daily build)
#define VERSION 1810011
char versionString[] = "0.8.0-a";
#define VERSION 1810031
char versionString[] = "0.8.0";
//AP and OTA default passwords (for maximum change them!)
@ -59,7 +59,7 @@ char otaPass[33] = "wledota";
//to toggle usb serial debug (un)comment following line(s)
#define DEBUG
//#define DEBUG
//Hardware CONFIG (only changeble HERE, not at runtime)
@ -111,7 +111,7 @@ byte nightlightDelayMins = 60;
bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over
bool fadeTransition = true; //enable crossfading color transition
bool enableSecTransition = true; //also enable transition for secondary color
uint16_t transitionDelay = 1200; //default crossfade duration in ms
uint16_t transitionDelay = 900; //default crossfade duration in ms
bool reverseMode = false; //flip entire LED strip (reverses all effect directions)
bool initLedsLast = false; //turn on LEDs only after WiFi connected/AP open
@ -161,9 +161,9 @@ bool e131Enabled = true; //settings for E1.31 (sACN) protoc
uint16_t e131Universe = 1;
bool e131Multicast = false;
char mqttTopic0[33] = ""; //main MQTT topic (individual per device, default is wled/mac)
char mqttTopic1[33] = "wled/all"; //second MQTT topic (for example to group devices)
char mqttServer[33] = "37.187.106.16"; //both domains and IPs should work (no SSL) 37.187.106.16
char mqttDeviceTopic[33] = ""; //main MQTT topic (individual per device, default is wled/mac)
char mqttGroupTopic[33] = "wled/all"; //second MQTT topic (for example to group devices)
char mqttServer[33] = ""; //both domains and IPs should work (no SSL)
bool huePollingEnabled = false; //poll hue bridge for light state
uint16_t huePollIntervalMs = 2500; //low values (< 1sec) may cause lag but offer quicker response
@ -272,7 +272,7 @@ bool onlyAP = false; //only Access Point active, no con
bool udpConnected = false, udpRgbConnected = false;
//ui style
char cssCol[9][5]={"","","","","",""};
char cssCol[6][9]={"","","","","",""};
String cssColorString="";
bool showWelcomePage = false;
@ -332,6 +332,9 @@ unsigned long realtimeTimeout = 0;
//mqtt
bool mqttInit = false;
long lastMQTTReconnectAttempt = 0;
long lastInterfaceUpdate = 0;
byte interfaceUpdateCallMode = 0;
uint32_t mqttFailedConAttempts = 0;
//auxiliary debug pin
byte auxTime = 0;

View File

@ -6,7 +6,7 @@
#define EEPSIZE 3072
//eeprom Version code, enables default settings instead of 0 init on update
#define EEPVER 8
#define EEPVER 9
//0 -> old version, default
//1 -> 0.4p 1711272 and up
//2 -> 0.4p 1711302 and up
@ -15,7 +15,8 @@
//5 -> 0.5.1 and up
//6 -> 0.6.0 and up
//7 -> 0.7.1 and up
//8 -> 0.8.0 and up
//8 -> 0.8.0-a and up
//9 -> 0.8.0
/*
* Erase all configuration data
@ -147,7 +148,7 @@ void saveSettingsToEEPROM()
int in = 900+k*8;
for (int i=in; i < in+8; ++i)
{
EEPROM.write(i, cssCol[i-in][k]);
EEPROM.write(i, cssCol[k][i-in]);
}}
EEPROM.write(948,currentTheme);
@ -242,6 +243,19 @@ void saveSettingsToEEPROM()
EEPROM.write(2280 + i, timerWeekday[i]);
EEPROM.write(2290 + i, timerMacro[i] );
}
for (int i = 2300; i < 2333; ++i)
{
EEPROM.write(i, mqttServer[i-2300]);
}
for (int i = 2333; i < 2366; ++i)
{
EEPROM.write(i, mqttDeviceTopic[i-2333]);
}
for (int i = 2366; i < 2399; ++i)
{
EEPROM.write(i, mqttGroupTopic[i-2366]);
}
EEPROM.commit();
}
@ -468,6 +482,25 @@ void loadSettingsFromEEPROM(bool first)
timerMacro[i] = EEPROM.read(2290 + i);
}
}
if (lastEEPROMversion > 8)
{
for (int i = 2300; i < 2333; ++i)
{
mqttServer[i-2300] = EEPROM.read(i);
if (mqttServer[i-2300] == 0) break;
}
for (int i = 2333; i < 2366; ++i)
{
mqttDeviceTopic[i-2333] = EEPROM.read(i);
if (mqttDeviceTopic[i-2333] == 0) break;
}
for (int i = 2366; i < 2399; ++i)
{
mqttGroupTopic[i-2366] = EEPROM.read(i);
if (mqttGroupTopic[i-2366] == 0) break;
}
}
receiveDirect = !EEPROM.read(2200);
enableRealtimeUI = EEPROM.read(2201);
@ -491,12 +524,6 @@ void loadSettingsFromEEPROM(bool first)
presetApplyCol = EEPROM.read(2211);
presetApplyFx = EEPROM.read(2212);
}
for (int i = 2220; i < 2255; ++i)
{
blynkApiKey[i-2220] = EEPROM.read(i);
if (blynkApiKey[i-2220] == 0) break;
}
bootPreset = EEPROM.read(389);
wifiLock = EEPROM.read(393);
@ -514,12 +541,18 @@ void loadSettingsFromEEPROM(bool first)
for (int i=in; i < in+8; ++i)
{
if (EEPROM.read(i) == 0) break;
cssCol[i-in][k] =EEPROM.read(i);
cssCol[k][i-in] =EEPROM.read(i);
}}
//custom macro memory (16 slots/ each 64byte)
//1024-2047 reserved
for (int i = 2220; i < 2255; ++i)
{
blynkApiKey[i-2220] = EEPROM.read(i);
if (blynkApiKey[i-2220] == 0) break;
}
//user MOD memory
//2944 - 3071 reserved

View File

@ -241,7 +241,9 @@ void getSettingsJS(byte subPage) //get values for settings form in javascript
sappend('c',"AL",alexaEnabled);
sappends('s',"AI",alexaInvocationName);
sappend('c',"SA",notifyAlexa);
sappends('s',"BK",(char*)((blynkEnabled)?"Hidden":""));
sappends('s',"MS",mqttServer);
sappends('s',"MD",mqttDeviceTopic);
sappends('s',"MG",mqttGroupTopic);
sappend('v',"H0",hueIP[0]);
sappend('v',"H1",hueIP[1]);
sappend('v',"H2",hueIP[2]);

View File

@ -170,6 +170,10 @@ void handleSettingsSet(byte subPage)
notifyAlexa = server.hasArg("SA");
if (server.hasArg("BK") && !server.arg("BK").equals("Hidden")) {strcpy(blynkApiKey,server.arg("BK").c_str()); initBlynk(blynkApiKey);}
strcpy(mqttServer, server.arg("MS").c_str());
strcpy(mqttDeviceTopic, server.arg("MD").c_str());
strcpy(mqttGroupTopic, server.arg("MG").c_str());
notifyHue = server.hasArg("SH");
for (int i=0;i<4;i++){

View File

@ -58,7 +58,7 @@ void wledInit()
}
prepareIds(); //UUID from MAC (for Alexa and MQTT)
if (mqttTopic0[0] == 0) strcpy(mqttTopic0, strcat("wled/", escapedMac.c_str()));
if (mqttDeviceTopic[0] == 0) strcpy(mqttDeviceTopic, strcat("wled/", escapedMac.c_str()));
if (!onlyAP) mqttInit = initMQTT();
if (!initLedsLast) strip.service();

View File

@ -92,12 +92,14 @@ void colorUpdated(int callMode)
whiteSecIT = whiteSec;
briIT = bri;
if (bri > 0) briLast = bri;
notify(callMode);
if (fadeTransition)
{
//set correct delay if not using notification delay
if (callMode != 3) transitionDelayTemp = transitionDelay;
if (transitionDelayTemp == 0) {setLedsStandard();strip.trigger();return;}
if (transitionDelayTemp == 0) {setLedsStandard(); strip.trigger(); return;}
if (transitionActive)
{
@ -120,11 +122,33 @@ void colorUpdated(int callMode)
setLedsStandard();
strip.trigger();
}
if (callMode != 9 && callMode != 5 && callMode != 8) updateBlynk();
if (callMode == 8) return;
//only update Blynk and mqtt every 2 seconds to reduce lag
if (millis() - lastInterfaceUpdate <= 2000)
{
interfaceUpdateCallMode = callMode;
return;
}
updateInterfaces(callMode);
}
void updateInterfaces(uint8_t callMode)
{
if (callMode != 9 && callMode != 5) updateBlynk();
publishMQTT();
lastInterfaceUpdate = millis();
}
void handleTransitions()
{
//handle still pending interface update
if (interfaceUpdateCallMode && millis() - lastInterfaceUpdate > 2000)
{
updateInterfaces(interfaceUpdateCallMode);
interfaceUpdateCallMode = 0; //disable
}
if (transitionActive && transitionDelayTemp > 0)
{
float tper = (millis() - transitionStartTime)/(float)transitionDelayTemp;

View File

@ -28,23 +28,38 @@ void callbackMQTT(char* topic, byte* payload, unsigned int length) {
colorUpdated(1);
} else if (strstr(topic, "/api"))
{
handleSet(String((char*)payload));
String apireq = "win&";
handleSet(apireq += (char*)payload));
} else
{
parseMQTTBriPayload((char*)payload);
}
}
void publishStatus()
void publishMQTT()
{
if (!mqtt.connected()) return;
DEBUG_PRINTLN("Publish MQTT");
char s[4];
sprintf(s,"%ld", bri);
mqtt.publish(strcat(mqttTopic0, "/g") , s);
XML_response(false);
mqtt.publish(strcat(mqttTopic0, "/vs"), obuf);
char s[10];
char subuf[38];
sprintf(s, "%ld", bri);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/g");
mqtt.publish(subuf, s);
sprintf(s, "#%X", white*16777216 + col[0]*65536 + col[1]*256 + col[2]);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/c");
mqtt.publish(subuf, s);
//if you want to use this, increase the MQTT buffer in PubSubClient.h to 350+
//it will publish the API response to MQTT
/*XML_response(false);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/v");
mqtt.publish(subuf, obuf);*/
}
bool reconnectMQTT()
@ -53,26 +68,26 @@ bool reconnectMQTT()
{
//re-subscribe to required topics
char subuf[38];
strcpy(subuf, mqttTopic0);
strcpy(subuf, mqttDeviceTopic);
if (mqttTopic0[0] != 0)
if (mqttDeviceTopic[0] != 0)
{
strcpy(subuf, mqttTopic0);
strcpy(subuf, mqttDeviceTopic);
mqtt.subscribe(subuf);
strcat(subuf, "/col");
mqtt.subscribe(subuf);
strcpy(subuf, mqttTopic0);
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/api");
mqtt.subscribe(subuf);
}
if (mqttTopic1[0] != 0)
if (mqttGroupTopic[0] != 0)
{
strcpy(subuf, mqttTopic1);
strcpy(subuf, mqttGroupTopic);
mqtt.subscribe(subuf);
strcat(subuf, "/col");
mqtt.subscribe(subuf);
strcpy(subuf, mqttTopic1);
strcpy(subuf, mqttGroupTopic);
strcat(subuf, "/api");
mqtt.subscribe(subuf);
}
@ -100,12 +115,20 @@ bool initMQTT()
void handleMQTT()
{
if (WiFi.status() != WL_CONNECTED || !mqttInit) return;
if (!mqtt.connected() && millis() - lastMQTTReconnectAttempt > 5000)
//every time connection is unsuccessful, the attempt interval is increased, since attempt will block program for 7 sec each time
if (!mqtt.connected() && millis() - lastMQTTReconnectAttempt > 5000 + (5000 * mqttFailedConAttempts * mqttFailedConAttempts))
{
DEBUG_PRINTLN("Attempting to connect MQTT...");
lastMQTTReconnectAttempt = millis();
if (!reconnectMQTT()) return;
if (!reconnectMQTT())
{
//still attempt reconnect about once daily
if (mqttFailedConAttempts < 120) mqttFailedConAttempts++;
return;
}
DEBUG_PRINTLN("MQTT con!");
mqttFailedConAttempts = 0;
}
mqtt.loop();
}

BIN
wled_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB