Added MQTT and WiFi support.

This commit is contained in:
Fabian Schlenz 2021-01-08 05:54:55 +01:00
parent fa888bcfab
commit bfc5f1dffe
9 changed files with 167 additions and 11 deletions

View File

@ -22,4 +22,16 @@
#define MAX_MILLIAMPS 1000 #define MAX_MILLIAMPS 1000
#define WIFI_SSID "..."
#define WIFI_PASS "..."
#define MQTT_CLIENT_ID "espleaf"
#define MQTT_USER "..."
#define MQTT_PASS "..."
#define MQTT_SERVER "..."
#define MQTT_SERVER_PORT 1883
#define MQTT_TOPIC_STATE "espleaf/state"
#define MQTT_TOPIC_STATE_LONG "espleaf/state_long"
#define MQTT_TOPIC_COMMANDS "esplead/cmnd"
//#define TEST_MODE //#define TEST_MODE

37
include/config.sample.h Normal file
View File

@ -0,0 +1,37 @@
#pragma once
#define CORNERS_PER_PART 3
#define LEDS_PER_CORNER 2
// Layout definition
// Every node has EDGES_PER_PART corners and edges.
// The edge the signal comes in is edge number 0.
// All other edges are numbered counter-clockwise.
// LAYOUT contains a list of edges the signal takes.
// First node is implied.
// Examples, assuming EDGES_PER_PART == 3:
// Example: Nodes arranged in a circle: {1, 2, 2, 2, 2}
// Example: Nodes arranged in a line: {1, 2, 1, 2, 1, 2}
#define NODE_COUNT 5
#define LAYOUT {2, 1, 1, 2}
#define LED_COUNT NODE_COUNT * CORNERS_PER_PART * LEDS_PER_CORNER
#define SPEEDUP 1
#define MAX_MILLIAMPS 1000
#define WIFI_SSID "..."
#define WIFI_PASS "..."
#define MQTT_CLIENT_ID "espleaf"
#define MQTT_USER "..."
#define MQTT_PASS "..."
#define MQTT_SERVER "..."
#define MQTT_SERVER_PORT 1883
#define MQTT_TOPIC_STATE "espleaf/state"
#define MQTT_TOPIC_STATE_LONG "espleaf/state_long"
#define MQTT_TOPIC_COMMANDS "esplead/cmnd"
//#define TEST_MODE

10
include/mqtt.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include "wifi.h"
#include "config.h"
#include <PubSubClient.h>
static PubSubClient mqtt(wifi);
void mqtt_setup();
void mqtt_loop();

View File

@ -21,3 +21,8 @@ enum AnimationMode {
AM_FIRST_NODE, AM_FIRST_NODE,
AM_FLASH AM_FLASH
}; };
extern AnimationMode mode;
extern AnimationMode temp_mode;
extern unsigned long temp_mode_until;

8
include/wifi.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#include <ESP8266WiFi.h>
#include "config.h"
static WiFiClient wifi;
void wifi_setup();

View File

@ -17,4 +17,5 @@ upload_speed = 921600
monitor_port = /dev/cu.wchusbserial* monitor_port = /dev/cu.wchusbserial*
monitor_speed = 74880 monitor_speed = 74880
monitor_filters = default, time, send_on_enter, esp8266_exception_decoder monitor_filters = default, time, send_on_enter, esp8266_exception_decoder
lib_deps = FastLED lib_deps = fastled/FastLED @ 3.4.0
PubSubClient

View File

@ -7,6 +7,7 @@
#include "edge.h" #include "edge.h"
#include "corner.h" #include "corner.h"
#include "prototypes.h" #include "prototypes.h"
#include "mqtt.h"
std::vector<Node*> nodes; std::vector<Node*> nodes;
std::list<Edge*> edges; std::list<Edge*> edges;
@ -15,6 +16,8 @@ std::vector<Corner*> corners;
CRGB leds[LED_COUNT]; CRGB leds[LED_COUNT];
AnimationMode mode = AM_CORNERS; AnimationMode mode = AM_CORNERS;
AnimationMode temp_mode;
unsigned long temp_mode_until;
unsigned long last_loop = 0; unsigned long last_loop = 0;
@ -76,7 +79,7 @@ void setup_fastled() {
set_all_leds(CRGB::Black); set_all_leds(CRGB::Black);
} }
void setup_wifi() { void setup_rng() {
LOGln("Starting WiFi scan for RNG initialization..."); LOGln("Starting WiFi scan for RNG initialization...");
WiFi.mode(WIFI_STA); WiFi.mode(WIFI_STA);
WiFi.disconnect(); WiFi.disconnect();
@ -97,11 +100,15 @@ void setup() {
setup_layout(); setup_layout();
setup_fastled(); setup_fastled();
setup_wifi();
#ifdef TEST_MODE #ifdef TEST_MODE
LOGln("TEST_MODE is active!"); LOGln("TEST_MODE is active!");
#else
setup_rng();
wifi_setup();
mqtt_setup();
#endif #endif
} }
void loop() { void loop() {
@ -119,13 +126,23 @@ void loop() {
} }
#else #else
// Normal mode // Normal mode
mqtt_loop();
EVERY_N_MILLISECONDS(20 / SPEEDUP) { EVERY_N_MILLISECONDS(20 / SPEEDUP) {
looping = false; looping = false;
if (mode == AM_CORNERS || mode == AM_FIRST_CORNER) { AnimationMode active_mode = mode;
if (temp_mode_until > 0) {
if (temp_mode_until>millis()) {
active_mode = temp_mode;
} else {
temp_mode_until = 0;
}
}
if (active_mode == AM_CORNERS || active_mode == AM_FIRST_CORNER) {
for(Corner* corner: corners) { for(Corner* corner: corners) {
corner->step(); corner->step();
if (mode == AM_FIRST_CORNER) { if (active_mode == AM_FIRST_CORNER) {
corner->infect(512, 512); corner->infect(512, 512);
} else { } else {
corner->infect(300, 600); corner->infect(300, 600);
@ -135,13 +152,13 @@ void loop() {
} }
if (random8(128)==0) { if (random8(128)==0) {
if (mode == AM_FIRST_CORNER) { if (active_mode == AM_FIRST_CORNER) {
corners[0]->blend_to(CHSV(random8(), 255, 255)); corners[0]->blend_to(CHSV(random8(), 255, 255));
} else { } else {
corners[random16(corners.size())]->blend_to(CHSV(random8(), 255, 255)); corners[random16(corners.size())]->blend_to(CHSV(random8(), 255, 255));
} }
} }
} else if (mode == AM_NODES || mode == AM_FIRST_NODE) { } else if (active_mode == AM_NODES || active_mode == AM_FIRST_NODE) {
for(Node* node : nodes) { for(Node* node : nodes) {
node->step(); node->step();
node->infect(512); node->infect(512);
@ -149,13 +166,13 @@ void loop() {
} }
if (random8(128)==0) { if (random8(128)==0) {
if (mode == AM_FIRST_NODE) { if (active_mode == AM_FIRST_NODE) {
nodes[0]->blend_to(CHSV(random8(), 255, 255)); nodes[0]->blend_to(CHSV(random8(), 255, 255));
} else { } else {
nodes[random8(nodes.size())]->blend_to(CHSV(random8(), 255, 255)); nodes[random8(nodes.size())]->blend_to(CHSV(random8(), 255, 255));
} }
} }
} else if (mode == AM_FLASH) { } else if (active_mode == AM_FLASH) {
for (Node* node : nodes) { for (Node* node : nodes) {
node->step(); node->step();
node->infect(512); node->infect(512);

53
src/mqtt.cpp Normal file
View File

@ -0,0 +1,53 @@
#include "mqtt.h"
#include "tools.h"
#include "prototypes.h"
void connect() {
LOGln("Connecting to MQTT broker...");
if (mqtt.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS, MQTT_TOPIC_STATE, 0, true, "OFFLINE")) {
LOGln("Connected.");
mqtt.publish(MQTT_TOPIC_STATE, "ONLINE", true);
char buffer[40];
snprintf(buffer, 40, "ONLINE %s", wifi.localIP().toString().c_str());
mqtt.publish(MQTT_TOPIC_STATE_LONG, buffer, true);
mqtt.subscribe(MQTT_TOPIC_COMMANDS);
} else {
LOGln("Connection failed. Reason: %d", mqtt.state());
delay(1000);
}
}
void callback(char* topic, byte* pl, unsigned int length) {
pl[length] = 0;
String payload((char*)pl);
uint16_t duration = 0;
int cp = payload.indexOf(",");
if (cp != -1) {
duration = payload.substring(cp+1).toInt();
payload = payload.substring(0, cp);
}
AnimationMode am;
if (payload.equals("corners")) am = AM_CORNERS;
else if (payload.equals("nodes")) am = AM_NODES;
if (duration > 0) {
temp_mode = am;
temp_mode_until = millis() + duration*1000;
} else {
mode = am;
}
}
void mqtt_setup() {
mqtt.setServer(MQTT_SERVER, MQTT_SERVER_PORT);
mqtt.setCallback(callback);
mqtt.setSocketTimeout(1);
connect();
}
void mqtt_loop() {
if (!mqtt.connected()) {
connect();
}
mqtt.loop();
}

13
src/wifi.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "wifi.h"
#include "tools.h"
void wifi_setup() {
LOG("Connecting to WiFi %s...", WIFI_SSID);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
LOG(".");
delay(300);
}
LOGln(" Connected as %s", WiFi.localIP().toString().c_str());
}