From 9e8104da70f7c725708ba8b0daedb597e827004e Mon Sep 17 00:00:00 2001 From: Patrick Balsiger Date: Fri, 16 Nov 2018 19:02:38 +0100 Subject: [PATCH] extract mesh networking to it's own repo --- .gitlab-ci.yml | 1 - README.md | 7 +- platformio.ini | 14 +--- src/MeshConfig.h | 18 ----- src/MeshNet.cpp | 68 ------------------ src/MeshNet.h | 40 ----------- src/MeshSprocketConfig.h | 56 --------------- src/SprocketMessage.h | 4 +- src/TaskScheduler.cpp | 15 ++++ src/examples/wifiMesh/MeshApp.h | 51 ------------- src/examples/wifiMesh/README.md | 7 -- src/examples/wifiMesh/config.h | 34 --------- src/examples/wifiMesh/main.cpp | 21 ------ src/plugins/MeshManPlugin.cpp_ | 71 ------------------- src/plugins/MeshNetworkPlugin.cpp | 47 ------------ .../{OtaTcpPlugin.cpp_ => OtaTcpPlugin.cpp} | 24 +------ src/utils/array.h | 6 ++ 17 files changed, 28 insertions(+), 456 deletions(-) delete mode 100644 src/MeshConfig.h delete mode 100644 src/MeshNet.cpp delete mode 100644 src/MeshNet.h delete mode 100644 src/MeshSprocketConfig.h create mode 100644 src/TaskScheduler.cpp delete mode 100644 src/examples/wifiMesh/MeshApp.h delete mode 100644 src/examples/wifiMesh/README.md delete mode 100644 src/examples/wifiMesh/config.h delete mode 100644 src/examples/wifiMesh/main.cpp delete mode 100644 src/plugins/MeshManPlugin.cpp_ delete mode 100644 src/plugins/MeshNetworkPlugin.cpp rename src/plugins/{OtaTcpPlugin.cpp_ => OtaTcpPlugin.cpp} (70%) create mode 100644 src/utils/array.h diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c5d1bc8..3d3437c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,7 +37,6 @@ firmware-build: - pio run --target clean - pio run --environment basic - pio run --environment wifi - - pio run --environment wifiMesh artifacts: paths: - .pioenvs/*/firmware.* diff --git a/README.md b/README.md index d34695f..f4ce1ed 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,7 @@ # Sprocket-Lib -Library to build a mesh network of Sprockets. ## Lifecycle -TODO docs -sprocket.init -> Serial.begin & SPIFFS.begin -sprocket.join(network) -> network.init & sprocket.activate -> plugins.activate -network->onReceive -> sprocket.dispatch -> plugins.onMessage &sprocket.onMessage - +TODO # Useful commands ```sh diff --git a/platformio.ini b/platformio.ini index 89edae7..73ea9a5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -21,8 +21,6 @@ lib_deps = Hash TaskScheduler SPIFFS - ESP8266mDNS - painlessMesh ;[env:build] ;src_filter = +<*> - @@ -45,15 +43,6 @@ monitor_baud = ${common.monitor_baud} framework = ${common.framework} lib_deps = ${common.lib_deps} -[env:wifiMesh] -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} - [env:wifi] src_filter = +<*> - + platform = ${common.platform} @@ -61,4 +50,5 @@ board = ${common.board} upload_speed = ${common.upload_speed} monitor_baud = ${common.monitor_baud} framework = ${common.framework} -lib_deps = ${common.lib_deps} \ No newline at end of file +lib_deps = ${common.lib_deps} + ESP8266mDNS \ No newline at end of file diff --git a/src/MeshConfig.h b/src/MeshConfig.h deleted file mode 100644 index 1a1d6e0..0000000 --- a/src/MeshConfig.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __MESHCONFIG__ -#define __MESHCONFIG__ - -// FIXME non-mesh config should have it's own struct -struct MeshConfig { - int stationMode; - int channel; - int meshPort; - const char* meshSSID; - const char* meshPassword; - const char* stationSSID; - const char* stationPassword; - const char* hostname; - uint16_t debugTypes; -}; - - -#endif \ No newline at end of file diff --git a/src/MeshNet.cpp b/src/MeshNet.cpp deleted file mode 100644 index 42c08ce..0000000 --- a/src/MeshNet.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "MeshNet.h" - -MeshNet::MeshNet(MeshConfig cfg) : Network() { - config.stationMode = cfg.stationMode; - config.channel = cfg.channel; - config.meshPort = cfg.meshPort; - config.meshSSID = cfg.meshSSID; - config.meshPassword = cfg.meshPassword; - config.stationSSID = cfg.stationSSID; - config.stationPassword = cfg.stationPassword; - config.hostname = cfg.hostname; - config.debugTypes = cfg.debugTypes; -} - -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)); - if(config.stationMode){ - connectStation(); - } - return 1; -} - -int MeshNet::connectStation() { - Serial.println("connect station"); - mesh.stationManual(config.stationSSID, config.stationPassword); - mesh.setHostname(config.hostname.c_str()); - return 1; -} -void MeshNet::sendTo(uint32_t target, String msg){ - mesh.sendSingle(target, msg); -} - -void MeshNet::broadcast(String msg, bool self){ - mesh.sendBroadcast(msg, self); - -} -void MeshNet::update(){ - // only needed when no scheduler was passed to mesh.init - mesh.update(); -} - -// example, not used, to be removed -void MeshNet::onReceive( std::function cb) { - mesh.onReceive(cb); -} - -void MeshNet::newConnectionCallback(uint32_t nodeId) { - Serial.printf("--> New Connection, nodeId = %u\n", nodeId); -} - -void MeshNet::changedConnectionCallback() { - Serial.printf("--> Changed connections %s\n",mesh.subConnectionJson().c_str()); -} - -void MeshNet::nodeTimeAdjustedCallback(int32_t offset) { - Serial.printf("--> Adjusted time %u. Offset = %d\n", mesh.getNodeTime(),offset); -} \ No newline at end of file diff --git a/src/MeshNet.h b/src/MeshNet.h deleted file mode 100644 index 5da24c0..0000000 --- a/src/MeshNet.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __MESHNET_H__ -#define __MESHNET_H__ - -#ifdef ESP32 -#include -#elif defined(ESP8266) -#include -#endif // ESP32 - -#include -#include -#include "Network.h" -#include "MeshConfig.h" -#include "MeshSprocketConfig.h" - -using namespace std; -using namespace std::placeholders; - -class MeshNet : public Network { - public: - painlessMesh mesh; - MeshSprocketConfig config; - MeshNet(MeshConfig cfg); - Network* init(); - 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, bool self = false); - void sendTo(uint32_t target, String msg); - void onReceive(std::function); - int isConnected(){ - return WiFi.status() == WL_CONNECTED; - } -}; - -#endif \ No newline at end of file diff --git a/src/MeshSprocketConfig.h b/src/MeshSprocketConfig.h deleted file mode 100644 index 14f89fc..0000000 --- a/src/MeshSprocketConfig.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef __MESH_SPROCKET_CONFIG__ -#define __MESH_SPROCKET_CONFIG__ - -#include -#include -#include -#include "MeshConfig.h" -#include "SprocketConfig.h" -#include "JsonStruct.h" - -#define JSON_stationMode "stationMode" -#define JSON_channel "channel" -#define JSON_meshPort "meshPort" -#define JSON_meshSSID "meshSSID" -#define JSON_meshPassword "meshPassword" -#define JSON_stationSSID "stationSSID" -#define JSON_stationPassword "stationPassword" -#define JSON_hostname "hostname" - -struct MeshSprocketConfig : public JsonStruct { - int stationMode; - int channel; - int meshPort; - String meshSSID; - String meshPassword; - String stationSSID; - String stationPassword; - String hostname; - uint16_t debugTypes; - - // ------------------------------------------------------------------------------------------ - void mapJsonObject(JsonObject& root) { - root[JSON_stationMode] = stationMode; - root[JSON_channel] = channel; - root[JSON_meshPort] = meshPort; - root[JSON_meshSSID] = meshSSID; - root[JSON_meshPassword] = meshPassword; - root[JSON_stationSSID] = stationSSID; - root[JSON_stationPassword] = stationPassword; - root[JSON_hostname] = hostname; - } - - // Map a json object to this struct. - void fromJsonObject(JsonObject& json) { - stationMode = getIntAttrFromJson(json, JSON_stationMode); - channel = getIntAttrFromJson(json, JSON_channel); - meshPort = getIntAttrFromJson(json, JSON_meshPort); - meshSSID = getAttrFromJson(json, JSON_meshSSID); - meshPassword = getAttrFromJson(json, JSON_meshPassword); - stationSSID = getAttrFromJson(json, JSON_stationSSID); - stationPassword = getAttrFromJson(json, JSON_stationPassword); - hostname = getAttrFromJson(json, JSON_hostname); - }; -}; - -#endif \ No newline at end of file diff --git a/src/SprocketMessage.h b/src/SprocketMessage.h index d80197e..5a0ce4e 100644 --- a/src/SprocketMessage.h +++ b/src/SprocketMessage.h @@ -1,5 +1,5 @@ -#ifndef __MESH_MESSAGE__ -#define __MESH_MESSAGE__ +#ifndef __SPROCKET_MESSAGE__ +#define __SPROCKET_MESSAGE__ #include #include diff --git a/src/TaskScheduler.cpp b/src/TaskScheduler.cpp new file mode 100644 index 0000000..fb4326b --- /dev/null +++ b/src/TaskScheduler.cpp @@ -0,0 +1,15 @@ +/* + * https://github.com/arkhipenko/TaskScheduler/tree/master/examples/Scheduler_example16_Multitab + */ + +// #define _TASK_TIMECRITICAL // Enable monitoring scheduling overruns +// #define _TASK_SLEEP_ON_IDLE_RUN // Enable 1 ms SLEEP_IDLE powerdowns between tasks if no callback methods were invoked during the pass +// #define _TASK_STATUS_REQUEST // Compile with support for StatusRequest functionality - triggering tasks on status change events in addition to time only +// #define _TASK_WDT_IDS // Compile with support for wdt control points and task ids +// #define _TASK_LTS_POINTER // Compile with support for local task storage pointer +#define _TASK_PRIORITY // Support for layered scheduling priority +// #define _TASK_MICRO_RES // Support for microsecond resolution +#define _TASK_STD_FUNCTION // Support for std::function (ESP8266 ONLY) +// #define _TASK_DEBUG // Make all methods and variables public for debug purposes + +#include diff --git a/src/examples/wifiMesh/MeshApp.h b/src/examples/wifiMesh/MeshApp.h deleted file mode 100644 index 696949d..0000000 --- a/src/examples/wifiMesh/MeshApp.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef __MESH_APP__ -#define __MESH_APP__ - -#include -#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); - PRINT_MSG(Serial,"MESH", "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/wifiMesh/README.md b/src/examples/wifiMesh/README.md deleted file mode 100644 index 53e7306..0000000 --- a/src/examples/wifiMesh/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Mesh Sprocket Example - -## OTA -mosquitto_sub -h citadel.lan -p 1883 -v -t '#' - -Enable OTA: -mosquitto_pub -h citadel.lan -p 1883 -t '/down/wirelos/gateway' -m '{"target":"broadcast", "domain": "wirelos", "msg": {"target":"broadcast", "type": 3, msg: "OTA"} }' diff --git a/src/examples/wifiMesh/config.h b/src/examples/wifiMesh/config.h deleted file mode 100644 index 2ac92af..0000000 --- a/src/examples/wifiMesh/config.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __MESH_CONFIG__ -#define __MESH_CONFIG__ - -// Scheduler config -#define _TASK_SLEEP_ON_IDLE_RUN -#define _TASK_STD_FUNCTION -#define _TASK_PRIORITY - -// Chip config -#define SERIAL_BAUD_RATE 115200 -#define STARTUP_DELAY 3000 - -// Mesh config -#define SPROCKET_MODE 0 -#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 "mesh-node" -#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION -//ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE - -// OTA config -#define OTA_PORT 8266 -#define OTA_PASSWORD "" - -// WebServer -#define WEB_CONTEXT_PATH "/" -#define WEB_DOC_ROOT "/www" -#define WEB_DEFAULT_FILE "index.html" - -#endif \ No newline at end of file diff --git a/src/examples/wifiMesh/main.cpp b/src/examples/wifiMesh/main.cpp deleted file mode 100644 index 009c280..0000000 --- a/src/examples/wifiMesh/main.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#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_ deleted file mode 100644 index 8f4d881..0000000 --- a/src/plugins/MeshManPlugin.cpp_ +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef __MESH_MAN_PLUGIN__ -#define __MESH_MAN_PLUGIN__ - -#include "TaskSchedulerDeclarations.h" -#include "ArduinoOTA.h" -#include "MeshNet.h" -#include "Plugin.h" -#include -#include -#include - -using namespace std; -using namespace std::placeholders; - - -class MeshManPlugin : public Plugin { - private: - MeshNet* net; - AsyncWebServer* server; - public: - MeshManPlugin(AsyncWebServer* webServer){ - server = webServer; - } - void activate(Scheduler* userScheduler, Network* network){ - net = static_cast(network); - server->on("/mesh", HTTP_GET, std::bind(&MeshManPlugin::getMeshConnections, this, std::placeholders::_1)); - server->on("/mesh", HTTP_POST, std::bind(&MeshManPlugin::sendMsg, this, std::placeholders::_1)); - server->on("/mesh/nodeId", HTTP_GET, std::bind(&MeshManPlugin::getNodeId, this, std::placeholders::_1)); - server->on("/mesh/broadcast", HTTP_POST, std::bind(&MeshManPlugin::broadcast, this, std::placeholders::_1)); - - subscribe("mesh/heartbeat", std::bind(&MeshManPlugin::gotHeartbeat, this, std::placeholders::_1)); - } - void gotHeartbeat(String msg){ - Serial.println(String("MeshManPlugin / Heartbeat: ") + msg); - } - void getMeshConnections(AsyncWebServerRequest *request) { - request->send(200, "text/plain", net->mesh.subConnectionJson()); - } - void broadcast(AsyncWebServerRequest *request) { - String msg = ""; - if(request->hasParam("msg", true)) { - msg = request->getParam("msg", true)->value(); - } - msg = msg + "\0"; - net->mesh.sendBroadcast(msg); - request->send(200, "text/plain", msg); - } - void sendMsg(AsyncWebServerRequest *request) { - String msg = ""; - uint32_t to = 0; - if(request->hasParam("msg", true)) { - msg = request->getParam("msg", true)->value(); - } - if(request->hasParam("nodeId", true)) { - to = atoi(request->getParam("nodeId", true)->value().c_str()); - } - msg = msg + "\0"; - net->mesh.sendSingle(to, msg); - request->send(200, "text/plain", msg); - } - void getNodeId(AsyncWebServerRequest *request) { - StaticJsonBuffer<200> jsonBuffer; - JsonObject& root = jsonBuffer.createObject(); - root["nodeId"] = net->mesh.getNodeId(); - String jsonString; - root.printTo(jsonString); - request->send(200, "text/plain", jsonString); - } -}; - -#endif \ No newline at end of file diff --git a/src/plugins/MeshNetworkPlugin.cpp b/src/plugins/MeshNetworkPlugin.cpp deleted file mode 100644 index d8398d6..0000000 --- a/src/plugins/MeshNetworkPlugin.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#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 -{ - public: - MeshNetworkPlugin(MeshConfig cfg) - { - network = new MeshNet(cfg); - } - - void activate(Scheduler *userScheduler) - { - network->onReceive(bind(&MeshNetworkPlugin::dispatch, this, _1, _2)); - subscribe("mesh/broadcast", bind(&MeshNetworkPlugin::broadcast, this, _1)); - // TODO mesh/sendTo - NetworkPlugin::activate(userScheduler); - } - 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/OtaTcpPlugin.cpp_ b/src/plugins/OtaTcpPlugin.cpp similarity index 70% rename from src/plugins/OtaTcpPlugin.cpp_ rename to src/plugins/OtaTcpPlugin.cpp index 6fcc6f1..54daa9a 100644 --- a/src/plugins/OtaTcpPlugin.cpp_ +++ b/src/plugins/OtaTcpPlugin.cpp @@ -3,7 +3,6 @@ #include "TaskSchedulerDeclarations.h" #include "ArduinoOTA.h" -#include "MeshNet.h" #include "Plugin.h" using namespace std; @@ -18,39 +17,20 @@ class OtaTcpPlugin : public Plugin { private: OtaConfig config; Task otaTask; - MeshNet* net; public: OtaTcpPlugin(OtaConfig cfg){ config = cfg; } - void connectUpdateNetwork() { - Serial.println("OTA connect to update-network"); - net->connectStation(); - } void enable() { Serial.println("OTA enable"); ArduinoOTA.begin(); otaTask.enable(); } - void onMessage(SprocketMessage msg) { - if(msg.type == SprocketMessage::OTA){ - Serial.println("OTA msg received"); - WiFi.disconnect(); - net->mesh.stop(); - connectUpdateNetwork(); - enable(); - //net->mesh.sendBroadcast("my ip:" + WiFi.localIP().toString(), true); - //net->mesh.sendBroadcast("gw ip:" + WiFi.gatewayIP().toString(), true); - WiFi.gatewayIP().printTo(Serial); - } - } - void activate(Scheduler* userScheduler, Network* network){ - // connect done in network class? - //connectUpdateNetwork(network); - net = static_cast(network); + void activate(Scheduler* userScheduler){ // setup task // TOOD check if we can increase the time OTA needs to be handled + // FIXME make this configurable otaTask.set(TASK_MILLISECOND * 1000, TASK_FOREVER, [](){ ArduinoOTA.handle(); }); diff --git a/src/utils/array.h b/src/utils/array.h new file mode 100644 index 0000000..65b7fd7 --- /dev/null +++ b/src/utils/array.h @@ -0,0 +1,6 @@ +#ifndef __ARRAY_UTILS__ +#define __ARRAY_UTILS__ + +#define ARRAY_LENGTH(array) sizeof(array)/sizeof(array[0]) + +#endif \ No newline at end of file