From b5c050ff47cffcd3c1ee175e12ce4aff89a96955 Mon Sep 17 00:00:00 2001 From: Lukas Bachschwell Date: Fri, 17 May 2019 10:29:48 +0200 Subject: [PATCH] Target structure and websocket lib --- .gitignore | 4 +- platformio.ini | 29 +++++- src/{main.cpp => controller_main.cpp} | 73 ++++++++++------ src/light_main.cpp | 121 ++++++++++++++++++++++++++ 4 files changed, 197 insertions(+), 30 deletions(-) rename src/{main.cpp => controller_main.cpp} (53%) create mode 100644 src/light_main.cpp diff --git a/.gitignore b/.gitignore index 2de98ab..04451df 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ .pio .pioenvs .piolibdeps -.vscode/.browse.c_cpp.db* -.vscode/c_cpp_properties.json -.vscode/launch.json +.vscode diff --git a/platformio.ini b/platformio.ini index a1323e6..aa88a70 100644 --- a/platformio.ini +++ b/platformio.ini @@ -8,7 +8,7 @@ ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html -[env:esp32-poe] +[env] platform = espressif32 board = esp32-poe framework = arduino @@ -16,5 +16,32 @@ framework = arduino upload_port=/dev/tty.wchusbserial230 monitor_baud = 115200 + +[env:controller] +src_filter = + lib_deps = ESP Async WebServer + +[env:LIGHT1] +src_filter = + +lib_deps = + WebSockets +build_flags = -DROLE=LIGHT1 + +[env:LIGHT2] +src_filter = + +lib_deps = + WebSockets +build_flags = -DROLE=LIGHT2 + +[env:LIGHT3] +src_filter = + +lib_deps = + WebSockets +build_flags = -DROLE=LIGHT3 + +[env:LIGHT3] +src_filter = + +lib_deps = + WebSockets +build_flags = -DROLE=LIGHT4 diff --git a/src/main.cpp b/src/controller_main.cpp similarity index 53% rename from src/main.cpp rename to src/controller_main.cpp index 3a914b7..228159b 100644 --- a/src/main.cpp +++ b/src/controller_main.cpp @@ -10,9 +10,44 @@ static bool eth_connected = false; AsyncWebServer server(80); +AsyncWebSocket ws("/ws"); const char *PARAM_MESSAGE = "message"; + +void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ + if(type == WS_EVT_CONNECT){ + Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); + client->printf("Hello Client %u :)", client->id()); + client->ping(); + } else if(type == WS_EVT_DISCONNECT){ + Serial.printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id()); + } else if(type == WS_EVT_ERROR){ + Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); + } else if(type == WS_EVT_PONG){ + Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); + } else if(type == WS_EVT_DATA){ + AwsFrameInfo * info = (AwsFrameInfo*)arg; + String msg = ""; + if(info->final && info->index == 0 && info->len == len){ + //the whole message is in a single frame and we got all of it's data + Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); + + if(info->opcode == WS_TEXT){ + for(size_t i=0; i < info->len; i++) { + msg += (char) data[i]; + } + } + + if(info->opcode == WS_TEXT) + client->text("I got your text message"); + + } else { + Serial.printf("Error: Message in multiple Frames"); + } + } +} + void notFound(AsyncWebServerRequest *request) { request->send(404, "text/plain", "Not found"); } void WiFiEvent(WiFiEvent_t event) { @@ -20,7 +55,7 @@ void WiFiEvent(WiFiEvent_t event) { case SYSTEM_EVENT_ETH_START: Serial.println("ETH Started"); // set eth hostname here - ETH.setHostname("esp32-ethernet"); + ETH.setHostname("a2clcontroller"); break; case SYSTEM_EVENT_ETH_CONNECTED: Serial.println("ETH Connected"); @@ -68,35 +103,21 @@ void setup() { } Serial.println("mDNS responder started"); - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { request->send(200, "text/plain", "Hello, world"); }); - - // Send a GET request to /get?message= - server.on("/get", HTTP_GET, [](AsyncWebServerRequest *request) { - String message; - if (request->hasParam(PARAM_MESSAGE)) { - message = request->getParam(PARAM_MESSAGE)->value(); - } else { - message = "No message sent"; - } - request->send(200, "text/plain", "Hello, GET: " + message); - }); - - // Send a POST request to /post with a form field message set to - server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request) { - String message; - if (request->hasParam(PARAM_MESSAGE, true)) { - message = request->getParam(PARAM_MESSAGE, true)->value(); - } else { - message = "No message sent"; - } - request->send(200, "text/plain", "Hello, POST: " + message); - }); - + ws.onEvent(onWsEvent); + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { request->send(200, "text/plain", "Current Status: To Be done"); }); server.onNotFound(notFound); - server.begin(); + // Add service to MDNS-SD MDNS.addService("http", "tcp", 80); } void loop() {} + + + + + +/////////////////////////// + + diff --git a/src/light_main.cpp b/src/light_main.cpp new file mode 100644 index 0000000..747ab6a --- /dev/null +++ b/src/light_main.cpp @@ -0,0 +1,121 @@ +#include +#include +#include + +#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT +#define ETH_PHY_POWER 12 + +#include + +WebSocketsClient webSocket; + + +static bool eth_connected = false; + +const char *PARAM_MESSAGE = "message"; + +void WiFiEvent(WiFiEvent_t event) { + switch (event) { + case SYSTEM_EVENT_ETH_START: + Serial.println("ETH Started"); + // set eth hostname here + ETH.setHostname("a2clight"); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + Serial.println("ETH Connected"); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + Serial.print("ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + Serial.println("ETH Disconnected"); + eth_connected = false; + break; + case SYSTEM_EVENT_ETH_STOP: + Serial.println("ETH Stopped"); + eth_connected = false; + break; + default: + break; + } +} + +void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { + + switch(type) { + case WStype_DISCONNECTED: + USE_SERIAL.printf("[WSc] Disconnected!\n"); + break; + case WStype_CONNECTED: { + USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); + + // send message to server when Connected + webSocket.sendTXT("Connected"); + } + break; + case WStype_TEXT: + USE_SERIAL.printf("[WSc] get text: %s\n", payload); + + // send message to server + // webSocket.sendTXT("message here"); + break; + case WStype_BIN: + USE_SERIAL.printf("[WSc] get binary length: %u\n", length); + hexdump(payload, length); + + // send data to server + // webSocket.sendBIN(payload, length); + break; + } + +} + +void setup() { + Serial.begin(115200); + WiFi.onEvent(WiFiEvent); + ETH.begin(); + + while (!eth_connected) { + delay(1000); + } + + if (!MDNS.begin("a2clight")) { + Serial.println("Error setting up MDNS responder!, system halt"); + while (1) { + delay(1000); + } + } + Serial.println("mDNS responder started"); + + webSocket.begin("a2clcontroller.local", 80, "/ws"); + webSocket.onEvent(webSocketEvent); + + // use HTTP Basic Authorization this is optional remove if not needed + //webSocket.setAuthorization("user", "Password"); + + // try ever 5000 again if connection has failed + webSocket.setReconnectInterval(5000); + + // start heartbeat (optional) + // ping server every 15000 ms + // expect pong from server within 3000 ms + // consider connection disconnected if pong is not received 2 times + webSocket.enableHeartbeat(15000, 3000, 2); + + // Add service to MDNS-SD + // MDNS.addService("http", "tcp", 80); +} + +void loop() { + webSocket.loop(); +} \ No newline at end of file