Adding to repo
This commit is contained in:
65
00_prologue.ino
Normal file
65
00_prologue.ino
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Libraries and global scope code
|
||||
*/
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <time.h>
|
||||
|
||||
BearSSL::WiFiClientSecure net;
|
||||
time_t now;
|
||||
unsigned long lastMillis = 0;
|
||||
|
||||
String devname; // Device identifier for MQTT
|
||||
|
||||
struct Settings {
|
||||
String name = "";
|
||||
String ip = "";
|
||||
uint8_t mode = 0, // Current animation effect
|
||||
offset = 0,
|
||||
brightness = 20; // Default brightness (range 0-255)
|
||||
long color = 0x00A4B3; // Starting color
|
||||
} settings;
|
||||
|
||||
struct State {
|
||||
String text = "";
|
||||
uint8_t mode = 0;
|
||||
long color = 0x00A4B3; // Starting color
|
||||
} state;
|
||||
|
||||
/*
|
||||
* Debugging might be nice sometimes
|
||||
*/
|
||||
#define USE_SERIAL //uncomment for Serial debugging statements
|
||||
bool serialinitialised = false;
|
||||
|
||||
char printbuffer[100];
|
||||
|
||||
void PRINT_SERIAL(const String& line) {
|
||||
#ifdef USE_SERIAL
|
||||
if(!serialinitialised){
|
||||
Serial.begin(115200);
|
||||
serialinitialised = true;
|
||||
}
|
||||
Serial.print(settings.ip + " " + settings.name + " ");
|
||||
Serial.print(line);
|
||||
#endif
|
||||
}
|
||||
void APPEND_SERIAL(const String& line) {
|
||||
#ifdef USE_SERIAL
|
||||
Serial.print(line);
|
||||
#endif
|
||||
}
|
||||
void PRINTLN_SERIAL(const String& line) {
|
||||
#ifdef USE_SERIAL
|
||||
PRINT_SERIAL(line);
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
void APPENDLN_SERIAL(const String& line) {
|
||||
#ifdef USE_SERIAL
|
||||
Serial.println(line);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define NOP __asm__ __volatile__ ("nop\n")
|
||||
1
10_wlan_conf.ino
Normal file
1
10_wlan_conf.ino
Normal file
@@ -0,0 +1 @@
|
||||
// Future use
|
||||
1
20_interface_webui.ino
Normal file
1
20_interface_webui.ino
Normal file
@@ -0,0 +1 @@
|
||||
// Future use
|
||||
158
30_interface_mqtt.ino
Normal file
158
30_interface_mqtt.ino
Normal file
@@ -0,0 +1,158 @@
|
||||
#ifdef ENABLE_MQTT
|
||||
|
||||
/*
|
||||
* Define a function newcmd in your module to be able to accept mqtt commands
|
||||
* Syntax and parameters are like this:
|
||||
*/
|
||||
void newcmd(String cmd);
|
||||
void module_message(const String& shorttopic, const String& message);
|
||||
|
||||
#include <PubSubClient.h>
|
||||
|
||||
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
|
||||
PubSubClient mqtt(net);
|
||||
String deviceprefix;
|
||||
|
||||
const char* fingerprint = "EA:2A:2B:80:C1:00:57:35:66:26:FF:FC:FA:27:EA:5F:3D:91:5A:F9";
|
||||
|
||||
long logtimerMillis = 0;
|
||||
|
||||
void mqtt_subscribe(const String& topic) {
|
||||
mqtt.subscribe(topic.c_str());
|
||||
PRINTLN_SERIAL("Subscribed to " + topic);
|
||||
}
|
||||
|
||||
void mqtt_publish(const String& topic, const String& message) {
|
||||
mqtt.publish(topic.c_str(), message.c_str());
|
||||
PRINTLN_SERIAL("Published " + topic + ": " + message);
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback routine is called when a topic we subscribed to got a message
|
||||
*/
|
||||
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
|
||||
String fulltopic((char*)0);
|
||||
String shorttopic((char*)0);
|
||||
String message((char*)0);
|
||||
|
||||
fulltopic.reserve(strlen(topic));
|
||||
fulltopic = String(topic);
|
||||
|
||||
// If deviceprefix is in topic, subtract it
|
||||
// Could do a similar thing for grouptopics if we implement them
|
||||
shorttopic.reserve(strlen(topic));
|
||||
shorttopic = String(topic);
|
||||
shorttopic.replace(deviceprefix, "");
|
||||
|
||||
// Decode message into string
|
||||
message.reserve(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
message += (char)payload[i];
|
||||
}
|
||||
PRINT_SERIAL(F("Received MQTT "));
|
||||
APPEND_SERIAL(fulltopic);
|
||||
APPEND_SERIAL(F(": "));
|
||||
APPENDLN_SERIAL(message);
|
||||
|
||||
// Deal with global topic messages
|
||||
if(fulltopic.equals(MQTT_PREFIX "ping")) {
|
||||
mqtt_publish(deviceprefix + "pong", "This is " + settings.name + " v" + FW_VERSION + " at " + settings.ip);
|
||||
|
||||
// Next quietly ignore all the things we send out ourselves
|
||||
} else if(shorttopic.equals(F("pong"))) {
|
||||
// Ignore quietly
|
||||
//NOP; // delay 62.5ns on a 16MHz AtMega
|
||||
} else if(shorttopic.equals(F("log"))) {
|
||||
// Ignore quietly
|
||||
//NOP; // delay 62.5ns on a 16MHz AtMega
|
||||
|
||||
// And now to add a catchall to hand off to other module
|
||||
} else {
|
||||
module_message(shorttopic, message);
|
||||
}
|
||||
}
|
||||
|
||||
void WifiMQTTconnect() {
|
||||
|
||||
if(WiFi.status() != WL_CONNECTED) {
|
||||
PRINTLN_SERIAL("Wifi not connected, connecting...");
|
||||
WiFi.mode(WIFI_STA); // Weird MQTT connection bug, https://github.com/knolleary/pubsubclient/issues/138#issuecomment-326113915
|
||||
WiFi.begin(WLAN_SSID, WLAN_PASS);
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
PRINTLN_SERIAL("Waiting for Wifi...");
|
||||
delay(500);
|
||||
}
|
||||
settings.ip = WiFi.localIP().toString();
|
||||
PRINTLN_SERIAL("Wifi connected");
|
||||
}
|
||||
|
||||
PRINT_SERIAL("Setting time using SNTP");
|
||||
configTime(-5 * 3600, 0, "pool.ntp.org", "time.nist.gov");
|
||||
now = time(nullptr);
|
||||
while (now < 1510592825) {
|
||||
delay(500);
|
||||
APPEND_SERIAL(".");
|
||||
now = time(nullptr);
|
||||
}
|
||||
APPENDLN_SERIAL(" done!");
|
||||
struct tm timeinfo;
|
||||
gmtime_r(&now, &timeinfo);
|
||||
PRINT_SERIAL("Current time: ");
|
||||
APPENDLN_SERIAL(asctime(&timeinfo));
|
||||
net.setInsecure(); // verification options set to none
|
||||
mqtt.setServer(MQTT_SERVER, MQTT_SERVERPORT);
|
||||
mqtt.setCallback(mqtt_callback);
|
||||
|
||||
if(!mqtt.connected()) {
|
||||
while (!mqtt.connected()) {
|
||||
PRINTLN_SERIAL("MQTT not connected, connecting...");
|
||||
|
||||
// Attempt to connect
|
||||
// Note - the default maximum packet size is 128 bytes. If the
|
||||
// combined length of clientId, username and password exceed this,
|
||||
// you will need to increase the value of MQTT_MAX_PACKET_SIZE in
|
||||
// PubSubClient.h
|
||||
if (mqtt.connect(settings.name.c_str(), MQTT_USERNAME, MQTT_PASSWORD)) {
|
||||
PRINTLN_SERIAL("MQTT connected");
|
||||
} else {
|
||||
PRINTLN_SERIAL("MQTT connection failed, rc=" + String(mqtt.state()) + "...");
|
||||
delay(10000); // @@@FIXME@@@ delays are not cool
|
||||
}
|
||||
}
|
||||
|
||||
// (re)subscribe to the topics we need
|
||||
deviceprefix = MQTT_PREFIX;
|
||||
deviceprefix = deviceprefix + settings.name + "/";
|
||||
|
||||
mqtt_subscribe(MQTT_PREFIX "ping"); // global topic: send a ping, and we will respond with some device info
|
||||
mqtt_subscribe(deviceprefix + "#");
|
||||
mqtt_publish(deviceprefix + "log", "Booting up " + settings.name + " running v" + FW_VERSION + " at " + settings.ip);
|
||||
mqtt_publish(deviceprefix + "log", "Free Heap: " + String(ESP.getFreeHeap()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void mqtt_setup() {
|
||||
PRINTLN_SERIAL(devname + "initialising module MQTT");
|
||||
}
|
||||
|
||||
void mqtt_loop() {
|
||||
long currentMillis = millis();
|
||||
|
||||
// Check for MQTT instructions
|
||||
if(!mqtt.connected()) {
|
||||
WifiMQTTconnect();
|
||||
} else {
|
||||
mqtt.loop();
|
||||
|
||||
// every 5 minutes (300000 milliseconds)
|
||||
if(currentMillis - logtimerMillis > 300000) {
|
||||
// reset timer
|
||||
logtimerMillis = currentMillis;
|
||||
// log something
|
||||
mqtt_publish(deviceprefix + "log", "Free Heap: " + String(ESP.getFreeHeap()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
68
60_module_sonoff.ino
Normal file
68
60_module_sonoff.ino
Normal file
@@ -0,0 +1,68 @@
|
||||
#ifdef ENABLE_SONOFF
|
||||
|
||||
/*
|
||||
* Interface with other modules
|
||||
*/
|
||||
void newcmd(String cmd) {
|
||||
cmd.toLowerCase();
|
||||
if(cmd.equals("off")) {
|
||||
settings.mode = 0;
|
||||
PRINTLN_SERIAL("Lights off");
|
||||
state.text = "Sonoff switched off";
|
||||
}
|
||||
if(cmd.equals("on")) {
|
||||
settings.mode = 1;
|
||||
PRINTLN_SERIAL("Lights on");
|
||||
state.text = "Sonoff switched off";
|
||||
}
|
||||
}
|
||||
|
||||
int sonoff_buttontoggle = 0; // counter for the number of button presses
|
||||
int sonoff_buttonstate = LOW; // current state of the button
|
||||
int sonoff_lastbuttonstate = LOW; // previous state of the button
|
||||
|
||||
/*
|
||||
* Setup and loop code. Be cooperative! No delays, timers.
|
||||
*/
|
||||
|
||||
void sonoff_setup() {
|
||||
PRINTLN_SERIAL("initialising module Sonoff");
|
||||
|
||||
pinMode(SONOFF_LED, OUTPUT); // Note that this LED is powered when voltage is LOW
|
||||
digitalWrite(SONOFF_LED, HIGH); // turn the LED off (HIGH is the voltage level)
|
||||
pinMode(SONOFF_RELAY, OUTPUT); // Note that this relay is powered when voltage is HIGH
|
||||
digitalWrite(SONOFF_RELAY, LOW); // turn the relay off (HIGH is the voltage level)
|
||||
}
|
||||
|
||||
void sonoff_loop() {
|
||||
// This is a matter of last resort kind of thing: the built-in button will toggle power on or off, regardless of MQTT or network availability
|
||||
// As good measure, we might try reporting some kind of state when connecting later on. @@@FIXME@@@
|
||||
|
||||
// read the pushbutton input pin:
|
||||
sonoff_buttonstate = digitalRead(SONOFF_BUTTON);
|
||||
|
||||
// compare the buttonState to its previous state
|
||||
if (sonoff_buttonstate != sonoff_lastbuttonstate) {
|
||||
// if the state has changed, increment the counter
|
||||
if (sonoff_buttonstate == LOW) {
|
||||
// if the current state is LOW then the button went from off to on:
|
||||
sonoff_buttontoggle = 1-sonoff_buttontoggle;
|
||||
PRINTLN_SERIAL("Button pressed");
|
||||
if (sonoff_buttontoggle == 1) {
|
||||
newcmd("on");
|
||||
} else {
|
||||
newcmd("off");
|
||||
}
|
||||
} else {
|
||||
// if the current state is LOW then the button went from on to off:
|
||||
PRINTLN_SERIAL("Button released");
|
||||
}
|
||||
// Delay a little bit to avoid bouncing
|
||||
delay(50); // @@@FIXME@@@ delays are undesirable!
|
||||
}
|
||||
// save the current state as the last state, for next time through the loop
|
||||
sonoff_lastbuttonstate = sonoff_buttonstate;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
221
70_module_moon.ino
Normal file
221
70_module_moon.ino
Normal file
@@ -0,0 +1,221 @@
|
||||
#ifdef ENABLE_MOON
|
||||
|
||||
// Needs refactoring
|
||||
// Use https://adrianotiger.github.io/Neopixel-Effect-Generator/ for inspiration
|
||||
// Read up on final comment at https://forum.arduino.cc/index.php?topic=534060.0
|
||||
|
||||
#include <Adafruit_NeoPixel.h>
|
||||
|
||||
/*
|
||||
* Based on https://adrianotiger.github.io/Neopixel-Effect-Generator/
|
||||
* TODO: Refactor for just a single string effect, less frills
|
||||
* Rainbow pattern
|
||||
*/
|
||||
class Strip
|
||||
{
|
||||
public:
|
||||
uint8_t effect;
|
||||
uint8_t effects;
|
||||
uint16_t effStep;
|
||||
unsigned long effStart;
|
||||
Adafruit_NeoPixel strip;
|
||||
Strip(uint16_t leds, uint8_t pin, uint8_t toteffects) : strip(leds, pin, NEO_GRB + NEO_KHZ800) {
|
||||
effect = -1;
|
||||
effects = toteffects;
|
||||
Reset();
|
||||
}
|
||||
void Reset(){
|
||||
effStep = 0;
|
||||
effect = (effect + 1) % effects;
|
||||
effStart = millis();
|
||||
}
|
||||
};
|
||||
|
||||
struct Loop
|
||||
{
|
||||
uint8_t currentChild;
|
||||
uint8_t childs;
|
||||
bool timeBased;
|
||||
uint16_t cycles;
|
||||
uint16_t currentTime;
|
||||
Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;}
|
||||
};
|
||||
|
||||
Strip strip_0(7, MOON_PIXEL, 7 );
|
||||
struct Loop strip0loop0(1, false, 1);
|
||||
|
||||
//[GLOBAL_VARIABLES]
|
||||
int speed = 200; // started at 101
|
||||
|
||||
uint8_t strip0_loop0_eff0() {
|
||||
// Strip ID: 0 - Effect: Rainbow - LEDS: 7
|
||||
// Steps: 35 - Delay: 100
|
||||
// Colors: 6 (255.255.0, 0.255.0, 0.0.255, 255.0.255, 255.0.0, 255.255.255, )
|
||||
// Options: toLeft=true,
|
||||
if(millis() - strip_0.effStart < 100 * (strip_0.effStep)) return 0x00;
|
||||
float factor1, factor2;
|
||||
uint16_t ind;
|
||||
for(uint16_t j=0;j<7;j++) {
|
||||
ind = strip_0.effStep + j * 1;
|
||||
switch((int)((ind % 35) / 5.833333333333333)) {
|
||||
case 0: factor1 = 1.0 - ((float)(ind % 35 - 0 * 5.833333333333333) / 5.833333333333333);
|
||||
factor2 = (float)((int)(ind - 0) % 35) / 5.833333333333333;
|
||||
strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 255 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2);
|
||||
break;
|
||||
case 1: factor1 = 1.0 - ((float)(ind % 35 - 1 * 5.833333333333333) / 5.833333333333333);
|
||||
factor2 = (float)((int)(ind - 5.833333333333333) % 35) / 5.833333333333333;
|
||||
strip_0.strip.setPixelColor(j, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2);
|
||||
break;
|
||||
case 2: factor1 = 1.0 - ((float)(ind % 35 - 2 * 5.833333333333333) / 5.833333333333333);
|
||||
factor2 = (float)((int)(ind - 11.666666666666666) % 35) / 5.833333333333333;
|
||||
strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 255 * factor1 + 255 * factor2);
|
||||
break;
|
||||
case 3: factor1 = 1.0 - ((float)(ind % 35 - 3 * 5.833333333333333) / 5.833333333333333);
|
||||
factor2 = (float)((int)(ind - 17.5) % 35) / 5.833333333333333;
|
||||
strip_0.strip.setPixelColor(j, 255 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2);
|
||||
break;
|
||||
case 4: factor1 = 1.0 - ((float)(ind % 35 - 4 * 5.833333333333333) / 5.833333333333333);
|
||||
factor2 = (float)((int)(ind - 23.333333333333332) % 35) / 5.833333333333333;
|
||||
strip_0.strip.setPixelColor(j, 255 * factor1 + 255 * factor2, 0 * factor1 + 255 * factor2, 0 * factor1 + 255 * factor2);
|
||||
break;
|
||||
case 5: factor1 = 1.0 - ((float)(ind % 35 - 5 * 5.833333333333333) / 5.833333333333333);
|
||||
factor2 = (float)((int)(ind - 29.166666666666664) % 35) / 5.833333333333333;
|
||||
strip_0.strip.setPixelColor(j, 255 * factor1 + 255 * factor2, 255 * factor1 + 255 * factor2, 255 * factor1 + 0 * factor2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(strip_0.effStep >= 35) {strip_0.Reset(); return 0x03; }
|
||||
else strip_0.effStep++;
|
||||
return 0x01;
|
||||
}
|
||||
|
||||
uint8_t strip0_loop0() {
|
||||
uint8_t ret = 0x00;
|
||||
switch(strip0loop0.currentChild) {
|
||||
case 0:
|
||||
ret = strip0_loop0_eff0();break;
|
||||
}
|
||||
if(ret & 0x02) {
|
||||
ret &= 0xfd;
|
||||
if(strip0loop0.currentChild + 1 >= strip0loop0.childs) {
|
||||
strip0loop0.currentChild = 0;
|
||||
if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;}
|
||||
}
|
||||
else {
|
||||
strip0loop0.currentChild++;
|
||||
}
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
void strips_loop() {
|
||||
if(strip0_loop0() & 0x01)
|
||||
strip_0.strip.show();
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface with other modules
|
||||
*/
|
||||
|
||||
void newcmd(String cmd) {
|
||||
cmd.toLowerCase();
|
||||
if(cmd.equals("off")) {
|
||||
settings.mode = 0;
|
||||
PRINTLN_SERIAL("Moon off");
|
||||
strip_0.strip.setBrightness(0); // 0-255
|
||||
state.text = "Moon switched off";
|
||||
}
|
||||
if(cmd.equals("on")) {
|
||||
settings.mode = 1;
|
||||
PRINTLN_SERIAL("Moon switched on");
|
||||
strip_0.strip.setBrightness(10); // 0-255
|
||||
state.text = "Moon switched off";
|
||||
}
|
||||
}
|
||||
|
||||
void module_message(const String& shorttopic, const String& message) {
|
||||
char msgptr[10];
|
||||
String buffer;
|
||||
|
||||
if(shorttopic.equalsIgnoreCase("cmd")) {
|
||||
if(message.equalsIgnoreCase("off")) {
|
||||
state.mode = 0;
|
||||
PRINTLN_SERIAL("Moon off");
|
||||
strip_0.strip.setBrightness(0); // 0-255
|
||||
state.text = "Moon switched off";
|
||||
} else if(message.equalsIgnoreCase("on")) {
|
||||
state.mode = 1;
|
||||
PRINTLN_SERIAL("Moon switched on");
|
||||
strip_0.strip.setBrightness(10); // 0-255
|
||||
state.text = "Moon switched off";
|
||||
}
|
||||
|
||||
} else if(shorttopic.equalsIgnoreCase("mode")) {
|
||||
if(message.equals("off")) {
|
||||
state.mode = 0;
|
||||
PRINTLN_SERIAL("Shutting off");
|
||||
} else if(message.startsWith("0x")) {
|
||||
state.mode = 1;
|
||||
message.toCharArray(msgptr, 9);
|
||||
state.color = strtoll( &msgptr[2], NULL, 16);
|
||||
sprintf(printbuffer, "Switching to static color 0x%x", state.color);
|
||||
PRINTLN_SERIAL(printbuffer);
|
||||
} else if(message.startsWith("#")) {
|
||||
state.mode = 1;
|
||||
message.toCharArray(msgptr, 8);
|
||||
state.color = strtoll( &msgptr[1], NULL, 16);
|
||||
sprintf(printbuffer, "Switching to static color 0x%x", state.color);
|
||||
PRINTLN_SERIAL(printbuffer);
|
||||
} else if(message.equals("rainbow")) {
|
||||
state.mode = 2;
|
||||
PRINTLN_SERIAL("Switching to rainbow mode");
|
||||
}
|
||||
mqtt_publish((deviceprefix + "log"), ("mode=" + String(state.mode))); // @@@FIXME@@@ this needs to go elsewhere
|
||||
|
||||
} else if(shorttopic.equalsIgnoreCase("brightness")) {
|
||||
PRINTLN_SERIAL("Setting brightness to " + message);
|
||||
settings.brightness = message.toInt();
|
||||
strip_0.strip.setBrightness(settings.brightness);
|
||||
buffer = "brightness=";
|
||||
buffer.concat(settings.brightness);
|
||||
mqtt_publish((deviceprefix + "log"), buffer.c_str()); // @@@FIXME@@@ this needs to go elsewhere
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup and loop code. Be cooperative! No delays, timers.
|
||||
*/
|
||||
|
||||
void moon_setup() {
|
||||
PRINTLN_SERIAL("initialising module Moon");
|
||||
strip_0.strip.setBrightness(2); // 0-255
|
||||
strip_0.strip.begin();
|
||||
}
|
||||
|
||||
void moon_loop() {
|
||||
uint16_t r;
|
||||
|
||||
switch(state.mode) {
|
||||
case 0: // Off
|
||||
for(r=0; r< strip_0.strip.numPixels(); r++) {
|
||||
strip_0.strip.setPixelColor(r, 0,0,0);
|
||||
}
|
||||
strip_0.strip.show();
|
||||
break;
|
||||
case 1: // Static color
|
||||
for(r=0; r< strip_0.strip.numPixels(); r++) {
|
||||
// Split the set color code up into r, g, b values
|
||||
int rval = state.color >> 16;
|
||||
int gval = state.color >> 8 & 0xFF;
|
||||
int bval = state.color & 0xFF;
|
||||
strip_0.strip.setPixelColor(r, rval, gval, bval);
|
||||
}
|
||||
strip_0.strip.show();
|
||||
break;
|
||||
case 2: // Rainbow
|
||||
strips_loop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
52
99_setup_loop.ino
Normal file
52
99_setup_loop.ino
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Setup and loop functions
|
||||
*/
|
||||
|
||||
/*************************** Sketch Code ************************************/
|
||||
void setup() {
|
||||
// Write banner
|
||||
PRINTLN_SERIAL("");
|
||||
PRINTLN_SERIAL("");
|
||||
PRINTLN_SERIAL("Booting " __FILE__ " built on " __DATE__ ", " __TIME__);
|
||||
|
||||
// Generate device name from MAC
|
||||
PRINTLN_SERIAL("Network interface: " + WiFi.macAddress());
|
||||
settings.name = DEVICEPREFIX;
|
||||
int devlen = settings.name.length();
|
||||
settings.name = settings.name + "_" + WiFi.macAddress();
|
||||
settings.name.remove(devlen+3, 1);
|
||||
settings.name.remove(devlen+5, 1);
|
||||
settings.name.remove(devlen+7, 1);
|
||||
settings.name.remove(devlen+9, 1);
|
||||
settings.name.remove(devlen+11, 1);
|
||||
// Only keep the last 6 characters from the MAC, hopefully that will be 'unique enough' in the LAN
|
||||
// If we run in to trouble, this can painlessly be removed and the resulting device name will just be longer
|
||||
settings.name.remove(devlen+1, 6);
|
||||
|
||||
PRINTLN_SERIAL("device name generated");
|
||||
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
mqtt_setup();
|
||||
#endif
|
||||
#ifdef ENABLE_SONOFF
|
||||
sonoff_setup();
|
||||
#endif
|
||||
#ifdef ENABLE_MOON
|
||||
moon_setup();
|
||||
#endif
|
||||
// Start the cooperative scheduler loops
|
||||
PRINTLN_SERIAL(devname + "done setting up, ready for main loop");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
#ifdef ENABLE_MQTT
|
||||
mqtt_loop();
|
||||
#endif
|
||||
#ifdef ENABLE_SONOFF
|
||||
sonoff_loop();
|
||||
#endif
|
||||
#ifdef ENABLE_MOON
|
||||
moon_loop();
|
||||
#endif
|
||||
}
|
||||
70
ESPGadget.ino
Normal file
70
ESPGadget.ino
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* ESP-SecureGadget by Florian Overkamp
|
||||
* An ESP8266 based IoT/remote controlled gadget
|
||||
* Design is modular so it can be used for things like Sonoff's but also for custom projects like Dex' Moon lamp
|
||||
*
|
||||
* Note that file ordering is important.
|
||||
*/
|
||||
|
||||
// Done:
|
||||
// Enable MQTT over SSL as per https://github.com/debsahu/ESP_MQTT_Secure/tree/master/ESP8266_MQTT_SSL/Arduino/ESP8266_PubSubClient_SSL
|
||||
// Cooperative multitasking: Use timers always. Avoid delays where they can be avoided.
|
||||
// Restructure mqtt topics a bit (report back with unique names for multiple fx lights, for instance)
|
||||
// Implement versioning so that new firmware can be done OTA
|
||||
|
||||
// Todo:
|
||||
// Split the wifi and mqtt code in order to support http interface
|
||||
// Stay on the lookout for watchdog crashes, see also https://www.sigmdel.ca/michel/program/esp8266/arduino/watchdogs_en.html#ESP8266_WDT_RECOV
|
||||
// Keeps crashing after a few days. Dunno why. https://www.pieterverhees.nl/sparklesagarbage/esp8266/130-difference-between-esp-reset-and-esp-restart
|
||||
// More on this subject https://github.com/esp8266/Arduino/issues/1017
|
||||
// Implement more visual effects
|
||||
// Implement speed controls for the visual effects
|
||||
// Implement OTA https://www.bakke.online/index.php/2017/06/02/self-updating-ota-firmware-for-esp8266/
|
||||
// Refactoring sources: https://www.arduinolibraries.info/architectures/esp8266
|
||||
// Refactor String usage to minimize heap pollution. https://cpp4arduino.com/2018/11/21/eight-tips-to-use-the-string-class-efficiently.html
|
||||
|
||||
#define DEVICEPREFIX "Gadget" // Should be no longer than 8(?) chars or the MQTT clientId will become too long
|
||||
const int FW_VERSION = 12;
|
||||
|
||||
// Version history:
|
||||
// v12: Refactored inbound commands to hook in to the modules (module_message function), completed assimilation of (never-published) Moon_Connected sketch
|
||||
// v11: Simplified scheduler, back to cooperative looping
|
||||
// v10: First 'production' run. MQTT over TLS, but no OTA support.
|
||||
|
||||
/*
|
||||
* Compile time settings
|
||||
*/
|
||||
|
||||
/************************* WiFi Access Point *********************************/
|
||||
#define WLAN_SSID "MY_SSID"
|
||||
#define WLAN_PASS "MY_WIFIPASSWD"
|
||||
|
||||
|
||||
/*********************** Select active modules *******************************/
|
||||
#define ENABLE_MQTT
|
||||
//#define ENABLE_SONOFF
|
||||
#define ENABLE_MOON
|
||||
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
/*************************** MQTT settings ***********************************/
|
||||
#define MQTT_SERVER "MY_MQTT_SERVER"
|
||||
#define MQTT_SERVERPORT 8883 // 8883 for MQTTS
|
||||
#define MQTT_USERNAME "MY_MQTT_USER"
|
||||
#define MQTT_PASSWORD "MY_MQTT_PASSWD"
|
||||
#define MQTT_PREFIX "iot/" // MQTT publish/subscribe will be prefixed by this (mind the trailing slash)
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SONOFF
|
||||
/*************************** MQTT settings ***********************************/
|
||||
#define SONOFF_BUTTON 0
|
||||
#define SONOFF_RELAY 12
|
||||
#define SONOFF_LED 13
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MOON
|
||||
/*********************** NeoPixel Moon settings ******************************/
|
||||
#define MOON_PIXEL 4 // Which GPIO pin is the NeoPixel connected to
|
||||
#define MOON_PIXEL_LEDS 7 // Amount of leds in the string
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user