mirror of
https://github.com/Links2004/arduinoWebSockets.git
synced 2025-07-12 15:06:30 +02:00
Port to Raspberry Pi Pico W core
Add support for the onboard WiFi chip on the Raspberry Pi Pico W (RP2040 based ) board using the arduino-pico Arduino core at https://github.com/earlephilhower/arduino-pico The PicoW WiFi stack is a mashup of the ESP8266 and ESP32 cores, so only minimal changes were required. Defines a new NETWORK_TYPE for the PicoW. ESP8266 examples renames to ESP8266_PICO because they all work unmodified (except for OTA which is handled differently on the Pico)
This commit is contained in:
committed by
Markus
parent
323592f622
commit
d9a5c629f0
106
examples/esp8266_pico/WebSocketClient/WebSocketClient.ino
Normal file
106
examples/esp8266_pico/WebSocketClient/WebSocketClient.ino
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* WebSocketClient.ino
|
||||
*
|
||||
* Created on: 24.05.2015
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
#include <Hash.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
#define USE_SERIAL Serial1
|
||||
|
||||
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;
|
||||
case WStype_PING:
|
||||
// pong will be send automatically
|
||||
USE_SERIAL.printf("[WSc] get ping\n");
|
||||
break;
|
||||
case WStype_PONG:
|
||||
// answer to a ping we send
|
||||
USE_SERIAL.printf("[WSc] get pong\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
//WiFi.disconnect();
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// server address, port and URL
|
||||
webSocket.begin("192.168.0.123", 81, "/");
|
||||
|
||||
// event handler
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
27
examples/esp8266_pico/WebSocketClientOTA/README.md
Normal file
27
examples/esp8266_pico/WebSocketClientOTA/README.md
Normal file
@ -0,0 +1,27 @@
|
||||
## Minimal example of WebsocketClientOTA and Python server
|
||||
|
||||
Take this as small example, how achieve OTA update on ESP8266 and ESP32.
|
||||
|
||||
Python server was wrote from train so take it only as bare example.
|
||||
It's working, but it's not mean to run in production.
|
||||
|
||||
|
||||
### Usage:
|
||||
|
||||
Start server:
|
||||
```bash
|
||||
cd python_ota_server
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip3 install -r requirements.txt
|
||||
python3 main.py
|
||||
```
|
||||
|
||||
Flash ESP with example sketch and start it.
|
||||
|
||||
Change version inside example sketch to higher and compile it and save it to bin file.
|
||||
|
||||
Rename it to `mydevice-1.0.1-esp8266.bin` and place it inside new folder firmware (server create it).
|
||||
|
||||
When the ESP connect to server, it check if version flashed is equal to fw in firmware folder. If higher FW version is present,
|
||||
start the flash process.
|
268
examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino
Normal file
268
examples/esp8266_pico/WebSocketClientOTA/WebSocketClientOTA.ino
Normal file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* WebSocketClientOTA.ino
|
||||
*
|
||||
* Created on: 25.10.2021
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#if defined(ESP8266)
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <Updater.h>
|
||||
#elif defined(ESP32)
|
||||
#include "WiFi.h"
|
||||
#include "ESPmDNS.h"
|
||||
#include <Update.h>
|
||||
#else
|
||||
#error Unsupported device
|
||||
#endif
|
||||
|
||||
#include <WiFiUdp.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
#include <Hash.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
// Variables:
|
||||
// Settable:
|
||||
const char *version = "1.0.0";
|
||||
const char *name = "mydevice";
|
||||
|
||||
// Others:
|
||||
#ifdef ESP8266
|
||||
const char *chip = "esp8266";
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
const char *chip = "esp32";
|
||||
#endif
|
||||
|
||||
uint32_t maxSketchSpace = 0;
|
||||
int SketchSize = 0;
|
||||
bool ws_conn = false;
|
||||
|
||||
String IpAddress2String(const IPAddress& ipAddress)
|
||||
{
|
||||
return String(ipAddress[0]) + String(".") +
|
||||
String(ipAddress[1]) + String(".") +
|
||||
String(ipAddress[2]) + String(".") +
|
||||
String(ipAddress[3]);
|
||||
}
|
||||
|
||||
void greetings_(){
|
||||
StaticJsonDocument<200> doc;
|
||||
doc["type"] = "greetings";
|
||||
doc["mac"] = WiFi.macAddress();
|
||||
doc["ip"] = IpAddress2String(WiFi.localIP());
|
||||
doc["version"] = version;
|
||||
doc["name"] = name;
|
||||
doc["chip"] = chip;
|
||||
|
||||
char data[200];
|
||||
serializeJson(doc, data);
|
||||
webSocket.sendTXT(data);
|
||||
}
|
||||
|
||||
void register_(){
|
||||
StaticJsonDocument<200> doc;
|
||||
doc["type"] = "register";
|
||||
doc["mac"] = WiFi.macAddress();
|
||||
|
||||
char data[200];
|
||||
serializeJson(doc, data);
|
||||
webSocket.sendTXT(data);
|
||||
ws_conn = true;
|
||||
}
|
||||
|
||||
typedef void (*CALLBACK_FUNCTION)(JsonDocument &msg);
|
||||
|
||||
typedef struct {
|
||||
char type[50];
|
||||
CALLBACK_FUNCTION func;
|
||||
} RESPONSES_STRUCT;
|
||||
|
||||
void OTA(JsonDocument &msg){
|
||||
USE_SERIAL.print(F("[WSc] OTA mode: "));
|
||||
const char* go = "go";
|
||||
const char* ok = "ok";
|
||||
if(strncmp( msg["value"], go, strlen(go)) == 0 ) {
|
||||
USE_SERIAL.print(F("go\n"));
|
||||
SketchSize = int(msg["size"]);
|
||||
maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
|
||||
USE_SERIAL.printf("[WSc] Max sketch size: %u\n", maxSketchSpace);
|
||||
USE_SERIAL.printf("[WSc] Sketch size: %d\n", SketchSize);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
if (!Update.begin(maxSketchSpace)) { //start with max available size
|
||||
Update.printError(Serial);
|
||||
ESP.restart();
|
||||
}
|
||||
} else if (strncmp( msg["value"], ok, strlen(ok)) == 0) {
|
||||
USE_SERIAL.print(F("OK\n"));
|
||||
register_();
|
||||
} else {
|
||||
USE_SERIAL.print(F("unknown value : "));
|
||||
USE_SERIAL.print(msg["value"].as<char>());
|
||||
USE_SERIAL.print(F("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void STATE(JsonDocument &msg){
|
||||
// Do something with message
|
||||
}
|
||||
|
||||
// Count of responses handled by RESPONSES_STRUCT
|
||||
// increase increase if another response handler is added
|
||||
int nrOfResponses = 2;
|
||||
|
||||
RESPONSES_STRUCT responses[] = {
|
||||
{"ota", OTA},
|
||||
{"state", STATE},
|
||||
};
|
||||
|
||||
void text(uint8_t * payload, size_t length){
|
||||
// Convert message to something usable
|
||||
char msgch[length];
|
||||
for (unsigned int i = 0; i < length; i++)
|
||||
{
|
||||
USE_SERIAL.print((char)payload[i]);
|
||||
msgch[i] = ((char)payload[i]);
|
||||
}
|
||||
msgch[length] = '\0';
|
||||
|
||||
// Parse Json
|
||||
StaticJsonDocument<200> doc_in;
|
||||
DeserializationError error = deserializeJson(doc_in, msgch);
|
||||
|
||||
if (error) {
|
||||
USE_SERIAL.print(F("deserializeJson() failed: "));
|
||||
USE_SERIAL.println(error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle each TYPE of message
|
||||
int b = 0;
|
||||
|
||||
for( b=0 ; b<nrOfResponses ; b++ )
|
||||
{
|
||||
if( strncmp(doc_in["type"], responses[b].type, strlen(responses[b].type)) == 0 ) {
|
||||
responses[b].func(doc_in);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
greetings_();
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
|
||||
|
||||
// send message to server
|
||||
// webSocket.sendTXT("message here");
|
||||
text(payload, length);
|
||||
break;
|
||||
case WStype_BIN:
|
||||
USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
|
||||
// hexdump(payload, length);
|
||||
if (Update.write(payload, length) != length) {
|
||||
Update.printError(Serial);
|
||||
ESP.restart();
|
||||
}
|
||||
yield();
|
||||
SketchSize -= length;
|
||||
USE_SERIAL.printf("[WSc] Sketch size left: %u\n", SketchSize);
|
||||
if (SketchSize < 1){
|
||||
if (Update.end(true)) { //true to set the size to the current progress
|
||||
USE_SERIAL.printf("Update Success: \nRebooting...\n");
|
||||
delay(5);
|
||||
yield();
|
||||
ESP.restart();
|
||||
} else {
|
||||
Update.printError(USE_SERIAL);
|
||||
ESP.restart();
|
||||
}
|
||||
USE_SERIAL.setDebugOutput(false);
|
||||
}
|
||||
|
||||
// send data to server
|
||||
// webSocket.sendBIN(payload, length);
|
||||
break;
|
||||
case WStype_PING:
|
||||
// pong will be send automatically
|
||||
USE_SERIAL.printf("[WSc] get ping\n");
|
||||
break;
|
||||
case WStype_PONG:
|
||||
// answer to a ping we send
|
||||
USE_SERIAL.printf("[WSc] get pong\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.print(F("\nMAC: "));
|
||||
USE_SERIAL.println(WiFi.macAddress());
|
||||
USE_SERIAL.print(F("\nDevice: "));
|
||||
USE_SERIAL.println(name);
|
||||
USE_SERIAL.printf("\nVersion: %s\n", version);
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "PASS");
|
||||
|
||||
//WiFi.disconnect();
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// server address, port and URL
|
||||
webSocket.begin("10.0.1.5", 8081, "/");
|
||||
|
||||
// event handler
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
|
||||
// use HTTP Basic Authorization this is optional remove if not needed
|
||||
// webSocket.setAuthorization("USER", "PASS");
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
@ -0,0 +1,235 @@
|
||||
"""Minimal example of Python websocket server
|
||||
handling OTA updates for ESP32 amd ESP8266
|
||||
|
||||
Check and upload of firmware works.
|
||||
Register and state function are jus for example.
|
||||
"""
|
||||
# pylint: disable=W0703,E1101
|
||||
import asyncio
|
||||
import copy
|
||||
import json
|
||||
import logging
|
||||
import subprocess
|
||||
import threading
|
||||
import time
|
||||
from os import listdir
|
||||
from os.path import join as join_pth
|
||||
from pathlib import Path
|
||||
|
||||
import websockets
|
||||
from packaging import version
|
||||
|
||||
# Logger settings
|
||||
logging.basicConfig(filename="ws_server.log")
|
||||
Logger = logging.getLogger('WS-OTA')
|
||||
Logger.addHandler(logging.StreamHandler())
|
||||
Logger.setLevel(logging.INFO)
|
||||
|
||||
# Path to directory with FW
|
||||
fw_path = join_pth(Path().absolute(), "firmware")
|
||||
|
||||
|
||||
def create_path(path: str) -> None:
|
||||
"""Check if path exist or create it"""
|
||||
Path(path).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
def shell(command):
|
||||
"""Handle execution of shell commands"""
|
||||
with subprocess.Popen(command, shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
universal_newlines=True
|
||||
) as process:
|
||||
for stdout_line in iter(process.stdout.readline, ""):
|
||||
Logger.debug(stdout_line)
|
||||
process.stdout.close()
|
||||
return_code = process.wait()
|
||||
Logger.debug("Shell returned: %s", return_code)
|
||||
|
||||
return process.returncode
|
||||
return None
|
||||
|
||||
|
||||
async def binary_send(websocket, fw_file):
|
||||
"""Read firmware file, divide it to chunks and send them"""
|
||||
with open(fw_file, "rb") as binaryfile:
|
||||
|
||||
while True:
|
||||
chunk = binaryfile.read(4096)
|
||||
if not chunk:
|
||||
break
|
||||
try:
|
||||
await websocket.send(chunk)
|
||||
except Exception as exception:
|
||||
Logger.exception(exception)
|
||||
return False
|
||||
asyncio.sleep(0.2)
|
||||
|
||||
|
||||
def version_checker(name, vdev, vapp):
|
||||
"""Parse and compare FW version"""
|
||||
|
||||
if version.parse(vdev) < version.parse(vapp):
|
||||
Logger.info("Client(%s) version %s is smaller than %s: Go for update", name, vdev, vapp)
|
||||
return True
|
||||
Logger.info("Client(%s) version %s is greater or equal to %s: Not updating", name, vdev, vapp)
|
||||
return False
|
||||
|
||||
|
||||
class WsOtaHandler (threading.Thread):
|
||||
"""Thread handling ota update
|
||||
|
||||
Running ota directly from message would kill WS
|
||||
as message bus would timeout.
|
||||
"""
|
||||
def __init__(self, name, message, websocket):
|
||||
threading.Thread.__init__(self, daemon=True)
|
||||
self.name = name
|
||||
self.msg = message
|
||||
self.websocket = websocket
|
||||
|
||||
def run(self, ):
|
||||
try:
|
||||
asyncio.run(self.start_())
|
||||
except Exception as exception:
|
||||
Logger.exception(exception)
|
||||
finally:
|
||||
pass
|
||||
|
||||
async def start_(self):
|
||||
"""Start _ota se asyncio future"""
|
||||
msg_task = asyncio.ensure_future(
|
||||
self._ota())
|
||||
|
||||
done, pending = await asyncio.wait(
|
||||
[msg_task],
|
||||
return_when=asyncio.FIRST_COMPLETED,
|
||||
)
|
||||
Logger.info("WS Ota Handler done: %s", done)
|
||||
for task in pending:
|
||||
task.cancel()
|
||||
|
||||
async def _ota(self):
|
||||
"""Check for new fw and update or pass"""
|
||||
device_name = self.msg['name']
|
||||
device_chip = self.msg['chip']
|
||||
device_version = self.msg['version']
|
||||
fw_version = ''
|
||||
fw_name = ''
|
||||
fw_device = ''
|
||||
|
||||
for filename in listdir(fw_path):
|
||||
fw_info = filename.split("-")
|
||||
fw_device = fw_info[0]
|
||||
if fw_device == device_name:
|
||||
fw_version = fw_info[1]
|
||||
fw_name = filename
|
||||
break
|
||||
|
||||
if not fw_version:
|
||||
Logger.info("Client(%s): No fw found!", device_name)
|
||||
msg = '{"type": "ota", "value":"ok"}'
|
||||
await self.websocket.send(msg)
|
||||
return
|
||||
|
||||
if not version_checker(device_name, device_version, fw_version):
|
||||
return
|
||||
|
||||
fw_file = join_pth(fw_path, fw_name)
|
||||
if device_chip == 'esp8266' and not fw_file.endswith('.gz'):
|
||||
# We can compress fw to make it smaller for upload
|
||||
fw_cpress = fw_file
|
||||
fw_file = fw_cpress + ".gz"
|
||||
cpress = f"gzip -9 {fw_cpress}"
|
||||
cstate = shell(cpress)
|
||||
if cstate:
|
||||
Logger.error("Cannot compress firmware: %s", fw_name)
|
||||
return
|
||||
|
||||
# Get size of fw
|
||||
size = Path(fw_file).stat().st_size
|
||||
|
||||
# Request ota mode
|
||||
msg = '{"type": "ota", "value":"go", "size":' + str(size) + '}'
|
||||
await self.websocket.send(msg)
|
||||
|
||||
# send file by chunks trough websocket
|
||||
await binary_send(self.websocket, fw_file)
|
||||
|
||||
|
||||
async def _register(websocket, message):
|
||||
mac = message.get('mac')
|
||||
name = message.get('name')
|
||||
Logger.info("Client(%s) mac: %s", name, mac)
|
||||
# Some code
|
||||
|
||||
response = {'type': 'registry', 'state': 'ok'}
|
||||
await websocket.send(json.dumps(response))
|
||||
|
||||
|
||||
async def _state(websocket, message):
|
||||
mac = message.get('mac')
|
||||
name = message.get('name')
|
||||
Logger.info("Client(%s) mac: %s", name, mac)
|
||||
# Some code
|
||||
|
||||
response = {'type': 'state', 'state': 'ok'}
|
||||
await websocket.send(json.dumps(response))
|
||||
|
||||
|
||||
async def _unhandled(websocket, msg):
|
||||
Logger.info("Unhandled message from device: %s", str(msg))
|
||||
response = {'type': 'response', 'state': 'nok'}
|
||||
await websocket.send(json.dumps(response))
|
||||
|
||||
|
||||
async def _greetings(websocket, message):
|
||||
WsOtaHandler('thread_ota', copy.deepcopy(message), websocket).start()
|
||||
|
||||
|
||||
async def message_received(websocket, message) -> None:
|
||||
"""Handle incoming messages
|
||||
|
||||
Check if message contain json and run waned function
|
||||
"""
|
||||
switcher = {"greetings": _greetings,
|
||||
"register": _register,
|
||||
"state": _state
|
||||
}
|
||||
|
||||
if message[0:1] == "{":
|
||||
try:
|
||||
msg_json = json.loads(message)
|
||||
except Exception as exception:
|
||||
Logger.error(exception)
|
||||
return
|
||||
|
||||
type_ = msg_json.get('type')
|
||||
name = msg_json.get('name')
|
||||
func = switcher.get(type_, _unhandled)
|
||||
Logger.debug("Client(%s)said: %s", name, type_)
|
||||
|
||||
try:
|
||||
await func(websocket, msg_json)
|
||||
except Exception as exception:
|
||||
Logger.error(exception)
|
||||
|
||||
|
||||
# pylint: disable=W0613
|
||||
async def ws_server(websocket, path) -> None:
|
||||
"""Run in cycle and wait for new messages"""
|
||||
async for message in websocket:
|
||||
await message_received(websocket, message)
|
||||
|
||||
|
||||
async def main():
|
||||
"""Server starter
|
||||
|
||||
Normal user can bind only port numbers greater than 1024
|
||||
"""
|
||||
async with websockets.serve(ws_server, "10.0.1.5", 8081):
|
||||
await asyncio.Future() # run forever
|
||||
|
||||
|
||||
create_path(fw_path)
|
||||
asyncio.run(main())
|
@ -0,0 +1,2 @@
|
||||
packaging
|
||||
websockets
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* WebSocketClientSSL.ino
|
||||
*
|
||||
* Created on: 10.12.2015
|
||||
*
|
||||
* note SSL is only possible with the ESP8266
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
#include <Hash.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
|
||||
#define USE_SERIAL Serial1
|
||||
|
||||
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() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
//WiFi.disconnect();
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
webSocket.beginSSL("192.168.0.123", 81);
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* WebSocketClientSSLWithCA.ino
|
||||
*
|
||||
* Created on: 27.10.2019
|
||||
*
|
||||
* note SSL is only possible with the ESP8266
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
#define USE_SERIAL Serial1
|
||||
|
||||
|
||||
// Can be obtained with:
|
||||
// openssl s_client -showcerts -connect echo.websocket.org:443 </dev/null
|
||||
const char ENDPOINT_CA_CERT[] PROGMEM = R"EOF(
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
|
||||
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0NlowSjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
|
||||
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
|
||||
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
|
||||
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWAa6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
|
||||
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
|
||||
CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNvbTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
|
||||
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAwVAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
|
||||
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
|
||||
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsFAAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
|
||||
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
|
||||
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlGPfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
|
||||
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
|
||||
-----END CERTIFICATE-----
|
||||
)EOF";
|
||||
|
||||
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() {
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
//When using BearSSL, client certificate and private key can be set:
|
||||
//webSocket.setSSLClientCertKey(clientCert, clientPrivateKey);
|
||||
//clientCert and clientPrivateKey can be of types (const char *, const char *) , or of types (BearSSL::X509List, BearSSL::PrivateKey)
|
||||
|
||||
webSocket.beginSslWithCA("echo.websocket.org", 443, "/", ENDPOINT_CA_CERT);
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* WebSocketClientSocketIO.ino
|
||||
*
|
||||
* Created on: 06.06.2016
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include <WebSocketsClient.h>
|
||||
#include <SocketIOclient.h>
|
||||
|
||||
#include <Hash.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
SocketIOclient socketIO;
|
||||
|
||||
#define USE_SERIAL Serial1
|
||||
|
||||
void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) {
|
||||
switch(type) {
|
||||
case sIOtype_DISCONNECT:
|
||||
USE_SERIAL.printf("[IOc] Disconnected!\n");
|
||||
break;
|
||||
case sIOtype_CONNECT:
|
||||
USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload);
|
||||
|
||||
// join default namespace (no auto join in Socket.IO V3)
|
||||
socketIO.send(sIOtype_CONNECT, "/");
|
||||
break;
|
||||
case sIOtype_EVENT:
|
||||
USE_SERIAL.printf("[IOc] get event: %s\n", payload);
|
||||
break;
|
||||
case sIOtype_ACK:
|
||||
USE_SERIAL.printf("[IOc] get ack: %u\n", length);
|
||||
hexdump(payload, length);
|
||||
break;
|
||||
case sIOtype_ERROR:
|
||||
USE_SERIAL.printf("[IOc] get error: %u\n", length);
|
||||
hexdump(payload, length);
|
||||
break;
|
||||
case sIOtype_BINARY_EVENT:
|
||||
USE_SERIAL.printf("[IOc] get binary: %u\n", length);
|
||||
hexdump(payload, length);
|
||||
break;
|
||||
case sIOtype_BINARY_ACK:
|
||||
USE_SERIAL.printf("[IOc] get binary ack: %u\n", length);
|
||||
hexdump(payload, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// disable AP
|
||||
if(WiFi.getMode() & WIFI_AP) {
|
||||
WiFi.softAPdisconnect(true);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
//WiFi.disconnect();
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
String ip = WiFi.localIP().toString();
|
||||
USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str());
|
||||
|
||||
// server address, port and URL
|
||||
socketIO.begin("10.11.100.100", 8880, "/socket.io/?EIO=4");
|
||||
|
||||
// event handler
|
||||
socketIO.onEvent(socketIOEvent);
|
||||
}
|
||||
|
||||
unsigned long messageTimestamp = 0;
|
||||
void loop() {
|
||||
socketIO.loop();
|
||||
|
||||
uint64_t now = millis();
|
||||
|
||||
if(now - messageTimestamp > 2000) {
|
||||
messageTimestamp = now;
|
||||
|
||||
// creat JSON message for Socket.IO (event)
|
||||
DynamicJsonDocument doc(1024);
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
|
||||
// add evnet name
|
||||
// Hint: socket.on('event_name', ....
|
||||
array.add("event_name");
|
||||
|
||||
// add payload (parameters) for the event
|
||||
JsonObject param1 = array.createNestedObject();
|
||||
param1["now"] = (uint32_t) now;
|
||||
|
||||
// JSON to String (serializion)
|
||||
String output;
|
||||
serializeJson(doc, output);
|
||||
|
||||
// Send event
|
||||
socketIO.sendEVENT(output);
|
||||
|
||||
// Print JSON for debugging
|
||||
USE_SERIAL.println(output);
|
||||
}
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* WebSocketClientSocketIOack.ino
|
||||
*
|
||||
* Created on: 20.07.2019
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include <WebSocketsClient.h>
|
||||
#include <SocketIOclient.h>
|
||||
|
||||
#include <Hash.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
SocketIOclient socketIO;
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
|
||||
void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) {
|
||||
switch(type) {
|
||||
case sIOtype_DISCONNECT:
|
||||
USE_SERIAL.printf("[IOc] Disconnected!\n");
|
||||
break;
|
||||
case sIOtype_CONNECT:
|
||||
USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload);
|
||||
|
||||
// join default namespace (no auto join in Socket.IO V3)
|
||||
socketIO.send(sIOtype_CONNECT, "/");
|
||||
break;
|
||||
case sIOtype_EVENT:
|
||||
{
|
||||
char * sptr = NULL;
|
||||
int id = strtol((char *)payload, &sptr, 10);
|
||||
USE_SERIAL.printf("[IOc] get event: %s id: %d\n", payload, id);
|
||||
if(id) {
|
||||
payload = (uint8_t *)sptr;
|
||||
}
|
||||
DynamicJsonDocument doc(1024);
|
||||
DeserializationError error = deserializeJson(doc, payload, length);
|
||||
if(error) {
|
||||
USE_SERIAL.print(F("deserializeJson() failed: "));
|
||||
USE_SERIAL.println(error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
String eventName = doc[0];
|
||||
USE_SERIAL.printf("[IOc] event name: %s\n", eventName.c_str());
|
||||
|
||||
// Message Includes a ID for a ACK (callback)
|
||||
if(id) {
|
||||
// creat JSON message for Socket.IO (ack)
|
||||
DynamicJsonDocument docOut(1024);
|
||||
JsonArray array = docOut.to<JsonArray>();
|
||||
|
||||
// add payload (parameters) for the ack (callback function)
|
||||
JsonObject param1 = array.createNestedObject();
|
||||
param1["now"] = millis();
|
||||
|
||||
// JSON to String (serializion)
|
||||
String output;
|
||||
output += id;
|
||||
serializeJson(docOut, output);
|
||||
|
||||
// Send event
|
||||
socketIO.send(sIOtype_ACK, output);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case sIOtype_ACK:
|
||||
USE_SERIAL.printf("[IOc] get ack: %u\n", length);
|
||||
hexdump(payload, length);
|
||||
break;
|
||||
case sIOtype_ERROR:
|
||||
USE_SERIAL.printf("[IOc] get error: %u\n", length);
|
||||
hexdump(payload, length);
|
||||
break;
|
||||
case sIOtype_BINARY_EVENT:
|
||||
USE_SERIAL.printf("[IOc] get binary: %u\n", length);
|
||||
hexdump(payload, length);
|
||||
break;
|
||||
case sIOtype_BINARY_ACK:
|
||||
USE_SERIAL.printf("[IOc] get binary ack: %u\n", length);
|
||||
hexdump(payload, length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
//USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// disable AP
|
||||
if(WiFi.getMode() & WIFI_AP) {
|
||||
WiFi.softAPdisconnect(true);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
//WiFi.disconnect();
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
String ip = WiFi.localIP().toString();
|
||||
USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str());
|
||||
|
||||
// server address, port and URL
|
||||
socketIO.begin("10.11.100.100", 8880, "/socket.io/?EIO=4");
|
||||
|
||||
// event handler
|
||||
socketIO.onEvent(socketIOEvent);
|
||||
}
|
||||
|
||||
unsigned long messageTimestamp = 0;
|
||||
void loop() {
|
||||
socketIO.loop();
|
||||
|
||||
uint64_t now = millis();
|
||||
|
||||
if(now - messageTimestamp > 2000) {
|
||||
messageTimestamp = now;
|
||||
|
||||
// creat JSON message for Socket.IO (event)
|
||||
DynamicJsonDocument doc(1024);
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
|
||||
// add evnet name
|
||||
// Hint: socket.on('event_name', ....
|
||||
array.add("event_name");
|
||||
|
||||
// add payload (parameters) for the event
|
||||
JsonObject param1 = array.createNestedObject();
|
||||
param1["now"] = (uint32_t) now;
|
||||
|
||||
// JSON to String (serializion)
|
||||
String output;
|
||||
serializeJson(doc, output);
|
||||
|
||||
// Send event
|
||||
socketIO.sendEVENT(output);
|
||||
|
||||
// Print JSON for debugging
|
||||
USE_SERIAL.println(output);
|
||||
}
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
/*
|
||||
WebSocketClientStomp.ino
|
||||
|
||||
Example for connecting and maintining a connection with a STOMP websocket connection.
|
||||
In this example, we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html).
|
||||
|
||||
Created on: 25.09.2017
|
||||
Author: Martin Becker <mgbckr>, Contact: becker@informatik.uni-wuerzburg.de
|
||||
*/
|
||||
|
||||
// PRE
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
|
||||
// LIBRARIES
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Hash.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
|
||||
// SETTINGS
|
||||
|
||||
const char* wlan_ssid = "yourssid";
|
||||
const char* wlan_password = "somepassword";
|
||||
|
||||
const char* ws_host = "the.host.net";
|
||||
const int ws_port = 80;
|
||||
|
||||
// URL for STOMP endpoint.
|
||||
// For the default config of Spring's STOMP support, the default URL is "/socketentry/websocket".
|
||||
const char* stompUrl = "/socketentry/websocket"; // don't forget the leading "/" !!!
|
||||
|
||||
|
||||
// VARIABLES
|
||||
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
|
||||
// FUNCTIONS
|
||||
|
||||
/**
|
||||
* STOMP messages need to be NULL-terminated (i.e., \0 or \u0000).
|
||||
* However, when we send a String or a char[] array without specifying
|
||||
* a length, the size of the message payload is derived by strlen() internally,
|
||||
* thus dropping any NULL values appended to the "msg"-String.
|
||||
*
|
||||
* To solve this, we first convert the String to a NULL terminated char[] array
|
||||
* via "c_str" and set the length of the payload to include the NULL value.
|
||||
*/
|
||||
void sendMessage(String & msg) {
|
||||
webSocket.sendTXT(msg.c_str(), msg.length() + 1);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
String msg = "CONNECT\r\naccept-version:1.1,1.0\r\nheart-beat:10000,10000\r\n\r\n";
|
||||
sendMessage(msg);
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
{
|
||||
// #####################
|
||||
// handle STOMP protocol
|
||||
// #####################
|
||||
|
||||
String text = (char*) payload;
|
||||
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
|
||||
|
||||
if (text.startsWith("CONNECTED")) {
|
||||
|
||||
// subscribe to some channels
|
||||
|
||||
String msg = "SUBSCRIBE\nid:sub-0\ndestination:/user/queue/messages\n\n";
|
||||
sendMessage(msg);
|
||||
delay(1000);
|
||||
|
||||
// and send a message
|
||||
|
||||
msg = "SEND\ndestination:/app/message\n\n{\"user\":\"esp\",\"message\":\"Hello!\"}";
|
||||
sendMessage(msg);
|
||||
delay(1000);
|
||||
|
||||
} else {
|
||||
|
||||
// do something with messages
|
||||
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
// setup serial
|
||||
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
// USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
|
||||
|
||||
// connect to WiFi
|
||||
|
||||
USE_SERIAL.print("Logging into WLAN: "); Serial.print(wlan_ssid); Serial.print(" ...");
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(wlan_ssid, wlan_password);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
USE_SERIAL.print(".");
|
||||
}
|
||||
USE_SERIAL.println(" success.");
|
||||
USE_SERIAL.print("IP: "); USE_SERIAL.println(WiFi.localIP());
|
||||
|
||||
|
||||
// connect to websocket
|
||||
webSocket.begin(ws_host, ws_port, stompUrl);
|
||||
webSocket.setExtraHeaders(); // remove "Origin: file://" header because it breaks the connection with Spring's default websocket config
|
||||
// webSocket.setExtraHeaders("foo: I am so funny\r\nbar: not"); // some headers, in case you feel funny
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
/*
|
||||
WebSocketClientStompOverSockJs.ino
|
||||
|
||||
Example for connecting and maintining a connection with a SockJS+STOMP websocket connection.
|
||||
In this example, we connect to a Spring application (see https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html).
|
||||
|
||||
Created on: 18.07.2017
|
||||
Author: Martin Becker <mgbckr>, Contact: becker@informatik.uni-wuerzburg.de
|
||||
*/
|
||||
|
||||
// PRE
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
|
||||
// LIBRARIES
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Hash.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WebSocketsClient.h>
|
||||
|
||||
|
||||
// SETTINGS
|
||||
|
||||
const char* wlan_ssid = "yourssid";
|
||||
const char* wlan_password = "somepassword";
|
||||
|
||||
const char* ws_host = "the.host.net";
|
||||
const int ws_port = 80;
|
||||
|
||||
// base URL for SockJS (websocket) connection
|
||||
// The complete URL will look something like this(cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36):
|
||||
// ws://<ws_host>:<ws_port>/<ws_baseurl>/<3digits>/<randomstring>/websocket
|
||||
// For the default config of Spring's SockJS/STOMP support, the default base URL is "/socketentry/".
|
||||
const char* ws_baseurl = "/socketentry/"; // don't forget leading and trailing "/" !!!
|
||||
|
||||
|
||||
// VARIABLES
|
||||
|
||||
WebSocketsClient webSocket;
|
||||
|
||||
|
||||
// FUNCTIONS
|
||||
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
{
|
||||
// #####################
|
||||
// handle SockJs+STOMP protocol
|
||||
// #####################
|
||||
|
||||
String text = (char*) payload;
|
||||
|
||||
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
|
||||
|
||||
if (payload[0] == 'h') {
|
||||
|
||||
USE_SERIAL.println("Heartbeat!");
|
||||
|
||||
} else if (payload[0] == 'o') {
|
||||
|
||||
// on open connection
|
||||
char *msg = "[\"CONNECT\\naccept-version:1.1,1.0\\nheart-beat:10000,10000\\n\\n\\u0000\"]";
|
||||
webSocket.sendTXT(msg);
|
||||
|
||||
} else if (text.startsWith("a[\"CONNECTED")) {
|
||||
|
||||
// subscribe to some channels
|
||||
|
||||
char *msg = "[\"SUBSCRIBE\\nid:sub-0\\ndestination:/user/queue/messages\\n\\n\\u0000\"]";
|
||||
webSocket.sendTXT(msg);
|
||||
delay(1000);
|
||||
|
||||
// and send a message
|
||||
|
||||
msg = "[\"SEND\\ndestination:/app/message\\n\\n{\\\"user\\\":\\\"esp\\\",\\\"message\\\":\\\"Hello!\\\"}\\u0000\"]";
|
||||
webSocket.sendTXT(msg);
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
// setup serial
|
||||
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
// USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
|
||||
|
||||
// connect to WiFi
|
||||
|
||||
USE_SERIAL.print("Logging into WLAN: "); Serial.print(wlan_ssid); Serial.print(" ...");
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(wlan_ssid, wlan_password);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
USE_SERIAL.print(".");
|
||||
}
|
||||
USE_SERIAL.println(" success.");
|
||||
USE_SERIAL.print("IP: "); USE_SERIAL.println(WiFi.localIP());
|
||||
|
||||
|
||||
// #####################
|
||||
// create socket url according to SockJS protocol (cf. http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html#section-36)
|
||||
// #####################
|
||||
String socketUrl = ws_baseurl;
|
||||
socketUrl += random(0, 999);
|
||||
socketUrl += "/";
|
||||
socketUrl += random(0, 999999); // should be a random string, but this works (see )
|
||||
socketUrl += "/websocket";
|
||||
|
||||
// connect to websocket
|
||||
webSocket.begin(ws_host, ws_port, socketUrl);
|
||||
webSocket.setExtraHeaders(); // remove "Origin: file://" header because it breaks the connection with Spring's default websocket config
|
||||
// webSocket.setExtraHeaders("foo: I am so funny\r\nbar: not"); // some headers, in case you feel funny
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
86
examples/esp8266_pico/WebSocketServer/WebSocketServer.ino
Normal file
86
examples/esp8266_pico/WebSocketServer/WebSocketServer.ino
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* WebSocketServer.ino
|
||||
*
|
||||
* Created on: 22.05.2015
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
#include <WebSocketsServer.h>
|
||||
#include <Hash.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
WebSocketsServer webSocket = WebSocketsServer(81);
|
||||
|
||||
#define USE_SERIAL Serial1
|
||||
|
||||
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
|
||||
|
||||
switch(type) {
|
||||
case WStype_DISCONNECTED:
|
||||
USE_SERIAL.printf("[%u] Disconnected!\n", num);
|
||||
break;
|
||||
case WStype_CONNECTED:
|
||||
{
|
||||
IPAddress ip = webSocket.remoteIP(num);
|
||||
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
|
||||
|
||||
// send message to client
|
||||
webSocket.sendTXT(num, "Connected");
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
|
||||
|
||||
// send message to client
|
||||
// webSocket.sendTXT(num, "message here");
|
||||
|
||||
// send data to all connected clients
|
||||
// webSocket.broadcastTXT("message here");
|
||||
break;
|
||||
case WStype_BIN:
|
||||
USE_SERIAL.printf("[%u] get binary length: %u\n", num, length);
|
||||
hexdump(payload, length);
|
||||
|
||||
// send message to client
|
||||
// webSocket.sendBIN(num, payload, length);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
webSocket.begin();
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
||||
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* WebSocketServerAllFunctionsDemo.ino
|
||||
*
|
||||
* Created on: 10.05.2018
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
#include <WebSocketsServer.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <Hash.h>
|
||||
|
||||
#define LED_RED 15
|
||||
#define LED_GREEN 12
|
||||
#define LED_BLUE 13
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
ESP8266WebServer server(80);
|
||||
WebSocketsServer webSocket = WebSocketsServer(81);
|
||||
|
||||
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
|
||||
|
||||
switch(type) {
|
||||
case WStype_DISCONNECTED:
|
||||
USE_SERIAL.printf("[%u] Disconnected!\n", num);
|
||||
break;
|
||||
case WStype_CONNECTED: {
|
||||
IPAddress ip = webSocket.remoteIP(num);
|
||||
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
|
||||
|
||||
// send message to client
|
||||
webSocket.sendTXT(num, "Connected");
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
|
||||
|
||||
if(payload[0] == '#') {
|
||||
// we get RGB data
|
||||
|
||||
// decode rgb data
|
||||
uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16);
|
||||
|
||||
analogWrite(LED_RED, ((rgb >> 16) & 0xFF));
|
||||
analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF));
|
||||
analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
//USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
pinMode(LED_RED, OUTPUT);
|
||||
pinMode(LED_GREEN, OUTPUT);
|
||||
pinMode(LED_BLUE, OUTPUT);
|
||||
|
||||
digitalWrite(LED_RED, 1);
|
||||
digitalWrite(LED_GREEN, 1);
|
||||
digitalWrite(LED_BLUE, 1);
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// start webSocket server
|
||||
webSocket.begin();
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
|
||||
if(MDNS.begin("esp8266")) {
|
||||
USE_SERIAL.println("MDNS responder started");
|
||||
}
|
||||
|
||||
// handle index
|
||||
server.on("/", []() {
|
||||
// send index.html
|
||||
server.send(200, "text/html", "<html><head><script>var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);connection.onopen = function () { connection.send('Connect ' + new Date()); }; connection.onerror = function (error) { console.log('WebSocket Error ', error);};connection.onmessage = function (e) { console.log('Server: ', e.data);};function sendRGB() { var r = parseInt(document.getElementById('r').value).toString(16); var g = parseInt(document.getElementById('g').value).toString(16); var b = parseInt(document.getElementById('b').value).toString(16); if(r.length < 2) { r = '0' + r; } if(g.length < 2) { g = '0' + g; } if(b.length < 2) { b = '0' + b; } var rgb = '#'+r+g+b; console.log('RGB: ' + rgb); connection.send(rgb); }</script></head><body>LED Control:<br/><br/>R: <input id=\"r\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>G: <input id=\"g\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>B: <input id=\"b\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/></body></html>");
|
||||
});
|
||||
|
||||
server.begin();
|
||||
|
||||
// Add service to MDNS
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
MDNS.addService("ws", "tcp", 81);
|
||||
|
||||
digitalWrite(LED_RED, 0);
|
||||
digitalWrite(LED_GREEN, 0);
|
||||
digitalWrite(LED_BLUE, 0);
|
||||
|
||||
}
|
||||
|
||||
unsigned long last_10sec = 0;
|
||||
unsigned int counter = 0;
|
||||
|
||||
void loop() {
|
||||
unsigned long t = millis();
|
||||
webSocket.loop();
|
||||
server.handleClient();
|
||||
|
||||
if((t - last_10sec) > 10 * 1000) {
|
||||
counter++;
|
||||
bool ping = (counter % 2);
|
||||
int i = webSocket.connectedClients(ping);
|
||||
USE_SERIAL.printf("%d Connected websocket clients ping: %d\n", i, ping);
|
||||
last_10sec = millis();
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* WebSocketServer.ino
|
||||
*
|
||||
* Created on: 22.05.2015
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
#include <WebSocketsServer.h>
|
||||
#include <Hash.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
WebSocketsServer webSocket = WebSocketsServer(81);
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
String fragmentBuffer = "";
|
||||
|
||||
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
|
||||
|
||||
switch(type) {
|
||||
case WStype_DISCONNECTED:
|
||||
USE_SERIAL.printf("[%u] Disconnected!\n", num);
|
||||
break;
|
||||
case WStype_CONNECTED: {
|
||||
IPAddress ip = webSocket.remoteIP(num);
|
||||
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
|
||||
|
||||
// send message to client
|
||||
webSocket.sendTXT(num, "Connected");
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
|
||||
break;
|
||||
case WStype_BIN:
|
||||
USE_SERIAL.printf("[%u] get binary length: %u\n", num, length);
|
||||
hexdump(payload, length);
|
||||
break;
|
||||
|
||||
// Fragmentation / continuation opcode handling
|
||||
// case WStype_FRAGMENT_BIN_START:
|
||||
case WStype_FRAGMENT_TEXT_START:
|
||||
fragmentBuffer = (char*)payload;
|
||||
USE_SERIAL.printf("[%u] get start start of Textfragment: %s\n", num, payload);
|
||||
break;
|
||||
case WStype_FRAGMENT:
|
||||
fragmentBuffer += (char*)payload;
|
||||
USE_SERIAL.printf("[%u] get Textfragment : %s\n", num, payload);
|
||||
break;
|
||||
case WStype_FRAGMENT_FIN:
|
||||
fragmentBuffer += (char*)payload;
|
||||
USE_SERIAL.printf("[%u] get end of Textfragment: %s\n", num, payload);
|
||||
USE_SERIAL.printf("[%u] full frame: %s\n", num, fragmentBuffer.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
webSocket.begin();
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
||||
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* WebSocketServerHooked.ino
|
||||
*
|
||||
* Created on: 22.05.2015
|
||||
* Hooked on: 28.10.2020
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
#include <WebSockets4WebServer.h>
|
||||
#include <Hash.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
ESP8266WebServer server(80);
|
||||
WebSockets4WebServer webSocket;
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
|
||||
|
||||
switch(type) {
|
||||
case WStype_DISCONNECTED:
|
||||
USE_SERIAL.printf("[%u] Disconnected!\n", num);
|
||||
break;
|
||||
case WStype_CONNECTED:
|
||||
{
|
||||
IPAddress ip = webSocket.remoteIP(num);
|
||||
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
|
||||
|
||||
// send message to client
|
||||
webSocket.sendTXT(num, "Connected");
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
|
||||
|
||||
// send message to client
|
||||
// webSocket.sendTXT(num, "message here");
|
||||
|
||||
// send data to all connected clients
|
||||
// webSocket.broadcastTXT("message here");
|
||||
break;
|
||||
case WStype_BIN:
|
||||
USE_SERIAL.printf("[%u] get binary length: %u\n", num, length);
|
||||
hexdump(payload, length);
|
||||
|
||||
// send message to client
|
||||
// webSocket.sendBIN(num, payload, length);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
server.on("/", []() {
|
||||
server.send(200, "text/plain", "I am a regular webserver on port 80!\r\n");
|
||||
server.send(200, "text/plain", "I am also a websocket server on '/ws' on the same port 80\r\n");
|
||||
});
|
||||
|
||||
server.addHook(webSocket.hookForWebserver("/ws", webSocketEvent));
|
||||
|
||||
server.begin();
|
||||
Serial.println("HTTP server started on port 80");
|
||||
Serial.println("WebSocket server started on the same port");
|
||||
Serial.printf("my network address is either 'arduinoWebsockets.local' (mDNS) or '%s'\n", WiFi.localIP().toString().c_str());
|
||||
|
||||
if (!MDNS.begin("arduinoWebsockets")) {
|
||||
Serial.println("Error setting up MDNS responder!");
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
server.handleClient();
|
||||
webSocket.loop();
|
||||
MDNS.update();
|
||||
}
|
20
examples/esp8266_pico/WebSocketServerHooked/emu
Executable file
20
examples/esp8266_pico/WebSocketServerHooked/emu
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
|
||||
# linux script to compile&run arduinoWebSockets in a mock environment
|
||||
|
||||
if [ -z "$ESP8266ARDUINO" ]; then
|
||||
echo "please set ESP8266ARDUINO env-var to where esp8266/arduino sits"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
where=$(pwd)
|
||||
|
||||
cd $ESP8266ARDUINO/tests/host/
|
||||
|
||||
make -j FORCE32=0 \
|
||||
ULIBDIRS=../../libraries/Hash/:~/dev/proj/arduino/libraries/arduinoWebSockets \
|
||||
${where}/WebSocketServerHooked
|
||||
|
||||
valgrind ./bin/WebSocketServerHooked/WebSocketServerHooked -b "$@"
|
45
examples/esp8266_pico/WebSocketServerHooked/ws-testclient.py
Executable file
45
examples/esp8266_pico/WebSocketServerHooked/ws-testclient.py
Executable file
@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# python websocket client to test with
|
||||
# emulator: server is at ws://127.0.0.1:9080/ws
|
||||
# esp8266: server is at ws:///ws
|
||||
# (uncomment the right line below)
|
||||
|
||||
#uri = "ws://127.0.0.1:9080/ws"
|
||||
uri = "ws://arduinoWebsockets.local/ws"
|
||||
|
||||
import websocket
|
||||
try:
|
||||
import thread
|
||||
except ImportError:
|
||||
import _thread as thread
|
||||
import time
|
||||
|
||||
def on_message(ws, message):
|
||||
print("message");
|
||||
print(message)
|
||||
|
||||
def on_error(ws, error):
|
||||
print("error")
|
||||
print(error)
|
||||
|
||||
def on_close(ws):
|
||||
print("### closed ###")
|
||||
|
||||
def on_open(ws):
|
||||
print("opened")
|
||||
def run(*args):
|
||||
for i in range(3):
|
||||
time.sleep(1)
|
||||
ws.send("Hello %d" % i)
|
||||
time.sleep(1)
|
||||
ws.close()
|
||||
print("thread terminating...")
|
||||
thread.start_new_thread(run, ())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
websocket.enableTrace(True)
|
||||
ws = websocket.WebSocketApp(uri, on_message = on_message, on_error = on_error, on_close = on_close)
|
||||
ws.on_open = on_open
|
||||
ws.run_forever()
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* WebSocketServerHttpHeaderValidation.ino
|
||||
*
|
||||
* Created on: 08.06.2016
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
#include <WebSocketsServer.h>
|
||||
#include <Hash.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
WebSocketsServer webSocket = WebSocketsServer(81);
|
||||
|
||||
#define USE_SERIAL Serial1
|
||||
|
||||
const unsigned long int validSessionId = 12345; //some arbitrary value to act as a valid sessionId
|
||||
|
||||
/*
|
||||
* Returns a bool value as an indicator to describe whether a user is allowed to initiate a websocket upgrade
|
||||
* based on the value of a cookie. This function expects the rawCookieHeaderValue to look like this "sessionId=<someSessionIdNumberValue>|"
|
||||
*/
|
||||
bool isCookieValid(String rawCookieHeaderValue) {
|
||||
|
||||
if (rawCookieHeaderValue.indexOf("sessionId") != -1) {
|
||||
String sessionIdStr = rawCookieHeaderValue.substring(rawCookieHeaderValue.indexOf("sessionId=") + 10, rawCookieHeaderValue.indexOf("|"));
|
||||
unsigned long int sessionId = strtoul(sessionIdStr.c_str(), NULL, 10);
|
||||
return sessionId == validSessionId;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The WebSocketServerHttpHeaderValFunc delegate passed to webSocket.onValidateHttpHeader
|
||||
*/
|
||||
bool validateHttpHeader(String headerName, String headerValue) {
|
||||
|
||||
//assume a true response for any headers not handled by this validator
|
||||
bool valid = true;
|
||||
|
||||
if(headerName.equalsIgnoreCase("Cookie")) {
|
||||
//if the header passed is the Cookie header, validate it according to the rules in 'isCookieValid' function
|
||||
valid = isCookieValid(headerValue);
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//Serial.setDebugOutput(true);
|
||||
USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
//connecting clients must supply a valid session cookie at websocket upgrade handshake negotiation time
|
||||
const char * headerkeys[] = { "Cookie" };
|
||||
size_t headerKeyCount = sizeof(headerkeys) / sizeof(char*);
|
||||
webSocket.onValidateHttpHeader(validateHttpHeader, headerkeys, headerKeyCount);
|
||||
webSocket.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
}
|
||||
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* WebSocketServer_LEDcontrol.ino
|
||||
*
|
||||
* Created on: 26.11.2015
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
#include <WebSocketsServer.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <Hash.h>
|
||||
|
||||
#define LED_RED 15
|
||||
#define LED_GREEN 12
|
||||
#define LED_BLUE 13
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
ESP8266WebServer server(80);
|
||||
WebSocketsServer webSocket = WebSocketsServer(81);
|
||||
|
||||
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
|
||||
|
||||
switch(type) {
|
||||
case WStype_DISCONNECTED:
|
||||
USE_SERIAL.printf("[%u] Disconnected!\n", num);
|
||||
break;
|
||||
case WStype_CONNECTED: {
|
||||
IPAddress ip = webSocket.remoteIP(num);
|
||||
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
|
||||
|
||||
// send message to client
|
||||
webSocket.sendTXT(num, "Connected");
|
||||
}
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
|
||||
|
||||
if(payload[0] == '#') {
|
||||
// we get RGB data
|
||||
|
||||
// decode rgb data
|
||||
uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16);
|
||||
|
||||
analogWrite(LED_RED, ((rgb >> 16) & 0xFF));
|
||||
analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF));
|
||||
analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
//USE_SERIAL.begin(921600);
|
||||
USE_SERIAL.begin(115200);
|
||||
|
||||
//USE_SERIAL.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
|
||||
for(uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
pinMode(LED_RED, OUTPUT);
|
||||
pinMode(LED_GREEN, OUTPUT);
|
||||
pinMode(LED_BLUE, OUTPUT);
|
||||
|
||||
digitalWrite(LED_RED, 1);
|
||||
digitalWrite(LED_GREEN, 1);
|
||||
digitalWrite(LED_BLUE, 1);
|
||||
|
||||
WiFiMulti.addAP("SSID", "passpasspass");
|
||||
|
||||
while(WiFiMulti.run() != WL_CONNECTED) {
|
||||
delay(100);
|
||||
}
|
||||
|
||||
// start webSocket server
|
||||
webSocket.begin();
|
||||
webSocket.onEvent(webSocketEvent);
|
||||
|
||||
if(MDNS.begin("esp8266")) {
|
||||
USE_SERIAL.println("MDNS responder started");
|
||||
}
|
||||
|
||||
// handle index
|
||||
server.on("/", []() {
|
||||
// send index.html
|
||||
server.send(200, "text/html", "<html><head><script>var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);connection.onopen = function () { connection.send('Connect ' + new Date()); }; connection.onerror = function (error) { console.log('WebSocket Error ', error);};connection.onmessage = function (e) { console.log('Server: ', e.data);};function sendRGB() { var r = parseInt(document.getElementById('r').value).toString(16); var g = parseInt(document.getElementById('g').value).toString(16); var b = parseInt(document.getElementById('b').value).toString(16); if(r.length < 2) { r = '0' + r; } if(g.length < 2) { g = '0' + g; } if(b.length < 2) { b = '0' + b; } var rgb = '#'+r+g+b; console.log('RGB: ' + rgb); connection.send(rgb); }</script></head><body>LED Control:<br/><br/>R: <input id=\"r\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>G: <input id=\"g\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>B: <input id=\"b\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/></body></html>");
|
||||
});
|
||||
|
||||
server.begin();
|
||||
|
||||
// Add service to MDNS
|
||||
MDNS.addService("http", "tcp", 80);
|
||||
MDNS.addService("ws", "tcp", 81);
|
||||
|
||||
digitalWrite(LED_RED, 0);
|
||||
digitalWrite(LED_GREEN, 0);
|
||||
digitalWrite(LED_BLUE, 0);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
webSocket.loop();
|
||||
server.handleClient();
|
||||
}
|
Reference in New Issue
Block a user