diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 33506d2..c5d1bc8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,11 +34,10 @@ firmware-build: stage: build image: python:2.7-stretch script: - - pio run -t clean + - pio run --target clean - pio run --environment basic - - pio run --environment mesh - - pio run --environment meshMqttBridge - - pio run --environment standalone + - pio run --environment wifi + - pio run --environment wifiMesh artifacts: paths: - .pioenvs/*/firmware.* diff --git a/platformio.ini b/platformio.ini index db1c121..4c386fc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -8,8 +8,8 @@ ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html -[platformio] -env_default = mesh +;[platformio] +;env_default = mesh [common] framework = arduino @@ -46,8 +46,8 @@ monitor_baud = ${common.monitor_baud} framework = ${common.framework} lib_deps = ${common.lib_deps} -[env:mesh] -src_filter = +<*> - + +[env:wifiMesh] +src_filter = +<*> - + platform = ${common.platform} board = ${common.board} upload_speed = ${common.upload_speed} @@ -55,31 +55,13 @@ monitor_baud = ${common.monitor_baud} framework = ${common.framework} lib_deps = ${common.lib_deps} painlessMesh - ESP8266mDNS - ArduinoOTA - ESP Async WebServer - ESPAsyncTCP -;upload_port = 192.168.1.247 -[env:meshMqttBridge] -src_filter = +<*> - + -platform = espressif8266 -board = esp12e -upload_speed = ${common.upload_speed} -monitor_baud = ${common.monitor_baud} -framework = ${common.framework} -lib_deps = ${common.lib_deps} - painlessMesh - PubSubClient - - -[env:standalone] -src_filter = +<*> - + +[env:wifi] +src_filter = +<*> - + platform = ${common.platform} board = ${common.board} upload_speed = ${common.upload_speed} monitor_baud = ${common.monitor_baud} framework = ${common.framework} lib_deps = ${common.lib_deps} - ArduinoOTA ESP Async WebServer \ No newline at end of file diff --git a/src/JsonStruct.h b/src/JsonStruct.h index cee2114..6b21a7d 100644 --- a/src/JsonStruct.h +++ b/src/JsonStruct.h @@ -16,10 +16,8 @@ struct JsonStruct { virtual void fromJsonObject(JsonObject& json); virtual int verifyJsonObject(JsonObject& json){ return json.success(); - //&& json.containsKey(JSON_DOMAIN) }; String toJsonString(){ - //StaticJsonBuffer<200> StringjsonBuffer; DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(300)); JsonObject& root = jsonBuffer.createObject(); mapJsonObject(root); @@ -44,7 +42,6 @@ struct JsonStruct { // Map a json object to this struct. // Parse a json string and map parsed object void fromJsonString(String& str){ - //StaticJsonBuffer<200> jsonBuffer; DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(300)); JsonObject& json = jsonBuffer.parseObject(str); valid = verifyJsonObject(json); @@ -56,13 +53,6 @@ struct JsonStruct { void fromFile(const char* path) { File configFile = SPIFFS.open(path, "r"); String cfgFileStr = configFile.readString(); - - // Allocate a buffer to store contents of the file. - //size_t size = configFile.size(); - //std::unique_ptr buf(new char[size]); - //configFile.readBytes(buf.get(), size); - //StaticJsonBuffer<1024> jsonBuffer; - //JsonObject& json = jsonBuffer.parseObject(buf.get()); DynamicJsonBuffer jsonBuffer; JsonObject& json = jsonBuffer.parseObject(cfgFileStr); diff --git a/src/MeshNet.cpp b/src/MeshNet.cpp index aa28adf..42c08ce 100644 --- a/src/MeshNet.cpp +++ b/src/MeshNet.cpp @@ -13,37 +13,36 @@ MeshNet::MeshNet(MeshConfig cfg) : Network() { } Network* MeshNet::init(){ - Serial.println("init mesh"); config.fromFile("/config.json"); - //mesh.setDebugMsgTypes( ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE ); // all types on mesh.setDebugMsgTypes( config.debugTypes ); + return this; +} + +int MeshNet::connect(){ mesh.init( config.meshSSID, config.meshPassword, scheduler, config.meshPort, WIFI_AP_STA, config.channel ); - mesh.onNewConnection(bind(&MeshNet::newConnectionCallback, this, _1)); mesh.onChangedConnections(bind(&MeshNet::changedConnectionCallback, this)); mesh.onNodeTimeAdjusted(bind(&MeshNet::nodeTimeAdjustedCallback, this, _1)); - - connectStation(config.stationMode); - - return this; + if(config.stationMode){ + connectStation(); + } + return 1; } -int MeshNet::connectStation(int doConnect) { - if(doConnect){ + +int MeshNet::connectStation() { Serial.println("connect station"); mesh.stationManual(config.stationSSID, config.stationPassword); mesh.setHostname(config.hostname.c_str()); return 1; - } - return 0; } void MeshNet::sendTo(uint32_t target, String msg){ mesh.sendSingle(target, msg); } -void MeshNet::broadcast(String msg){ - mesh.sendBroadcast(msg); +void MeshNet::broadcast(String msg, bool self){ + mesh.sendBroadcast(msg, self); } void MeshNet::update(){ diff --git a/src/MeshNet.h b/src/MeshNet.h index 6ff9463..5da24c0 100644 --- a/src/MeshNet.h +++ b/src/MeshNet.h @@ -11,7 +11,7 @@ #include #include "Network.h" #include "MeshConfig.h" -#include "base/MeshSprocketConfig.h" +#include "MeshSprocketConfig.h" using namespace std; using namespace std::placeholders; @@ -22,13 +22,14 @@ class MeshNet : public Network { MeshSprocketConfig config; MeshNet(MeshConfig cfg); Network* init(); - int connectStation(int); + int connect(); + int connectStation(); void configure(MeshSprocketConfig cfg); void update(); void newConnectionCallback(uint32_t nodeId); void changedConnectionCallback(); void nodeTimeAdjustedCallback(int32_t offset); - void broadcast(String msg); + void broadcast(String msg, bool self = false); void sendTo(uint32_t target, String msg); void onReceive(std::function); int isConnected(){ diff --git a/src/base/MeshSprocketConfig.h b/src/MeshSprocketConfig.h similarity index 100% rename from src/base/MeshSprocketConfig.h rename to src/MeshSprocketConfig.h diff --git a/src/Network.h b/src/Network.h index 62bbec9..f40d4ed 100644 --- a/src/Network.h +++ b/src/Network.h @@ -16,7 +16,7 @@ class Network { virtual int connectStation() { return 0; }; virtual int isConnected(){ return 0; }; virtual void update() {}; - virtual void broadcast(String msg){}; + virtual void broadcast(String msg, bool self = false){}; virtual void sendTo(uint32_t target, String msg) {}; virtual void onReceive(std::function) {}; Network* setScheduler(Scheduler* s) { diff --git a/src/Plugin.h b/src/Plugin.h index bce5744..9c83644 100644 --- a/src/Plugin.h +++ b/src/Plugin.h @@ -1,18 +1,22 @@ #ifndef __SPROCKET_PLUGIN__ #define __SPROCKET_PLUGIN__ +#define _TASK_SLEEP_ON_IDLE_RUN +#define _TASK_STD_FUNCTION +#define _TASK_PRIORITY + #include #include -#include +#include #include class Plugin { public: Mediator* mediator; - virtual void activate(Scheduler*, Network*); - virtual void enable(){}; - virtual void disable(){}; - virtual void onMessage(SprocketMessage msg){}; + virtual void activate(Scheduler*); + virtual void enable(){} + virtual void disable(){} + virtual void onMessage(SprocketMessage msg){} Plugin* mediate(Mediator* m) { mediator = m; return this; diff --git a/src/Sprocket.cpp b/src/Sprocket.cpp index 27c942e..7a63ec0 100644 --- a/src/Sprocket.cpp +++ b/src/Sprocket.cpp @@ -13,34 +13,22 @@ Sprocket* Sprocket::init(SprocketConfig cfg){ delay(cfg.startupDelay); Serial.begin(cfg.serialBaudRate); SPIFFS.begin(); + scheduler = new Scheduler(); return this; } Sprocket* Sprocket::activate() { - return activate(&scheduler); -} -Sprocket* Sprocket::activate(Scheduler* scheduler, Network* network) { - // setup plugins - activatePlugins(scheduler, network); - return this; -} - -Sprocket* Sprocket::join(Network& net){ - Serial.println("join network"); - net.init(&scheduler); - //net.onReceive(bind(&Sprocket::dispatch,this, _1, _2)); - net.connect(); - network = net; - return activate(&scheduler, &net); + activatePlugins(scheduler); + return activate(scheduler); } Sprocket* Sprocket::addTask(Task& tsk){ - scheduler.addTask(tsk); + scheduler->addTask(tsk); tsk.enable(); return this; } void Sprocket::loop(){ - scheduler.execute(); + scheduler->execute(); } void Sprocket::dispatch( uint32_t from, String &msg ) { @@ -57,8 +45,8 @@ void Sprocket::addPlugin(Plugin* p){ plugins.push_back(p); } -void Sprocket::activatePlugins(Scheduler* scheduler, Network* network){ +void Sprocket::activatePlugins(Scheduler* scheduler){ for(Plugin* p : plugins){ - p->activate(scheduler, network); + p->activate(scheduler); } -} \ No newline at end of file +} diff --git a/src/Sprocket.h b/src/Sprocket.h index 56388af..b192f2a 100644 --- a/src/Sprocket.h +++ b/src/Sprocket.h @@ -1,6 +1,10 @@ #ifndef __SPROCKET_H__ #define __SPROCKET_H__ +#define _TASK_SLEEP_ON_IDLE_RUN +#define _TASK_STD_FUNCTION +#define _TASK_PRIORITY + #include //#include #include @@ -23,7 +27,7 @@ class Sprocket : public Mediator { protected: // TODO move scheduler out of Sprocket // => see difference between standalone and mesh sprochet usage of scheduler - Scheduler scheduler; + Scheduler* scheduler; Network network; private: SprocketMessage currentMessage; @@ -33,17 +37,14 @@ class Sprocket : public Mediator { Sprocket(); Sprocket(SprocketConfig); Sprocket* init(SprocketConfig); - Sprocket* join(Network&); Sprocket* addTask(Task&); virtual void loop(); virtual Sprocket* activate(); - virtual Sprocket* activate(Scheduler*) { return this; } - virtual Sprocket* activate(Scheduler*, Network*); + virtual Sprocket* activate(Scheduler*) { return this; }; virtual void dispatch( uint32_t from, String &msg ); void addPlugin(Plugin* p); - void activatePlugins(Scheduler* scheduler, Network* network); - void dispatchMessageToPlugins(SprocketMessage msg); + void activatePlugins(Scheduler* scheduler); }; #endif \ No newline at end of file diff --git a/src/base/SprocketMessage.h b/src/SprocketMessage.h similarity index 100% rename from src/base/SprocketMessage.h rename to src/SprocketMessage.h diff --git a/src/WiFiNet.cpp b/src/WiFiNet.cpp index e2e7a68..9f64390 100644 --- a/src/WiFiNet.cpp +++ b/src/WiFiNet.cpp @@ -22,14 +22,12 @@ Network* WiFiNet::init() { return this; } int WiFiNet::connect(){ - if(config.valid){ - WiFi.hostname(config.hostname); - Serial.println("Hostname: " + config.hostname); - if(!connectStation()) { - createAccessPoint(); - } - startDNS(); + WiFi.hostname(config.hostname); + Serial.println("Hostname: " + config.hostname); + if(!connectStation()) { + createAccessPoint(); } + startDNS(); return 1; } @@ -41,6 +39,7 @@ int WiFiNet::connectStation(){ WiFi.begin(config.stationSSID.c_str(), config.stationPassword.c_str()); Serial.println("connect to " + config.stationSSID); + // TODO use tasks while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); diff --git a/src/base/MeshSprocket.h b/src/base/MeshSprocket.h deleted file mode 100644 index 40a6ef2..0000000 --- a/src/base/MeshSprocket.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef __MESH_SPROCKET__ -#define __MESH_SPROCKET__ - -#define DEBUG_ESP_OTA -#include -#include -#include -#include -#include -#include -#include "config.h" -#include "utils_print.h" - -using namespace std; -using namespace std::placeholders; - -class MeshSprocket : public Sprocket { - public: - MeshNet* net; - - MeshSprocket(){}; - MeshSprocket(SprocketConfig cfg) : Sprocket(cfg) { - - } - - Sprocket* activate(Scheduler* scheduler, Network* network) { - Sprocket::activate(scheduler, network); - net = static_cast(network); - net->onReceive(bind(&MeshSprocket::dispatch,this, _1, _2)); - - return this; - } using Sprocket::activate; - - // TODO transmit SprocketMessage - virtual void dispatch( uint32_t from, String &msg ) { - SprocketMessage sMsg; - sMsg.fromJsonString(msg); - if(sMsg.valid){ - sMsg.from = from; - publish(sMsg.topic, sMsg.payload); - } - } - - void loop() { - net->update(); - scheduler.execute(); - } -}; - -#endif \ No newline at end of file diff --git a/src/examples/mesh/MeshApp.h b/src/examples/mesh/MeshApp.h deleted file mode 100644 index d7cbec7..0000000 --- a/src/examples/mesh/MeshApp.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef __MESH_APP__ -#define __MESH_APP__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "Mediator.h" - -using namespace std; -using namespace std::placeholders; - -AsyncWebServer WEBSERVER(80); - -class MeshApp : public MeshSprocket { - public: - Task heartbeatTask; - - MeshApp(SprocketConfig cfg, OtaConfig otaCfg, WebServerConfig webCfg) : MeshSprocket(cfg) { - addPlugin(new OtaTcpPlugin(otaCfg)); - addPlugin(new WebServerPlugin(webCfg, &WEBSERVER)); - addPlugin(new WebConfigPlugin(&WEBSERVER)); - addPlugin(new MeshManPlugin(&WEBSERVER)); - subscribe("mesh/heartbeat", bind(&MeshApp::messageHandler, this, _1)); - } - - Sprocket* activate(Scheduler* scheduler, Network* network) { - // call parent method that enables dispatching and plugins - MeshSprocket::activate(scheduler, network); - - // add a task that sends stuff to the mesh - heartbeatTask.set(TASK_SECOND * 5, TASK_FOREVER, bind(&MeshApp::heartbeat, this, net)); - addTask(heartbeatTask); - - return this; - } using MeshSprocket::activate; - - void messageHandler(String msg){ - Serial.println(String("MeshApp: ") + msg); - } - - void heartbeat(MeshNet* network){ - SprocketMessage msg; // = { "wirelos", "broadcast", "local", "alive", 0, }; - msg.domain = "wirelos"; - msg.to = "broadcast"; - msg.payload = "alive"; - msg.topic = "mesh/heartbeat"; - msg.type = SprocketMessage::APP; - String msgStr = msg.toJsonString(); - network->mesh.sendBroadcast(msgStr, true); - //String mMsg = String("hoi"); - //publish("mediatorMsg", "hi mediator"); - } - //void onMessage( uint32_t from, String &msg ) { - // Serial.printf("MeshApp onMessage: received from %u msg=%s\n", from, msg.c_str()); - //} -}; - -#endif \ No newline at end of file diff --git a/src/examples/mesh/main.cpp b/src/examples/mesh/main.cpp deleted file mode 100644 index 1b985dd..0000000 --- a/src/examples/mesh/main.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "config.h" -#include "MeshNet.h" -#include "MeshApp.h" - -MeshNet net({ - SPROCKET_MODE, WIFI_CHANNEL, - MESH_PORT, MESH_PREFIX, MESH_PASSWORD, - STATION_SSID, STATION_PASSWORD, HOSTNAME, - MESH_DEBUG_TYPES -}); -MeshApp sprocket( - { STARTUP_DELAY, SERIAL_BAUD_RATE }, - { OTA_PORT, OTA_PASSWORD }, - { WEB_CONTEXT_PATH, WEB_DOC_ROOT, WEB_DEFAULT_FILE } -); - -void setup() { - sprocket.join(net); -} - -void loop() { - sprocket.loop(); - yield(); -} \ No newline at end of file diff --git a/src/examples/meshMqttBridge/MqttMeshBridge.cpp b/src/examples/meshMqttBridge/MqttMeshBridge.cpp deleted file mode 100644 index 9c775e8..0000000 --- a/src/examples/meshMqttBridge/MqttMeshBridge.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef __MESH_MQTT_BRIDGE_APP__ -#define __MESH_MQTT_BRIDGE_APP__ - -#include -#include -#include -#include "Sprocket.h" -#include "MeshNet.h" - -#define MQTT_TOPIC_FROM "mesh/from/" -#define MQTT_TOPIC_FROM_GATEWAY "mesh/from/gateway" -#define MQTT_TOPIC_TO_ALL "mesh/to/#" - -using namespace std; -using namespace std::placeholders; - -struct MqttConfig { - const char* clientName; - const char* brokerHost; - int brokerPort; - const char* topicRoot; -}; - -class MqttMeshBridge : public Sprocket { - public: - MeshNet* net; - PubSubClient* client; - WiFiClient wifiClient; - Task connectTask; - Task processTask; - MqttConfig mqttConfig; - - MqttMeshBridge(SprocketConfig sprktCfg, MqttConfig cfg) : Sprocket(sprktCfg) { - mqttConfig = cfg; - } - - Sprocket* activate(Scheduler* scheduler){ - enableConnectTask(scheduler); - enableProcessTask(scheduler); - return this; - } - - Sprocket* activate(Scheduler* scheduler, Network* network) { - Serial.println("activate MQTT bridge"); - net = static_cast(network); - net->mesh.onReceive(bind(&MqttMeshBridge::receivedCallback,this, _1, _2)); - client = new PubSubClient(mqttConfig.brokerHost, mqttConfig.brokerPort, bind(&MqttMeshBridge::mqttCallback, this, _1, _2, _3), wifiClient); - return activate(scheduler); - } - - private: - void enableConnectTask(Scheduler* scheduler) { - connectTask.set(TASK_SECOND * 5, TASK_FOREVER, bind(&MqttMeshBridge::connect, this)); - scheduler->addTask(connectTask); - connectTask.enable(); - } - - void enableProcessTask(Scheduler* scheduler) { - processTask.set(TASK_MILLISECOND * 5, TASK_FOREVER, bind(&MqttMeshBridge::process, this)); - scheduler->addTask(processTask); - processTask.enable(); - } - - void process(){ - client->loop(); - } - - void connect() { - if (!client->connected()) { - if (client->connect(mqttConfig.clientName)) { - Serial.println("MQTT connected"); - client->publish(MQTT_TOPIC_FROM_GATEWAY,"Ready!"); - client->subscribe(MQTT_TOPIC_TO_ALL); - } - } - } - - void receivedCallback( uint32_t from, String &msg ) { - Serial.printf("bridge: Received from %u msg=%s\n", from, msg.c_str()); - String topic = MQTT_TOPIC_FROM + String(from); - client->publish(topic.c_str(), msg.c_str()); - } - - void mqttCallback(char* topic, uint8_t* payload, unsigned int length) { - char* cleanPayload = (char*)malloc(length+1); - payload[length] = '\0'; - memcpy(cleanPayload, payload, length+1); - String msg = String(cleanPayload); - free(cleanPayload); - - int topicRootLength = String(mqttConfig.topicRoot).length(); - String targetStr = String(topic).substring(topicRootLength + 4); - - if(targetStr == "gateway"){ - if(msg == "getNodes") { - client->publish(MQTT_TOPIC_FROM_GATEWAY, net->mesh.subConnectionJson().c_str()); - } - } else if(targetStr == "broadcast") { - net->mesh.sendBroadcast(msg); - } else { - uint32_t target = strtoul(targetStr.c_str(), NULL, 10); - if(net->mesh.isConnected(target)){ - net->mesh.sendSingle(target, msg); - } else { - client->publish(MQTT_TOPIC_FROM_GATEWAY, "Client not connected!"); - } - } - } - -}; - -#endif \ No newline at end of file diff --git a/src/examples/meshMqttBridge/config.h b/src/examples/meshMqttBridge/config.h deleted file mode 100644 index 5a10475..0000000 --- a/src/examples/meshMqttBridge/config.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __BRIDGE_CONFIG__ -#define __BRIDGE_CONFIG__ - -// Scheduler config -#define _TASK_SLEEP_ON_IDLE_RUN -#define _TASK_STD_FUNCTION - -// Chip config -#define SERIAL_BAUD_RATE 115200 -#define STARTUP_DELAY 3000 - -// Mesh config -#define STATION_MODE 1 -#define WIFI_CHANNEL 11 -#define MESH_PORT 5555 -#define MESH_PREFIX "whateverYouLike" -#define MESH_PASSWORD "somethingSneaky" -#define STATION_SSID "Th1ngs4P" -#define STATION_PASSWORD "th3r31sn0sp00n" -#define HOSTNAME "mqtt-bridge" -#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION - -// Bridge config -#define MQTT_CLIENT_NAME HOSTNAME -#define MQTT_BROKER "citadel.lan" -#define MQTT_PORT 1883 -#define MQTT_TOPIC_ROOT "mesh" - -#endif \ No newline at end of file diff --git a/src/examples/meshMqttBridge/main.cpp b/src/examples/meshMqttBridge/main.cpp deleted file mode 100644 index 46f0fce..0000000 --- a/src/examples/meshMqttBridge/main.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "config.h" -#include "MeshNet.h" -#include "MqttMeshBridge.cpp" - -MeshNet net({ - STATION_MODE, WIFI_CHANNEL, - MESH_PORT, MESH_PREFIX, MESH_PASSWORD, - STATION_SSID, STATION_PASSWORD, HOSTNAME, - MESH_DEBUG_TYPES -}); - -MqttMeshBridge sprocket( - { STARTUP_DELAY, SERIAL_BAUD_RATE }, - { MQTT_CLIENT_NAME, MQTT_BROKER, MQTT_PORT, MQTT_TOPIC_ROOT } -); - -void setup() { - sprocket.join(net); -} - -void loop() { - sprocket.loop(); - yield(); -} \ No newline at end of file diff --git a/src/examples/standalone/WiFiApp.h b/src/examples/standalone/WiFiApp.h deleted file mode 100644 index 46f31ae..0000000 --- a/src/examples/standalone/WiFiApp.h +++ /dev/null @@ -1,46 +0,0 @@ - -#ifndef __WIFI_APP__ -#define __WIFI_APP__ - -#include -#include -#include -#include -#include -#include -#include "Mediator.h" - -using namespace std; -using namespace std::placeholders; - -AsyncWebServer WEBSERVER(80); - -class WiFiApp : public Sprocket { - public: - Scheduler* ts; - Task someTask; - WiFiApp(SprocketConfig cfg, OtaConfig otaCfg, WebServerConfig webCfg) : Sprocket(cfg) { - //addPlugin(new OtaTcpPlugin(otaCfg)); - addPlugin(new WebServerPlugin(webCfg, &WEBSERVER)); - addPlugin(new WebConfigPlugin(&WEBSERVER)); - ts = new Scheduler(); - } - - Sprocket* activate(Scheduler* scheduler, Network* network) { - Sprocket::activate(ts, network); - Serial.println("activate WiFiApp"); - // add a task - someTask.set(TASK_SECOND, TASK_FOREVER, [](){ - Serial.println("do stuff in task"); - }); - //addTask(someTask); - return this; - } using Sprocket::activate; - void loop(){ - //Sprocket::loop(); - ts->execute(); - yield(); - } -}; - -#endif \ No newline at end of file diff --git a/src/examples/standalone/main.cpp b/src/examples/standalone/main.cpp deleted file mode 100644 index 7f263f2..0000000 --- a/src/examples/standalone/main.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "config.h" -#include "WiFiNet.h" -#include "WiFiApp.h" - -/* WiFiConfig wifiCfg = { - .stationMode=SPROCKET_MODE, - .stationSSID=STATION_SSID, - .stationPassword=STATION_PASSWORD, - .apSSID=AP_SSID, - .apPassword=AP_PASSWORD, - .hostname=HOSTNAME, - .connectTimeout=CONNECT_TIMEOUT -}; */ - -WiFiNet net(SPROCKET_MODE,STATION_SSID, STATION_PASSWORD,AP_SSID, AP_PASSWORD,HOSTNAME,CONNECT_TIMEOUT); -WiFiApp sprocket( - { STARTUP_DELAY, SERIAL_BAUD_RATE }, - { OTA_PORT, OTA_PASSWORD }, - { WEB_CONTEXT_PATH, WEB_DOC_ROOT, WEB_DEFAULT_FILE } -); - -void setup() { - delay(3000); - sprocket.join(net); -} - -void loop() { - sprocket.loop(); - yield(); -} \ No newline at end of file diff --git a/src/examples/wifi/WiFiApp.h b/src/examples/wifi/WiFiApp.h new file mode 100644 index 0000000..ab0c1f5 --- /dev/null +++ b/src/examples/wifi/WiFiApp.h @@ -0,0 +1,24 @@ + +#ifndef __WIFI_APP__ +#define __WIFI_APP__ + +#include +#include +#include +#include +#include + +using namespace std; +using namespace std::placeholders; + +class WiFiApp : public Sprocket { + public: + AsyncWebServer* server; + WiFiApp(SprocketConfig cfg, WebServerConfig webCfg) : Sprocket(cfg) { + server = new AsyncWebServer(webCfg.port); + addPlugin(new WebServerPlugin(webCfg, server)); + addPlugin(new WebConfigPlugin(server)); + } +}; + +#endif \ No newline at end of file diff --git a/src/examples/standalone/config.h b/src/examples/wifi/config.h similarity index 96% rename from src/examples/standalone/config.h rename to src/examples/wifi/config.h index 6e39aeb..1ce975a 100644 --- a/src/examples/standalone/config.h +++ b/src/examples/wifi/config.h @@ -27,5 +27,6 @@ #define WEB_CONTEXT_PATH "/" #define WEB_DOC_ROOT "/www" #define WEB_DEFAULT_FILE "index.html" +#define WEB_SERVER_PORT 80 #endif \ No newline at end of file diff --git a/src/examples/wifi/main.cpp b/src/examples/wifi/main.cpp new file mode 100644 index 0000000..8e300df --- /dev/null +++ b/src/examples/wifi/main.cpp @@ -0,0 +1,28 @@ +#include "config.h" +#include "WiFiNet.h" +#include "WiFiApp.h" + +WiFiNet wifi( + SPROCKET_MODE, + STATION_SSID, + STATION_PASSWORD, + AP_SSID, + AP_PASSWORD, + HOSTNAME, + CONNECT_TIMEOUT); +WiFiApp sprocket( + {STARTUP_DELAY, SERIAL_BAUD_RATE}, + {WEB_CONTEXT_PATH, WEB_DOC_ROOT, WEB_DEFAULT_FILE, WEB_SERVER_PORT}); + +void setup() +{ + delay(3000); + wifi.connect(); + sprocket.activate(); +} + +void loop() +{ + sprocket.loop(); + yield(); +} \ No newline at end of file diff --git a/src/examples/wifiMesh/MeshApp.h b/src/examples/wifiMesh/MeshApp.h new file mode 100644 index 0000000..e3a272f --- /dev/null +++ b/src/examples/wifiMesh/MeshApp.h @@ -0,0 +1,50 @@ +#ifndef __MESH_APP__ +#define __MESH_APP__ + +#include +#include +#include + +using namespace std; +using namespace std::placeholders; + +class MeshApp : public Sprocket +{ + public: + Task heartbeatTask; + + MeshApp(SprocketConfig cfg, MeshConfig meshCfg) : Sprocket(cfg) + { + addPlugin(new MeshNetworkPlugin(meshCfg)); + subscribe("device/heartbeat", bind(&MeshApp::messageHandler, this, _1)); + } + + Sprocket *activate(Scheduler *scheduler) + { + // add a task that sends stuff to the mesh + heartbeatTask.set(TASK_SECOND * 5, TASK_FOREVER, bind(&MeshApp::heartbeat, this)); + addTask(heartbeatTask); + Serial.println("MeshApp activated"); + return this; + } + using Sprocket::activate; + + void messageHandler(String msg) + { + Serial.println(String("MeshApp: ") + msg); + } + + void heartbeat() + { + SprocketMessage msg; + msg.domain = "wirelos"; + msg.to = "broadcast"; + msg.payload = "alive"; + msg.topic = "device/heartbeat"; + msg.type = SprocketMessage::APP; + String msgStr = msg.toJsonString(); + publish("mesh/broadcast", msgStr); + } +}; + +#endif \ No newline at end of file diff --git a/src/examples/mesh/README.md b/src/examples/wifiMesh/README.md similarity index 100% rename from src/examples/mesh/README.md rename to src/examples/wifiMesh/README.md diff --git a/src/examples/mesh/config.h b/src/examples/wifiMesh/config.h similarity index 97% rename from src/examples/mesh/config.h rename to src/examples/wifiMesh/config.h index e1a48a5..2ac92af 100644 --- a/src/examples/mesh/config.h +++ b/src/examples/wifiMesh/config.h @@ -4,6 +4,7 @@ // Scheduler config #define _TASK_SLEEP_ON_IDLE_RUN #define _TASK_STD_FUNCTION +#define _TASK_PRIORITY // Chip config #define SERIAL_BAUD_RATE 115200 diff --git a/src/examples/wifiMesh/main.cpp b/src/examples/wifiMesh/main.cpp new file mode 100644 index 0000000..009c280 --- /dev/null +++ b/src/examples/wifiMesh/main.cpp @@ -0,0 +1,21 @@ +#include "config.h" +#include "MeshApp.h" + +MeshApp sprocket( + {STARTUP_DELAY, SERIAL_BAUD_RATE}, + {SPROCKET_MODE, WIFI_CHANNEL, + MESH_PORT, MESH_PREFIX, MESH_PASSWORD, + STATION_SSID, STATION_PASSWORD, HOSTNAME, + MESH_DEBUG_TYPES}); + +void setup() +{ + delay(3000); + sprocket.activate(); +} + +void loop() +{ + sprocket.loop(); + yield(); +} \ No newline at end of file diff --git a/src/plugins/MeshManPlugin.cpp b/src/plugins/MeshManPlugin.cpp_ similarity index 98% rename from src/plugins/MeshManPlugin.cpp rename to src/plugins/MeshManPlugin.cpp_ index 324907f..8f4d881 100644 --- a/src/plugins/MeshManPlugin.cpp +++ b/src/plugins/MeshManPlugin.cpp_ @@ -5,7 +5,7 @@ #include "ArduinoOTA.h" #include "MeshNet.h" #include "Plugin.h" -#include +#include #include #include diff --git a/src/plugins/MeshNetworkPlugin.cpp b/src/plugins/MeshNetworkPlugin.cpp new file mode 100644 index 0000000..1b4c571 --- /dev/null +++ b/src/plugins/MeshNetworkPlugin.cpp @@ -0,0 +1,52 @@ +#ifndef __MESH_NETWORK_PLUGIN__ +#define __MESH_NETWORK_PLUGIN__ + +#include "Plugin.h" +#include "TaskSchedulerDeclarations.h" +#include +#include +#include "plugins/NetworkPlugin.cpp" +#include + +using namespace std; +using namespace std::placeholders; + +class MeshNetworkPlugin : public NetworkPlugin +{ + private: + Scheduler *meshScheduler; + + public: + MeshNetworkPlugin(MeshConfig cfg) + { + network = new MeshNet(cfg); + meshScheduler = new Scheduler(); + } + + void activate(Scheduler *userScheduler) + { + userScheduler->setHighPriorityScheduler(meshScheduler); + network->onReceive(bind(&MeshNetworkPlugin::dispatch, this, _1, _2)); + subscribe("mesh/broadcast", bind(&MeshNetworkPlugin::broadcast, this, _1)); + // TODO mesh/sendTo + NetworkPlugin::activate(meshScheduler); + } + void broadcast(String msg) + { + network->broadcast(msg, true); + } + void dispatch(uint32_t from, String &msg) + { + SprocketMessage sMsg; + sMsg.fromJsonString(msg); + if (sMsg.valid) + { + sMsg.from = String(from); + publish(sMsg.topic, sMsg.payload); + return; + } + publish("mesh/message", msg); + } +}; + +#endif \ No newline at end of file diff --git a/src/plugins/NetworkPlugin.cpp b/src/plugins/NetworkPlugin.cpp new file mode 100644 index 0000000..530e0b2 --- /dev/null +++ b/src/plugins/NetworkPlugin.cpp @@ -0,0 +1,28 @@ +#ifndef __NETWORK_PLUGIN__ +#define __NETWORK_PLUGIN__ + +#include "TaskSchedulerDeclarations.h" +#include "Plugin.h" +#include "Network.h" + +class NetworkPlugin : public Plugin +{ + protected: + Network *network; + + public: + NetworkPlugin() {} + NetworkPlugin(Network *net) + { + network = net; + } + + void activate(Scheduler *userScheduler) + { + Serial.println("join network"); + network->init(userScheduler); + network->connect(); + } +}; + +#endif \ No newline at end of file diff --git a/src/plugins/OtaTcpPlugin.cpp b/src/plugins/OtaTcpPlugin.cpp_ similarity index 98% rename from src/plugins/OtaTcpPlugin.cpp rename to src/plugins/OtaTcpPlugin.cpp_ index 746f828..6fcc6f1 100644 --- a/src/plugins/OtaTcpPlugin.cpp +++ b/src/plugins/OtaTcpPlugin.cpp_ @@ -26,7 +26,7 @@ class OtaTcpPlugin : public Plugin { } void connectUpdateNetwork() { Serial.println("OTA connect to update-network"); - net->connectStation(1); + net->connectStation(); } void enable() { Serial.println("OTA enable"); diff --git a/src/plugins/WebConfigPlugin.cpp b/src/plugins/WebConfigPlugin.cpp index 7118b2b..ba56945 100644 --- a/src/plugins/WebConfigPlugin.cpp +++ b/src/plugins/WebConfigPlugin.cpp @@ -5,7 +5,8 @@ #include "TaskSchedulerDeclarations.h" #include "ArduinoOTA.h" #include "Plugin.h" -#include +#include +#include using namespace std; using namespace std::placeholders; @@ -19,7 +20,7 @@ class WebConfigPlugin : public Plugin { server = webServer; server->serveStatic("/config.json", SPIFFS, "config.json"); } - void activate(Scheduler* userScheduler, Network* network){ + void activate(Scheduler* userScheduler){ server->on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){ Serial.println("GET /heap"); request->send(200, "text/plain", String(ESP.getFreeHeap())); diff --git a/src/plugins/WebSO.h b/src/plugins/WebServerConfig.h similarity index 50% rename from src/plugins/WebSO.h rename to src/plugins/WebServerConfig.h index 3a34072..70c2433 100644 --- a/src/plugins/WebSO.h +++ b/src/plugins/WebServerConfig.h @@ -1,13 +1,11 @@ -#ifndef __SHARED_PLUGINS__ -#define __SHARED_PLUGINS__ - -#include -extern AsyncWebServer WEBSERVER; +#ifndef __WEB_SERVER_CONFIG__ +#define __WEB_SERVER_CONFIG__ struct WebServerConfig { const char* contextPath; const char* docRoot; const char* defaultFile; + int port; }; #endif \ No newline at end of file diff --git a/src/plugins/WebServerPlugin.cpp b/src/plugins/WebServerPlugin.cpp index 6758e9a..54bf060 100644 --- a/src/plugins/WebServerPlugin.cpp +++ b/src/plugins/WebServerPlugin.cpp @@ -2,9 +2,10 @@ #define __WEB_SERVER_PLUGIN__ #include +#include #include "TaskSchedulerDeclarations.h" #include "Plugin.h" -#include +#include using namespace std; using namespace std::placeholders; @@ -18,7 +19,7 @@ class WebServerPlugin : public Plugin { config = cfg; server = webServer; } - void activate(Scheduler* userScheduler, Network* network){ + void activate(Scheduler* userScheduler){ server->serveStatic(config.contextPath, SPIFFS, config.docRoot).setDefaultFile(config.defaultFile); // TODO add auth if configured // server->setAuthentication("user", "pass");