Merge branch 'debsahu/master'
Support for AMQTT, NEOANIMATIONFX
This commit is contained in:
commit
9b7ca2ac47
4 changed files with 1157 additions and 396 deletions
|
@ -8,7 +8,7 @@
|
||||||
// needed for library WiFiManager
|
// needed for library WiFiManager
|
||||||
#include <DNSServer.h>
|
#include <DNSServer.h>
|
||||||
#include <ESP8266WebServer.h>
|
#include <ESP8266WebServer.h>
|
||||||
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
|
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
|
||||||
|
|
||||||
#include <WiFiClient.h>
|
#include <WiFiClient.h>
|
||||||
#include <ESP8266mDNS.h>
|
#include <ESP8266mDNS.h>
|
||||||
|
@ -35,6 +35,18 @@
|
||||||
PubSubClient mqtt_client(espClient);
|
PubSubClient mqtt_client(espClient);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
#include <AsyncMqttClient.h> //https://github.com/marvinroger/async-mqtt-client
|
||||||
|
//https://github.com/me-no-dev/ESPAsyncTCP
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AsyncMqttClient amqttClient;
|
||||||
|
WiFiEventHandler wifiConnectHandler;
|
||||||
|
WiFiEventHandler wifiDisconnectHandler;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Instanciate HTTP(80) / WebSockets(81) Server
|
// Instanciate HTTP(80) / WebSockets(81) Server
|
||||||
|
@ -43,10 +55,29 @@ ESP8266WebServer server(80);
|
||||||
WebSocketsServer webSocket = WebSocketsServer(81);
|
WebSocketsServer webSocket = WebSocketsServer(81);
|
||||||
|
|
||||||
#ifdef HTTP_OTA
|
#ifdef HTTP_OTA
|
||||||
#include <ESP8266HTTPUpdateServer.h>
|
#include <ESP8266HTTPUpdateServer.h>
|
||||||
ESP8266HTTPUpdateServer httpUpdater;
|
ESP8266HTTPUpdateServer httpUpdater;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_NEOANIMATIONFX
|
||||||
|
// ***************************************************************************
|
||||||
|
// Load libraries / Instanciate NeoAnimationFX library
|
||||||
|
// ***************************************************************************
|
||||||
|
// https://github.com/debsahu/NeoAnimationFX
|
||||||
|
#include <NeoAnimationFX.h>
|
||||||
|
#define NEOMETHOD NeoPBBGRB800
|
||||||
|
|
||||||
|
NEOMETHOD neoStrip(NUMLEDS);
|
||||||
|
NeoAnimationFX<NEOMETHOD> strip(neoStrip);
|
||||||
|
|
||||||
|
// Uses Pin RX / GPIO3 (Only pin that is supported, due to hardware limitations)
|
||||||
|
// NEOMETHOD NeoPBBGRB800 uses GRB config 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||||
|
// NEOMETHOD NeoPBBGRB400 uses GRB config 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||||
|
// NEOMETHOD NeoPBBRGB800 uses RGB config 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
|
||||||
|
// NEOMETHOD NeoPBBRGB400 uses RGB config 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_WS2812FX
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Load libraries / Instanciate WS2812FX library
|
// Load libraries / Instanciate WS2812FX library
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
@ -66,14 +97,23 @@ WS2812FX strip = WS2812FX(NUMLEDS, PIN, NEO_GRB + NEO_KHZ800);
|
||||||
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
|
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
|
||||||
// and minimize distance between Arduino and first pixel. Avoid connecting
|
// and minimize distance between Arduino and first pixel. Avoid connecting
|
||||||
// on a live circuit...if you must, connect GND first.
|
// on a live circuit...if you must, connect GND first.
|
||||||
|
#endif
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Load library "ticker" for blinking status led
|
// Load library "ticker" for blinking status led
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#include <Ticker.h>
|
#include <Ticker.h>
|
||||||
Ticker ticker;
|
Ticker ticker;
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
Ticker ha_send_data;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
Ticker mqttReconnectTimer;
|
||||||
|
Ticker wifiReconnectTimer;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
Ticker spiffs_save_state;
|
||||||
|
#endif
|
||||||
void tick()
|
void tick()
|
||||||
{
|
{
|
||||||
//toggle state
|
//toggle state
|
||||||
|
@ -81,33 +121,33 @@ void tick()
|
||||||
digitalWrite(BUILTIN_LED, !state); // set pin to the opposite state
|
digitalWrite(BUILTIN_LED, !state); // set pin to the opposite state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_STATE_SAVE_EEPROM
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// EEPROM helper
|
// EEPROM helper
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
String readEEPROM(int offset, int len) {
|
String readEEPROM(int offset, int len) {
|
||||||
String res = "";
|
String res = "";
|
||||||
for (int i = 0; i < len; ++i)
|
for (int i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
res += char(EEPROM.read(i + offset));
|
res += char(EEPROM.read(i + offset));
|
||||||
//DBG_OUTPUT_PORT.println(char(EEPROM.read(i + offset)));
|
//DBG_OUTPUT_PORT.println(char(EEPROM.read(i + offset)));
|
||||||
|
}
|
||||||
|
DBG_OUTPUT_PORT.printf("readEEPROM(): %s\n", res.c_str());
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
DBG_OUTPUT_PORT.printf("readEEPROM(): %s\n", res.c_str());
|
|
||||||
return res;
|
void writeEEPROM(int offset, int len, String value) {
|
||||||
}
|
DBG_OUTPUT_PORT.printf("writeEEPROM(): %s\n", value.c_str());
|
||||||
|
for (int i = 0; i < len; ++i)
|
||||||
void writeEEPROM(int offset, int len, String value) {
|
{
|
||||||
DBG_OUTPUT_PORT.printf("writeEEPROM(): %s\n", value.c_str());
|
if (i < value.length()) {
|
||||||
for (int i = 0; i < len; ++i)
|
EEPROM.write(i + offset, value[i]);
|
||||||
{
|
} else {
|
||||||
if (i < value.length()) {
|
EEPROM.write(i + offset, NULL);
|
||||||
EEPROM.write(i + offset, value[i]);
|
}
|
||||||
} else {
|
|
||||||
EEPROM.write(i + offset, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Saved state handling
|
// Saved state handling
|
||||||
|
@ -130,7 +170,6 @@ String getValue(String data, char separator, int index)
|
||||||
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
|
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Callback for WiFiManager library when config mode is entered
|
// Callback for WiFiManager library when config mode is entered
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
@ -171,12 +210,12 @@ void saveConfigCallback () {
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
#include "colormodes.h"
|
#include "colormodes.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// MAIN
|
// MAIN
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
void setup() {
|
void setup() {
|
||||||
|
// system_update_cpu_freq(160);
|
||||||
|
|
||||||
DBG_OUTPUT_PORT.begin(115200);
|
DBG_OUTPUT_PORT.begin(115200);
|
||||||
EEPROM.begin(512);
|
EEPROM.begin(512);
|
||||||
|
|
||||||
|
@ -189,185 +228,6 @@ void setup() {
|
||||||
// start ticker with 0.5 because we start in AP mode and try to connect
|
// start ticker with 0.5 because we start in AP mode and try to connect
|
||||||
ticker.attach(0.5, tick);
|
ticker.attach(0.5, tick);
|
||||||
|
|
||||||
wifi_station_set_hostname(const_cast<char*>(HOSTNAME));
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
// Setup: Neopixel
|
|
||||||
// ***************************************************************************
|
|
||||||
strip.init();
|
|
||||||
strip.setBrightness(brightness);
|
|
||||||
strip.setSpeed(convertSpeed(ws2812fx_speed));
|
|
||||||
//strip.setMode(FX_MODE_RAINBOW_CYCLE);
|
|
||||||
strip.setColor(main_color.red, main_color.green, main_color.blue);
|
|
||||||
strip.start();
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
// Setup: WiFiManager
|
|
||||||
// ***************************************************************************
|
|
||||||
// The extra parameters to be configured (can be either global or just in the setup)
|
|
||||||
// After connecting, parameter.getValue() will get you the configured value
|
|
||||||
// id/name placeholder/prompt default length
|
|
||||||
#ifdef ENABLE_MQTT
|
|
||||||
String settings_available = readEEPROM(134, 1);
|
|
||||||
if (settings_available == "1") {
|
|
||||||
readEEPROM(0, 64).toCharArray(mqtt_host, 64); // 0-63
|
|
||||||
readEEPROM(64, 6).toCharArray(mqtt_port, 6); // 64-69
|
|
||||||
readEEPROM(70, 32).toCharArray(mqtt_user, 32); // 70-101
|
|
||||||
readEEPROM(102, 32).toCharArray(mqtt_pass, 32); // 102-133
|
|
||||||
DBG_OUTPUT_PORT.printf("MQTT host: %s\n", mqtt_host);
|
|
||||||
DBG_OUTPUT_PORT.printf("MQTT port: %s\n", mqtt_port);
|
|
||||||
DBG_OUTPUT_PORT.printf("MQTT user: %s\n", mqtt_user);
|
|
||||||
DBG_OUTPUT_PORT.printf("MQTT pass: %s\n", mqtt_pass);
|
|
||||||
}
|
|
||||||
|
|
||||||
WiFiManagerParameter custom_mqtt_host("host", "MQTT hostname", mqtt_host, 64);
|
|
||||||
WiFiManagerParameter custom_mqtt_port("port", "MQTT port", mqtt_port, 6);
|
|
||||||
WiFiManagerParameter custom_mqtt_user("user", "MQTT user", mqtt_user, 32);
|
|
||||||
WiFiManagerParameter custom_mqtt_pass("pass", "MQTT pass", mqtt_pass, 32);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Local intialization. Once its business is done, there is no need to keep it around
|
|
||||||
WiFiManager wifiManager;
|
|
||||||
//reset settings - for testing
|
|
||||||
//wifiManager.resetSettings();
|
|
||||||
|
|
||||||
//set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
|
|
||||||
wifiManager.setAPCallback(configModeCallback);
|
|
||||||
|
|
||||||
#ifdef ENABLE_MQTT
|
|
||||||
//set config save notify callback
|
|
||||||
wifiManager.setSaveConfigCallback(saveConfigCallback);
|
|
||||||
|
|
||||||
//add all your parameters here
|
|
||||||
wifiManager.addParameter(&custom_mqtt_host);
|
|
||||||
wifiManager.addParameter(&custom_mqtt_port);
|
|
||||||
wifiManager.addParameter(&custom_mqtt_user);
|
|
||||||
wifiManager.addParameter(&custom_mqtt_pass);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//fetches ssid and pass and tries to connect
|
|
||||||
//if it does not connect it starts an access point with the specified name
|
|
||||||
//here "AutoConnectAP"
|
|
||||||
//and goes into a blocking loop awaiting configuration
|
|
||||||
if (!wifiManager.autoConnect(HOSTNAME)) {
|
|
||||||
DBG_OUTPUT_PORT.println("failed to connect and hit timeout");
|
|
||||||
//reset and try again, or maybe put it to deep sleep
|
|
||||||
ESP.reset();
|
|
||||||
delay(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_MQTT
|
|
||||||
//read updated parameters
|
|
||||||
strcpy(mqtt_host, custom_mqtt_host.getValue());
|
|
||||||
strcpy(mqtt_port, custom_mqtt_port.getValue());
|
|
||||||
strcpy(mqtt_user, custom_mqtt_user.getValue());
|
|
||||||
strcpy(mqtt_pass, custom_mqtt_pass.getValue());
|
|
||||||
|
|
||||||
//save the custom parameters to FS
|
|
||||||
if (shouldSaveConfig) {
|
|
||||||
DBG_OUTPUT_PORT.println("Saving WiFiManager config");
|
|
||||||
|
|
||||||
writeEEPROM(0, 64, mqtt_host); // 0-63
|
|
||||||
writeEEPROM(64, 6, mqtt_port); // 64-69
|
|
||||||
writeEEPROM(70, 32, mqtt_user); // 70-101
|
|
||||||
writeEEPROM(102, 32, mqtt_pass); // 102-133
|
|
||||||
writeEEPROM(134, 1, "1"); // 134 --> always "1"
|
|
||||||
EEPROM.commit();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//if you get here you have connected to the WiFi
|
|
||||||
DBG_OUTPUT_PORT.println("connected...yeey :)");
|
|
||||||
ticker.detach();
|
|
||||||
//keep LED on
|
|
||||||
digitalWrite(BUILTIN_LED, LOW);
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
// Configure OTA
|
|
||||||
// ***************************************************************************
|
|
||||||
#ifdef ENABLE_OTA
|
|
||||||
DBG_OUTPUT_PORT.println("Arduino OTA activated.");
|
|
||||||
|
|
||||||
// Port defaults to 8266
|
|
||||||
ArduinoOTA.setPort(8266);
|
|
||||||
|
|
||||||
// Hostname defaults to esp8266-[ChipID]
|
|
||||||
ArduinoOTA.setHostname(HOSTNAME);
|
|
||||||
|
|
||||||
// No authentication by default
|
|
||||||
// ArduinoOTA.setPassword("admin");
|
|
||||||
|
|
||||||
// Password can be set with it's md5 value as well
|
|
||||||
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
|
|
||||||
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
|
|
||||||
|
|
||||||
ArduinoOTA.onStart([]() {
|
|
||||||
DBG_OUTPUT_PORT.println("Arduino OTA: Start updating");
|
|
||||||
});
|
|
||||||
ArduinoOTA.onEnd([]() {
|
|
||||||
DBG_OUTPUT_PORT.println("Arduino OTA: End");
|
|
||||||
});
|
|
||||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
|
||||||
DBG_OUTPUT_PORT.printf("Arduino OTA Progress: %u%%\r", (progress / (total / 100)));
|
|
||||||
});
|
|
||||||
ArduinoOTA.onError([](ota_error_t error) {
|
|
||||||
DBG_OUTPUT_PORT.printf("Arduino OTA Error[%u]: ", error);
|
|
||||||
if (error == OTA_AUTH_ERROR) DBG_OUTPUT_PORT.println("Arduino OTA: Auth Failed");
|
|
||||||
else if (error == OTA_BEGIN_ERROR) DBG_OUTPUT_PORT.println("Arduino OTA: Begin Failed");
|
|
||||||
else if (error == OTA_CONNECT_ERROR) DBG_OUTPUT_PORT.println("Arduino OTA: Connect Failed");
|
|
||||||
else if (error == OTA_RECEIVE_ERROR) DBG_OUTPUT_PORT.println("Arduino OTA: Receive Failed");
|
|
||||||
else if (error == OTA_END_ERROR) DBG_OUTPUT_PORT.println("Arduino OTA: End Failed");
|
|
||||||
});
|
|
||||||
|
|
||||||
ArduinoOTA.begin();
|
|
||||||
DBG_OUTPUT_PORT.println("");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
// Configure MQTT
|
|
||||||
// ***************************************************************************
|
|
||||||
#ifdef ENABLE_MQTT
|
|
||||||
if (mqtt_host != "" && String(mqtt_port).toInt() > 0) {
|
|
||||||
snprintf(mqtt_intopic, sizeof mqtt_intopic, "%s/in", HOSTNAME);
|
|
||||||
snprintf(mqtt_outtopic, sizeof mqtt_outtopic, "%s/out", HOSTNAME);
|
|
||||||
|
|
||||||
DBG_OUTPUT_PORT.printf("MQTT active: %s:%d\n", mqtt_host, String(mqtt_port).toInt());
|
|
||||||
|
|
||||||
mqtt_client.setServer(mqtt_host, String(mqtt_port).toInt());
|
|
||||||
mqtt_client.setCallback(mqtt_callback);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
// Setup: MDNS responder
|
|
||||||
// ***************************************************************************
|
|
||||||
bool mdns_result = MDNS.begin(HOSTNAME);
|
|
||||||
|
|
||||||
DBG_OUTPUT_PORT.print("Open http://");
|
|
||||||
DBG_OUTPUT_PORT.print(WiFi.localIP());
|
|
||||||
DBG_OUTPUT_PORT.println("/ to open McLighting.");
|
|
||||||
|
|
||||||
DBG_OUTPUT_PORT.print("Use http://");
|
|
||||||
DBG_OUTPUT_PORT.print(HOSTNAME);
|
|
||||||
DBG_OUTPUT_PORT.println(".local/ when you have Bonjour installed.");
|
|
||||||
|
|
||||||
DBG_OUTPUT_PORT.print("New users: Open http://");
|
|
||||||
DBG_OUTPUT_PORT.print(WiFi.localIP());
|
|
||||||
DBG_OUTPUT_PORT.println("/upload to upload the webpages first.");
|
|
||||||
|
|
||||||
DBG_OUTPUT_PORT.println("");
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
// Setup: WebSocket server
|
|
||||||
// ***************************************************************************
|
|
||||||
webSocket.begin();
|
|
||||||
webSocket.onEvent(webSocketEvent);
|
|
||||||
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Setup: SPIFFS
|
// Setup: SPIFFS
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
@ -385,6 +245,213 @@ void setup() {
|
||||||
DBG_OUTPUT_PORT.printf("FS Usage: %d/%d bytes\n\n", fs_info.usedBytes, fs_info.totalBytes);
|
DBG_OUTPUT_PORT.printf("FS Usage: %d/%d bytes\n\n", fs_info.usedBytes, fs_info.totalBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wifi_station_set_hostname(const_cast<char*>(HOSTNAME));
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// Setup: Neopixel
|
||||||
|
// ***************************************************************************
|
||||||
|
strip.init();
|
||||||
|
strip.setBrightness(brightness);
|
||||||
|
strip.setSpeed(convertSpeed(ws2812fx_speed));
|
||||||
|
//strip.setMode(FX_MODE_RAINBOW_CYCLE);
|
||||||
|
strip.setColor(main_color.red, main_color.green, main_color.blue);
|
||||||
|
strip.start();
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// Setup: WiFiManager
|
||||||
|
// ***************************************************************************
|
||||||
|
// The extra parameters to be configured (can be either global or just in the setup)
|
||||||
|
// After connecting, parameter.getValue() will get you the configured value
|
||||||
|
// id/name placeholder/prompt default length
|
||||||
|
#if defined(ENABLE_MQTT) or defined(ENABLE_AMQTT)
|
||||||
|
#if defined(ENABLE_STATE_SAVE_SPIFFS)
|
||||||
|
(readConfigFS()) ? DBG_OUTPUT_PORT.println("WiFiManager config FS Read success!"): DBG_OUTPUT_PORT.println("WiFiManager config FS Read failure!");
|
||||||
|
#else
|
||||||
|
String settings_available = readEEPROM(134, 1);
|
||||||
|
if (settings_available == "1") {
|
||||||
|
readEEPROM(0, 64).toCharArray(mqtt_host, 64); // 0-63
|
||||||
|
readEEPROM(64, 6).toCharArray(mqtt_port, 6); // 64-69
|
||||||
|
readEEPROM(70, 32).toCharArray(mqtt_user, 32); // 70-101
|
||||||
|
readEEPROM(102, 32).toCharArray(mqtt_pass, 32); // 102-133
|
||||||
|
DBG_OUTPUT_PORT.printf("MQTT host: %s\n", mqtt_host);
|
||||||
|
DBG_OUTPUT_PORT.printf("MQTT port: %s\n", mqtt_port);
|
||||||
|
DBG_OUTPUT_PORT.printf("MQTT user: %s\n", mqtt_user);
|
||||||
|
DBG_OUTPUT_PORT.printf("MQTT pass: %s\n", mqtt_pass);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
WiFiManagerParameter custom_mqtt_host("host", "MQTT hostname", mqtt_host, 64);
|
||||||
|
WiFiManagerParameter custom_mqtt_port("port", "MQTT port", mqtt_port, 6);
|
||||||
|
WiFiManagerParameter custom_mqtt_user("user", "MQTT user", mqtt_user, 32);
|
||||||
|
WiFiManagerParameter custom_mqtt_pass("pass", "MQTT pass", mqtt_pass, 32);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Local intialization. Once its business is done, there is no need to keep it around
|
||||||
|
WiFiManager wifiManager;
|
||||||
|
//reset settings - for testing
|
||||||
|
//wifiManager.resetSettings();
|
||||||
|
|
||||||
|
//set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
|
||||||
|
wifiManager.setAPCallback(configModeCallback);
|
||||||
|
|
||||||
|
#if defined(ENABLE_MQTT) or defined(ENABLE_AMQTT)
|
||||||
|
//set config save notify callback
|
||||||
|
wifiManager.setSaveConfigCallback(saveConfigCallback);
|
||||||
|
|
||||||
|
//add all your parameters here
|
||||||
|
wifiManager.addParameter(&custom_mqtt_host);
|
||||||
|
wifiManager.addParameter(&custom_mqtt_port);
|
||||||
|
wifiManager.addParameter(&custom_mqtt_user);
|
||||||
|
wifiManager.addParameter(&custom_mqtt_pass);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WiFi.setSleepMode(WIFI_NONE_SLEEP);
|
||||||
|
|
||||||
|
//fetches ssid and pass and tries to connect
|
||||||
|
//if it does not connect it starts an access point with the specified name
|
||||||
|
//here "AutoConnectAP"
|
||||||
|
//and goes into a blocking loop awaiting configuration
|
||||||
|
if (!wifiManager.autoConnect(HOSTNAME)) {
|
||||||
|
DBG_OUTPUT_PORT.println("failed to connect and hit timeout");
|
||||||
|
//reset and try again, or maybe put it to deep sleep
|
||||||
|
ESP.reset();
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(ENABLE_MQTT) or defined(ENABLE_AMQTT)
|
||||||
|
//read updated parameters
|
||||||
|
strcpy(mqtt_host, custom_mqtt_host.getValue());
|
||||||
|
strcpy(mqtt_port, custom_mqtt_port.getValue());
|
||||||
|
strcpy(mqtt_user, custom_mqtt_user.getValue());
|
||||||
|
strcpy(mqtt_pass, custom_mqtt_pass.getValue());
|
||||||
|
|
||||||
|
//save the custom parameters to FS
|
||||||
|
#if defined(ENABLE_STATE_SAVE_SPIFFS)
|
||||||
|
(writeConfigFS(shouldSaveConfig)) ? DBG_OUTPUT_PORT.println("WiFiManager config FS Save success!"): DBG_OUTPUT_PORT.println("WiFiManager config FS Save failure!");
|
||||||
|
#else if defined(ENABLE_STATE_SAVE_EEPROM)
|
||||||
|
if (shouldSaveConfig) {
|
||||||
|
DBG_OUTPUT_PORT.println("Saving WiFiManager config");
|
||||||
|
|
||||||
|
writeEEPROM(0, 64, mqtt_host); // 0-63
|
||||||
|
writeEEPROM(64, 6, mqtt_port); // 64-69
|
||||||
|
writeEEPROM(70, 32, mqtt_user); // 70-101
|
||||||
|
writeEEPROM(102, 32, mqtt_pass); // 102-133
|
||||||
|
writeEEPROM(134, 1, "1"); // 134 --> always "1"
|
||||||
|
EEPROM.commit();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
|
||||||
|
wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//if you get here you have connected to the WiFi
|
||||||
|
DBG_OUTPUT_PORT.println("connected...yeey :)");
|
||||||
|
ticker.detach();
|
||||||
|
//keep LED on
|
||||||
|
digitalWrite(BUILTIN_LED, LOW);
|
||||||
|
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// Configure OTA
|
||||||
|
// ***************************************************************************
|
||||||
|
#ifdef ENABLE_OTA
|
||||||
|
DBG_OUTPUT_PORT.println("Arduino OTA activated.");
|
||||||
|
|
||||||
|
// Port defaults to 8266
|
||||||
|
ArduinoOTA.setPort(8266);
|
||||||
|
|
||||||
|
// Hostname defaults to esp8266-[ChipID]
|
||||||
|
ArduinoOTA.setHostname(HOSTNAME);
|
||||||
|
|
||||||
|
// No authentication by default
|
||||||
|
// ArduinoOTA.setPassword("admin");
|
||||||
|
|
||||||
|
// Password can be set with it's md5 value as well
|
||||||
|
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
|
||||||
|
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
|
||||||
|
|
||||||
|
ArduinoOTA.onStart([]() {
|
||||||
|
DBG_OUTPUT_PORT.println("Arduino OTA: Start updating");
|
||||||
|
});
|
||||||
|
ArduinoOTA.onEnd([]() {
|
||||||
|
DBG_OUTPUT_PORT.println("Arduino OTA: End");
|
||||||
|
});
|
||||||
|
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||||
|
DBG_OUTPUT_PORT.printf("Arduino OTA Progress: %u%%\r", (progress / (total / 100)));
|
||||||
|
});
|
||||||
|
ArduinoOTA.onError([](ota_error_t error) {
|
||||||
|
DBG_OUTPUT_PORT.printf("Arduino OTA Error[%u]: ", error);
|
||||||
|
if (error == OTA_AUTH_ERROR) DBG_OUTPUT_PORT.println("Arduino OTA: Auth Failed");
|
||||||
|
else if (error == OTA_BEGIN_ERROR) DBG_OUTPUT_PORT.println("Arduino OTA: Begin Failed");
|
||||||
|
else if (error == OTA_CONNECT_ERROR) DBG_OUTPUT_PORT.println("Arduino OTA: Connect Failed");
|
||||||
|
else if (error == OTA_RECEIVE_ERROR) DBG_OUTPUT_PORT.println("Arduino OTA: Receive Failed");
|
||||||
|
else if (error == OTA_END_ERROR) DBG_OUTPUT_PORT.println("Arduino OTA: End Failed");
|
||||||
|
});
|
||||||
|
|
||||||
|
ArduinoOTA.begin();
|
||||||
|
DBG_OUTPUT_PORT.println("");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// Configure MQTT
|
||||||
|
// ***************************************************************************
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
if (mqtt_host != "" && String(mqtt_port).toInt() > 0) {
|
||||||
|
snprintf(mqtt_intopic, sizeof mqtt_intopic, "%s/in", HOSTNAME);
|
||||||
|
snprintf(mqtt_outtopic, sizeof mqtt_outtopic, "%s/out", HOSTNAME);
|
||||||
|
|
||||||
|
DBG_OUTPUT_PORT.printf("MQTT active: %s:%d\n", mqtt_host, String(mqtt_port).toInt());
|
||||||
|
|
||||||
|
mqtt_client.setServer(mqtt_host, String(mqtt_port).toInt());
|
||||||
|
mqtt_client.setCallback(mqtt_callback);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
if (mqtt_host != "" && String(mqtt_port).toInt() > 0) {
|
||||||
|
amqttClient.onConnect(onMqttConnect);
|
||||||
|
amqttClient.onDisconnect(onMqttDisconnect);
|
||||||
|
amqttClient.onMessage(onMqttMessage);
|
||||||
|
amqttClient.setServer(mqtt_host, String(mqtt_port).toInt());
|
||||||
|
amqttClient.setClientId(mqtt_clientid);
|
||||||
|
|
||||||
|
connectToMqtt();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// #ifdef ENABLE_HOMEASSISTANT
|
||||||
|
// ha_send_data.attach(5, tickerSendState); // Send HA data back only every 5 sec
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// Setup: MDNS responder
|
||||||
|
// ***************************************************************************
|
||||||
|
bool mdns_result = MDNS.begin(HOSTNAME);
|
||||||
|
|
||||||
|
DBG_OUTPUT_PORT.print("Open http://");
|
||||||
|
DBG_OUTPUT_PORT.print(WiFi.localIP());
|
||||||
|
DBG_OUTPUT_PORT.println("/ to open McLighting.");
|
||||||
|
|
||||||
|
DBG_OUTPUT_PORT.print("Use http://");
|
||||||
|
DBG_OUTPUT_PORT.print(HOSTNAME);
|
||||||
|
DBG_OUTPUT_PORT.println(".local/ when you have Bonjour installed.");
|
||||||
|
|
||||||
|
DBG_OUTPUT_PORT.print("New users: Open http://");
|
||||||
|
DBG_OUTPUT_PORT.print(WiFi.localIP());
|
||||||
|
DBG_OUTPUT_PORT.println("/upload to upload the webpages first.");
|
||||||
|
|
||||||
|
DBG_OUTPUT_PORT.println("");
|
||||||
|
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
// Setup: WebSocket server
|
||||||
|
// ***************************************************************************
|
||||||
|
webSocket.begin();
|
||||||
|
webSocket.onEvent(webSocketEvent);
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// Setup: SPIFFS Webserver handler
|
// Setup: SPIFFS Webserver handler
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
@ -462,7 +529,19 @@ void setup() {
|
||||||
brightness = 0;
|
brightness = 0;
|
||||||
}
|
}
|
||||||
strip.setBrightness(brightness);
|
strip.setBrightness(brightness);
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String(String("OK %") + String(brightness)).c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK %") + String(brightness)).c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
stateOn = true;
|
||||||
|
if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState);
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||||
|
#endif
|
||||||
getStatusJSON();
|
getStatusJSON();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -472,14 +551,23 @@ void setup() {
|
||||||
DBG_OUTPUT_PORT.print("/get_brightness: ");
|
DBG_OUTPUT_PORT.print("/get_brightness: ");
|
||||||
DBG_OUTPUT_PORT.println(str_brightness);
|
DBG_OUTPUT_PORT.println(str_brightness);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/set_speed", []() {
|
server.on("/set_speed", []() {
|
||||||
if (server.arg("d").toInt() >= 0) {
|
if (server.arg("d").toInt() >= 0) {
|
||||||
ws2812fx_speed = server.arg("d").toInt();
|
ws2812fx_speed = server.arg("d").toInt();
|
||||||
ws2812fx_speed = constrain(ws2812fx_speed, 0, 255);
|
ws2812fx_speed = constrain(ws2812fx_speed, 0, 255);
|
||||||
strip.setSpeed(convertSpeed(ws2812fx_speed));
|
strip.setSpeed(convertSpeed(ws2812fx_speed));
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String(String("OK ?") + String(ws2812fx_speed)).c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ?") + String(ws2812fx_speed)).c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
getStatusJSON();
|
getStatusJSON();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -511,6 +599,18 @@ void setup() {
|
||||||
mode = OFF;
|
mode = OFF;
|
||||||
getArgs();
|
getArgs();
|
||||||
getStatusJSON();
|
getStatusJSON();
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String("OK =off").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =off").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
stateOn = false;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/all", []() {
|
server.on("/all", []() {
|
||||||
|
@ -518,6 +618,18 @@ void setup() {
|
||||||
mode = ALL;
|
mode = ALL;
|
||||||
getArgs();
|
getArgs();
|
||||||
getStatusJSON();
|
getStatusJSON();
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String("OK =all").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =all").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
stateOn = true;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/wipe", []() {
|
server.on("/wipe", []() {
|
||||||
|
@ -525,6 +637,18 @@ void setup() {
|
||||||
mode = WIPE;
|
mode = WIPE;
|
||||||
getArgs();
|
getArgs();
|
||||||
getStatusJSON();
|
getStatusJSON();
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String("OK =wipe").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =wipe").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
stateOn = true;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/rainbow", []() {
|
server.on("/rainbow", []() {
|
||||||
|
@ -532,6 +656,18 @@ void setup() {
|
||||||
mode = RAINBOW;
|
mode = RAINBOW;
|
||||||
getArgs();
|
getArgs();
|
||||||
getStatusJSON();
|
getStatusJSON();
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String("OK =rainbow").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =rainbow").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
stateOn = true;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/rainbowCycle", []() {
|
server.on("/rainbowCycle", []() {
|
||||||
|
@ -539,6 +675,18 @@ void setup() {
|
||||||
mode = RAINBOWCYCLE;
|
mode = RAINBOWCYCLE;
|
||||||
getArgs();
|
getArgs();
|
||||||
getStatusJSON();
|
getStatusJSON();
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String("OK =rainbowCycle").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =rainbowCycle").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
stateOn = true;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/theaterchase", []() {
|
server.on("/theaterchase", []() {
|
||||||
|
@ -546,13 +694,56 @@ void setup() {
|
||||||
mode = THEATERCHASE;
|
mode = THEATERCHASE;
|
||||||
getArgs();
|
getArgs();
|
||||||
getStatusJSON();
|
getStatusJSON();
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String("OK =theaterchase").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =theaterchase").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
stateOn = true;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.on("/twinkleRandom", []() {
|
||||||
|
exit_func = true;
|
||||||
|
mode = TWINKLERANDOM;
|
||||||
|
getArgs();
|
||||||
|
getStatusJSON();
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String("OK =twinkleRandom").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =twinkleRandom").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
stateOn = true;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||||
|
#endif
|
||||||
|
});
|
||||||
|
|
||||||
server.on("/theaterchaseRainbow", []() {
|
server.on("/theaterchaseRainbow", []() {
|
||||||
exit_func = true;
|
exit_func = true;
|
||||||
mode = THEATERCHASERAINBOW;
|
mode = THEATERCHASERAINBOW;
|
||||||
getArgs();
|
getArgs();
|
||||||
getStatusJSON();
|
getStatusJSON();
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String("OK =theaterchaseRainbow").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =theaterchaseRainbow").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
stateOn = true;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/tv", []() {
|
server.on("/tv", []() {
|
||||||
|
@ -560,6 +751,18 @@ void setup() {
|
||||||
mode = TV;
|
mode = TV;
|
||||||
getArgs();
|
getArgs();
|
||||||
getStatusJSON();
|
getStatusJSON();
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String("OK =tv").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =tv").c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
stateOn = true;
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/get_modes", []() {
|
server.on("/get_modes", []() {
|
||||||
|
@ -570,20 +773,40 @@ void setup() {
|
||||||
getArgs();
|
getArgs();
|
||||||
mode = SET_MODE;
|
mode = SET_MODE;
|
||||||
getStatusJSON();
|
getStatusJSON();
|
||||||
|
|
||||||
|
#ifdef ENABLE_MQTT
|
||||||
|
mqtt_client.publish(mqtt_outtopic, String(String("OK /") + String(ws2812fx_mode).c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK /") + String(ws2812fx_mode)).c_str());
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
stateOn = true;
|
||||||
|
if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState);
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if(!spiffs_save_state.active()) spiffs_save_state.once(3, tickerSpiffsSaveState);
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef HTTP_OTA
|
#ifdef HTTP_OTA
|
||||||
httpUpdater.setup(&server,"/update");
|
httpUpdater.setup(&server,"/update");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HTTP_OTA
|
||||||
|
httpUpdater.setup(&server, "/update");
|
||||||
|
#endif
|
||||||
|
|
||||||
server.begin();
|
server.begin();
|
||||||
|
|
||||||
// Start MDNS service
|
// Start MDNS service
|
||||||
if (mdns_result) {
|
if (mdns_result) {
|
||||||
MDNS.addService("http", "tcp", 80);
|
MDNS.addService("http", "tcp", 80);
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
#ifdef ENABLE_STATE_SAVE
|
(readStateFS()) ? DBG_OUTPUT_PORT.println(" Success!") : DBG_OUTPUT_PORT.println(" Failure!");
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_EEPROM
|
||||||
// Load state string from EEPROM
|
// Load state string from EEPROM
|
||||||
String saved_state_string = readEEPROM(256, 32);
|
String saved_state_string = readEEPROM(256, 32);
|
||||||
String chk = getValue(saved_state_string, '|', 0);
|
String chk = getValue(saved_state_string, '|', 0);
|
||||||
|
@ -599,24 +822,43 @@ void setup() {
|
||||||
void loop() {
|
void loop() {
|
||||||
#ifdef ENABLE_BUTTON
|
#ifdef ENABLE_BUTTON
|
||||||
button();
|
button();
|
||||||
#endif
|
#endif
|
||||||
server.handleClient();
|
server.handleClient();
|
||||||
webSocket.loop();
|
webSocket.loop();
|
||||||
|
|
||||||
#ifdef ENABLE_OTA
|
#ifdef ENABLE_OTA
|
||||||
ArduinoOTA.handle();
|
ArduinoOTA.handle();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_MQTT
|
#ifdef ENABLE_MQTT
|
||||||
if (mqtt_host != "" && String(mqtt_port).toInt() > 0 && mqtt_reconnect_retries < MQTT_MAX_RECONNECT_TRIES) {
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
if (!mqtt_client.connected()) {
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
mqtt_reconnect();
|
ha_send_data.detach();
|
||||||
} else {
|
#endif
|
||||||
mqtt_client.loop();
|
DBG_OUTPUT_PORT.println("WiFi disconnected, reconnecting!");
|
||||||
|
WiFi.disconnect();
|
||||||
|
WiFi.setSleepMode(WIFI_NONE_SLEEP);
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.begin();
|
||||||
|
} else {
|
||||||
|
if (mqtt_host != "" && String(mqtt_port).toInt() > 0 && mqtt_reconnect_retries < MQTT_MAX_RECONNECT_TRIES) {
|
||||||
|
if (!mqtt_client.connected()) {
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
ha_send_data.detach();
|
||||||
|
#endif
|
||||||
|
DBG_OUTPUT_PORT.println("MQTT disconnected, reconnecting!");
|
||||||
|
mqtt_reconnect();
|
||||||
|
} else {
|
||||||
|
mqtt_client.loop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
|
// if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState);
|
||||||
|
if (new_ha_mqtt_msg) sendState();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Simple statemachine that handles the different modes
|
// Simple statemachine that handles the different modes
|
||||||
if (mode == SET_MODE) {
|
if (mode == SET_MODE) {
|
||||||
DBG_OUTPUT_PORT.printf("SET_MODE: %d %d\n", ws2812fx_mode, mode);
|
DBG_OUTPUT_PORT.printf("SET_MODE: %d %d\n", ws2812fx_mode, mode);
|
||||||
|
@ -624,8 +866,9 @@ void loop() {
|
||||||
mode = HOLD;
|
mode = HOLD;
|
||||||
}
|
}
|
||||||
if (mode == OFF) {
|
if (mode == OFF) {
|
||||||
strip.setColor(0,0,0);
|
// strip.setColor(0,0,0);
|
||||||
strip.setMode(FX_MODE_STATIC);
|
// strip.setMode(FX_MODE_STATIC);
|
||||||
|
if(strip.isRunning()) strip.stop(); //should clear memory
|
||||||
// mode = HOLD;
|
// mode = HOLD;
|
||||||
}
|
}
|
||||||
if (mode == ALL) {
|
if (mode == ALL) {
|
||||||
|
@ -633,6 +876,18 @@ void loop() {
|
||||||
strip.setMode(FX_MODE_STATIC);
|
strip.setMode(FX_MODE_STATIC);
|
||||||
mode = HOLD;
|
mode = HOLD;
|
||||||
}
|
}
|
||||||
|
if (mode == SETCOLOR) {
|
||||||
|
strip.setColor(main_color.red, main_color.green, main_color.blue);
|
||||||
|
mode = HOLD;
|
||||||
|
}
|
||||||
|
if (mode == SETSPEED) {
|
||||||
|
strip.setSpeed(convertSpeed(ws2812fx_speed));
|
||||||
|
// mode = HOLD;
|
||||||
|
}
|
||||||
|
if (mode == BRIGHTNESS) {
|
||||||
|
strip.setBrightness(brightness);
|
||||||
|
mode = HOLD;
|
||||||
|
}
|
||||||
if (mode == WIPE) {
|
if (mode == WIPE) {
|
||||||
strip.setColor(main_color.red, main_color.green, main_color.blue);
|
strip.setColor(main_color.red, main_color.green, main_color.blue);
|
||||||
strip.setMode(FX_MODE_COLOR_WIPE);
|
strip.setMode(FX_MODE_COLOR_WIPE);
|
||||||
|
@ -661,11 +916,13 @@ void loop() {
|
||||||
mode = HOLD;
|
mode = HOLD;
|
||||||
}
|
}
|
||||||
if (mode == HOLD || mode == CUSTOM) {
|
if (mode == HOLD || mode == CUSTOM) {
|
||||||
|
if(!strip.isRunning()) strip.start();
|
||||||
if (exit_func) {
|
if (exit_func) {
|
||||||
exit_func = false;
|
exit_func = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mode == TV) {
|
if (mode == TV) {
|
||||||
|
if(!strip.isRunning()) strip.start();
|
||||||
tv();
|
tv();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -674,11 +931,16 @@ void loop() {
|
||||||
strip.service();
|
strip.service();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
if (updateStateFS) {
|
||||||
|
(writeStateFS()) ? DBG_OUTPUT_PORT.println(" Success!") : DBG_OUTPUT_PORT.println(" Failure!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_STATE_SAVE
|
#ifdef ENABLE_STATE_SAVE_EEPROM
|
||||||
// Check for state changes
|
// Check for state changes
|
||||||
sprintf(current_state, "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d", mode, strip.getMode(), ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue);
|
sprintf(current_state, "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d", mode, strip.getMode(), ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue);
|
||||||
|
|
||||||
if (strcmp(current_state, last_state) != 0) {
|
if (strcmp(current_state, last_state) != 0) {
|
||||||
// DBG_OUTPUT_PORT.printf("STATE CHANGED: %s / %s\n", last_state, current_state);
|
// DBG_OUTPUT_PORT.printf("STATE CHANGED: %s / %s\n", last_state, current_state);
|
||||||
strcpy(last_state, current_state);
|
strcpy(last_state, current_state);
|
||||||
|
|
|
@ -1,16 +1,31 @@
|
||||||
|
//#define USE_NEOANIMATIONFX // Uses NeoAnimationFX, PIN is ignored & set to RX/GPIO3
|
||||||
|
#define USE_WS2812FX // Uses WS2812FX
|
||||||
|
|
||||||
// Neopixel
|
// Neopixel
|
||||||
#define PIN 5 // PIN (5 / D1) where neopixel / WS2811 strip is attached
|
#define PIN 5 // PIN (14 / D5) where neopixel / WS2811 strip is attached
|
||||||
#define NUMLEDS 24 // Number of leds in the strip
|
#define NUMLEDS 24 // Number of leds in the strip
|
||||||
// #define BUILTIN_LED 2 // ESP-12F has the built in LED on GPIO2, see https://github.com/esp8266/Arduino/issues/2192
|
#define BUILTIN_LED 2 // ESP-12F has the built in LED on GPIO2, see https://github.com/esp8266/Arduino/issues/2192
|
||||||
#define BUTTON 4 // Input pin (4 / D2) for switching the LED strip on / off, connect this PIN to ground to trigger button.
|
#define BUTTON 4 // Input pin (4 / D2) for switching the LED strip on / off, connect this PIN to ground to trigger button.
|
||||||
|
|
||||||
const char HOSTNAME[] = "McLighting01"; // Friedly hostname
|
const char HOSTNAME[] = "McLighting01"; // Friedly hostname
|
||||||
|
|
||||||
//#define HTTP_OTA // If defined, enable Added ESP8266HTTPUpdateServer
|
|
||||||
#define ENABLE_OTA // If defined, enable Arduino OTA code.
|
#define ENABLE_OTA // If defined, enable Arduino OTA code.
|
||||||
#define ENABLE_MQTT // If defined, enable MQTT client code, see: https://github.com/toblum/McLighting/wiki/MQTT-API
|
#define ENABLE_MQTT // If defined, enable MQTT client code, see: https://github.com/toblum/McLighting/wiki/MQTT-API
|
||||||
#define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT must be active
|
#define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT must be active
|
||||||
// #define ENABLE_BUTTON // If defined, enable button handling code, see: https://github.com/toblum/McLighting/wiki/Button-control
|
#define ENABLE_BUTTON // If defined, enable button handling code, see: https://github.com/toblum/McLighting/wiki/Button-control
|
||||||
|
|
||||||
|
#if defined(USE_NEOANIMATIONFX) and defined(USE_WS2812FX)
|
||||||
|
#error "Cant have both NeoAnimationFX and WS2812FX enabled. Choose either one."
|
||||||
|
#endif
|
||||||
|
#if !defined(USE_NEOANIMATIONFX) and !defined(USE_WS2812FX)
|
||||||
|
#error "Need to either use NeoAnimationFX and WS2812FX mode."
|
||||||
|
#endif
|
||||||
|
#if defined(ENABLE_MQTT) and defined(ENABLE_AMQTT)
|
||||||
|
#error "Cant have both PubSubClient and AsyncMQTT enabled. Choose either one."
|
||||||
|
#endif
|
||||||
|
#if ( (defined(ENABLE_HOMEASSISTANT) and !defined(ENABLE_MQTT)) and (defined(ENABLE_HOMEASSISTANT) and !defined(ENABLE_AMQTT)) )
|
||||||
|
#error "To use HA, you have to either enable PubCubClient or AsyncMQTT"
|
||||||
|
#endif
|
||||||
|
|
||||||
// parameters for automatically cycling favorite patterns
|
// parameters for automatically cycling favorite patterns
|
||||||
uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds)
|
uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds)
|
||||||
|
@ -20,33 +35,44 @@ uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds)
|
||||||
{0x0000ff, 200, 42, 15.0} // fireworks for 15 seconds
|
{0x0000ff, 200, 42, 15.0} // fireworks for 15 seconds
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_MQTT
|
#if defined(ENABLE_MQTT) or defined(ENABLE_AMQTT)
|
||||||
#define MQTT_MAX_PACKET_SIZE 512
|
#ifdef ENABLE_MQTT
|
||||||
#define MQTT_MAX_RECONNECT_TRIES 4
|
#define MQTT_MAX_PACKET_SIZE 512
|
||||||
|
#define MQTT_MAX_RECONNECT_TRIES 4
|
||||||
|
|
||||||
int mqtt_reconnect_retries = 0;
|
int mqtt_reconnect_retries = 0;
|
||||||
char mqtt_intopic[strlen(HOSTNAME) + 4 + 5]; // Topic in will be: <HOSTNAME>/in
|
char mqtt_intopic[strlen(HOSTNAME) + 4 + 5]; // Topic in will be: <HOSTNAME>/in
|
||||||
char mqtt_outtopic[strlen(HOSTNAME) + 5 + 5]; // Topic out will be: <HOSTNAME>/out
|
char mqtt_outtopic[strlen(HOSTNAME) + 5 + 5]; // Topic out will be: <HOSTNAME>/out
|
||||||
|
uint8_t qossub = 0; // PubSubClient can sub qos 0 or 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_AMQTT
|
||||||
|
String mqtt_intopic = String(HOSTNAME) + "/in";
|
||||||
|
String mqtt_outtopic = String(HOSTNAME) + "/out";
|
||||||
|
uint8_t qossub = 0; // AMQTT can sub qos 0 or 1 or 2
|
||||||
|
uint8_t qospub = 0; // AMQTT can pub qos 0 or 1 or 2
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_HOMEASSISTANT
|
#ifdef ENABLE_HOMEASSISTANT
|
||||||
String mqtt_ha = "home/" + String(HOSTNAME) + "_ha/";
|
String mqtt_ha = "home/" + String(HOSTNAME) + "_ha/";
|
||||||
String mqtt_ha_state_in = mqtt_ha + "state/in";
|
String mqtt_ha_state_in = mqtt_ha + "state/in";
|
||||||
String mqtt_ha_state_out = mqtt_ha + "state/out";
|
String mqtt_ha_state_out = mqtt_ha + "state/out";
|
||||||
String mqtt_ha_speed = mqtt_ha + "speed";
|
|
||||||
|
|
||||||
const char* on_cmd = "ON";
|
const char* on_cmd = "ON";
|
||||||
const char* off_cmd = "OFF";
|
const char* off_cmd = "OFF";
|
||||||
bool stateOn = false;
|
bool stateOn = false;
|
||||||
bool animation_on = false;
|
bool animation_on = false;
|
||||||
String effectString = "Static";
|
bool new_ha_mqtt_msg = false;
|
||||||
|
uint16_t color_temp = 327; // min is 154 and max is 500
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char * mqtt_clientid = HOSTNAME; // Set ClientID to HOSTNAME to be unique
|
const char mqtt_clientid[] = "NeoPixelsStrip"; // MQTT ClientID
|
||||||
|
|
||||||
|
char mqtt_host[64] = "";
|
||||||
|
char mqtt_port[6] = "";
|
||||||
|
char mqtt_user[32] = "";
|
||||||
|
char mqtt_pass[32] = "";
|
||||||
|
|
||||||
char mqtt_host[64] = "";
|
|
||||||
char mqtt_port[6] = "";
|
|
||||||
char mqtt_user[32] = "";
|
|
||||||
char mqtt_pass[32] = "";
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,7 +82,7 @@ uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds)
|
||||||
#define DBG_OUTPUT_PORT Serial // Set debug output port
|
#define DBG_OUTPUT_PORT Serial // Set debug output port
|
||||||
|
|
||||||
// List of all color modes
|
// List of all color modes
|
||||||
enum MODE { SET_MODE, HOLD, OFF, ALL, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW, TV, CUSTOM };
|
enum MODE { SET_MODE, HOLD, OFF, ALL, SETCOLOR, SETSPEED, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW, TV, CUSTOM };
|
||||||
|
|
||||||
MODE mode = RAINBOW; // Standard mode that is active when software starts
|
MODE mode = RAINBOW; // Standard mode that is active when software starts
|
||||||
|
|
||||||
|
@ -80,14 +106,18 @@ typedef struct ledstate LEDState; // Define the datatype LEDState
|
||||||
LEDState ledstates[NUMLEDS]; // Get an array of led states to store the state of the whole strip
|
LEDState ledstates[NUMLEDS]; // Get an array of led states to store the state of the whole strip
|
||||||
LEDState main_color = { 255, 0, 0 }; // Store the "main color" of the strip used in single color modes
|
LEDState main_color = { 255, 0, 0 }; // Store the "main color" of the strip used in single color modes
|
||||||
|
|
||||||
#define ENABLE_STATE_SAVE // If defined, save state on reboot
|
#define ENABLE_STATE_SAVE_SPIFFS // If defined, saves state on SPIFFS
|
||||||
#ifdef ENABLE_STATE_SAVE
|
//#define ENABLE_STATE_SAVE_EEPROM // If defined, save state on reboot
|
||||||
|
#ifdef ENABLE_STATE_SAVE_EEPROM
|
||||||
char current_state[32]; // Keeps the current state representation
|
char current_state[32]; // Keeps the current state representation
|
||||||
char last_state[32]; // Save the last state as string representation
|
char last_state[32]; // Save the last state as string representation
|
||||||
unsigned long time_statechange = 0; // Time when the state last changed
|
unsigned long time_statechange = 0; // Time when the state last changed
|
||||||
int timeout_statechange_save = 5000; // Timeout in ms to wait before state is saved
|
int timeout_statechange_save = 5000; // Timeout in ms to wait before state is saved
|
||||||
bool state_save_requested = false; // State has to be saved after timeout
|
bool state_save_requested = false; // State has to be saved after timeout
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_STATE_SAVE_SPIFFS
|
||||||
|
bool updateStateFS = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Button handling
|
// Button handling
|
||||||
#ifdef ENABLE_BUTTON
|
#ifdef ENABLE_BUTTON
|
||||||
|
@ -102,4 +132,14 @@ LEDState main_color = { 255, 0, 0 }; // Store the "main color" of the strip use
|
||||||
byte KeyPressCount = 0;
|
byte KeyPressCount = 0;
|
||||||
byte prevKeyState = HIGH; // button is active low
|
byte prevKeyState = HIGH; // button is active low
|
||||||
boolean buttonState = false;
|
boolean buttonState = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define PIN 14 // PIN (14 / D5) where neopixel / WS2811 strip is attached
|
||||||
|
#define NUMLEDS 300 // Number of leds in the strip
|
||||||
|
#define BUILTIN_LED 2 // ESP-12F has the built in LED on GPIO2, see https://github.com/esp8266/Arduino/issues/2192
|
||||||
|
#define BUTTON 0 // Input pin (4 / D2) for switching the LED strip on / off, connect this PIN to ground to trigger button.
|
||||||
|
#define HTTP_OTA // If defined, enable ESP8266HTTPUpdateServer OTA code.
|
||||||
|
//#define ENABLE_OTA // If defined, enable Arduino OTA code.
|
||||||
|
#define ENABLE_AMQTT // If defined, enable Async MQTT code, see: https://github.com/marvinroger/async-mqtt-client
|
||||||
|
//#define ENABLE_MQTT // If defined, enable MQTT client code, see: https://github.com/toblum/McLighting/wiki/MQTT-API
|
||||||
|
const char * mqtt_clientid = HOSTNAME; // Set ClientID to HOSTNAME to be unique
|
File diff suppressed because it is too large
Load diff
|
@ -3,6 +3,7 @@ light:
|
||||||
name: "NeoPixel LEDs"
|
name: "NeoPixel LEDs"
|
||||||
state_topic: "home/McLighting01_ha/state/out"
|
state_topic: "home/McLighting01_ha/state/out"
|
||||||
command_topic: "home/McLighting01_ha/state/in"
|
command_topic: "home/McLighting01_ha/state/in"
|
||||||
|
on_command_type: 'first'
|
||||||
effect: true
|
effect: true
|
||||||
effect_list:
|
effect_list:
|
||||||
######
|
######
|
||||||
|
@ -62,6 +63,7 @@ light:
|
||||||
- "Tricolor Chase"
|
- "Tricolor Chase"
|
||||||
- "ICU"
|
- "ICU"
|
||||||
brightness: true
|
brightness: true
|
||||||
|
color_temp: true
|
||||||
rgb: true
|
rgb: true
|
||||||
optimistic: false
|
optimistic: false
|
||||||
qos: 0
|
qos: 0
|
||||||
|
@ -77,7 +79,7 @@ input_number:
|
||||||
|
|
||||||
automation:
|
automation:
|
||||||
- id: 71938579813759813757
|
- id: 71938579813759813757
|
||||||
alias: NeoPixel Animation Speed
|
alias: NeoPixel Animation Speed Send
|
||||||
initial_state: true
|
initial_state: true
|
||||||
hide_entity: false
|
hide_entity: false
|
||||||
trigger:
|
trigger:
|
||||||
|
@ -85,7 +87,18 @@ automation:
|
||||||
platform: state
|
platform: state
|
||||||
action:
|
action:
|
||||||
- data_template:
|
- data_template:
|
||||||
payload_template: '{{ trigger.to_state.state | int }}'
|
payload_template: '{"speed": {{ trigger.to_state.state | int }}}'
|
||||||
retain: true
|
retain: true
|
||||||
topic: home/McLighting01_ha/speed
|
topic: home/McLighting01_ha/state/in
|
||||||
service: mqtt.publish
|
service: mqtt.publish
|
||||||
|
|
||||||
|
- id: 93786598732698756967
|
||||||
|
alias: NeoPixel Animation Speed Receive
|
||||||
|
trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: home/McLighting01_ha/state/out
|
||||||
|
action:
|
||||||
|
- data_template:
|
||||||
|
entity_id: input_number.neopixel_animation_speed
|
||||||
|
value: '{{ trigger.payload_json.speed | int }}'
|
||||||
|
service: input_number.set_value
|
Loading…
Reference in a new issue