Initial commit, getting all the stuff from PlatformIO

This commit is contained in:
2025-11-02 17:55:41 +00:00
commit 4b4b816a8c
3003 changed files with 1213319 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
#include <Arduino.h>
#include <PicoMQTT.h>
PicoMQTT::Server mqtt;
void setup() {
// Usual setup
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin("wifiname", "password");
while (WiFi.status() != WL_CONNECTED) { delay(1000); }
Serial.printf("WiFi connected, IP: %s\n", WiFi.localIP().toString().c_str());
mqtt.begin();
}
void loop() {
// This will automatically handle client connections. By default, all clients are accepted.
mqtt.loop();
}

View File

@@ -0,0 +1,85 @@
#!/usr/bin/env python3
import argparse
import time
import multiprocessing
import paho.mqtt.client as mqtt
def consumer(barrier, conn, host, expected_messages, timeout):
pid = multiprocessing.current_process().pid
client = mqtt.Client(f"consumer_{pid}")
# client.username_pw_set("username", "password")
total_messages = 0
first_message_time = None
last_message_time = None
def on_message(client, userdata, msg):
nonlocal total_messages, first_message_time, last_message_time
total_messages += 1
last_message_time = time.time()
first_message_time = first_message_time or last_message_time
def on_subscribe(client, userdata, mid, granted_qos):
barrier.wait()
client.on_message = on_message
client.on_subscribe = on_subscribe
client.connect(host)
client.loop_start()
client.subscribe("benchmark")
while total_messages < expected_messages:
if first_message_time and total_messages >= 2:
elapsed_time = time.time() - first_message_time
if elapsed_time >= timeout:
break
time.sleep(1)
client.loop_stop()
elapsed_time = last_message_time - first_message_time
rate = (total_messages - 1) / elapsed_time
conn.send(rate)
parser = argparse.ArgumentParser()
parser.add_argument("host")
parser.add_argument("--consumers", type=int, default=1)
parser.add_argument("--messages", type=int, default=1000)
parser.add_argument("--size", type=int, default=1)
parser.add_argument("--timeout", type=int, default=10)
args = parser.parse_args()
client = mqtt.Client("producer")
client.connect(args.host)
barrier = multiprocessing.Barrier(args.consumers + 1)
pipe = multiprocessing.Pipe(False)
consumers = [
multiprocessing.Process(
target=consumer, args=(barrier, pipe[1], args.host, args.messages, args.timeout)
)
for _ in range(args.consumers)
]
message = "0" * args.size
for consumer in consumers:
consumer.start()
# wait for all processes to connect
barrier.wait()
# fire messages
while any(p.is_alive() for p in consumers):
client.publish("benchmark", message)
# wait for consumers
for consumer in consumers:
consumer.join()
# collect results
rate = sum(pipe[0].recv() for _ in consumers) / len(consumers)
print(f"{rate:.1f}")

View File

@@ -0,0 +1,37 @@
#!/usr/bin/env bash
# Usage:
# ./benchmark.sh <ESP IP>
export LC_NUMERIC=C
HOST="$1"
REPEAT=5
CONSUMER_COUNTS="12 10 5 1"
SIZES="10000 5000 1000 500 100 50 10 5 1"
printf "message size\t"
for CONSUMERS in $CONSUMER_COUNTS
do
printf "%i consumers\t" $CONSUMERS
done
printf "\n"
for SIZE in $SIZES
do
printf "%i\t" $SIZE
for CONSUMERS in $CONSUMER_COUNTS
do
RESULT=$({
for ITERATION in $(seq $REPEAT)
do
./benchmark.py --size=$SIZE --consumers=$CONSUMERS "$HOST"
# potential interference may go away by itself if we wait
sleep 1
done
} | awk '{ sum += $1; count += 1 } END { print sum / count }')
printf "%.1f\t" $RESULT
done
printf "\n"
done

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env python3
import csv
import sys
import pygal
data = list(csv.DictReader(sys.stdin, dialect="excel-tab"))
X = "message size"
SERIES = [e for e in data[0].keys() if e and e != X]
chart = pygal.XY(
legend_at_bottom=True,
logarithmic=True,
x_title="payload size [B]",
y_title="messages delivery rate [1/s]",
pretty_print=True,
stroke_style={"width": 50},
x_label_rotation=-90,
)
for name in SERIES:
chart.add(name, [(float(e[X]), float(e[name])) for e in data])
sys.stdout.write(chart.render().decode("utf-8"))