Speed and Stability updates

If LEDs>100, stalls ESP8266. So bunch of code cleanup and merge with
existing variables used by other sections. Should be more efficient. As
of now on Arduino ESP 2.4.1, WiFi.setSleepMode(WIFI_NONE_SLEEP); is
required for MQTT function. ESP8266 is anyways connected to constant
power supply, so power consumtion is not immidiate concern now.
* HTTP OTA
* Arduino OTA
* Async MQTT
* PubSubClient
* HomeAssistant
This commit is contained in:
debsahu 2018-03-20 19:08:18 -04:00
parent 88cd8d7961
commit 583d1396b7
4 changed files with 1200 additions and 952 deletions
Arduino/McLighting
clients/HomeAssistant

View file

@ -35,6 +35,18 @@
PubSubClient mqtt_client(espClient);
#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
@ -42,6 +54,10 @@
ESP8266WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);
#ifdef HTTP_OTA
#include <ESP8266HTTPUpdateServer.h>
ESP8266HTTPUpdateServer httpUpdater;
#endif
// ***************************************************************************
// Load libraries / Instanciate WS2812FX library
@ -69,6 +85,13 @@ WS2812FX strip = WS2812FX(NUMLEDS, PIN, NEO_GRB + NEO_KHZ800);
// ***************************************************************************
#include <Ticker.h>
Ticker ticker;
#ifdef ENABLE_HOMEASSISTANT
Ticker ha_send_data;
#endif
#ifdef ENABLE_AMQTT
Ticker mqttReconnectTimer;
Ticker wifiReconnectTimer;
#endif
void tick()
{
@ -126,7 +149,6 @@ String getValue(String data, char separator, int index)
return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}
// ***************************************************************************
// Callback for WiFiManager library when config mode is entered
// ***************************************************************************
@ -167,15 +189,15 @@ void saveConfigCallback () {
// ***************************************************************************
#include "colormodes.h"
// ***************************************************************************
// MAIN
// ***************************************************************************
void setup() {
// system_update_cpu_freq(160);
DBG_OUTPUT_PORT.begin(115200);
EEPROM.begin(512);
// set builtin led pin as output
pinMode(BUILTIN_LED, OUTPUT);
// button pin setup
@ -203,7 +225,7 @@ void setup() {
// 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
#if defined(ENABLE_MQTT) or defined(ENABLE_AMQTT)
String settings_available = readEEPROM(134, 1);
if (settings_available == "1") {
readEEPROM(0, 64).toCharArray(mqtt_host, 64); // 0-63
@ -215,13 +237,12 @@ void setup() {
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
@ -230,7 +251,7 @@ void setup() {
//set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
wifiManager.setAPCallback(configModeCallback);
#ifdef ENABLE_MQTT
#if defined(ENABLE_MQTT) or defined(ENABLE_AMQTT)
//set config save notify callback
wifiManager.setSaveConfigCallback(saveConfigCallback);
@ -241,6 +262,8 @@ void setup() {
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"
@ -252,7 +275,7 @@ void setup() {
delay(1000);
}
#ifdef ENABLE_MQTT
#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());
@ -272,6 +295,11 @@ void setup() {
}
#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();
@ -336,6 +364,21 @@ void setup() {
}
#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, sendState); // Send HA data back only every 5 sec
#endif
// ***************************************************************************
// Setup: MDNS responder
@ -572,6 +615,10 @@ void setup() {
getStatusJSON();
});
#ifdef HTTP_OTA
httpUpdater.setup(&server, "/firmware", "admin", "allforfun");
#endif
server.begin();
// Start MDNS service
@ -604,11 +651,26 @@ void loop() {
#endif
#ifdef ENABLE_MQTT
if (mqtt_host != "" && String(mqtt_port).toInt() > 0 && mqtt_reconnect_retries < MQTT_MAX_RECONNECT_TRIES) {
if (!mqtt_client.connected()) {
mqtt_reconnect();
} else {
mqtt_client.loop();
if (WiFi.status() != WL_CONNECTED) {
#ifdef ENABLE_HOMEASSISTANT
ha_send_data.detach();
#endif
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
@ -629,6 +691,14 @@ void loop() {
strip.setMode(FX_MODE_STATIC);
mode = HOLD;
}
if (mode == SETCOLOR) {
strip.setColor(main_color.red, main_color.green, main_color.blue);
mode = HOLD;
}
if (mode == BRIGHTNESS) {
strip.setBrightness(brightness);
mode = HOLD;
}
if (mode == WIPE) {
strip.setColor(main_color.red, main_color.green, main_color.blue);
strip.setMode(FX_MODE_COLOR_WIPE);

View file

@ -1,15 +1,24 @@
// Neopixel
#define PIN 5 // PIN (14 / D5) where neopixel / WS2811 strip is attached
#define NUMLEDS 24 // Number of leds in the strip
#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 4 // Input pin (4 / D2) for switching the LED strip on / off, connect this PIN to ground to trigger button.
#define BUTTON 0 // 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
#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 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
#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(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
uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds)
@ -19,13 +28,20 @@ uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds)
{0x0000ff, 200, 42, 15.0} // fireworks for 15 seconds
};
#ifdef ENABLE_MQTT
#define MQTT_MAX_PACKET_SIZE 512
#define MQTT_MAX_RECONNECT_TRIES 4
#if defined(ENABLE_MQTT) or defined(ENABLE_AMQTT)
#ifdef ENABLE_MQTT
#define MQTT_MAX_PACKET_SIZE 512
#define MQTT_MAX_RECONNECT_TRIES 4
int mqtt_reconnect_retries = 0;
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
#endif
int mqtt_reconnect_retries = 0;
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
#ifdef ENABLE_AMQTT
String mqtt_intopic = String(HOSTNAME) + "/in";
String mqtt_outtopic = String(HOSTNAME) + "/out";
#endif
#ifdef ENABLE_HOMEASSISTANT
String mqtt_ha = "home/" + String(HOSTNAME) + "_ha/";
@ -37,15 +53,17 @@ uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds)
const char* off_cmd = "OFF";
bool stateOn = false;
bool animation_on = false;
String effectString = "Static";
bool new_ha_mqtt_msg = true;
uint16_t color_temp = 327; // min is 154 and max is 500
#endif
const char mqtt_clientid[] = "NeoPixelStrip01"; // MQTT ClientID
char mqtt_host[64] = "";
char mqtt_port[6] = "";
char mqtt_user[32] = "";
char mqtt_pass[32] = "";
const char mqtt_clientid[] = "NeoPixelsStrip"; // MQTT ClientID
char mqtt_host[64] = "";
char mqtt_port[6] = "";
char mqtt_user[32] = "";
char mqtt_pass[32] = "";
#endif
@ -55,7 +73,7 @@ uint32_t autoParams[][4] = { // color, speed, mode, duration (seconds)
#define DBG_OUTPUT_PORT Serial // Set debug output port
// 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, BRIGHTNESS, WIPE, RAINBOW, RAINBOWCYCLE, THEATERCHASE, TWINKLERANDOM, THEATERCHASERAINBOW, TV, CUSTOM };
MODE mode = RAINBOW; // Standard mode that is active when software starts

File diff suppressed because it is too large Load diff

View file

@ -3,6 +3,7 @@ light:
name: "NeoPixel LEDs"
state_topic: "home/McLighting01_ha/state/out"
command_topic: "home/McLighting01_ha/state/in"
on_command_type: 'first'
effect: true
effect_list:
######
@ -62,6 +63,7 @@ light:
- "Tricolor Chase"
- "ICU"
brightness: true
color_temp: true
rgb: true
optimistic: false
qos: 0