First working version
initial Running vversion
This commit is contained in:
parent
afe0b75022
commit
d337fca495
8
watering/.vscode/settings.json
vendored
8
watering/.vscode/settings.json
vendored
@ -9,6 +9,12 @@
|
|||||||
"vector": "cpp",
|
"vector": "cpp",
|
||||||
"string_view": "cpp",
|
"string_view": "cpp",
|
||||||
"initializer_list": "cpp",
|
"initializer_list": "cpp",
|
||||||
"regex": "cpp"
|
"regex": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"memory": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
164
watering/data/index.html
Normal file
164
watering/data/index.html
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Simple.css Test Page</title>
|
||||||
|
<link rel="stylesheet" href="simple.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body id="top">
|
||||||
|
<header>
|
||||||
|
<h1>Gartenbewässerung</h1>
|
||||||
|
<p>%HOSTNAME% <mark style="border-color: var(--warn);" id="connectionTxt">Connecting...</mark></p>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<header>
|
||||||
|
<h1 style="margin-bottom: 1rem;">%NAME_VALVE1%</h1>
|
||||||
|
<mark id="state1" style="border-color: var(--fail);margin-left: 1.2rem;">Unbekannt</mark>
|
||||||
|
</header>
|
||||||
|
<p>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h3 id="hour1" style="margin-bottom: 0.1rem;">--</h3>Std.
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<h3 id="min1" style="margin-bottom: 0.1rem;">--</h3>Min.
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<h3 id="sec1" style="margin-bottom: 0.1rem;">--</h3>Sek.
|
||||||
|
</td>
|
||||||
|
</table>
|
||||||
|
<button onclick="document.getElementById('dialog-vorn').showModal()">Bewässern</button><button
|
||||||
|
onclick="fetch('/setValve?valve=6&set=close')">Stop</button>
|
||||||
|
</p>
|
||||||
|
<section id="valve2" style="display:none;">
|
||||||
|
<header>
|
||||||
|
<h1 style="margin-bottom: 1rem;">%NAME_VALVE2%</h1>
|
||||||
|
<mark id="state2" style="border-color: var(--fail);margin-left: 1.2rem;">Unbekannt</mark>
|
||||||
|
</header>
|
||||||
|
<p>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h3 id="hour2" style="margin-bottom: 0.1rem;">--</h3>Std.
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<h3 id="min2" style="margin-bottom: 0.1rem;">--</h3>Min.
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<h3 id="sec2" style="margin-bottom: 0.1rem;">--</h3>Sek.
|
||||||
|
</td>
|
||||||
|
</table>
|
||||||
|
<button onclick="document.getElementById('dialog-trog').showModal()">Bewässern</button><button
|
||||||
|
onclick="fetch('/setValve?valve=1&set=close')">Stop</button>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<footer>WEG Wagner 2025
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<dialog id="dialog-vorn">
|
||||||
|
<h2>Timer</h2>
|
||||||
|
<form>
|
||||||
|
<p><strong>Garten vorn:</strong></p>
|
||||||
|
<p><input type="number" id="time1" name="time" min="10" max="120" value="60" /> Minuten</p>
|
||||||
|
<button onclick="sendValve1On()">Start</button>
|
||||||
|
<button>Abbrechen</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
<dialog id="dialog-trog">
|
||||||
|
<h2>Timer</h2>
|
||||||
|
<form>
|
||||||
|
<p><strong>Tröge:</strong></p>
|
||||||
|
<p><input type="number" id="time2" name="time" min="10" max="120" value="60" /> Minuten</p>
|
||||||
|
<button onclick="sendValve2On()">Start</button>
|
||||||
|
<button>Abbrechen</button>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function sendValve1On() {
|
||||||
|
fetch('/setValve?valve=6&set=open&timer=' + document.getElementById("time1").value);
|
||||||
|
}
|
||||||
|
function sendValve2On() {
|
||||||
|
fetch('/setValve?valve=1&set=open&timer=' + document.getElementById("time2").value);
|
||||||
|
}
|
||||||
|
|
||||||
|
var gateway = `ws://${window.location.hostname}/ws`;
|
||||||
|
var websocket;
|
||||||
|
function initWebSocket() {
|
||||||
|
console.log('Trying to open a WebSocket connection...');
|
||||||
|
websocket = new WebSocket(gateway);
|
||||||
|
websocket.onopen = onOpen;
|
||||||
|
websocket.onclose = onClose;
|
||||||
|
websocket.onmessage = onMessage; // <-- add this line
|
||||||
|
}
|
||||||
|
function onOpen(event) {
|
||||||
|
console.log('Connection opened');
|
||||||
|
document.getElementById("connectionTxt").innerHTML = "Connected";
|
||||||
|
document.getElementById("connectionTxt").style = "border-color: var(--ok);";
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClose(event) {
|
||||||
|
console.log('Connection closed');
|
||||||
|
document.getElementById("connectionTxt").innerHTML = "Not Connected";
|
||||||
|
document.getElementById("connectionTxt").style = "border-color: var(--fail);";
|
||||||
|
setTimeout(initWebSocket, 2000);
|
||||||
|
}
|
||||||
|
function onMessage(event) {
|
||||||
|
var state;
|
||||||
|
let data = JSON.parse(event.data);
|
||||||
|
if(data.hasOwnProperty("numValves")){
|
||||||
|
if(data.numValves == 2){
|
||||||
|
document.getElementById("valve2").style = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(data.timers[6] > 0){
|
||||||
|
hours = Math.floor(data.timers[6]/3600);
|
||||||
|
data.timers[6] = data.timers[6] - hours*3600;
|
||||||
|
mins = Math.floor(data.timers[6]/60);
|
||||||
|
data.timers[6] = data.timers[6] - mins*60;
|
||||||
|
secs = data.timers[6];
|
||||||
|
document.getElementById("hour1").innerHTML = (hours < 10) ?"0"+String(hours):String(hours);
|
||||||
|
document.getElementById("min1").innerHTML = (mins < 10) ?"0"+String(mins):String(mins);
|
||||||
|
document.getElementById("sec1").innerHTML = (secs < 10) ?"0"+String(secs):String(secs);
|
||||||
|
document.getElementById("state1").style = "border-color: var(--warn);margin-left: 1.2rem;";
|
||||||
|
document.getElementById("state1").innerHTML = "Wasser AN";
|
||||||
|
}else{
|
||||||
|
document.getElementById("state1").style = "border-color: var(--ok);margin-left: 1.2rem;";
|
||||||
|
document.getElementById("state1").innerHTML = "Wasser AUS";
|
||||||
|
document.getElementById("hour1").innerHTML = "--";
|
||||||
|
document.getElementById("min1").innerHTML = "--";
|
||||||
|
document.getElementById("sec1").innerHTML = "--";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data.timers[1] > 0){
|
||||||
|
hours = Math.floor(data.timers[1]/3600);
|
||||||
|
data.timers[1] = data.timers[1] - hours*3600;
|
||||||
|
mins = Math.floor(data.timers[1]/60);
|
||||||
|
data.timers[1] = data.timers[1] - mins*60;
|
||||||
|
secs = data.timers[1];
|
||||||
|
document.getElementById("hour2").innerHTML = (hours < 10) ?"0"+String(hours):String(hours);
|
||||||
|
document.getElementById("min2").innerHTML = (mins < 10) ?"0"+String(mins):String(mins);
|
||||||
|
document.getElementById("sec2").innerHTML = (secs < 10) ?"0"+String(secs):String(secs);
|
||||||
|
document.getElementById("state2").style = "border-color: var(--warn);margin-left: 1.2rem;";
|
||||||
|
document.getElementById("state2").innerHTML = "Wasser AN";
|
||||||
|
}else{
|
||||||
|
document.getElementById("state2").style = "border-color: var(--ok);margin-left: 1.2rem;";
|
||||||
|
document.getElementById("state2").innerHTML = "Wasser AUS";
|
||||||
|
document.getElementById("hour2").innerHTML = "--";
|
||||||
|
document.getElementById("min2").innerHTML = "--";
|
||||||
|
document.getElementById("sec2").innerHTML = "--";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener('load', onLoad);
|
||||||
|
function onLoad(event) {
|
||||||
|
initWebSocket();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
762
watering/data/simple.css
Normal file
762
watering/data/simple.css
Normal file
@ -0,0 +1,762 @@
|
|||||||
|
/* Global variables. */
|
||||||
|
:root {
|
||||||
|
/* Set sans-serif & mono fonts */
|
||||||
|
--sans-font: -apple-system, BlinkMacSystemFont, "Avenir Next", Avenir,
|
||||||
|
"Nimbus Sans L", Roboto, "Noto Sans", "Segoe UI", Arial, Helvetica,
|
||||||
|
"Helvetica Neue", sans-serif;
|
||||||
|
--mono-font: Consolas, Menlo, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
|
||||||
|
--standard-border-radius: 8px;
|
||||||
|
|
||||||
|
/* Default (light) theme */
|
||||||
|
--bg: #fff;
|
||||||
|
--accent-bg: #f5f7ff;
|
||||||
|
--text: #212121;
|
||||||
|
--text-light: #585858;
|
||||||
|
--border: #898EA4;
|
||||||
|
--accent: #0d47a1;
|
||||||
|
--ok: #279c1c;
|
||||||
|
--warn: #f1d323;
|
||||||
|
--fail: #d12e2e;
|
||||||
|
--accent-hover: #1266e2;
|
||||||
|
--accent-text: var(--bg);
|
||||||
|
--code: #d81b60;
|
||||||
|
--preformatted: #444;
|
||||||
|
--marked: #e9c92b;
|
||||||
|
--disabled: #efefef;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark theme */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
color-scheme: dark;
|
||||||
|
--bg: #212121;
|
||||||
|
--accent-bg: #2b2b2b;
|
||||||
|
--text: #dcdcdc;
|
||||||
|
--text-light: #ababab;
|
||||||
|
--accent: #113b1e;
|
||||||
|
--ok: #279c1c;
|
||||||
|
--warn: #ddd125;
|
||||||
|
--fail: #ce3030;
|
||||||
|
--accent-hover: #1b5a2f;
|
||||||
|
--accent-text: var(--bg);
|
||||||
|
--code: #f06292;
|
||||||
|
--preformatted: #ccc;
|
||||||
|
--disabled: #111;
|
||||||
|
}
|
||||||
|
/* Add a bit of transparency so light media isn't so glaring in dark mode */
|
||||||
|
img,
|
||||||
|
video {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset box-sizing */
|
||||||
|
*, *::before, *::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset default appearance */
|
||||||
|
textarea,
|
||||||
|
select,
|
||||||
|
input,
|
||||||
|
progress {
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
/* Set the font globally */
|
||||||
|
font-family: var(--sans-font);
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make the body a nice central block */
|
||||||
|
body {
|
||||||
|
color: var(--text);
|
||||||
|
background-color: var(--bg);
|
||||||
|
font-size: 1.15rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr min(45rem, 90%) 1fr;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
body > * {
|
||||||
|
grid-column: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make the header bg full width, but the content inline with body */
|
||||||
|
body > header {
|
||||||
|
background-color: var(--accent-bg);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 0.5rem 0.5rem 0.5rem;
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > header > *:only-child {
|
||||||
|
margin-block-start: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > header h1 {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 1rem auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > header p {
|
||||||
|
max-width: 40rem;
|
||||||
|
margin: 1rem auto;
|
||||||
|
}
|
||||||
|
/* Add a little padding to ensure spacing is correct between content and header nav */
|
||||||
|
main {
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
}
|
||||||
|
body > footer {
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding: 0rem 1rem 1.5rem 1rem;
|
||||||
|
color: var(--text-light);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Format headers */
|
||||||
|
h1 {
|
||||||
|
font-size: 3rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
padding-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 2.6rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 2rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 1.44rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h5 {
|
||||||
|
font-size: 1.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
font-size: 0.96rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent long strings from overflowing container */
|
||||||
|
p, h1, h2, h3, h4, h5, h6 {
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix line height when title wraps */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3 {
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reduce header size on mobile */
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 2.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-size: 1.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Format links & buttons */
|
||||||
|
a,
|
||||||
|
a:visited {
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
.button,
|
||||||
|
a.button, /* extra specificity to override a */
|
||||||
|
input[type="submit"],
|
||||||
|
input[type="reset"],
|
||||||
|
input[type="button"] {
|
||||||
|
border: 1px solid var(--accent);
|
||||||
|
background-color: var(--accent);
|
||||||
|
color: var(--text);
|
||||||
|
padding: 0.5rem 0.9rem;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button[aria-disabled="true"],
|
||||||
|
input:disabled,
|
||||||
|
textarea:disabled,
|
||||||
|
select:disabled,
|
||||||
|
button[disabled] {
|
||||||
|
cursor: not-allowed;
|
||||||
|
background-color: var(--disabled);
|
||||||
|
border-color: var(--disabled);
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"] {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the cursor to '?' on an abbreviation and style the abbreviation to show that there is more information underneath */
|
||||||
|
abbr[title] {
|
||||||
|
cursor: help;
|
||||||
|
text-decoration-line: underline;
|
||||||
|
text-decoration-style: dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:enabled:hover,
|
||||||
|
.button:not([aria-disabled="true"]):hover,
|
||||||
|
input[type="submit"]:enabled:hover,
|
||||||
|
input[type="reset"]:enabled:hover,
|
||||||
|
input[type="button"]:enabled:hover {
|
||||||
|
background-color: var(--accent-hover);
|
||||||
|
border-color: var(--accent-hover);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:focus-visible,
|
||||||
|
button:focus-visible:where(:enabled),
|
||||||
|
input:enabled:focus-visible:where(
|
||||||
|
[type="submit"],
|
||||||
|
[type="reset"],
|
||||||
|
[type="button"]
|
||||||
|
) {
|
||||||
|
outline: 2px solid var(--accent);
|
||||||
|
outline-offset: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Format navigation */
|
||||||
|
header nav {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 2;
|
||||||
|
padding: 1rem 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use flexbox to allow items to wrap, as needed */
|
||||||
|
header nav ul,
|
||||||
|
header nav ol {
|
||||||
|
align-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List items are inline elements, make them behave more like blocks */
|
||||||
|
header nav ul li,
|
||||||
|
header nav ol li {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
header nav a,
|
||||||
|
header nav a:visited {
|
||||||
|
margin: 0 0.5rem 1rem 0.5rem;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
color: var(--text);
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.1rem 1rem;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
header nav a:hover,
|
||||||
|
header nav a.current,
|
||||||
|
header nav a[aria-current="page"],
|
||||||
|
header nav a[aria-current="true"] {
|
||||||
|
border-color: var(--accent);
|
||||||
|
color: var(--accent);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reduce nav side on mobile */
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
header nav a {
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
text-decoration: underline;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Consolidate box styling */
|
||||||
|
aside, details, pre, progress {
|
||||||
|
background-color: var(--accent-bg);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
font-size: 1rem;
|
||||||
|
width: 30%;
|
||||||
|
padding: 0 15px;
|
||||||
|
margin-inline-start: 15px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
*[dir="rtl"] aside {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make aside full-width on mobile */
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
aside {
|
||||||
|
width: 100%;
|
||||||
|
float: none;
|
||||||
|
margin-inline-start: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
article, fieldset, dialog {
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
padding: 1rem;
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
article h2:first-child,
|
||||||
|
section h2:first-child,
|
||||||
|
article h3:first-child,
|
||||||
|
section h3:first-child {
|
||||||
|
margin-top: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
padding: 0rem 1rem;
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't double separators when chaining sections */
|
||||||
|
section + section,
|
||||||
|
section:first-child {
|
||||||
|
border-top: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section + section {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
details {
|
||||||
|
padding: 0.7rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
summary {
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0.7rem 1rem;
|
||||||
|
margin: -0.7rem -1rem;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
details[open] > summary + * {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
details[open] > summary {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
details[open] > :last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Format tables */
|
||||||
|
table {
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
border-spacing: 20px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure > table {
|
||||||
|
width: max-content;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: var(--accent-bg);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even) {
|
||||||
|
/* Set every other cell slightly darker. Improves readability. */
|
||||||
|
background-color: var(--accent-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
table caption {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Format forms */
|
||||||
|
textarea,
|
||||||
|
select,
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
.button {
|
||||||
|
font-size: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
padding: 0.5rem;
|
||||||
|
margin: 0 0.5rem 0 0.5rem;
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
box-shadow: none;
|
||||||
|
max-width: 100%;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
textarea,
|
||||||
|
select,
|
||||||
|
input {
|
||||||
|
color: var(--text);
|
||||||
|
background-color: var(--bg);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
textarea:not([cols]) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add arrow to drop-down */
|
||||||
|
select:not([multiple]) {
|
||||||
|
background-image: linear-gradient(45deg, transparent 49%, var(--text) 51%),
|
||||||
|
linear-gradient(135deg, var(--text) 51%, transparent 49%);
|
||||||
|
background-position: calc(100% - 15px), calc(100% - 10px);
|
||||||
|
background-size: 5px 5px, 5px 5px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
padding-inline-end: 25px;
|
||||||
|
}
|
||||||
|
*[dir="rtl"] select:not([multiple]) {
|
||||||
|
background-position: 10px, 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* checkbox and radio button style */
|
||||||
|
input[type="checkbox"],
|
||||||
|
input[type="radio"] {
|
||||||
|
vertical-align: middle;
|
||||||
|
position: relative;
|
||||||
|
width: min-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"] + label,
|
||||||
|
input[type="radio"] + label {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="radio"] {
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"]:checked,
|
||||||
|
input[type="radio"]:checked {
|
||||||
|
background-color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"]:checked::after {
|
||||||
|
/* Creates a rectangle with colored right and bottom borders which is rotated to look like a check mark */
|
||||||
|
content: " ";
|
||||||
|
width: 0.18em;
|
||||||
|
height: 0.32em;
|
||||||
|
border-radius: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0.05em;
|
||||||
|
left: 0.17em;
|
||||||
|
background-color: transparent;
|
||||||
|
border-right: solid var(--bg) 0.08em;
|
||||||
|
border-bottom: solid var(--bg) 0.08em;
|
||||||
|
font-size: 1.8em;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
input[type="radio"]:checked::after {
|
||||||
|
/* creates a colored circle for the checked radio button */
|
||||||
|
content: " ";
|
||||||
|
width: 0.25em;
|
||||||
|
height: 0.25em;
|
||||||
|
border-radius: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0.125em;
|
||||||
|
background-color: var(--bg);
|
||||||
|
left: 0.125em;
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Makes input fields wider on smaller screens */
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
textarea,
|
||||||
|
select,
|
||||||
|
input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set a height for color input */
|
||||||
|
input[type="color"] {
|
||||||
|
height: 2.5rem;
|
||||||
|
padding: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do not show border around file selector button */
|
||||||
|
input[type="file"] {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Misc body elements */
|
||||||
|
hr {
|
||||||
|
border: none;
|
||||||
|
height: 1px;
|
||||||
|
background: var(--border);
|
||||||
|
margin: 1rem auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
padding: 2px 5px;
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
border: 2px solid var(--marked);
|
||||||
|
background-color: var(--bg);
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
|
||||||
|
mark a {
|
||||||
|
color: #0d47a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
img,
|
||||||
|
video {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 0;
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure > img,
|
||||||
|
figure > picture > img {
|
||||||
|
display: block;
|
||||||
|
margin-inline: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
figcaption {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--text-light);
|
||||||
|
margin-block: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin-inline-start: 2rem;
|
||||||
|
margin-inline-end: 0;
|
||||||
|
margin-block: 2rem;
|
||||||
|
padding: 0.4rem 0.8rem;
|
||||||
|
border-inline-start: 0.35rem solid var(--accent);
|
||||||
|
color: var(--text-light);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
cite {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--text-light);
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use mono font for code elements */
|
||||||
|
code,
|
||||||
|
pre,
|
||||||
|
pre span,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: var(--mono-font);
|
||||||
|
color: var(--code);
|
||||||
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
color: var(--preformatted);
|
||||||
|
border: 1px solid var(--preformatted);
|
||||||
|
border-bottom: 3px solid var(--preformatted);
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
padding: 0.1rem 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
padding: 1rem 1.4rem;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
color: var(--preformatted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix embedded code within pre */
|
||||||
|
pre code {
|
||||||
|
color: var(--preformatted);
|
||||||
|
background: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Progress bars */
|
||||||
|
/* Declarations are repeated because you */
|
||||||
|
/* cannot combine vendor-specific selectors */
|
||||||
|
progress {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress:indeterminate {
|
||||||
|
background-color: var(--accent-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress::-webkit-progress-bar {
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
background-color: var(--accent-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress::-webkit-progress-value {
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
background-color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
progress::-moz-progress-bar {
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
background-color: var(--accent);
|
||||||
|
transition-property: width;
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress:indeterminate::-moz-progress-bar {
|
||||||
|
background-color: var(--accent-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog {
|
||||||
|
background-color: var(--bg);
|
||||||
|
max-width: 40rem;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog::backdrop {
|
||||||
|
background-color: var(--bg);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 720px) {
|
||||||
|
dialog {
|
||||||
|
max-width: calc(100vw - 2rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Superscript & Subscript */
|
||||||
|
/* Prevent scripts from affecting line-height. */
|
||||||
|
sup, sub {
|
||||||
|
vertical-align: baseline;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
top: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Classes for notices */
|
||||||
|
.notice {
|
||||||
|
background: var(--accent-bg);
|
||||||
|
border: 2px solid var(--border);
|
||||||
|
border-radius: var(--standard-border-radius);
|
||||||
|
padding: 1.5rem;
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print */
|
||||||
|
@media print {
|
||||||
|
@page {
|
||||||
|
margin: 1cm;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
body > header {
|
||||||
|
background-color: unset;
|
||||||
|
}
|
||||||
|
body > header nav,
|
||||||
|
body > footer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
article {
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
a[href^="http"]::after {
|
||||||
|
content: " <" attr(href) ">";
|
||||||
|
}
|
||||||
|
abbr[title]:after {
|
||||||
|
content: " (" attr(title) ")";
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
widows: 3;
|
||||||
|
orphans: 3;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
mark {
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
pre, table, figure, img, svg {
|
||||||
|
break-inside: avoid;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
watering/lib/2024-08-21_1456_V-Markt Immenstadt.pdf
Normal file
BIN
watering/lib/2024-08-21_1456_V-Markt Immenstadt.pdf
Normal file
Binary file not shown.
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 10",
|
|
||||||
"image": "conanio/clang10",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang10"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 11",
|
|
||||||
"image": "conanio/clang11",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang11"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
FROM ubuntu:22.04
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y cmake git clang-13 libc++-13-dev libc++abi-13-dev
|
|
||||||
ENV CC=clang-13 CXX=clang++-13
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 13",
|
|
||||||
"build": {
|
|
||||||
"dockerfile": "Dockerfile"
|
|
||||||
},
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang13"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
FROM ubuntu:22.04
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y cmake git clang-14 libc++-14-dev libc++abi-14-dev
|
|
||||||
ENV CC=clang-14 CXX=clang++-14
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 14",
|
|
||||||
"build": {
|
|
||||||
"dockerfile": "Dockerfile"
|
|
||||||
},
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang14"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
FROM ubuntu:22.04
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y cmake git clang-15 libc++-15-dev libc++abi-15-dev
|
|
||||||
ENV CC=clang-15 CXX=clang++-15
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 15",
|
|
||||||
"build": {
|
|
||||||
"dockerfile": "Dockerfile"
|
|
||||||
},
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang15"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
FROM ubuntu:22.04
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y cmake git clang-16 libc++-16-dev libc++abi-16-dev
|
|
||||||
ENV CC=clang-16 CXX=clang++-16
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 16",
|
|
||||||
"build": {
|
|
||||||
"dockerfile": "Dockerfile"
|
|
||||||
},
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang16"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
FROM ubuntu:24.04
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y cmake git clang-17 libc++-17-dev libc++abi-17-dev
|
|
||||||
ENV CC=clang-17 CXX=clang++-17
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 17",
|
|
||||||
"build": {
|
|
||||||
"dockerfile": "Dockerfile"
|
|
||||||
},
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang17"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 5",
|
|
||||||
"image": "conanio/clang50",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang5"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 6",
|
|
||||||
"image": "conanio/clang60",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang6"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 7",
|
|
||||||
"image": "conanio/clang7",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang7"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 8",
|
|
||||||
"image": "conanio/clang8",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang8"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Clang 9",
|
|
||||||
"image": "conanio/clang9",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-clang9"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "GCC 10",
|
|
||||||
"image": "conanio/gcc10",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-gcc10"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "GCC 11",
|
|
||||||
"image": "conanio/gcc11",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-gcc11"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
FROM ubuntu:22.04
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y cmake git g++-12
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "GCC 12",
|
|
||||||
"build": {
|
|
||||||
"dockerfile": "Dockerfile",
|
|
||||||
},
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-gcc12"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "GCC 4.8",
|
|
||||||
"image": "conanio/gcc48",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-gcc48"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools",
|
|
||||||
"josetr.cmake-language-support-vscode",
|
|
||||||
"ms-vscode.cpptools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "GCC 5",
|
|
||||||
"image": "conanio/gcc5",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-gcc5"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "GCC 6",
|
|
||||||
"image": "conanio/gcc6",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-gcc6"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "GCC 7",
|
|
||||||
"image": "conanio/gcc7",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-gcc7"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "GCC 8",
|
|
||||||
"image": "conanio/gcc8",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-gcc8"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "GCC 9",
|
|
||||||
"image": "conanio/gcc9",
|
|
||||||
"runArgs": [
|
|
||||||
"--name=ArduinoJson-gcc9"
|
|
||||||
],
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.cmake-tools"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"cmake.generator": "Unix Makefiles",
|
|
||||||
"cmake.buildDirectory": "/tmp/build"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
4
watering/lib/ArduinoJson/.github/FUNDING.yml
vendored
4
watering/lib/ArduinoJson/.github/FUNDING.yml
vendored
@ -1,4 +0,0 @@
|
|||||||
github: bblanchon
|
|
||||||
custom:
|
|
||||||
- https://arduinojson.org/book/
|
|
||||||
- https://donate.benoitblanchon.fr/
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
---
|
|
||||||
name: 🐛 Bug report
|
|
||||||
about: Report a bug in ArduinoJson
|
|
||||||
title: ''
|
|
||||||
labels: 'bug'
|
|
||||||
assignees: ''
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- ⚠️ IMPORTANT ⚠️
|
|
||||||
Before opening a bug report, please use the ArduinoJson Troubleshooter as it may find a solution to your issue; if not, please include the Troubleshooter's report in the description.
|
|
||||||
-->
|
|
||||||
|
|
||||||
**Describe the bug**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**Troubleshooter report**
|
|
||||||
Here is the report generated by the [ArduinoJson Troubleshooter](https://arduinojson.org/v7/troubleshooter/):
|
|
||||||
[Paste the report here]
|
|
||||||
|
|
||||||
**Environment**
|
|
||||||
Here is the environment that I used:
|
|
||||||
* Microcontroller: [e.g. ESP8266]
|
|
||||||
* Core/runtime: [e.g. ESP8266 core for Arduino v3.0.2]
|
|
||||||
* IDE: [e.g. Arduino IDE 1.8.16]
|
|
||||||
|
|
||||||
**Reproduction**
|
|
||||||
Here is a small snippet that reproduces the issue.
|
|
||||||
|
|
||||||
```c++
|
|
||||||
JsonDocument doc;
|
|
||||||
|
|
||||||
DeserializationError error = deserializeJson(doc, "{\"hello\":\"world\"}");
|
|
||||||
|
|
||||||
[insert repro code here]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Compiler output**
|
|
||||||
If relevant, include the complete compiler output (i.e. not just the line that contains the error.)
|
|
||||||
|
|
||||||
|
|
||||||
**Program output**
|
|
||||||
If relevant, include the repro program output.
|
|
||||||
|
|
||||||
Expected output:
|
|
||||||
|
|
||||||
```
|
|
||||||
[insert expected output here]
|
|
||||||
```
|
|
||||||
|
|
||||||
Actual output:
|
|
||||||
|
|
||||||
```
|
|
||||||
[insert actual output here]
|
|
||||||
```
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
blank_issues_enabled: true
|
|
||||||
contact_links:
|
|
||||||
- name: 👨🏫 ArduinoJson Assistant
|
|
||||||
url: https://arduinojson.org/v7/assistant/
|
|
||||||
about: An online tool that computes memory requirements and generates scaffolding code for your project.
|
|
||||||
- name: 👨⚕️ ArduinoJson Troubleshooter
|
|
||||||
url: https://arduinojson.org/v7/troubleshooter/
|
|
||||||
about: An online tool that helps you diagnose the most common issues with ArduinoJson.
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
---
|
|
||||||
name: 💡 Feature request
|
|
||||||
about: Suggest an idea for ArduinoJson
|
|
||||||
title: ''
|
|
||||||
labels: enhancement
|
|
||||||
assignees: ''
|
|
||||||
---
|
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
|
||||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
||||||
|
|
||||||
**Describe the solution you'd like**
|
|
||||||
A clear and concise description of what you want to happen.
|
|
||||||
|
|
||||||
**Describe alternatives you've considered**
|
|
||||||
A clear and concise description of any alternative solutions or features you've considered.
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context or screenshots about the feature request here.
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
---
|
|
||||||
name: 😭 Help!
|
|
||||||
about: Ask for help
|
|
||||||
title: ''
|
|
||||||
labels: 'question'
|
|
||||||
assignees: ''
|
|
||||||
---
|
|
||||||
|
|
||||||
<!-- ⚠️ IMPORTANT ⚠️
|
|
||||||
Before asking for help, please use the ArduinoJson Troubleshooter as it may find a solution to your issue; if not, please include the Troubleshooter's report in the description.
|
|
||||||
-->
|
|
||||||
|
|
||||||
**Describe the issue**
|
|
||||||
A clear and concise description of what you're trying to do.
|
|
||||||
You don't need to explain every aspect of your project: focus on the problem you're having.
|
|
||||||
|
|
||||||
**Troubleshooter report**
|
|
||||||
Here is the report generated by the [ArduinoJson Troubleshooter](https://arduinojson.org/v7/troubleshooter/):
|
|
||||||
[Paste the report here]
|
|
||||||
|
|
||||||
**Environment**
|
|
||||||
Here is the environment that I'm using':
|
|
||||||
* Microconroller: [e.g. ESP8266]
|
|
||||||
* Core/runtime: [e.g. ESP8266 core for Arduino v3.0.2]
|
|
||||||
* IDE: [e.g. Arduino IDE 1.8.16]
|
|
||||||
|
|
||||||
**Reproduction**
|
|
||||||
Here is a small snippet that demonstrate the problem.
|
|
||||||
|
|
||||||
```c++
|
|
||||||
JsonDocument doc;
|
|
||||||
|
|
||||||
DeserializationError error = deserializeJson(doc, "{\"hello\":\"world\"}");
|
|
||||||
|
|
||||||
// insert code here
|
|
||||||
```
|
|
||||||
|
|
||||||
**Program output**
|
|
||||||
If relevant, include the program output.
|
|
||||||
|
|
||||||
Expected output:
|
|
||||||
|
|
||||||
```
|
|
||||||
[insert expected output here]
|
|
||||||
```
|
|
||||||
|
|
||||||
Actual output:
|
|
||||||
|
|
||||||
```
|
|
||||||
[insert actual output here]
|
|
||||||
```
|
|
||||||
606
watering/lib/ArduinoJson/.github/workflows/ci.yml
vendored
606
watering/lib/ArduinoJson/.github/workflows/ci.yml
vendored
@ -1,606 +0,0 @@
|
|||||||
name: Continuous Integration
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
name: Lint
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
steps:
|
|
||||||
- name: Install
|
|
||||||
run: sudo apt-get install -y clang-format
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Symlinks
|
|
||||||
run: find * -type l -printf "::error::%p is a symlink. This is forbidden by the Arduino Library Specification." -exec false {} +
|
|
||||||
- name: Clang-format
|
|
||||||
run: |
|
|
||||||
find src/ extras/ -name '*.[ch]pp' | xargs clang-format -i --verbose --style=file
|
|
||||||
git diff --exit-code
|
|
||||||
- name: Check URLs
|
|
||||||
run: |
|
|
||||||
grep -hREo "(http|https)://[a-zA-Z0-9./?=_%:-]*" src/ | sort -u | while read -r URL
|
|
||||||
do
|
|
||||||
STATUS=$(curl -s -o /dev/null -I -w "%{http_code}" "$URL")
|
|
||||||
[ "$STATUS" -ge 400 ] && echo "::warning title=HTTP $STATUS::$URL returned $STATUS"
|
|
||||||
done || true
|
|
||||||
|
|
||||||
gcc:
|
|
||||||
name: GCC
|
|
||||||
needs: lint
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- gcc: "4.8"
|
|
||||||
- gcc: "5"
|
|
||||||
- gcc: "6"
|
|
||||||
- gcc: "7"
|
|
||||||
cxxflags: -fsanitize=leak -fno-sanitize-recover=all
|
|
||||||
- gcc: "8"
|
|
||||||
cxxflags: -fsanitize=undefined -fno-sanitize-recover=all
|
|
||||||
- gcc: "9"
|
|
||||||
cxxflags: -fsanitize=address -fno-sanitize-recover=all
|
|
||||||
- gcc: "10"
|
|
||||||
cxxflags: -funsigned-char # Issue #1715
|
|
||||||
- gcc: "11"
|
|
||||||
- gcc: "12"
|
|
||||||
steps:
|
|
||||||
- name: Workaround for actions/runner-images#9491
|
|
||||||
run: sudo sysctl vm.mmap_rnd_bits=28
|
|
||||||
|
|
||||||
- name: Install
|
|
||||||
run: |
|
|
||||||
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 40976EAF437D05B5 3B4FE6ACC0B21F32
|
|
||||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial main universe'
|
|
||||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic main universe'
|
|
||||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ focal main universe'
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y gcc-${{ matrix.gcc }} g++-${{ matrix.gcc }}
|
|
||||||
timeout-minutes: 5
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
timeout-minutes: 1
|
|
||||||
|
|
||||||
- name: Configure
|
|
||||||
run: cmake -DCMAKE_BUILD_TYPE=Debug .
|
|
||||||
env:
|
|
||||||
CC: gcc-${{ matrix.gcc }}
|
|
||||||
CXX: g++-${{ matrix.gcc }}
|
|
||||||
CXXFLAGS: ${{ matrix.cxxflags }}
|
|
||||||
timeout-minutes: 1
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: cmake --build .
|
|
||||||
timeout-minutes: 10
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: ctest --output-on-failure -C Debug .
|
|
||||||
env:
|
|
||||||
UBSAN_OPTIONS: print_stacktrace=1
|
|
||||||
timeout-minutes: 2
|
|
||||||
|
|
||||||
clang:
|
|
||||||
name: Clang
|
|
||||||
needs: lint
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- clang: "3.9"
|
|
||||||
runner: ubuntu-20.04
|
|
||||||
archive: bionic
|
|
||||||
- clang: "4.0"
|
|
||||||
runner: ubuntu-20.04
|
|
||||||
archive: bionic
|
|
||||||
- clang: "5.0"
|
|
||||||
runner: ubuntu-20.04
|
|
||||||
archive: bionic
|
|
||||||
- clang: "6.0"
|
|
||||||
runner: ubuntu-20.04
|
|
||||||
archive: bionic
|
|
||||||
- clang: "7"
|
|
||||||
runner: ubuntu-20.04
|
|
||||||
- clang: "8"
|
|
||||||
cxxflags: -fsanitize=leak -fno-sanitize-recover=all
|
|
||||||
runner: ubuntu-20.04
|
|
||||||
- clang: "9"
|
|
||||||
cxxflags: -fsanitize=undefined -fno-sanitize-recover=all
|
|
||||||
runner: ubuntu-20.04
|
|
||||||
- clang: "10"
|
|
||||||
cxxflags: -fsanitize=address -fno-sanitize-recover=all
|
|
||||||
runner: ubuntu-20.04
|
|
||||||
- clang: "11"
|
|
||||||
runner: ubuntu-22.04
|
|
||||||
- clang: "12"
|
|
||||||
runner: ubuntu-22.04
|
|
||||||
- clang: "13"
|
|
||||||
runner: ubuntu-22.04
|
|
||||||
- clang: "14"
|
|
||||||
runner: ubuntu-22.04
|
|
||||||
- clang: "15"
|
|
||||||
runner: ubuntu-22.04
|
|
||||||
runs-on: ${{ matrix.runner }}
|
|
||||||
steps:
|
|
||||||
- name: Add archive repositories
|
|
||||||
if: matrix.archive
|
|
||||||
run: |
|
|
||||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ ${{ matrix.archive }} main'
|
|
||||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ ${{ matrix.archive }} universe'
|
|
||||||
- name: Install Clang ${{ matrix.clang }}
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y clang-${{ matrix.clang }}
|
|
||||||
- name: Install libc++ ${{ matrix.clang }}
|
|
||||||
if: matrix.clang >= 11
|
|
||||||
run: sudo apt-get install -y libc++-${{ matrix.clang }}-dev libc++abi-${{ matrix.clang }}-dev
|
|
||||||
- name: Install libunwind ${{ matrix.clang }}
|
|
||||||
if: matrix.clang == 12 # dependency is missing in Ubuntu 22.04
|
|
||||||
run: sudo apt-get install -y libunwind-${{ matrix.clang }}-dev
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Configure
|
|
||||||
run: cmake -DCMAKE_BUILD_TYPE=Debug .
|
|
||||||
env:
|
|
||||||
CC: clang-${{ matrix.clang }}
|
|
||||||
CXX: clang++-${{ matrix.clang }}
|
|
||||||
CXXFLAGS: >-
|
|
||||||
${{ matrix.cxxflags }}
|
|
||||||
${{ matrix.clang < 11 && '-I/usr/lib/llvm-10/include/c++/v1/' || '' }}
|
|
||||||
- name: Build
|
|
||||||
run: cmake --build .
|
|
||||||
- name: Test
|
|
||||||
run: ctest --output-on-failure -C Debug .
|
|
||||||
env:
|
|
||||||
UBSAN_OPTIONS: print_stacktrace=1
|
|
||||||
|
|
||||||
conf_test:
|
|
||||||
name: Test configuration on Linux
|
|
||||||
needs: [gcc, clang]
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Install
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y g++-multilib gcc-avr avr-libc
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: AVR
|
|
||||||
run: avr-g++ -std=c++11 -Isrc extras/conf_test/avr.cpp
|
|
||||||
- name: GCC 32-bit
|
|
||||||
run: g++ -std=c++11 -m32 -Isrc extras/conf_test/x86.cpp
|
|
||||||
- name: GCC 64-bit
|
|
||||||
run: g++ -std=c++11 -m64 -Isrc extras/conf_test/x64.cpp
|
|
||||||
- name: Clang 32-bit
|
|
||||||
run: clang++ -std=c++11 -m32 -Isrc extras/conf_test/x86.cpp
|
|
||||||
- name: Clang 64-bit
|
|
||||||
run: clang++ -std=c++11 -m64 -Isrc extras/conf_test/x64.cpp
|
|
||||||
|
|
||||||
conf_test_windows:
|
|
||||||
name: Test configuration on Windows
|
|
||||||
runs-on: windows-2019
|
|
||||||
needs: [gcc, clang]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: 32-bit
|
|
||||||
run: |
|
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars32.bat"
|
|
||||||
cl /Isrc extras/conf_test/x86.cpp
|
|
||||||
shell: cmd
|
|
||||||
- name: 64-bit
|
|
||||||
run: |
|
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
|
||||||
cl /Isrc extras/conf_test/x64.cpp
|
|
||||||
shell: cmd
|
|
||||||
|
|
||||||
xcode:
|
|
||||||
name: XCode
|
|
||||||
needs: clang
|
|
||||||
runs-on: macos-13
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- xcode: "14.1"
|
|
||||||
- xcode: "14.2"
|
|
||||||
- xcode: "14.3.1"
|
|
||||||
- xcode: "15.0.1"
|
|
||||||
- xcode: "15.1"
|
|
||||||
- xcode: "15.2"
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Select XCode version
|
|
||||||
run: sudo xcode-select --switch /Applications/Xcode_${{ matrix.xcode }}.app
|
|
||||||
- name: Configure
|
|
||||||
run: cmake -DCMAKE_BUILD_TYPE=Debug .
|
|
||||||
- name: Build
|
|
||||||
run: cmake --build .
|
|
||||||
- name: Test
|
|
||||||
run: ctest --output-on-failure -C Debug .
|
|
||||||
|
|
||||||
# DISABLED: Running on AppVeyor instead because it supports older versions of the compiler
|
|
||||||
# msvc:
|
|
||||||
# name: Visual Studio
|
|
||||||
# strategy:
|
|
||||||
# fail-fast: false
|
|
||||||
# matrix:
|
|
||||||
# include:
|
|
||||||
# - os: windows-2016
|
|
||||||
# - os: windows-2019
|
|
||||||
# runs-on: ${{ matrix.os }}
|
|
||||||
# steps:
|
|
||||||
# - name: Checkout
|
|
||||||
# uses: actions/checkout@v4
|
|
||||||
# - name: Configure
|
|
||||||
# run: cmake -DCMAKE_BUILD_TYPE=Debug .
|
|
||||||
# - name: Build
|
|
||||||
# run: cmake --build .
|
|
||||||
# - name: Test
|
|
||||||
# run: ctest --output-on-failure -C Debug .
|
|
||||||
|
|
||||||
arduino:
|
|
||||||
name: Arduino
|
|
||||||
needs: gcc
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- core: arduino:avr
|
|
||||||
board: arduino:avr:uno
|
|
||||||
- core: arduino:samd
|
|
||||||
board: arduino:samd:mkr1000
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install arduino-cli
|
|
||||||
run: curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
|
|
||||||
- name: Install core
|
|
||||||
run: arduino-cli core install ${{ matrix.core }}
|
|
||||||
- name: Install libraries
|
|
||||||
run: arduino-cli lib install SD Ethernet
|
|
||||||
- name: Build JsonConfigFile
|
|
||||||
run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/JsonConfigFile/JsonConfigFile.ino"
|
|
||||||
- name: Build JsonFilterExample
|
|
||||||
run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/JsonFilterExample/JsonFilterExample.ino"
|
|
||||||
- name: Build JsonGeneratorExample
|
|
||||||
run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/JsonGeneratorExample/JsonGeneratorExample.ino"
|
|
||||||
- name: Build JsonHttpClient
|
|
||||||
run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/JsonHttpClient/JsonHttpClient.ino"
|
|
||||||
- name: Build JsonParserExample
|
|
||||||
run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/JsonParserExample/JsonParserExample.ino"
|
|
||||||
- name: Build JsonServer
|
|
||||||
run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/JsonServer/JsonServer.ino"
|
|
||||||
- name: Build JsonUdpBeacon
|
|
||||||
run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/JsonUdpBeacon/JsonUdpBeacon.ino"
|
|
||||||
- name: Build MsgPackParser
|
|
||||||
run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/MsgPackParser/MsgPackParser.ino"
|
|
||||||
- name: Build ProgmemExample
|
|
||||||
run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/ProgmemExample/ProgmemExample.ino"
|
|
||||||
- name: Build StringExample
|
|
||||||
run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/StringExample/StringExample.ino"
|
|
||||||
|
|
||||||
platformio:
|
|
||||||
name: PlatformIO
|
|
||||||
needs: gcc
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- platform: atmelavr
|
|
||||||
board: leonardo
|
|
||||||
libraries:
|
|
||||||
- SD
|
|
||||||
- Ethernet
|
|
||||||
conf_test: avr
|
|
||||||
- platform: espressif8266
|
|
||||||
board: huzzah
|
|
||||||
conf_test: esp8266
|
|
||||||
- platform: espressif32
|
|
||||||
board: esp32dev
|
|
||||||
libraries:
|
|
||||||
- Ethernet
|
|
||||||
conf_test: esp8266
|
|
||||||
- platform: atmelsam
|
|
||||||
board: mkr1000USB
|
|
||||||
libraries:
|
|
||||||
- SD
|
|
||||||
- Ethernet
|
|
||||||
conf_test: esp8266
|
|
||||||
- platform: teensy
|
|
||||||
board: teensy31
|
|
||||||
conf_test: esp8266
|
|
||||||
- platform: ststm32
|
|
||||||
board: adafruit_feather_f405
|
|
||||||
libraries:
|
|
||||||
- SD
|
|
||||||
- Ethernet
|
|
||||||
conf_test: esp8266
|
|
||||||
- platform: nordicnrf52
|
|
||||||
board: adafruit_feather_nrf52840
|
|
||||||
libraries:
|
|
||||||
- SD
|
|
||||||
- Ethernet
|
|
||||||
conf_test: esp8266
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Set up cache for pip
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ~/.cache/pip
|
|
||||||
key: ${{ runner.os }}-pip
|
|
||||||
- name: Set up Python 3.x
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: "3.x"
|
|
||||||
- name: Install PlatformIO
|
|
||||||
run: pip install platformio
|
|
||||||
- name: Install adafruit-nrfutil
|
|
||||||
if: ${{ matrix.platform == 'nordicnrf52' }}
|
|
||||||
run: pip install adafruit-nrfutil
|
|
||||||
- name: Include Adafruit_TinyUSB.h # https://github.com/adafruit/Adafruit_nRF52_Arduino/issues/653
|
|
||||||
if: ${{ matrix.platform == 'nordicnrf52' }}
|
|
||||||
run: find examples/ -name '*.ino' -exec sed -i 's/\(#include <ArduinoJson.h>\)/\1\n#include <Adafruit_TinyUSB.h>/' {} +
|
|
||||||
- name: Set up cache for platformio
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ~/.platformio
|
|
||||||
key: ${{ runner.os }}-platformio-${{ matrix.platform }}
|
|
||||||
- name: Install platform "${{ matrix.platform }}"
|
|
||||||
run: platformio platform install ${{ matrix.platform }}
|
|
||||||
- name: Install libraries
|
|
||||||
if: ${{ matrix.libraries }}
|
|
||||||
run: platformio lib install arduino-libraries/${{ join(matrix.libraries, ' arduino-libraries/') }}
|
|
||||||
- name: Test configuration
|
|
||||||
run: platformio ci "extras/conf_test/${{ matrix.conf_test }}.cpp" -l '.' -b ${{ matrix.board }}
|
|
||||||
if: ${{ matrix.conf_test }}
|
|
||||||
- name: Build JsonConfigFile
|
|
||||||
run: platformio ci "examples/JsonConfigFile/JsonConfigFile.ino" -l '.' -b ${{ matrix.board }}
|
|
||||||
- name: Build JsonFilterExample
|
|
||||||
run: platformio ci "examples/JsonFilterExample/JsonFilterExample.ino" -l '.' -b ${{ matrix.board }}
|
|
||||||
- name: Build JsonGeneratorExample
|
|
||||||
run: platformio ci "examples/JsonGeneratorExample/JsonGeneratorExample.ino" -l '.' -b ${{ matrix.board }}
|
|
||||||
- name: Build JsonHttpClient
|
|
||||||
run: platformio ci "examples/JsonHttpClient/JsonHttpClient.ino" -l '.' -b ${{ matrix.board }}
|
|
||||||
- name: Build JsonParserExample
|
|
||||||
run: platformio ci "examples/JsonParserExample/JsonParserExample.ino" -l '.' -b ${{ matrix.board }}
|
|
||||||
- name: Build JsonServer
|
|
||||||
if: ${{ matrix.platform != 'espressif32' }}
|
|
||||||
run: platformio ci "examples/JsonServer/JsonServer.ino" -l '.' -b ${{ matrix.board }}
|
|
||||||
- name: Build JsonUdpBeacon
|
|
||||||
run: platformio ci "examples/JsonUdpBeacon/JsonUdpBeacon.ino" -l '.' -b ${{ matrix.board }}
|
|
||||||
- name: Build MsgPackParser
|
|
||||||
run: platformio ci "examples/MsgPackParser/MsgPackParser.ino" -l '.' -b ${{ matrix.board }}
|
|
||||||
- name: Build ProgmemExample
|
|
||||||
run: platformio ci "examples/ProgmemExample/ProgmemExample.ino" -l '.' -b ${{ matrix.board }}
|
|
||||||
- name: Build StringExample
|
|
||||||
run: platformio ci "examples/StringExample/StringExample.ino" -l '.' -b ${{ matrix.board }}
|
|
||||||
- name: PlatformIO prune
|
|
||||||
if: ${{ always() }}
|
|
||||||
run: platformio system prune -f
|
|
||||||
|
|
||||||
particle:
|
|
||||||
name: Particle
|
|
||||||
needs: gcc
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.event_name == 'push'
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- board: argon
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install Particle CLI
|
|
||||||
run: sudo npm install -g particle-cli
|
|
||||||
- name: Login to Particle
|
|
||||||
run: particle login -t "${{ secrets.PARTICLE_TOKEN }}"
|
|
||||||
- name: Compile
|
|
||||||
run: extras/ci/particle.sh ${{ matrix.board }}
|
|
||||||
|
|
||||||
arm:
|
|
||||||
name: GCC for ARM processor
|
|
||||||
needs: gcc
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Install
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y g++-arm-linux-gnueabihf
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Configure
|
|
||||||
run: cmake .
|
|
||||||
env:
|
|
||||||
CC: arm-linux-gnueabihf-gcc
|
|
||||||
CXX: arm-linux-gnueabihf-g++
|
|
||||||
- name: Build
|
|
||||||
run: cmake --build .
|
|
||||||
|
|
||||||
coverage:
|
|
||||||
needs: gcc
|
|
||||||
name: Coverage
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Install
|
|
||||||
run: sudo apt-get install -y lcov ninja-build
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Configure
|
|
||||||
run: cmake -G Ninja -DCOVERAGE=true .
|
|
||||||
- name: Build
|
|
||||||
run: ninja
|
|
||||||
- name: Test
|
|
||||||
run: ctest --output-on-failure -LE 'WillFail|Fuzzing' -T test
|
|
||||||
- name: lcov --capture
|
|
||||||
run: lcov --capture --no-external --directory . --output-file coverage.info
|
|
||||||
- name: lcov --remove
|
|
||||||
run: lcov --remove coverage.info "$(pwd)/extras/*" --output-file coverage_filtered.info
|
|
||||||
- name: genhtml
|
|
||||||
run: mkdir coverage && genhtml coverage_filtered.info -o coverage -t ArduinoJson
|
|
||||||
- name: Upload HTML report
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: Coverage report
|
|
||||||
path: coverage
|
|
||||||
- name: Upload to Coveralls
|
|
||||||
uses: coverallsapp/github-action@v2
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
path-to-lcov: coverage_filtered.info
|
|
||||||
|
|
||||||
valgrind:
|
|
||||||
needs: gcc
|
|
||||||
name: Valgrind
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Install
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y valgrind ninja-build
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Configure
|
|
||||||
run: cmake -G Ninja -D MEMORYCHECK_COMMAND_OPTIONS="--error-exitcode=1 --leak-check=full" .
|
|
||||||
- name: Build
|
|
||||||
run: ninja
|
|
||||||
- name: Memcheck
|
|
||||||
run: ctest --output-on-failure -LE WillFail -T memcheck
|
|
||||||
id: memcheck
|
|
||||||
- name: MemoryChecker.*.log
|
|
||||||
run: cat Testing/Temporary/MemoryChecker.*.log > $GITHUB_STEP_SUMMARY
|
|
||||||
if: failure()
|
|
||||||
|
|
||||||
clang-tidy:
|
|
||||||
needs: clang
|
|
||||||
name: Clang-Tidy
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Install
|
|
||||||
run: sudo apt-get install -y clang-tidy cmake ninja-build
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Configure
|
|
||||||
run: cmake -G Ninja -DCMAKE_CXX_CLANG_TIDY="clang-tidy-10;--warnings-as-errors=*" -DCMAKE_BUILD_TYPE=Debug .
|
|
||||||
env:
|
|
||||||
CC: clang-10
|
|
||||||
CXX: clang++-10
|
|
||||||
- name: Check
|
|
||||||
run: cmake --build . -- -k 0
|
|
||||||
|
|
||||||
amalgamate:
|
|
||||||
needs: gcc
|
|
||||||
name: Amalgamate ArduinoJson.h
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Setup
|
|
||||||
run: |
|
|
||||||
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
|
||||||
VERSION=${GITHUB_REF#refs/tags/}
|
|
||||||
else
|
|
||||||
VERSION=${GITHUB_SHA::7}
|
|
||||||
fi
|
|
||||||
echo "ARDUINOJSON_H=ArduinoJson-$VERSION.h" >> $GITHUB_ENV
|
|
||||||
echo "ARDUINOJSON_HPP=ArduinoJson-$VERSION.hpp" >> $GITHUB_ENV
|
|
||||||
- name: Amalgamate ArduinoJson.h
|
|
||||||
run: extras/scripts/build-single-header.sh "src/ArduinoJson.h" "$ARDUINOJSON_H"
|
|
||||||
- name: Amalgamate ArduinoJson.hpp
|
|
||||||
run: extras/scripts/build-single-header.sh "src/ArduinoJson.hpp" "$ARDUINOJSON_HPP"
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: Single headers
|
|
||||||
path: |
|
|
||||||
${{ env.ARDUINOJSON_H }}
|
|
||||||
${{ env.ARDUINOJSON_HPP }}
|
|
||||||
- name: Smoke test ArduinoJson.h
|
|
||||||
run: |
|
|
||||||
g++ -x c++ - <<END
|
|
||||||
#include "$ARDUINOJSON_H"
|
|
||||||
int main() {
|
|
||||||
JsonDocument doc;
|
|
||||||
deserializeJson(doc, "{}");
|
|
||||||
}
|
|
||||||
END
|
|
||||||
- name: Smoke test ArduinoJson.hpp
|
|
||||||
run: |
|
|
||||||
g++ -x c++ - <<END
|
|
||||||
#include "$ARDUINOJSON_HPP"
|
|
||||||
int main() {
|
|
||||||
ArduinoJson::JsonDocument doc;
|
|
||||||
deserializeJson(doc, "{}");
|
|
||||||
}
|
|
||||||
END
|
|
||||||
|
|
||||||
esp-idf:
|
|
||||||
needs: gcc
|
|
||||||
name: ESP-IDF
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Setup cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ~/.espressif
|
|
||||||
key: ${{ runner.os }}-esp-idf
|
|
||||||
- name: Checkout ArduinoJson
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Checkout ESP-IDF
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: espressif/esp-idf
|
|
||||||
path: esp-idf
|
|
||||||
submodules: true
|
|
||||||
- name: Install ESP-IDF
|
|
||||||
run: ./esp-idf/install.sh
|
|
||||||
- name: Add component
|
|
||||||
# NOTE: we cannot commit the symlink because the Arduino Library Specification forbids it.
|
|
||||||
run: |
|
|
||||||
mkdir -p extras/ci/espidf/components
|
|
||||||
ln -s $PWD extras/ci/espidf/components/ArduinoJson
|
|
||||||
- name: Build example
|
|
||||||
run: |
|
|
||||||
source esp-idf/export.sh
|
|
||||||
cd extras/ci/espidf
|
|
||||||
idf.py build
|
|
||||||
|
|
||||||
codeql:
|
|
||||||
name: CodeQL
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
needs: gcc
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v3
|
|
||||||
with:
|
|
||||||
languages: cpp
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
cmake -DCMAKE_BUILD_TYPE=Debug .
|
|
||||||
cmake --build .
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
uses: github/codeql-action/analyze@v3
|
|
||||||
with:
|
|
||||||
category: "/language:cpp"
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
name: Lock Threads
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 0 * * *'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lock:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: dessant/lock-threads@v5
|
|
||||||
with:
|
|
||||||
github-token: ${{ github.token }}
|
|
||||||
issue-inactive-days: 30
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
name: Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- v*.*.*
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
name: Create release
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Set variables
|
|
||||||
id: init
|
|
||||||
run: |
|
|
||||||
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
|
||||||
echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Write release body
|
|
||||||
id: body
|
|
||||||
run: |
|
|
||||||
FILENAME=RELEASE.md
|
|
||||||
tee $FILENAME <<END
|
|
||||||
## Changes
|
|
||||||
|
|
||||||
$(extras/scripts/extract_changes.awk CHANGELOG.md)
|
|
||||||
|
|
||||||
[View version history](https://github.com/bblanchon/ArduinoJson/blob/${{ steps.init.outputs.tag }}/CHANGELOG.md)
|
|
||||||
END
|
|
||||||
echo "filename=$FILENAME" >> $GITHUB_OUTPUT
|
|
||||||
- name: Amalgamate ArduinoJson.h
|
|
||||||
id: amalgamate_h
|
|
||||||
run: |
|
|
||||||
FILENAME=ArduinoJson-${{ steps.init.outputs.tag }}.h
|
|
||||||
extras/scripts/build-single-header.sh src/ArduinoJson.h "$FILENAME"
|
|
||||||
echo "filename=$FILENAME" >> $GITHUB_OUTPUT
|
|
||||||
- name: Amalgamate ArduinoJson.hpp
|
|
||||||
id: amalgamate_hpp
|
|
||||||
run: |
|
|
||||||
FILENAME=ArduinoJson-${{ steps.init.outputs.tag }}.hpp
|
|
||||||
extras/scripts/build-single-header.sh src/ArduinoJson.hpp "$FILENAME"
|
|
||||||
echo "filename=$FILENAME" >> $GITHUB_OUTPUT
|
|
||||||
- name: Create release
|
|
||||||
uses: ncipollo/release-action@v1
|
|
||||||
with:
|
|
||||||
bodyFile: ${{ steps.body.outputs.filename }}
|
|
||||||
name: ArduinoJson ${{ steps.init.outputs.version }}
|
|
||||||
artifacts: ${{ steps.amalgamate_h.outputs.filename }},${{ steps.amalgamate_hpp.outputs.filename }}
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
idf:
|
|
||||||
name: IDF Component Registry
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Upload component to the component registry
|
|
||||||
uses: espressif/upload-components-ci-action@v1
|
|
||||||
with:
|
|
||||||
name: ArduinoJson
|
|
||||||
namespace: bblanchon
|
|
||||||
api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }}
|
|
||||||
|
|
||||||
particle:
|
|
||||||
name: Particle
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Install
|
|
||||||
run: npm install -g particle-cli
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Login
|
|
||||||
run: particle login --token ${{ secrets.PARTICLE_TOKEN }}
|
|
||||||
- name: Publish
|
|
||||||
run: bash -eux extras/scripts/publish-particle-library.sh
|
|
||||||
|
|
||||||
platformio:
|
|
||||||
name: PlatformIO
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Set up Python 3.x
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: "3.x"
|
|
||||||
- name: Install PlatformIO
|
|
||||||
run: pip install platformio
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Publish
|
|
||||||
run: pio pkg publish --no-interactive --no-notify
|
|
||||||
env:
|
|
||||||
PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_AUTH_TOKEN }}
|
|
||||||
246
watering/lib/AsyncTCP/.clang-format
Normal file
246
watering/lib/AsyncTCP/.clang-format
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
# Clang format version: 18.1.3
|
||||||
|
---
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: BlockIndent
|
||||||
|
AlignArrayOfStructures: None
|
||||||
|
AlignConsecutiveAssignments:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: true
|
||||||
|
AlignConsecutiveBitFields:
|
||||||
|
Enabled: true
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveDeclarations:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveMacros:
|
||||||
|
Enabled: true
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveShortCaseStatements:
|
||||||
|
Enabled: true
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCaseColons: false
|
||||||
|
AlignEscapedNewlines: Left
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments:
|
||||||
|
Kind: Always
|
||||||
|
OverEmptyLines: 0
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowBreakBeforeNoexceptSpecifier: Never
|
||||||
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
AllowShortCompoundRequirementOnASingleLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLambdasOnASingleLine: Empty
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
|
AttributeMacros:
|
||||||
|
- __capability
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: true
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakAdjacentStringLiterals: true
|
||||||
|
BreakAfterAttributes: Always
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakArrays: false
|
||||||
|
BreakBeforeBinaryOperators: NonAssignment
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeConceptDeclarations: Always
|
||||||
|
BreakBeforeInlineASMColon: OnlyMultiline
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 160
|
||||||
|
CommentPragmas: ""
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerIndentWidth: 2
|
||||||
|
ContinuationIndentWidth: 2
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IfMacros:
|
||||||
|
- KJ_IF_MAYBE
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: ^"(llvm|llvm-c|clang|clang-c)/
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: ^(<|"(gtest|gmock|isl|json)/)
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: .*
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
IncludeIsMainRegex: ""
|
||||||
|
IncludeIsMainSourceRegex: ""
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentExternBlock: NoIndent
|
||||||
|
IndentGotoLabels: false
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentRequiresClause: false
|
||||||
|
IndentWidth: 2
|
||||||
|
IndentWrappedFunctionNames: true
|
||||||
|
InsertBraces: true
|
||||||
|
InsertNewlineAtEOF: true
|
||||||
|
InsertTrailingCommas: None
|
||||||
|
IntegerLiteralSeparator:
|
||||||
|
Binary: 0
|
||||||
|
BinaryMinDigits: 0
|
||||||
|
Decimal: 0
|
||||||
|
DecimalMinDigits: 0
|
||||||
|
Hex: 0
|
||||||
|
HexMinDigits: 0
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtEOF: false
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
LambdaBodyIndentation: Signature
|
||||||
|
Language: Cpp
|
||||||
|
LineEnding: LF
|
||||||
|
MacroBlockBegin: ""
|
||||||
|
MacroBlockEnd: ""
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PPIndentWidth: -1
|
||||||
|
PackConstructorInitializers: BinPack
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakOpenParenthesis: 0
|
||||||
|
PenaltyBreakScopeResolution: 500
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Right
|
||||||
|
QualifierAlignment: Leave
|
||||||
|
ReferenceAlignment: Pointer
|
||||||
|
ReflowComments: false
|
||||||
|
RemoveBracesLLVM: false
|
||||||
|
RemoveParentheses: Leave
|
||||||
|
RemoveSemicolon: false
|
||||||
|
RequiresClausePosition: OwnLine
|
||||||
|
RequiresExpressionIndentation: OuterScope
|
||||||
|
SeparateDefinitionBlocks: Leave
|
||||||
|
ShortNamespaceLines: 1
|
||||||
|
SkipMacroDefinitionBody: false
|
||||||
|
SortIncludes: Never
|
||||||
|
SortJavaStaticImport: Before
|
||||||
|
SortUsingDeclarations: LexicographicNumeric
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeJsonColon: false
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeParensOptions:
|
||||||
|
AfterControlStatements: true
|
||||||
|
AfterForeachMacros: true
|
||||||
|
AfterFunctionDeclarationName: false
|
||||||
|
AfterFunctionDefinitionName: false
|
||||||
|
AfterIfMacros: true
|
||||||
|
AfterOverloadedOperator: true
|
||||||
|
AfterPlacementOperator: true
|
||||||
|
AfterRequiresInClause: false
|
||||||
|
AfterRequiresInExpression: false
|
||||||
|
BeforeNonEmptyParentheses: false
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
SpacesInAngles: Never
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
|
SpacesInParens: Never
|
||||||
|
SpacesInParensOptions:
|
||||||
|
InConditionalStatements: false
|
||||||
|
InCStyleCasts: false
|
||||||
|
InEmptyParentheses: false
|
||||||
|
Other: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Auto
|
||||||
|
StatementAttributeLikeMacros:
|
||||||
|
- Q_EMIT
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 2
|
||||||
|
UseTab: Never
|
||||||
|
VerilogBreakBetweenInstancePorts: true
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
|
- CF_SWIFT_NAME
|
||||||
|
- NS_SWIFT_NAME
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- STRINGIZE
|
||||||
|
BracedInitializerIndentWidth: 2
|
||||||
8
watering/lib/AsyncTCP/.codespellrc
Normal file
8
watering/lib/AsyncTCP/.codespellrc
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[codespell]
|
||||||
|
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/spell-check/.codespellrc
|
||||||
|
# In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here:
|
||||||
|
ignore-words-list = ba,licence
|
||||||
|
skip = ./.git,./.licenses,__pycache__,.clang-format,.codespellrc,.editorconfig,.flake8,.prettierignore,.yamllint.yml,.gitignore
|
||||||
|
builtin = clear,informal,en-GB_to_en-US
|
||||||
|
check-filenames =
|
||||||
|
check-hidden =
|
||||||
60
watering/lib/AsyncTCP/.editorconfig
Normal file
60
watering/lib/AsyncTCP/.editorconfig
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/general/.editorconfig
|
||||||
|
# See: https://editorconfig.org/
|
||||||
|
# The formatting style defined in this file is the official standardized style to be used in all Arduino Tooling
|
||||||
|
# projects and should not be modified.
|
||||||
|
# Note: indent style for each file type is defined even when it matches the universal config in order to make it clear
|
||||||
|
# that this type has an official style.
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.{adoc,asc,asciidoc}]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{bash,sh}]
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{c,cc,cp,cpp,cxx,h,hh,hpp,hxx,ii,inl,ino,ixx,pde,tpl,tpp,txx}]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{go,mod}]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
[*.java]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{js,jsx,json,jsonc,json5,ts,tsx}]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{md,mdx,mkdn,mdown,markdown}]
|
||||||
|
indent_size = unset
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.proto]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.py]
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.svg]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{yaml,yml}]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[{.gitconfig,.gitmodules}]
|
||||||
|
indent_style = tab
|
||||||
6
watering/lib/AsyncTCP/.gitignore
vendored
Normal file
6
watering/lib/AsyncTCP/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.DS_Store
|
||||||
|
.lh
|
||||||
|
/.pio
|
||||||
|
/.vscode
|
||||||
|
|
||||||
|
/logs
|
||||||
2
watering/lib/AsyncTCP/.gitpod.Dockerfile
vendored
Normal file
2
watering/lib/AsyncTCP/.gitpod.Dockerfile
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
FROM gitpod/workspace-python-3.11
|
||||||
|
USER gitpod
|
||||||
9
watering/lib/AsyncTCP/.gitpod.yml
Normal file
9
watering/lib/AsyncTCP/.gitpod.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
tasks:
|
||||||
|
- command: pip install --upgrade pip && pip install -U platformio && platformio run
|
||||||
|
|
||||||
|
image:
|
||||||
|
file: .gitpod.Dockerfile
|
||||||
|
|
||||||
|
vscode:
|
||||||
|
extensions:
|
||||||
|
- shardulm94.trailing-spaces
|
||||||
42
watering/lib/AsyncTCP/.pre-commit-config.yaml
Normal file
42
watering/lib/AsyncTCP/.pre-commit-config.yaml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
exclude: |
|
||||||
|
(?x)(
|
||||||
|
^\.github\/|
|
||||||
|
LICENSE\.md$
|
||||||
|
)
|
||||||
|
|
||||||
|
default_language_version:
|
||||||
|
# force all unspecified python hooks to run python3
|
||||||
|
python: python3
|
||||||
|
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: "v5.0.0"
|
||||||
|
hooks:
|
||||||
|
# Generic checks
|
||||||
|
- id: check-case-conflict
|
||||||
|
- id: check-symlinks
|
||||||
|
- id: debug-statements
|
||||||
|
- id: destroyed-symlinks
|
||||||
|
- id: detect-private-key
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
exclude: ^.*\.(bin|BIN)$
|
||||||
|
- id: mixed-line-ending
|
||||||
|
args: [--fix=lf]
|
||||||
|
- id: trailing-whitespace
|
||||||
|
args: [--markdown-linebreak-ext=md]
|
||||||
|
exclude: ^platformio\.ini$
|
||||||
|
|
||||||
|
- repo: https://github.com/codespell-project/codespell
|
||||||
|
rev: "v2.3.0"
|
||||||
|
hooks:
|
||||||
|
# Spell checking
|
||||||
|
- id: codespell
|
||||||
|
exclude: ^.*\.(svd|SVD)$
|
||||||
|
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
|
rev: "v18.1.3"
|
||||||
|
hooks:
|
||||||
|
# C/C++ formatting
|
||||||
|
- id: clang-format
|
||||||
|
types_or: [c, c++]
|
||||||
|
exclude: ^.*\/build_opt\.h$
|
||||||
15
watering/lib/AsyncTCP/CMakeLists.txt
Normal file
15
watering/lib/AsyncTCP/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
set(COMPONENT_SRCDIRS
|
||||||
|
"src"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(COMPONENT_ADD_INCLUDEDIRS
|
||||||
|
"src"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(COMPONENT_REQUIRES
|
||||||
|
"arduino-esp32"
|
||||||
|
)
|
||||||
|
|
||||||
|
register_component()
|
||||||
|
|
||||||
|
target_compile_options(${COMPONENT_TARGET} PRIVATE -fno-rtti)
|
||||||
129
watering/lib/AsyncTCP/CODE_OF_CONDUCT.md
Normal file
129
watering/lib/AsyncTCP/CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socioeconomic status,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity
|
||||||
|
and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the
|
||||||
|
overall community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or
|
||||||
|
advances of any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email
|
||||||
|
address, without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
https://sidweb.nl/cms3/en/contact.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series
|
||||||
|
of actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or
|
||||||
|
permanent ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within
|
||||||
|
the community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.0, available at
|
||||||
|
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
|
enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
https://www.contributor-covenant.org/faq. Translations are available at
|
||||||
|
https://www.contributor-covenant.org/translations.
|
||||||
30
watering/lib/AsyncTCP/Kconfig.projbuild
Normal file
30
watering/lib/AsyncTCP/Kconfig.projbuild
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
menu "AsyncTCP Configuration"
|
||||||
|
|
||||||
|
choice ASYNC_TCP_RUNNING_CORE
|
||||||
|
bool "Core on which AsyncTCP's thread is running"
|
||||||
|
default ASYNC_TCP_RUN_CORE1
|
||||||
|
help
|
||||||
|
Select on which core AsyncTCP is running
|
||||||
|
|
||||||
|
config ASYNC_TCP_RUN_CORE0
|
||||||
|
bool "CORE 0"
|
||||||
|
config ASYNC_TCP_RUN_CORE1
|
||||||
|
bool "CORE 1"
|
||||||
|
config ASYNC_TCP_RUN_NO_AFFINITY
|
||||||
|
bool "BOTH"
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config ASYNC_TCP_RUNNING_CORE
|
||||||
|
int
|
||||||
|
default 0 if ASYNC_TCP_RUN_CORE0
|
||||||
|
default 1 if ASYNC_TCP_RUN_CORE1
|
||||||
|
default -1 if ASYNC_TCP_RUN_NO_AFFINITY
|
||||||
|
|
||||||
|
config ASYNC_TCP_USE_WDT
|
||||||
|
bool "Enable WDT for the AsyncTCP task"
|
||||||
|
default "y"
|
||||||
|
help
|
||||||
|
Enable WDT for the AsyncTCP task, so it will trigger if a handler is locking the thread.
|
||||||
|
|
||||||
|
endmenu
|
||||||
165
watering/lib/AsyncTCP/LICENSE
Normal file
165
watering/lib/AsyncTCP/LICENSE
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
||||||
55
watering/lib/AsyncTCP/README.md
Normal file
55
watering/lib/AsyncTCP/README.md
Normal file
@ -0,0 +1,55 @@
|
|||||||
|

|
||||||
|
|
||||||
|
# AsyncTCP
|
||||||
|
|
||||||
|
[](https://opensource.org/license/lgpl-3-0/)
|
||||||
|
[](https://github.com/ESP32Async/AsyncTCP/actions/workflows/ci.yml)
|
||||||
|
[](https://registry.platformio.org/libraries/ESP32Async/AsyncTCP)
|
||||||
|
|
||||||
|
Discord Server: [https://discord.gg/X7zpGdyUcY](https://discord.gg/X7zpGdyUcY)
|
||||||
|
|
||||||
|
## Async TCP Library for ESP32 Arduino
|
||||||
|
|
||||||
|
This is a fully asynchronous TCP library, aimed at enabling trouble-free, multi-connection network environment for Espressif's ESP32 MCUs.
|
||||||
|
|
||||||
|
This library is the base for [ESPAsyncWebServer](https://github.com/ESP32Async/ESPAsyncWebServer)
|
||||||
|
|
||||||
|
## How to install
|
||||||
|
|
||||||
|
The library can be downloaded from the releases page at [https://github.com/ESP32Async/AsyncTCP/releases](https://github.com/ESP32Async/AsyncTCP/releases).
|
||||||
|
|
||||||
|
It is also deployed in these registries:
|
||||||
|
|
||||||
|
- Arduino Library Registry: [https://github.com/arduino/library-registry](https://github.com/arduino/library-registry)
|
||||||
|
|
||||||
|
- ESP Component Registry [https://components.espressif.com/components/esp32async/asynctcp/](https://components.espressif.com/components/esp32async/asynctcp/)
|
||||||
|
|
||||||
|
- PlatformIO Registry: [https://registry.platformio.org/libraries/esp32async/AsyncTCP](https://registry.platformio.org/libraries/esp32async/AsyncTCP)
|
||||||
|
|
||||||
|
- Use: `lib_deps=ESP32Async/AsyncTCP` to point to latest version
|
||||||
|
- Use: `lib_deps=ESP32Async/AsyncTCP @ ^<x.y.z>` to point to latest version with the same major version
|
||||||
|
- Use: `lib_deps=ESP32Async/AsyncTCP @ <x.y.z>` to always point to the same version (reproductible build)
|
||||||
|
|
||||||
|
## AsyncClient and AsyncServer
|
||||||
|
|
||||||
|
The base classes on which everything else is built. They expose all possible scenarios, but are really raw and require more skills to use.
|
||||||
|
|
||||||
|
## Important recommendations
|
||||||
|
|
||||||
|
Most of the crashes are caused by improper configuration of the library for the project.
|
||||||
|
Here are some recommendations to avoid them.
|
||||||
|
|
||||||
|
I personally use the following configuration in my projects:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 // (keep default)
|
||||||
|
-D CONFIG_ASYNC_TCP_PRIORITY=10 // (keep default)
|
||||||
|
-D CONFIG_ASYNC_TCP_QUEUE_SIZE=64 // (keep default)
|
||||||
|
-D CONFIG_ASYNC_TCP_RUNNING_CORE=1 // force async_tcp task to be on same core as the app (default is core 0)
|
||||||
|
-D CONFIG_ASYNC_TCP_STACK_SIZE=4096 // reduce the stack size (default is 16K)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
- ESP32
|
||||||
|
- Arduino Core 2.x and 3.x
|
||||||
25
watering/lib/AsyncTCP/arduino-cli-dev.yaml
Normal file
25
watering/lib/AsyncTCP/arduino-cli-dev.yaml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
board_manager:
|
||||||
|
additional_urls:
|
||||||
|
- https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json
|
||||||
|
directories:
|
||||||
|
builtin.libraries: ./src/
|
||||||
|
build_cache:
|
||||||
|
compilations_before_purge: 10
|
||||||
|
ttl: 720h0m0s
|
||||||
|
daemon:
|
||||||
|
port: "50051"
|
||||||
|
library:
|
||||||
|
enable_unsafe_install: false
|
||||||
|
logging:
|
||||||
|
file: ""
|
||||||
|
format: text
|
||||||
|
level: info
|
||||||
|
metrics:
|
||||||
|
addr: :9090
|
||||||
|
enabled: true
|
||||||
|
output:
|
||||||
|
no_color: false
|
||||||
|
sketch:
|
||||||
|
always_export_binaries: false
|
||||||
|
updater:
|
||||||
|
enable_notification: true
|
||||||
25
watering/lib/AsyncTCP/arduino-cli.yaml
Normal file
25
watering/lib/AsyncTCP/arduino-cli.yaml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
board_manager:
|
||||||
|
additional_urls:
|
||||||
|
- https://espressif.github.io/arduino-esp32/package_esp32_index.json
|
||||||
|
directories:
|
||||||
|
builtin.libraries: ./src/
|
||||||
|
build_cache:
|
||||||
|
compilations_before_purge: 10
|
||||||
|
ttl: 720h0m0s
|
||||||
|
daemon:
|
||||||
|
port: "50051"
|
||||||
|
library:
|
||||||
|
enable_unsafe_install: false
|
||||||
|
logging:
|
||||||
|
file: ""
|
||||||
|
format: text
|
||||||
|
level: info
|
||||||
|
metrics:
|
||||||
|
addr: :9090
|
||||||
|
enabled: true
|
||||||
|
output:
|
||||||
|
no_color: false
|
||||||
|
sketch:
|
||||||
|
always_export_binaries: false
|
||||||
|
updater:
|
||||||
|
enable_notification: true
|
||||||
3
watering/lib/AsyncTCP/component.mk
Normal file
3
watering/lib/AsyncTCP/component.mk
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
COMPONENT_ADD_INCLUDEDIRS := src
|
||||||
|
COMPONENT_SRCDIRS := src
|
||||||
|
CXXFLAGS += -fno-rtti
|
||||||
168
watering/lib/AsyncTCP/examples/AsyncSend/AsyncSend.ino
Normal file
168
watering/lib/AsyncTCP/examples/AsyncSend/AsyncSend.ino
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
/*
|
||||||
|
This example demonstrates how to send data to a remote server asynchronously.
|
||||||
|
Run on the remote computer: nc -l -p 1234
|
||||||
|
|
||||||
|
You should see in the logs:
|
||||||
|
|
||||||
|
Connected!
|
||||||
|
Will send 5760 bytes...
|
||||||
|
Acked 1436 bytes in 19 ms
|
||||||
|
Will send 1436 bytes...
|
||||||
|
Acked 1436 bytes in 2 ms
|
||||||
|
Will send 996 bytes...
|
||||||
|
Waiting for acks...
|
||||||
|
Acked 1436 bytes in 1 ms
|
||||||
|
Acked 1436 bytes in 5 ms
|
||||||
|
Acked 1452 bytes in 17 ms
|
||||||
|
Acked 996 bytes in 28 ms
|
||||||
|
Buffer received - next send in 2 sec
|
||||||
|
Will send 5760 bytes...
|
||||||
|
Acked 1436 bytes in 14 ms
|
||||||
|
Will send 1436 bytes...
|
||||||
|
Acked 1436 bytes in 2 ms
|
||||||
|
Acked 1436 bytes in 0 ms
|
||||||
|
Acked 1452 bytes in 1 ms
|
||||||
|
Will send 996 bytes...
|
||||||
|
Waiting for acks...
|
||||||
|
Acked 1436 bytes in 3 ms
|
||||||
|
Acked 996 bytes in 18 ms
|
||||||
|
Buffer received - next send in 2 sec
|
||||||
|
|
||||||
|
And in the remote terminal 3072 characters sent [......... ...........] and so on.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <StreamString.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define WIFI_SSID "IoT"
|
||||||
|
#define WIFI_PASSWORD ""
|
||||||
|
|
||||||
|
#define REMOTE_IP "192.168.125.116"
|
||||||
|
#define REMOTE_PORT 1234
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 8 * 1024
|
||||||
|
|
||||||
|
static char buffer[BUFFER_SIZE] = {0};
|
||||||
|
static size_t bufferPos = 0;
|
||||||
|
|
||||||
|
// 0 == disconnected
|
||||||
|
// 1 == connecting
|
||||||
|
// 2 == connected
|
||||||
|
static uint8_t state = 0;
|
||||||
|
|
||||||
|
// number of bytes waiting for a ack
|
||||||
|
static size_t waitingAck = 0;
|
||||||
|
|
||||||
|
static AsyncClient client;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect to WiFi
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
Serial.println("Connected to WiFi!");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
// fill buffer
|
||||||
|
buffer[0] = '[';
|
||||||
|
for (size_t i = 1; i < BUFFER_SIZE - 1; i++) {
|
||||||
|
buffer[i] = '.';
|
||||||
|
}
|
||||||
|
buffer[BUFFER_SIZE - 1] = ']';
|
||||||
|
|
||||||
|
// register a callback when the client disconnects
|
||||||
|
client.onDisconnect([](void *arg, AsyncClient *client) {
|
||||||
|
Serial.printf("Disconnected.\n");
|
||||||
|
state = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
// register a callback when an error occurs
|
||||||
|
client.onError([](void *arg, AsyncClient *client, int8_t error) {
|
||||||
|
Serial.printf("Error: %s\n", client->errorToString(error));
|
||||||
|
});
|
||||||
|
|
||||||
|
// register a callback when data arrives, to accumulate it
|
||||||
|
client.onData([](void *arg, AsyncClient *client, void *data, size_t len) {
|
||||||
|
Serial.printf("Received %u bytes...\n", len);
|
||||||
|
Serial.write((uint8_t *)data, len);
|
||||||
|
});
|
||||||
|
|
||||||
|
// register a callback when we are connected
|
||||||
|
client.onConnect([](void *arg, AsyncClient *client) {
|
||||||
|
Serial.printf("Connected!\n");
|
||||||
|
state = 2;
|
||||||
|
});
|
||||||
|
|
||||||
|
client.onAck([](void *arg, AsyncClient *client, size_t len, uint32_t time) {
|
||||||
|
Serial.printf("Acked %u bytes in %" PRIu32 " ms\n", len, time);
|
||||||
|
assert(waitingAck >= len);
|
||||||
|
waitingAck -= len;
|
||||||
|
});
|
||||||
|
|
||||||
|
client.setRxTimeout(20000);
|
||||||
|
client.setNoDelay(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
switch (state) {
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
Serial.printf("Connecting...\n");
|
||||||
|
if (!client.connect(REMOTE_IP, REMOTE_PORT)) {
|
||||||
|
Serial.printf("Failed to connect!\n");
|
||||||
|
delay(1000); // to not flood logs
|
||||||
|
} else {
|
||||||
|
state = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
Serial.printf("Still connecting...\n");
|
||||||
|
delay(500); // to not flood logs
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
// fill PCB space until we can
|
||||||
|
size_t willSend;
|
||||||
|
while (bufferPos < BUFFER_SIZE && (willSend = client.write(buffer + bufferPos, BUFFER_SIZE - bufferPos))) {
|
||||||
|
Serial.printf("Will send %u bytes...\n", willSend);
|
||||||
|
bufferPos += willSend;
|
||||||
|
waitingAck += willSend;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we have sent the whole buffer ?
|
||||||
|
if (bufferPos >= BUFFER_SIZE) {
|
||||||
|
// wait for acks, or send again after 2 sec
|
||||||
|
if (waitingAck) {
|
||||||
|
Serial.printf("Waiting for acks...\n");
|
||||||
|
delay(100);
|
||||||
|
} else {
|
||||||
|
Serial.printf("Buffer received - next send in 2 sec\n");
|
||||||
|
delay(2000);
|
||||||
|
bufferPos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
87
watering/lib/AsyncTCP/examples/Client/Client.ino
Normal file
87
watering/lib/AsyncTCP/examples/Client/Client.ino
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
|
||||||
|
// Run a server at the root of the project with:
|
||||||
|
// > python3 -m http.server 3333
|
||||||
|
// Now you can open a browser and test it works by visiting http://192.168.125.122:3333/ or http://192.168.125.122:3333/README.md
|
||||||
|
#define HOST "192.168.125.122"
|
||||||
|
#define PORT 3333
|
||||||
|
|
||||||
|
// WiFi SSID to connect to
|
||||||
|
#define WIFI_SSID "IoT"
|
||||||
|
|
||||||
|
// 16 slots on esp32 (CONFIG_LWIP_MAX_ACTIVE_TCP)
|
||||||
|
#define MAX_CLIENTS CONFIG_LWIP_MAX_ACTIVE_TCP
|
||||||
|
// #define MAX_CLIENTS 1
|
||||||
|
|
||||||
|
size_t permits = MAX_CLIENTS;
|
||||||
|
|
||||||
|
void makeRequest() {
|
||||||
|
if (!permits) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.printf("** permits: %d\n", permits);
|
||||||
|
|
||||||
|
AsyncClient *client = new AsyncClient;
|
||||||
|
|
||||||
|
client->onError([](void *arg, AsyncClient *client, int8_t error) {
|
||||||
|
Serial.printf("** error occurred %s \n", client->errorToString(error));
|
||||||
|
client->close(true);
|
||||||
|
delete client;
|
||||||
|
});
|
||||||
|
|
||||||
|
client->onConnect([](void *arg, AsyncClient *client) {
|
||||||
|
permits--;
|
||||||
|
Serial.printf("** client has been connected: %" PRIu16 "\n", client->localPort());
|
||||||
|
|
||||||
|
client->onDisconnect([](void *arg, AsyncClient *client) {
|
||||||
|
Serial.printf("** client has been disconnected: %" PRIu16 "\n", client->localPort());
|
||||||
|
client->close(true);
|
||||||
|
delete client;
|
||||||
|
|
||||||
|
permits++;
|
||||||
|
makeRequest();
|
||||||
|
});
|
||||||
|
|
||||||
|
client->onData([](void *arg, AsyncClient *client, void *data, size_t len) {
|
||||||
|
Serial.printf("** data received by client: %" PRIu16 ": len=%u\n", client->localPort(), len);
|
||||||
|
});
|
||||||
|
|
||||||
|
client->write("GET /README.md HTTP/1.1\r\nHost: " HOST "\r\nUser-Agent: ESP\r\nConnection: close\r\n\r\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
if (client->connect(HOST, PORT)) {
|
||||||
|
} else {
|
||||||
|
Serial.println("** connection failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.begin(WIFI_SSID);
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
Serial.println("** connected to WiFi");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < MAX_CLIENTS; i++) {
|
||||||
|
makeRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
delay(1000);
|
||||||
|
Serial.printf("** free heap: %" PRIu32 "\n", ESP.getFreeHeap());
|
||||||
|
}
|
||||||
111
watering/lib/AsyncTCP/examples/FetchWebsite/FetchWebsite.ino
Normal file
111
watering/lib/AsyncTCP/examples/FetchWebsite/FetchWebsite.ino
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <StreamString.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define WIFI_SSID "IoT"
|
||||||
|
#define WIFI_PASSWORD ""
|
||||||
|
|
||||||
|
void fetchAsync(const char *host, std::function<void(const StreamString *)> onDone) {
|
||||||
|
Serial.printf("[%s] Fetching: http://%s...\n", host, host);
|
||||||
|
|
||||||
|
// buffer where we will accumulate the received data
|
||||||
|
StreamString *content = new StreamString();
|
||||||
|
|
||||||
|
// reserve enough space to avoid reallocations
|
||||||
|
content->reserve(32 * 1024);
|
||||||
|
|
||||||
|
// create a new client
|
||||||
|
AsyncClient *client = new AsyncClient();
|
||||||
|
|
||||||
|
// register a callback when the client disconnects
|
||||||
|
client->onDisconnect([content, host, onDone](void *arg, AsyncClient *client) {
|
||||||
|
Serial.printf("[%s] Disconnected.\n", host);
|
||||||
|
onDone(content);
|
||||||
|
delete client;
|
||||||
|
delete content;
|
||||||
|
});
|
||||||
|
|
||||||
|
// register a callback when an error occurs
|
||||||
|
client->onError([host, onDone](void *arg, AsyncClient *client, int8_t error) {
|
||||||
|
Serial.printf("[%s] Error: %s\n", host, client->errorToString(error));
|
||||||
|
});
|
||||||
|
|
||||||
|
// register a callback when data arrives, to accumulate it
|
||||||
|
client->onData([host, content](void *arg, AsyncClient *client, void *data, size_t len) {
|
||||||
|
Serial.printf("[%s] Received %u bytes...\n", host, len);
|
||||||
|
content->write((const uint8_t *)data, len);
|
||||||
|
});
|
||||||
|
|
||||||
|
// register a callback when we are connected
|
||||||
|
client->onConnect([host](void *arg, AsyncClient *client) {
|
||||||
|
Serial.printf("[%s] Connected!\n", host);
|
||||||
|
|
||||||
|
// send request
|
||||||
|
client->write("GET / HTTP/1.1\r\n");
|
||||||
|
client->write("Host: ");
|
||||||
|
client->write(host);
|
||||||
|
client->write("\r\n");
|
||||||
|
client->write("User-Agent: ESP32\r\n");
|
||||||
|
client->write("Connection: close\r\n");
|
||||||
|
client->write("\r\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
Serial.printf("[%s] Connecting...\n", host);
|
||||||
|
|
||||||
|
client->setRxTimeout(20000);
|
||||||
|
// client->setAckTimeout(10000);
|
||||||
|
client->setNoDelay(true);
|
||||||
|
|
||||||
|
if (!client->connect(host, 80)) {
|
||||||
|
Serial.printf("[%s] Failed to connect!\n", host);
|
||||||
|
delete client;
|
||||||
|
delete content;
|
||||||
|
onDone(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect to WiFi
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
Serial.println("Connected to WiFi!");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
// fetch asynchronously 2 websites:
|
||||||
|
|
||||||
|
// equivalent to curl -v --raw http://www.google.com/
|
||||||
|
fetchAsync("www.google.com", [](const StreamString *content) {
|
||||||
|
if (content) {
|
||||||
|
Serial.printf("[www.google.com] Fetched website:\n%s\n", content->c_str());
|
||||||
|
} else {
|
||||||
|
Serial.println("[www.google.com] Failed to fetch website!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// equivalent to curl -v --raw http://www.time.org/
|
||||||
|
fetchAsync("www.time.org", [](const StreamString *content) {
|
||||||
|
if (content) {
|
||||||
|
Serial.printf("[www.time.org] Fetched website:\n%s\n", content->c_str());
|
||||||
|
} else {
|
||||||
|
Serial.println("[www.time.org] Failed to fetch website!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
32
watering/lib/AsyncTCP/idf_component.yml
Normal file
32
watering/lib/AsyncTCP/idf_component.yml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
description: "Async TCP Library for ESP32 Arduino"
|
||||||
|
url: "https://github.com/ESP32Async/AsyncTCP"
|
||||||
|
license: "LGPL-3.0-or-later"
|
||||||
|
tags:
|
||||||
|
- arduino
|
||||||
|
files:
|
||||||
|
exclude:
|
||||||
|
- "idf_component_examples/"
|
||||||
|
- "idf_component_examples/**/*"
|
||||||
|
- "examples/"
|
||||||
|
- "examples/**/*"
|
||||||
|
- ".gitignore"
|
||||||
|
- ".clang-format"
|
||||||
|
- ".gitpod.Dockerfile"
|
||||||
|
- ".gitpod.yml"
|
||||||
|
- ".codespellrc"
|
||||||
|
- ".editorconfig"
|
||||||
|
- ".pre-commit-config.yaml"
|
||||||
|
- "arduino-cli.yaml"
|
||||||
|
- "arduino-cli-dev.yaml"
|
||||||
|
- "CODE_OF_CONDUCT.md"
|
||||||
|
- "component.mk"
|
||||||
|
- "library.json"
|
||||||
|
- "library.properties"
|
||||||
|
- "platformio.ini"
|
||||||
|
- "pre-commit.requirements.txt"
|
||||||
|
dependencies:
|
||||||
|
espressif/arduino-esp32:
|
||||||
|
version: "^3.1.1"
|
||||||
|
require: public
|
||||||
|
examples:
|
||||||
|
- path: ./idf_component_examples/client
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
# For more information about build system see
|
||||||
|
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
|
||||||
|
# The following five lines of boilerplate have to be in your project's
|
||||||
|
# CMakeLists in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(main)
|
||||||
@ -0,0 +1 @@
|
|||||||
|
### Basic example to show how AsyncTCP client works
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
idf_component_register(SRCS "main.cpp"
|
||||||
|
INCLUDE_DIRS ".")
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
## IDF Component Manager Manifest File
|
||||||
|
dependencies:
|
||||||
|
esp32async/asynctcp:
|
||||||
|
version: "*"
|
||||||
|
override_path: "../../../"
|
||||||
|
pre_release: true
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "AsyncTCP.h"
|
||||||
|
#include "WiFi.h"
|
||||||
|
|
||||||
|
// Run a server at the root of the project with:
|
||||||
|
// > python3 -m http.server 3333
|
||||||
|
// Now you can open a browser and test it works by visiting http://192.168.125.122:3333/ or http://192.168.125.122:3333/README.md
|
||||||
|
#define HOST "192.168.125.122"
|
||||||
|
#define PORT 3333
|
||||||
|
|
||||||
|
// WiFi SSID to connect to
|
||||||
|
#define WIFI_SSID "*********"
|
||||||
|
#define WIFI_PASS "*********"
|
||||||
|
|
||||||
|
bool client_running = false;
|
||||||
|
|
||||||
|
void makeRequest() {
|
||||||
|
client_running = true;
|
||||||
|
AsyncClient *client = new AsyncClient;
|
||||||
|
if (client == nullptr) {
|
||||||
|
Serial.println("** could not allocate client");
|
||||||
|
client_running = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
client->onError([](void *arg, AsyncClient *client, int8_t error) {
|
||||||
|
Serial.printf("** error occurred %s \n", client->errorToString(error));
|
||||||
|
client->close(true);
|
||||||
|
delete client;
|
||||||
|
client_running = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
client->onConnect([](void *arg, AsyncClient *client) {
|
||||||
|
Serial.printf("** client has been connected: %" PRIu16 "\n", client->localPort());
|
||||||
|
|
||||||
|
client->onDisconnect([](void *arg, AsyncClient *client) {
|
||||||
|
Serial.printf("** client has been disconnected: %" PRIu16 "\n", client->localPort());
|
||||||
|
client->close(true);
|
||||||
|
delete client;
|
||||||
|
client_running = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
client->onData([](void *arg, AsyncClient *client, void *data, size_t len) {
|
||||||
|
Serial.printf("** data received by client: %" PRIu16 ": len=%u\n", client->localPort(), len);
|
||||||
|
});
|
||||||
|
|
||||||
|
client->write("GET /README.md HTTP/1.1\r\nHost: " HOST "\r\nUser-Agent: ESP\r\nConnection: close\r\n\r\n");
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!client->connect(HOST, PORT)) {
|
||||||
|
Serial.println("** connection failed");
|
||||||
|
client_running = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
Serial.print("Connecting to ");
|
||||||
|
Serial.print(WIFI_SSID);
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASS);
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
Serial.print("Connected to WiFi. IP: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (!client_running) {
|
||||||
|
makeRequest();
|
||||||
|
}
|
||||||
|
delay(1000);
|
||||||
|
Serial.printf("** free heap: %" PRIu32 "\n", ESP.getFreeHeap());
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
#
|
||||||
|
# Arduino ESP32
|
||||||
|
#
|
||||||
|
CONFIG_AUTOSTART_ARDUINO=y
|
||||||
|
# end of Arduino ESP32
|
||||||
|
|
||||||
|
#
|
||||||
|
# FREERTOS
|
||||||
|
#
|
||||||
|
CONFIG_FREERTOS_HZ=1000
|
||||||
|
# end of FREERTOS
|
||||||
|
# end of Component config
|
||||||
31
watering/lib/AsyncTCP/library.json
Normal file
31
watering/lib/AsyncTCP/library.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "AsyncTCP",
|
||||||
|
"version": "3.3.8",
|
||||||
|
"description": "Asynchronous TCP Library for ESP32",
|
||||||
|
"keywords": "async,tcp",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/ESP32Async/AsyncTCP.git"
|
||||||
|
},
|
||||||
|
"authors":
|
||||||
|
{
|
||||||
|
"name": "ESP32Async",
|
||||||
|
"maintainer": true
|
||||||
|
},
|
||||||
|
"license": "LGPL-3.0",
|
||||||
|
"frameworks": "arduino",
|
||||||
|
"platforms": [
|
||||||
|
"espressif32",
|
||||||
|
"libretiny"
|
||||||
|
],
|
||||||
|
"export": {
|
||||||
|
"include": [
|
||||||
|
"examples",
|
||||||
|
"src",
|
||||||
|
"library.json",
|
||||||
|
"library.properties",
|
||||||
|
"LICENSE",
|
||||||
|
"README.md"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
11
watering/lib/AsyncTCP/library.properties
Normal file
11
watering/lib/AsyncTCP/library.properties
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name=Async TCP
|
||||||
|
includes=AsyncTCP.h
|
||||||
|
version=3.3.8
|
||||||
|
author=ESP32Async
|
||||||
|
maintainer=ESP32Async
|
||||||
|
sentence=Async TCP Library for ESP32
|
||||||
|
paragraph=Async TCP Library for ESP32
|
||||||
|
category=Other
|
||||||
|
url=https://github.com/ESP32Async/AsyncTCP.git
|
||||||
|
architectures=*
|
||||||
|
license=LGPL-3.0
|
||||||
45
watering/lib/AsyncTCP/platformio.ini
Normal file
45
watering/lib/AsyncTCP/platformio.ini
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
[platformio]
|
||||||
|
default_envs = arduino-2, arduino-3
|
||||||
|
lib_dir = .
|
||||||
|
; src_dir = examples/Client
|
||||||
|
; src_dir = examples/FetchWebsite
|
||||||
|
src_dir = examples/AsyncSend
|
||||||
|
|
||||||
|
[env]
|
||||||
|
framework = arduino
|
||||||
|
build_flags =
|
||||||
|
-Wall -Wextra
|
||||||
|
-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=5000
|
||||||
|
-D CONFIG_ASYNC_TCP_PRIORITY=10
|
||||||
|
-D CONFIG_ASYNC_TCP_QUEUE_SIZE=64
|
||||||
|
-D CONFIG_ASYNC_TCP_RUNNING_CORE=1
|
||||||
|
-D CONFIG_ASYNC_TCP_STACK_SIZE=4096
|
||||||
|
-D CONFIG_ARDUHAL_LOG_COLORS
|
||||||
|
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
|
||||||
|
upload_protocol = esptool
|
||||||
|
monitor_speed = 115200
|
||||||
|
monitor_filters = esp32_exception_decoder, log2file
|
||||||
|
board = esp32dev
|
||||||
|
|
||||||
|
[env:arduino-2]
|
||||||
|
platform = espressif32@6.10.0
|
||||||
|
|
||||||
|
[env:arduino-3]
|
||||||
|
platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20/platform-espressif32.zip
|
||||||
|
|
||||||
|
[env:arduino-3-latest]
|
||||||
|
platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20-rc2/platform-espressif32.zip
|
||||||
|
|
||||||
|
; CI
|
||||||
|
|
||||||
|
[env:ci-arduino-2]
|
||||||
|
platform = espressif32@6.10.0
|
||||||
|
board = ${sysenv.PIO_BOARD}
|
||||||
|
|
||||||
|
[env:ci-arduino-3]
|
||||||
|
platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20/platform-espressif32.zip
|
||||||
|
board = ${sysenv.PIO_BOARD}
|
||||||
|
|
||||||
|
[env:ci-arduino-3-latest]
|
||||||
|
platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20-rc2/platform-espressif32.zip
|
||||||
|
board = ${sysenv.PIO_BOARD}
|
||||||
1
watering/lib/AsyncTCP/pre-commit.requirements.txt
Normal file
1
watering/lib/AsyncTCP/pre-commit.requirements.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
pre-commit==4.1.0
|
||||||
1682
watering/lib/AsyncTCP/src/AsyncTCP.cpp
Normal file
1682
watering/lib/AsyncTCP/src/AsyncTCP.cpp
Normal file
File diff suppressed because it is too large
Load Diff
335
watering/lib/AsyncTCP/src/AsyncTCP.h
Normal file
335
watering/lib/AsyncTCP/src/AsyncTCP.h
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
#ifndef ASYNCTCP_H_
|
||||||
|
#define ASYNCTCP_H_
|
||||||
|
|
||||||
|
#include "AsyncTCPVersion.h"
|
||||||
|
#define ASYNCTCP_FORK_ESP32Async
|
||||||
|
|
||||||
|
#include "IPAddress.h"
|
||||||
|
#if ESP_IDF_VERSION_MAJOR < 5
|
||||||
|
#include "IPv6Address.h"
|
||||||
|
#endif
|
||||||
|
#include "lwip/ip6_addr.h"
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#ifndef LIBRETINY
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
extern "C" {
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "lwip/pbuf.h"
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern "C" {
|
||||||
|
#include <lwip/pbuf.h>
|
||||||
|
#include <semphr.h>
|
||||||
|
}
|
||||||
|
#define CONFIG_ASYNC_TCP_RUNNING_CORE -1 // any available core
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// If core is not defined, then we are running in Arduino or PIO
|
||||||
|
#ifndef CONFIG_ASYNC_TCP_RUNNING_CORE
|
||||||
|
#define CONFIG_ASYNC_TCP_RUNNING_CORE -1 // any available core
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// guard AsyncTCP task with watchdog
|
||||||
|
#ifndef CONFIG_ASYNC_TCP_USE_WDT
|
||||||
|
#define CONFIG_ASYNC_TCP_USE_WDT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_ASYNC_TCP_STACK_SIZE
|
||||||
|
#define CONFIG_ASYNC_TCP_STACK_SIZE 8192 * 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_ASYNC_TCP_PRIORITY
|
||||||
|
#define CONFIG_ASYNC_TCP_PRIORITY 10
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_ASYNC_TCP_QUEUE_SIZE
|
||||||
|
#define CONFIG_ASYNC_TCP_QUEUE_SIZE 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_ASYNC_TCP_MAX_ACK_TIME
|
||||||
|
#define CONFIG_ASYNC_TCP_MAX_ACK_TIME 5000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class AsyncClient;
|
||||||
|
|
||||||
|
#define ASYNC_WRITE_FLAG_COPY 0x01 // will allocate new buffer to hold the data while sending (else will hold reference to the data given)
|
||||||
|
#define ASYNC_WRITE_FLAG_MORE 0x02 // will not send PSH flag, meaning that there should be more data to be sent before the application should react.
|
||||||
|
|
||||||
|
typedef std::function<void(void *, AsyncClient *)> AcConnectHandler;
|
||||||
|
typedef std::function<void(void *, AsyncClient *, size_t len, uint32_t time)> AcAckHandler;
|
||||||
|
typedef std::function<void(void *, AsyncClient *, int8_t error)> AcErrorHandler;
|
||||||
|
typedef std::function<void(void *, AsyncClient *, void *data, size_t len)> AcDataHandler;
|
||||||
|
typedef std::function<void(void *, AsyncClient *, struct pbuf *pb)> AcPacketHandler;
|
||||||
|
typedef std::function<void(void *, AsyncClient *, uint32_t time)> AcTimeoutHandler;
|
||||||
|
|
||||||
|
struct tcp_pcb;
|
||||||
|
struct ip_addr;
|
||||||
|
|
||||||
|
class AsyncClient {
|
||||||
|
public:
|
||||||
|
AsyncClient(tcp_pcb *pcb = 0);
|
||||||
|
~AsyncClient();
|
||||||
|
|
||||||
|
AsyncClient &operator=(const AsyncClient &other);
|
||||||
|
AsyncClient &operator+=(const AsyncClient &other);
|
||||||
|
|
||||||
|
bool operator==(const AsyncClient &other) const;
|
||||||
|
|
||||||
|
bool operator!=(const AsyncClient &other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
bool connect(const IPAddress &ip, uint16_t port);
|
||||||
|
#if ESP_IDF_VERSION_MAJOR < 5
|
||||||
|
bool connect(const IPv6Address &ip, uint16_t port);
|
||||||
|
#endif
|
||||||
|
bool connect(const char *host, uint16_t port);
|
||||||
|
/**
|
||||||
|
* @brief close connection
|
||||||
|
*
|
||||||
|
* @param now - ignored
|
||||||
|
*/
|
||||||
|
void close(bool now = false);
|
||||||
|
// same as close()
|
||||||
|
void stop() {
|
||||||
|
close(false);
|
||||||
|
};
|
||||||
|
int8_t abort();
|
||||||
|
bool free();
|
||||||
|
|
||||||
|
// ack is not pending
|
||||||
|
bool canSend() const;
|
||||||
|
// TCP buffer space available
|
||||||
|
size_t space() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief add data to be send (but do not send yet)
|
||||||
|
* @note add() would call lwip's tcp_write()
|
||||||
|
By default apiflags=ASYNC_WRITE_FLAG_COPY
|
||||||
|
You could try to use apiflags with this flag unset to pass data by reference and avoid copy to socket buffer,
|
||||||
|
but looks like it does not work for Arduino's lwip in ESP32/IDF at least
|
||||||
|
it is enforced in https://github.com/espressif/esp-lwip/blob/0606eed9d8b98a797514fdf6eabb4daf1c8c8cd9/src/core/tcp_out.c#L422C5-L422C30
|
||||||
|
if LWIP_NETIF_TX_SINGLE_PBUF is set, and it is set indeed in IDF
|
||||||
|
https://github.com/espressif/esp-idf/blob/a0f798cfc4bbd624aab52b2c194d219e242d80c1/components/lwip/port/include/lwipopts.h#L744
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @param size
|
||||||
|
* @param apiflags
|
||||||
|
* @return size_t amount of data that has been copied
|
||||||
|
*/
|
||||||
|
size_t add(const char *data, size_t size, uint8_t apiflags = ASYNC_WRITE_FLAG_COPY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief send data previously add()'ed
|
||||||
|
*
|
||||||
|
* @return true on success
|
||||||
|
* @return false on error
|
||||||
|
*/
|
||||||
|
bool send();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief add and enqueue data for sending
|
||||||
|
* @note it is same as add() + send()
|
||||||
|
* @note only make sense when canSend() == true
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @param size
|
||||||
|
* @param apiflags
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
size_t write(const char *data, size_t size, uint8_t apiflags = ASYNC_WRITE_FLAG_COPY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief add and enqueue data for sending
|
||||||
|
* @note treats data as null-terminated string
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @return size_t
|
||||||
|
*/
|
||||||
|
size_t write(const char *data) {
|
||||||
|
return data == NULL ? 0 : write(data, strlen(data));
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t state() const;
|
||||||
|
bool connecting() const;
|
||||||
|
bool connected() const;
|
||||||
|
bool disconnecting() const;
|
||||||
|
bool disconnected() const;
|
||||||
|
|
||||||
|
// disconnected or disconnecting
|
||||||
|
bool freeable() const;
|
||||||
|
|
||||||
|
uint16_t getMss() const;
|
||||||
|
|
||||||
|
uint32_t getRxTimeout() const;
|
||||||
|
// no RX data timeout for the connection in seconds
|
||||||
|
void setRxTimeout(uint32_t timeout);
|
||||||
|
|
||||||
|
uint32_t getAckTimeout() const;
|
||||||
|
// no ACK timeout for the last sent packet in milliseconds
|
||||||
|
void setAckTimeout(uint32_t timeout);
|
||||||
|
|
||||||
|
void setNoDelay(bool nodelay) const;
|
||||||
|
bool getNoDelay();
|
||||||
|
|
||||||
|
void setKeepAlive(uint32_t ms, uint8_t cnt);
|
||||||
|
|
||||||
|
uint32_t getRemoteAddress() const;
|
||||||
|
uint16_t getRemotePort() const;
|
||||||
|
uint32_t getLocalAddress() const;
|
||||||
|
uint16_t getLocalPort() const;
|
||||||
|
#if LWIP_IPV6
|
||||||
|
ip6_addr_t getRemoteAddress6() const;
|
||||||
|
ip6_addr_t getLocalAddress6() const;
|
||||||
|
#if ESP_IDF_VERSION_MAJOR < 5
|
||||||
|
IPv6Address remoteIP6() const;
|
||||||
|
IPv6Address localIP6() const;
|
||||||
|
#else
|
||||||
|
IPAddress remoteIP6() const;
|
||||||
|
IPAddress localIP6() const;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// compatibility
|
||||||
|
IPAddress remoteIP() const;
|
||||||
|
uint16_t remotePort() const;
|
||||||
|
IPAddress localIP() const;
|
||||||
|
uint16_t localPort() const;
|
||||||
|
|
||||||
|
// set callback - on successful connect
|
||||||
|
void onConnect(AcConnectHandler cb, void *arg = 0);
|
||||||
|
// set callback - disconnected
|
||||||
|
void onDisconnect(AcConnectHandler cb, void *arg = 0);
|
||||||
|
// set callback - ack received
|
||||||
|
void onAck(AcAckHandler cb, void *arg = 0);
|
||||||
|
// set callback - unsuccessful connect or error
|
||||||
|
void onError(AcErrorHandler cb, void *arg = 0);
|
||||||
|
// set callback - data received (called if onPacket is not used)
|
||||||
|
void onData(AcDataHandler cb, void *arg = 0);
|
||||||
|
// set callback - data received
|
||||||
|
// !!! You MUST call ackPacket() or free the pbuf yourself to prevent memory leaks
|
||||||
|
void onPacket(AcPacketHandler cb, void *arg = 0);
|
||||||
|
// set callback - ack timeout
|
||||||
|
void onTimeout(AcTimeoutHandler cb, void *arg = 0);
|
||||||
|
// set callback - every 125ms when connected
|
||||||
|
void onPoll(AcConnectHandler cb, void *arg = 0);
|
||||||
|
|
||||||
|
// ack pbuf from onPacket
|
||||||
|
void ackPacket(struct pbuf *pb);
|
||||||
|
// ack data that you have not acked using the method below
|
||||||
|
size_t ack(size_t len);
|
||||||
|
// will not ack the current packet. Call from onData
|
||||||
|
void ackLater() {
|
||||||
|
_ack_pcb = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *errorToString(int8_t error);
|
||||||
|
const char *stateToString() const;
|
||||||
|
|
||||||
|
// internal callbacks - Do NOT call any of the functions below in user code!
|
||||||
|
static int8_t _s_poll(void *arg, struct tcp_pcb *tpcb);
|
||||||
|
static int8_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, int8_t err);
|
||||||
|
static int8_t _s_fin(void *arg, struct tcp_pcb *tpcb, int8_t err);
|
||||||
|
static int8_t _s_lwip_fin(void *arg, struct tcp_pcb *tpcb, int8_t err);
|
||||||
|
static void _s_error(void *arg, int8_t err);
|
||||||
|
static int8_t _s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len);
|
||||||
|
static int8_t _s_connected(void *arg, struct tcp_pcb *tpcb, int8_t err);
|
||||||
|
static void _s_dns_found(const char *name, struct ip_addr *ipaddr, void *arg);
|
||||||
|
static void _tcp_error(void *arg, int8_t err);
|
||||||
|
|
||||||
|
int8_t _recv(tcp_pcb *pcb, pbuf *pb, int8_t err);
|
||||||
|
tcp_pcb *pcb() {
|
||||||
|
return _pcb;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class AsyncServer;
|
||||||
|
|
||||||
|
bool _connect(ip_addr_t addr, uint16_t port);
|
||||||
|
|
||||||
|
tcp_pcb *_pcb;
|
||||||
|
int8_t _closed_slot;
|
||||||
|
|
||||||
|
AcConnectHandler _connect_cb;
|
||||||
|
void *_connect_cb_arg;
|
||||||
|
AcConnectHandler _discard_cb;
|
||||||
|
void *_discard_cb_arg;
|
||||||
|
AcAckHandler _sent_cb;
|
||||||
|
void *_sent_cb_arg;
|
||||||
|
AcErrorHandler _error_cb;
|
||||||
|
void *_error_cb_arg;
|
||||||
|
AcDataHandler _recv_cb;
|
||||||
|
void *_recv_cb_arg;
|
||||||
|
AcPacketHandler _pb_cb;
|
||||||
|
void *_pb_cb_arg;
|
||||||
|
AcTimeoutHandler _timeout_cb;
|
||||||
|
void *_timeout_cb_arg;
|
||||||
|
AcConnectHandler _poll_cb;
|
||||||
|
void *_poll_cb_arg;
|
||||||
|
|
||||||
|
bool _ack_pcb;
|
||||||
|
uint32_t _tx_last_packet;
|
||||||
|
uint32_t _rx_ack_len;
|
||||||
|
uint32_t _rx_last_packet;
|
||||||
|
uint32_t _rx_timeout;
|
||||||
|
uint32_t _rx_last_ack;
|
||||||
|
uint32_t _ack_timeout;
|
||||||
|
uint16_t _connect_port;
|
||||||
|
|
||||||
|
int8_t _close();
|
||||||
|
void _free_closed_slot();
|
||||||
|
bool _allocate_closed_slot();
|
||||||
|
int8_t _connected(tcp_pcb *pcb, int8_t err);
|
||||||
|
void _error(int8_t err);
|
||||||
|
int8_t _poll(tcp_pcb *pcb);
|
||||||
|
int8_t _sent(tcp_pcb *pcb, uint16_t len);
|
||||||
|
int8_t _fin(tcp_pcb *pcb, int8_t err);
|
||||||
|
int8_t _lwip_fin(tcp_pcb *pcb, int8_t err);
|
||||||
|
void _dns_found(struct ip_addr *ipaddr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
AsyncClient *prev;
|
||||||
|
AsyncClient *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AsyncServer {
|
||||||
|
public:
|
||||||
|
AsyncServer(IPAddress addr, uint16_t port);
|
||||||
|
#if ESP_IDF_VERSION_MAJOR < 5
|
||||||
|
AsyncServer(IPv6Address addr, uint16_t port);
|
||||||
|
#endif
|
||||||
|
AsyncServer(uint16_t port);
|
||||||
|
~AsyncServer();
|
||||||
|
void onClient(AcConnectHandler cb, void *arg);
|
||||||
|
void begin();
|
||||||
|
void end();
|
||||||
|
void setNoDelay(bool nodelay);
|
||||||
|
bool getNoDelay() const;
|
||||||
|
uint8_t status() const;
|
||||||
|
|
||||||
|
// Do not use any of the functions below!
|
||||||
|
static int8_t _s_accept(void *arg, tcp_pcb *newpcb, int8_t err);
|
||||||
|
static int8_t _s_accepted(void *arg, AsyncClient *client);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint16_t _port;
|
||||||
|
bool _bind4 = false;
|
||||||
|
bool _bind6 = false;
|
||||||
|
IPAddress _addr;
|
||||||
|
#if ESP_IDF_VERSION_MAJOR < 5
|
||||||
|
IPv6Address _addr6;
|
||||||
|
#endif
|
||||||
|
bool _noDelay;
|
||||||
|
tcp_pcb *_pcb;
|
||||||
|
AcConnectHandler _connect_cb;
|
||||||
|
void *_connect_cb_arg;
|
||||||
|
|
||||||
|
int8_t _accept(tcp_pcb *newpcb, int8_t err);
|
||||||
|
int8_t _accepted(AsyncClient *client);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* ASYNCTCP_H_ */
|
||||||
40
watering/lib/AsyncTCP/src/AsyncTCPVersion.h
Normal file
40
watering/lib/AsyncTCP/src/AsyncTCPVersion.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Major version number (X.x.x) */
|
||||||
|
#define ASYNCTCP_VERSION_MAJOR 3
|
||||||
|
/** Minor version number (x.X.x) */
|
||||||
|
#define ASYNCTCP_VERSION_MINOR 3
|
||||||
|
/** Patch version number (x.x.X) */
|
||||||
|
#define ASYNCTCP_VERSION_PATCH 8
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macro to convert version number into an integer
|
||||||
|
*
|
||||||
|
* To be used in comparisons, such as ASYNCTCP_VERSION >= ASYNCTCP_VERSION_VAL(2, 0, 0)
|
||||||
|
*/
|
||||||
|
#define ASYNCTCP_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current version, as an integer
|
||||||
|
*
|
||||||
|
* To be used in comparisons, such as ASYNCTCP_VERSION_NUM >= ASYNCTCP_VERSION_VAL(2, 0, 0)
|
||||||
|
*/
|
||||||
|
#define ASYNCTCP_VERSION_NUM ASYNCTCP_VERSION_VAL(ASYNCTCP_VERSION_MAJOR, ASYNCTCP_VERSION_MINOR, ASYNCTCP_VERSION_PATCH)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current version, as string
|
||||||
|
*/
|
||||||
|
#define df2xstr(s) #s
|
||||||
|
#define df2str(s) df2xstr(s)
|
||||||
|
#define ASYNCTCP_VERSION df2str(ASYNCTCP_VERSION_MAJOR) "." df2str(ASYNCTCP_VERSION_MINOR) "." df2str(ASYNCTCP_VERSION_PATCH)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
246
watering/lib/ESPAsyncWebServer/.clang-format
Normal file
246
watering/lib/ESPAsyncWebServer/.clang-format
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
# Clang format version: 18.1.3
|
||||||
|
---
|
||||||
|
BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: BlockIndent
|
||||||
|
AlignArrayOfStructures: None
|
||||||
|
AlignConsecutiveAssignments:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: true
|
||||||
|
AlignConsecutiveBitFields:
|
||||||
|
Enabled: true
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveDeclarations:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveMacros:
|
||||||
|
Enabled: true
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveShortCaseStatements:
|
||||||
|
Enabled: true
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCaseColons: false
|
||||||
|
AlignEscapedNewlines: Left
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments:
|
||||||
|
Kind: Always
|
||||||
|
OverEmptyLines: 0
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowBreakBeforeNoexceptSpecifier: Never
|
||||||
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
AllowShortCompoundRequirementOnASingleLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLambdasOnASingleLine: Empty
|
||||||
|
AllowShortLoopsOnASingleLine: true
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
|
AttributeMacros:
|
||||||
|
- __capability
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: true
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakAdjacentStringLiterals: true
|
||||||
|
BreakAfterAttributes: Always
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakArrays: false
|
||||||
|
BreakBeforeBinaryOperators: NonAssignment
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeConceptDeclarations: Always
|
||||||
|
BreakBeforeInlineASMColon: OnlyMultiline
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 160
|
||||||
|
CommentPragmas: ""
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerIndentWidth: 2
|
||||||
|
ContinuationIndentWidth: 2
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IfMacros:
|
||||||
|
- KJ_IF_MAYBE
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: ^"(llvm|llvm-c|clang|clang-c)/
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: ^(<|"(gtest|gmock|isl|json)/)
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: .*
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
IncludeIsMainRegex: ""
|
||||||
|
IncludeIsMainSourceRegex: ""
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentExternBlock: NoIndent
|
||||||
|
IndentGotoLabels: false
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentRequiresClause: false
|
||||||
|
IndentWidth: 2
|
||||||
|
IndentWrappedFunctionNames: true
|
||||||
|
InsertBraces: true
|
||||||
|
InsertNewlineAtEOF: true
|
||||||
|
InsertTrailingCommas: None
|
||||||
|
IntegerLiteralSeparator:
|
||||||
|
Binary: 0
|
||||||
|
BinaryMinDigits: 0
|
||||||
|
Decimal: 0
|
||||||
|
DecimalMinDigits: 0
|
||||||
|
Hex: 0
|
||||||
|
HexMinDigits: 0
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtEOF: false
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
LambdaBodyIndentation: Signature
|
||||||
|
Language: Cpp
|
||||||
|
LineEnding: LF
|
||||||
|
MacroBlockBegin: ""
|
||||||
|
MacroBlockEnd: ""
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PPIndentWidth: -1
|
||||||
|
PackConstructorInitializers: BinPack
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakOpenParenthesis: 0
|
||||||
|
PenaltyBreakScopeResolution: 500
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Right
|
||||||
|
QualifierAlignment: Leave
|
||||||
|
ReferenceAlignment: Pointer
|
||||||
|
ReflowComments: false
|
||||||
|
RemoveBracesLLVM: false
|
||||||
|
RemoveParentheses: Leave
|
||||||
|
RemoveSemicolon: false
|
||||||
|
RequiresClausePosition: OwnLine
|
||||||
|
RequiresExpressionIndentation: OuterScope
|
||||||
|
SeparateDefinitionBlocks: Leave
|
||||||
|
ShortNamespaceLines: 1
|
||||||
|
SkipMacroDefinitionBody: false
|
||||||
|
SortIncludes: Never
|
||||||
|
SortJavaStaticImport: Before
|
||||||
|
SortUsingDeclarations: LexicographicNumeric
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeJsonColon: false
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeParensOptions:
|
||||||
|
AfterControlStatements: true
|
||||||
|
AfterForeachMacros: true
|
||||||
|
AfterFunctionDeclarationName: false
|
||||||
|
AfterFunctionDefinitionName: false
|
||||||
|
AfterIfMacros: true
|
||||||
|
AfterOverloadedOperator: true
|
||||||
|
AfterPlacementOperator: true
|
||||||
|
AfterRequiresInClause: false
|
||||||
|
AfterRequiresInExpression: false
|
||||||
|
BeforeNonEmptyParentheses: false
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
SpacesInAngles: Never
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
|
SpacesInParens: Never
|
||||||
|
SpacesInParensOptions:
|
||||||
|
InConditionalStatements: false
|
||||||
|
InCStyleCasts: false
|
||||||
|
InEmptyParentheses: false
|
||||||
|
Other: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Auto
|
||||||
|
StatementAttributeLikeMacros:
|
||||||
|
- Q_EMIT
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 2
|
||||||
|
UseTab: Never
|
||||||
|
VerilogBreakBetweenInstancePorts: true
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
|
- CF_SWIFT_NAME
|
||||||
|
- NS_SWIFT_NAME
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- STRINGIZE
|
||||||
|
BracedInitializerIndentWidth: 2
|
||||||
8
watering/lib/ESPAsyncWebServer/.codespellrc
Normal file
8
watering/lib/ESPAsyncWebServer/.codespellrc
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[codespell]
|
||||||
|
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/spell-check/.codespellrc
|
||||||
|
# In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here:
|
||||||
|
ignore-words-list = ba,licence,varius
|
||||||
|
skip = ./.git,./.licenses,__pycache__,.clang-format,.codespellrc,.editorconfig,.flake8,.prettierignore,.yamllint.yml,.gitignore
|
||||||
|
builtin = clear,informal,en-GB_to_en-US
|
||||||
|
check-filenames =
|
||||||
|
check-hidden =
|
||||||
60
watering/lib/ESPAsyncWebServer/.editorconfig
Normal file
60
watering/lib/ESPAsyncWebServer/.editorconfig
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/general/.editorconfig
|
||||||
|
# See: https://editorconfig.org/
|
||||||
|
# The formatting style defined in this file is the official standardized style to be used in all Arduino Tooling
|
||||||
|
# projects and should not be modified.
|
||||||
|
# Note: indent style for each file type is defined even when it matches the universal config in order to make it clear
|
||||||
|
# that this type has an official style.
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.{adoc,asc,asciidoc}]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{bash,sh}]
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{c,cc,cp,cpp,cxx,h,hh,hpp,hxx,ii,inl,ino,ixx,pde,tpl,tpp,txx}]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{go,mod}]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
[*.java]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{js,jsx,json,jsonc,json5,ts,tsx}]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{md,mdx,mkdn,mdown,markdown}]
|
||||||
|
indent_size = unset
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.proto]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.py]
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.svg]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{yaml,yml}]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[{.gitconfig,.gitmodules}]
|
||||||
|
indent_style = tab
|
||||||
5
watering/lib/ESPAsyncWebServer/.gitignore
vendored
Normal file
5
watering/lib/ESPAsyncWebServer/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.DS_Store
|
||||||
|
.lh
|
||||||
|
/.pio
|
||||||
|
/.vscode
|
||||||
|
/logs
|
||||||
2
watering/lib/ESPAsyncWebServer/.gitpod.Dockerfile
vendored
Normal file
2
watering/lib/ESPAsyncWebServer/.gitpod.Dockerfile
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
FROM gitpod/workspace-python-3.11
|
||||||
|
USER gitpod
|
||||||
9
watering/lib/ESPAsyncWebServer/.gitpod.yml
Normal file
9
watering/lib/ESPAsyncWebServer/.gitpod.yml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
tasks:
|
||||||
|
- command: pip install --upgrade pip && pip install -U platformio && platformio run
|
||||||
|
|
||||||
|
image:
|
||||||
|
file: .gitpod.Dockerfile
|
||||||
|
|
||||||
|
vscode:
|
||||||
|
extensions:
|
||||||
|
- shardulm94.trailing-spaces
|
||||||
42
watering/lib/ESPAsyncWebServer/.pre-commit-config.yaml
Normal file
42
watering/lib/ESPAsyncWebServer/.pre-commit-config.yaml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
exclude: |
|
||||||
|
(?x)(
|
||||||
|
^\.github\/|
|
||||||
|
LICENSE$
|
||||||
|
)
|
||||||
|
|
||||||
|
default_language_version:
|
||||||
|
# force all unspecified python hooks to run python3
|
||||||
|
python: python3
|
||||||
|
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: "v5.0.0"
|
||||||
|
hooks:
|
||||||
|
# Generic checks
|
||||||
|
- id: check-case-conflict
|
||||||
|
- id: check-symlinks
|
||||||
|
- id: debug-statements
|
||||||
|
- id: destroyed-symlinks
|
||||||
|
- id: detect-private-key
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
exclude: ^.*\.(bin|BIN)$
|
||||||
|
- id: mixed-line-ending
|
||||||
|
args: [--fix=lf]
|
||||||
|
- id: trailing-whitespace
|
||||||
|
args: [--markdown-linebreak-ext=md]
|
||||||
|
exclude: ^platformio\.ini$
|
||||||
|
|
||||||
|
- repo: https://github.com/codespell-project/codespell
|
||||||
|
rev: "v2.3.0"
|
||||||
|
hooks:
|
||||||
|
# Spell checking
|
||||||
|
- id: codespell
|
||||||
|
exclude: ^.*\.(svd|SVD)$
|
||||||
|
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
|
rev: "v18.1.3"
|
||||||
|
hooks:
|
||||||
|
# C/C++ formatting
|
||||||
|
- id: clang-format
|
||||||
|
types_or: [c, c++]
|
||||||
|
exclude: ^.*\/build_opt\.h$
|
||||||
9
watering/lib/ESPAsyncWebServer/CMakeLists.txt
Normal file
9
watering/lib/ESPAsyncWebServer/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
set(COMPONENT_SRCDIRS
|
||||||
|
"src"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(COMPONENT_ADD_INCLUDEDIRS
|
||||||
|
"src"
|
||||||
|
)
|
||||||
|
|
||||||
|
register_component()
|
||||||
129
watering/lib/ESPAsyncWebServer/CODE_OF_CONDUCT.md
Normal file
129
watering/lib/ESPAsyncWebServer/CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socioeconomic status,
|
||||||
|
nationality, personal appearance, race, religion, or sexual identity
|
||||||
|
and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the
|
||||||
|
overall community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or
|
||||||
|
advances of any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email
|
||||||
|
address, without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement at
|
||||||
|
https://sidweb.nl/cms3/en/contact.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series
|
||||||
|
of actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or
|
||||||
|
permanent ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within
|
||||||
|
the community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.0, available at
|
||||||
|
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||||
|
enforcement ladder](https://github.com/mozilla/diversity).
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
https://www.contributor-covenant.org/faq. Translations are available at
|
||||||
|
https://www.contributor-covenant.org/translations.
|
||||||
165
watering/lib/ESPAsyncWebServer/LICENSE
Normal file
165
watering/lib/ESPAsyncWebServer/LICENSE
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
||||||
141
watering/lib/ESPAsyncWebServer/README.md
Normal file
141
watering/lib/ESPAsyncWebServer/README.md
Normal file
@ -0,0 +1,141 @@
|
|||||||
|

|
||||||
|
|
||||||
|
# ESPAsyncWebServer
|
||||||
|
|
||||||
|
[](https://GitHub.com/ESP32Async/ESPAsyncWebServer/releases/)
|
||||||
|
[](https://registry.platformio.org/libraries/ESP32Async/ESPAsyncWebServer)
|
||||||
|
|
||||||
|
[](https://opensource.org/license/lgpl-3-0/)
|
||||||
|
[](code_of_conduct.md)
|
||||||
|
|
||||||
|
[](https://GitHub.com/ESP32Async/ESPAsyncWebServer/commit/)
|
||||||
|
[](https://gitpod.io/#https://github.com/ESP32Async/ESPAsyncWebServer)
|
||||||
|
|
||||||
|
[](https://discord.gg/X7zpGdyUcY)
|
||||||
|
|
||||||
|
[](https://github.com/ESP32Async/ESPAsyncWebServer/wiki)
|
||||||
|
|
||||||
|
## Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266, RP2040 and RP2350
|
||||||
|
|
||||||
|
Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.
|
||||||
|
|
||||||
|
- [Documentation](#documentation)
|
||||||
|
- [How to install](#how-to-install)
|
||||||
|
- [Dependencies](#dependencies)
|
||||||
|
- [ESP32 / pioarduino](#esp32--pioarduino)
|
||||||
|
- [ESP8266 / pioarduino](#esp8266--pioarduino)
|
||||||
|
- [Unofficial dependencies](#unofficial-dependencies)
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
The complete [project documentation](https://github.com/ESP32Async/ESPAsyncWebServer/wiki) is available in the Wiki section.
|
||||||
|
|
||||||
|
## How to install
|
||||||
|
|
||||||
|
The library can be downloaded from the releases page at [https://github.com/ESP32Async/ESPAsyncWebServer/releases](https://github.com/ESP32Async/ESPAsyncWebServer/releases).
|
||||||
|
|
||||||
|
It is also deployed in these registries:
|
||||||
|
|
||||||
|
- Arduino Library Registry: [https://github.com/arduino/library-registry](https://github.com/arduino/library-registry)
|
||||||
|
|
||||||
|
- ESP Component Registry [https://components.espressif.com/components/esp32async/espasyncwebserver](https://components.espressif.com/components/esp32async/espasyncwebserver)
|
||||||
|
|
||||||
|
- PlatformIO Registry: [https://registry.platformio.org/libraries/esp32async/ESPAsyncWebServer](https://registry.platformio.org/libraries/esp32async/ESPAsyncWebServer)
|
||||||
|
|
||||||
|
- Use: `lib_deps=ESP32Async/ESPAsyncWebServer` to point to latest version
|
||||||
|
- Use: `lib_deps=ESP32Async/ESPAsyncWebServer @ ^<x.y.z>` to point to latest version with the same major version
|
||||||
|
- Use: `lib_deps=ESP32Async/ESPAsyncWebServer @ <x.y.z>` to always point to the same version (reproductible build)
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
### ESP32 / pioarduino
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[env:stable]
|
||||||
|
platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip
|
||||||
|
lib_compat_mode = strict
|
||||||
|
lib_ldf_mode = chain
|
||||||
|
lib_deps =
|
||||||
|
ESP32Async/AsyncTCP
|
||||||
|
ESP32Async/ESPAsyncWebServer
|
||||||
|
```
|
||||||
|
|
||||||
|
### ESP8266 / pioarduino
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[env:stable]
|
||||||
|
platform = espressif8266
|
||||||
|
lib_compat_mode = strict
|
||||||
|
lib_ldf_mode = chain
|
||||||
|
lib_deps =
|
||||||
|
ESP32Async/ESPAsyncTCP
|
||||||
|
ESP32Async/ESPAsyncWebServer
|
||||||
|
```
|
||||||
|
|
||||||
|
### Unofficial dependencies
|
||||||
|
|
||||||
|
**AsyncTCPSock**
|
||||||
|
|
||||||
|
AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the library dependencies and adding AsyncTCPSock instead:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
lib_compat_mode = strict
|
||||||
|
lib_ldf_mode = chain
|
||||||
|
lib_deps =
|
||||||
|
https://github.com/ESP32Async/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip
|
||||||
|
ESP32Async/ESPAsyncWebServer
|
||||||
|
lib_ignore =
|
||||||
|
AsyncTCP
|
||||||
|
ESP32Async/AsyncTCP
|
||||||
|
```
|
||||||
|
|
||||||
|
**RPAsyncTCP**
|
||||||
|
|
||||||
|
RPAsyncTCP replaces AsyncTCP to provide support for RP2040(+WiFi) and RP2350(+WiFi) boards. For example - Raspberry Pi Pico W and Raspberry Pi Pico 2W.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
lib_compat_mode = strict
|
||||||
|
lib_ldf_mode = chain
|
||||||
|
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
|
||||||
|
board = rpipicow
|
||||||
|
board_build.core = earlephilhower
|
||||||
|
lib_deps =
|
||||||
|
ayushsharma82/RPAsyncTCP@^1.3.2
|
||||||
|
ESP32Async/ESPAsyncWebServer
|
||||||
|
lib_ignore =
|
||||||
|
lwIP_ESPHost
|
||||||
|
build_flags = ${env.build_flags}
|
||||||
|
-Wno-missing-field-initializers
|
||||||
|
```
|
||||||
|
|
||||||
|
## Important recommendations for build options
|
||||||
|
|
||||||
|
Most of the crashes are caused by improper use or configuration of the AsyncTCP library used for the project.
|
||||||
|
Here are some recommendations to avoid them and build-time flags you can change.
|
||||||
|
|
||||||
|
`CONFIG_ASYNC_TCP_MAX_ACK_TIME` - defines a timeout for TCP connection to be considered alive when waiting for data.
|
||||||
|
In some bad network conditions you might consider increasing it.
|
||||||
|
|
||||||
|
`CONFIG_ASYNC_TCP_QUEUE_SIZE` - defines the length of the queue for events related to connections handling.
|
||||||
|
Both the server and AsyncTCP library were optimized to control the queue automatically. Do NOT try blindly increasing the queue size, it does not help you in a way you might think it is. If you receive debug messages about queue throttling, try to optimize your server callbacks code to execute as fast as possible.
|
||||||
|
Read #165 thread, it might give you some hints.
|
||||||
|
|
||||||
|
`CONFIG_ASYNC_TCP_RUNNING_CORE` - CPU core thread affinity that runs the queue events handling and executes server callbacks. Default is ANY core, so it means that for dualcore SoCs both cores could handle server activities. If your server's code is too heavy and unoptimized or you see that sometimes
|
||||||
|
server might affect other network activities, you might consider to bind it to the same core that runs Arduino code (1) to minimize affect on radio part. Otherwise you can leave the default to let RTOS decide where to run the thread based on priority
|
||||||
|
|
||||||
|
`CONFIG_ASYNC_TCP_STACK_SIZE` - stack size for the thread that runs sever events and callbacks. Default is 16k that is a way too much waste for well-defined short async code or simple static file handling. You might want to cosider reducing it to 4-8k to same RAM usage. If you do not know what this is or not sure about your callback code demands - leave it as default, should be enough even for very hungry callbacks in most cases.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This relates to ESP32 only, ESP8266 uses different ESPAsyncTCP lib that does not has this build options
|
||||||
|
|
||||||
|
I personally use the following configuration in my projects:
|
||||||
|
|
||||||
|
```c++
|
||||||
|
-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 // (keep default)
|
||||||
|
-D CONFIG_ASYNC_TCP_PRIORITY=10 // (keep default)
|
||||||
|
-D CONFIG_ASYNC_TCP_QUEUE_SIZE=64 // (keep default)
|
||||||
|
-D CONFIG_ASYNC_TCP_RUNNING_CORE=1 // force async_tcp task to be on same core as Arduino app (default is any core)
|
||||||
|
-D CONFIG_ASYNC_TCP_STACK_SIZE=4096 // reduce the stack size (default is 16K)
|
||||||
|
```
|
||||||
|
|
||||||
|
If you need to serve chunk requests with a really low buffer (which should be avoided), you can set `-D ASYNCWEBSERVER_USE_CHUNK_INFLIGHT=0` to disable the in-flight control.
|
||||||
48
watering/lib/ESPAsyncWebServer/data/README.md
Normal file
48
watering/lib/ESPAsyncWebServer/data/README.md
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.
|
||||||
BIN
watering/lib/ESPAsyncWebServer/docs/logo.png
Normal file
BIN
watering/lib/ESPAsyncWebServer/docs/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 479 KiB |
BIN
watering/lib/ESPAsyncWebServer/docs/logo.webp
Normal file
BIN
watering/lib/ESPAsyncWebServer/docs/logo.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 131 KiB |
BIN
watering/lib/ESPAsyncWebServer/docs/perf-c10-asynctcpsock.png
Normal file
BIN
watering/lib/ESPAsyncWebServer/docs/perf-c10-asynctcpsock.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 310 KiB |
BIN
watering/lib/ESPAsyncWebServer/docs/perf-c10.png
Normal file
BIN
watering/lib/ESPAsyncWebServer/docs/perf-c10.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 295 KiB |
@ -0,0 +1,47 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
#include <DNSServer.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP("esp-captive");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Shows how to use AsyncResponseStream.
|
||||||
|
// The internal buffer will be allocated and data appended to it,
|
||||||
|
// until the response is sent, then this buffer is read and committed on the network.
|
||||||
|
//
|
||||||
|
// curl -v http://192.168.4.1/
|
||||||
|
//
|
||||||
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
AsyncResponseStream *response = request->beginResponseStream("plain/text", 40 * 1024);
|
||||||
|
for (int i = 0; i < 32 * 1024; i++) {
|
||||||
|
response->write('a');
|
||||||
|
}
|
||||||
|
request->send(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
157
watering/lib/ESPAsyncWebServer/examples/Auth/Auth.ino
Normal file
157
watering/lib/ESPAsyncWebServer/examples/Auth/Auth.ino
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
//
|
||||||
|
// Authentication and authorization middlewares
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
|
||||||
|
// basicAuth
|
||||||
|
static AsyncAuthenticationMiddleware basicAuth;
|
||||||
|
static AsyncAuthenticationMiddleware basicAuthHash;
|
||||||
|
|
||||||
|
// simple digest authentication
|
||||||
|
static AsyncAuthenticationMiddleware digestAuth;
|
||||||
|
static AsyncAuthenticationMiddleware digestAuthHash;
|
||||||
|
|
||||||
|
// complex authentication which adds request attributes for the next middlewares and handler
|
||||||
|
static AsyncMiddlewareFunction complexAuth([](AsyncWebServerRequest *request, ArMiddlewareNext next) {
|
||||||
|
if (!request->authenticate("user", "password")) {
|
||||||
|
return request->requestAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
// add attributes to the request for the next middlewares and handler
|
||||||
|
request->setAttribute("user", "Mathieu");
|
||||||
|
request->setAttribute("role", "staff");
|
||||||
|
if (request->hasParam("token")) {
|
||||||
|
request->setAttribute("token", request->getParam("token")->value().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
static AsyncAuthorizationMiddleware authz([](AsyncWebServerRequest *request) {
|
||||||
|
return request->getAttribute("token") == "123";
|
||||||
|
});
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP("esp-captive");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// basic authentication
|
||||||
|
basicAuth.setUsername("admin");
|
||||||
|
basicAuth.setPassword("admin");
|
||||||
|
basicAuth.setRealm("MyApp");
|
||||||
|
basicAuth.setAuthFailureMessage("Authentication failed");
|
||||||
|
basicAuth.setAuthType(AsyncAuthType::AUTH_BASIC);
|
||||||
|
basicAuth.generateHash(); // precompute hash (optional but recommended)
|
||||||
|
|
||||||
|
// basic authentication with hash
|
||||||
|
basicAuthHash.setUsername("admin");
|
||||||
|
basicAuthHash.setPasswordHash("YWRtaW46YWRtaW4="); // BASE64(admin:admin)
|
||||||
|
basicAuthHash.setRealm("MyApp");
|
||||||
|
basicAuthHash.setAuthFailureMessage("Authentication failed");
|
||||||
|
basicAuthHash.setAuthType(AsyncAuthType::AUTH_BASIC);
|
||||||
|
|
||||||
|
// digest authentication
|
||||||
|
digestAuth.setUsername("admin");
|
||||||
|
digestAuth.setPassword("admin");
|
||||||
|
digestAuth.setRealm("MyApp");
|
||||||
|
digestAuth.setAuthFailureMessage("Authentication failed");
|
||||||
|
digestAuth.setAuthType(AsyncAuthType::AUTH_DIGEST);
|
||||||
|
digestAuth.generateHash(); // precompute hash (optional but recommended)
|
||||||
|
|
||||||
|
// digest authentication with hash
|
||||||
|
digestAuthHash.setUsername("admin");
|
||||||
|
digestAuthHash.setPasswordHash("f499b71f9a36d838b79268e145e132f7"); // MD5(user:realm:pass)
|
||||||
|
digestAuthHash.setRealm("MyApp");
|
||||||
|
digestAuthHash.setAuthFailureMessage("Authentication failed");
|
||||||
|
digestAuthHash.setAuthType(AsyncAuthType::AUTH_DIGEST);
|
||||||
|
|
||||||
|
// basic authentication method
|
||||||
|
// curl -v -u admin:admin http://192.168.4.1/auth-basic
|
||||||
|
server
|
||||||
|
.on(
|
||||||
|
"/auth-basic", HTTP_GET,
|
||||||
|
[](AsyncWebServerRequest *request) {
|
||||||
|
request->send(200, "text/plain", "Hello, world!");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.addMiddleware(&basicAuth);
|
||||||
|
|
||||||
|
// basic authentication method with hash
|
||||||
|
// curl -v -u admin:admin http://192.168.4.1/auth-basic-hash
|
||||||
|
server
|
||||||
|
.on(
|
||||||
|
"/auth-basic-hash", HTTP_GET,
|
||||||
|
[](AsyncWebServerRequest *request) {
|
||||||
|
request->send(200, "text/plain", "Hello, world!");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.addMiddleware(&basicAuthHash);
|
||||||
|
|
||||||
|
// digest authentication
|
||||||
|
// curl -v -u admin:admin --digest http://192.168.4.1/auth-digest
|
||||||
|
server
|
||||||
|
.on(
|
||||||
|
"/auth-digest", HTTP_GET,
|
||||||
|
[](AsyncWebServerRequest *request) {
|
||||||
|
request->send(200, "text/plain", "Hello, world!");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.addMiddleware(&digestAuth);
|
||||||
|
|
||||||
|
// digest authentication with hash
|
||||||
|
// curl -v -u admin:admin --digest http://192.168.4.1/auth-digest-hash
|
||||||
|
server
|
||||||
|
.on(
|
||||||
|
"/auth-digest-hash", HTTP_GET,
|
||||||
|
[](AsyncWebServerRequest *request) {
|
||||||
|
request->send(200, "text/plain", "Hello, world!");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.addMiddleware(&digestAuthHash);
|
||||||
|
|
||||||
|
// test digest auth custom authorization middleware
|
||||||
|
// curl -v --digest -u user:password http://192.168.4.1/auth-custom?token=123 => OK
|
||||||
|
// curl -v --digest -u user:password http://192.168.4.1/auth-custom?token=456 => 403
|
||||||
|
// curl -v --digest -u user:FAILED http://192.168.4.1/auth-custom?token=456 => 401
|
||||||
|
server
|
||||||
|
.on(
|
||||||
|
"/auth-custom", HTTP_GET,
|
||||||
|
[](AsyncWebServerRequest *request) {
|
||||||
|
String buffer = "Hello ";
|
||||||
|
buffer.concat(request->getAttribute("user"));
|
||||||
|
buffer.concat(" with role: ");
|
||||||
|
buffer.concat(request->getAttribute("role"));
|
||||||
|
request->send(200, "text/plain", buffer);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.addMiddlewares({&complexAuth, &authz});
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// not needed
|
||||||
|
void loop() {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
60
watering/lib/ESPAsyncWebServer/examples/CORS/CORS.ino
Normal file
60
watering/lib/ESPAsyncWebServer/examples/CORS/CORS.ino
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
//
|
||||||
|
// How to use CORS middleware
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
static AsyncCorsMiddleware cors;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP("esp-captive");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cors.setOrigin("http://192.168.4.1");
|
||||||
|
cors.setMethods("POST, GET, OPTIONS, DELETE");
|
||||||
|
cors.setHeaders("X-Custom-Header");
|
||||||
|
cors.setAllowCredentials(false);
|
||||||
|
cors.setMaxAge(600);
|
||||||
|
|
||||||
|
server.addMiddleware(&cors);
|
||||||
|
|
||||||
|
// Test CORS preflight request
|
||||||
|
// curl -v -X OPTIONS -H "origin: http://192.168.4.1" http://192.168.4.1/cors
|
||||||
|
//
|
||||||
|
// Test CORS request
|
||||||
|
// curl -v -H "origin: http://192.168.4.1" http://192.168.4.1/cors
|
||||||
|
//
|
||||||
|
// Test non-CORS request
|
||||||
|
// curl -v http://192.168.4.1/cors
|
||||||
|
//
|
||||||
|
server.on("/cors", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
request->send(200, "text/plain", "Hello, world!");
|
||||||
|
});
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// not needed
|
||||||
|
void loop() {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
#include <DNSServer.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
#include "ESPAsyncWebServer.h"
|
||||||
|
|
||||||
|
static DNSServer dnsServer;
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
|
||||||
|
class CaptiveRequestHandler : public AsyncWebHandler {
|
||||||
|
public:
|
||||||
|
bool canHandle(__unused AsyncWebServerRequest *request) const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleRequest(AsyncWebServerRequest *request) {
|
||||||
|
AsyncResponseStream *response = request->beginResponseStream("text/html");
|
||||||
|
response->print("<!DOCTYPE html><html><head><title>Captive Portal</title></head><body>");
|
||||||
|
response->print("<p>This is our captive portal front page.</p>");
|
||||||
|
response->printf("<p>You were trying to reach: http://%s%s</p>", request->host().c_str(), request->url().c_str());
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
response->printf("<p>Try opening <a href='http://%s'>this link</a> instead</p>", WiFi.softAPIP().toString().c_str());
|
||||||
|
#endif
|
||||||
|
response->print("</body></html>");
|
||||||
|
request->send(response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println();
|
||||||
|
Serial.println("Configuring access point...");
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
if (!WiFi.softAP("esp-captive")) {
|
||||||
|
Serial.println("Soft AP creation failed.");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
dnsServer.start(53, "*", WiFi.softAPIP());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); // only when requested from AP
|
||||||
|
// more handlers...
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
dnsServer.processNextRequest();
|
||||||
|
}
|
||||||
@ -0,0 +1,133 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
//
|
||||||
|
// Shows how to catch all requests and send a 404 Not Found response
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
|
||||||
|
static const char *htmlContent PROGMEM = R"(
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Sample HTML</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Hello, World!</h1>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
)";
|
||||||
|
|
||||||
|
static const size_t htmlContentLength = strlen_P(htmlContent);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP("esp-captive");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// curl -v http://192.168.4.1/
|
||||||
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
// need to cast to uint8_t*
|
||||||
|
// if you do not, the const char* will be copied in a temporary String buffer
|
||||||
|
request->send(200, "text/html", (uint8_t *)htmlContent, htmlContentLength);
|
||||||
|
});
|
||||||
|
|
||||||
|
// catch any request, and send a 404 Not Found response
|
||||||
|
// except for /game_log which is handled by onRequestBody
|
||||||
|
//
|
||||||
|
// curl -v http://192.168.4.1/foo
|
||||||
|
//
|
||||||
|
server.onNotFound([](AsyncWebServerRequest *request) {
|
||||||
|
if (request->url() == "/game_log") {
|
||||||
|
return; // response object already created by onRequestBody
|
||||||
|
}
|
||||||
|
|
||||||
|
request->send(404, "text/plain", "Not found");
|
||||||
|
});
|
||||||
|
|
||||||
|
// See: https://github.com/ESP32Async/ESPAsyncWebServer/issues/6
|
||||||
|
// catch any POST request and send a 200 OK response
|
||||||
|
//
|
||||||
|
// curl -v -X POST http://192.168.4.1/game_log -H "Content-Type: application/json" -d '{"game": "test"}'
|
||||||
|
//
|
||||||
|
server.onRequestBody([](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
|
||||||
|
if (request->url() == "/game_log") {
|
||||||
|
request->send(200, "application/json", "{\"status\":\"OK\"}");
|
||||||
|
}
|
||||||
|
// note that there is no else here: the goal is only to prepare a response based on some body content
|
||||||
|
// onNotFound will always be called after this, and will not override the response object if `/game_log` is requested
|
||||||
|
});
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// not needed
|
||||||
|
void loop() {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
@ -0,0 +1,140 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
//
|
||||||
|
// Chunk response with caching example
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
|
||||||
|
static const char *htmlContent PROGMEM = R"(
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Sample HTML</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Hello, World!</h1>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
)";
|
||||||
|
|
||||||
|
static const size_t htmlContentLength = strlen_P(htmlContent);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP("esp-captive");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// first time: serves the file and cache headers
|
||||||
|
// curl -N -v http://192.168.4.1/ --output -
|
||||||
|
//
|
||||||
|
// secodn time: serves 304
|
||||||
|
// curl -N -v -H "if-none-match: 4272" http://192.168.4.1/ --output -
|
||||||
|
//
|
||||||
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
String etag = String(htmlContentLength);
|
||||||
|
|
||||||
|
if (request->header(asyncsrv::T_INM) == etag) {
|
||||||
|
request->send(304);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncWebServerResponse *response = request->beginChunkedResponse("text/html", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
|
||||||
|
Serial.printf("%u / %u\n", index, htmlContentLength);
|
||||||
|
|
||||||
|
// finished ?
|
||||||
|
if (htmlContentLength <= index) {
|
||||||
|
Serial.println("finished");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// serve a maximum of 256 or maxLen bytes of the remaining content
|
||||||
|
// this small number is specifically chosen to demonstrate the chunking
|
||||||
|
// DO NOT USE SUCH SMALL NUMBER IN PRODUCTION
|
||||||
|
// Reducing the chunk size will increase the response time, thus reducing the server's capacity in processing concurrent requests
|
||||||
|
const int chunkSize = min((size_t)256, min(maxLen, htmlContentLength - index));
|
||||||
|
Serial.printf("sending: %u\n", chunkSize);
|
||||||
|
|
||||||
|
memcpy(buffer, htmlContent + index, chunkSize);
|
||||||
|
|
||||||
|
return chunkSize;
|
||||||
|
});
|
||||||
|
|
||||||
|
response->addHeader(asyncsrv::T_Cache_Control, "public,max-age=60");
|
||||||
|
response->addHeader(asyncsrv::T_ETag, etag);
|
||||||
|
|
||||||
|
request->send(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
@ -0,0 +1,216 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
//
|
||||||
|
// Shows how to wait in a chunk response for incoming data
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
#if __has_include("ArduinoJson.h")
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <AsyncJson.h>
|
||||||
|
#include <AsyncMessagePack.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const char *htmlContent PROGMEM = R"(
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Sample HTML</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Hello, World!</h1>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
)";
|
||||||
|
|
||||||
|
static const size_t htmlContentLength = strlen_P(htmlContent);
|
||||||
|
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
static AsyncLoggingMiddleware requestLogger;
|
||||||
|
|
||||||
|
static String triggerUART;
|
||||||
|
static int key = -1;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP("esp-captive");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// adds some internal request logging for debugging
|
||||||
|
requestLogger.setEnabled(true);
|
||||||
|
requestLogger.setOutput(Serial);
|
||||||
|
|
||||||
|
server.addMiddleware(&requestLogger);
|
||||||
|
|
||||||
|
#if __has_include("ArduinoJson.h")
|
||||||
|
|
||||||
|
//
|
||||||
|
// HOW TO RUN THIS EXAMPLE:
|
||||||
|
//
|
||||||
|
// 1. Trigger a request that will be blocked for a long time:
|
||||||
|
// > time curl -v -X POST http://192.168.4.1/api -H "Content-Type: application/json" -d '{"input": "Please type a key to continue in Serial console..."}' --output -
|
||||||
|
//
|
||||||
|
// 2. While waiting, in another terminal, run some concurrent requests:
|
||||||
|
// > time curl -v http://192.168.4.1/
|
||||||
|
//
|
||||||
|
// 3. Type a key in the Serial console to continue the processing within 30 seconds.
|
||||||
|
// This should unblock the first request.
|
||||||
|
//
|
||||||
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
// need to cast to uint8_t*
|
||||||
|
// if you do not, the const char* will be copied in a temporary String buffer
|
||||||
|
request->send(200, "text/html", (uint8_t *)htmlContent, htmlContentLength);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on(
|
||||||
|
"/api", HTTP_POST,
|
||||||
|
[](AsyncWebServerRequest *request) {
|
||||||
|
// request parsing has finished
|
||||||
|
|
||||||
|
// no data ?
|
||||||
|
if (!((String *)request->_tempObject)->length()) {
|
||||||
|
request->send(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonDocument doc;
|
||||||
|
|
||||||
|
// deserialize and check for errors
|
||||||
|
if (deserializeJson(doc, *(String *)request->_tempObject)) {
|
||||||
|
request->send(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start UART com: UART will send the data to the Serial console and wait for the key press
|
||||||
|
triggerUART = doc["input"].as<const char *>();
|
||||||
|
key = -1;
|
||||||
|
|
||||||
|
AsyncWebServerResponse *response = request->beginChunkedResponse("text/plain", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
|
||||||
|
// still waiting for UARY ?
|
||||||
|
if (triggerUART.length() && key == -1) {
|
||||||
|
return RESPONSE_TRY_AGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// finished ?
|
||||||
|
if (!triggerUART.length() && key == -1) {
|
||||||
|
return 0; // 0 means we are done
|
||||||
|
}
|
||||||
|
|
||||||
|
// log_d("UART answered!");
|
||||||
|
|
||||||
|
String answer = "You typed: ";
|
||||||
|
answer.concat((char)key);
|
||||||
|
|
||||||
|
// note: I did not check for maxLen, but you should (see ChunkResponse.ino)
|
||||||
|
memcpy(buffer, answer.c_str(), answer.length());
|
||||||
|
|
||||||
|
// finish!
|
||||||
|
triggerUART = emptyString;
|
||||||
|
key = -1;
|
||||||
|
|
||||||
|
return answer.length();
|
||||||
|
});
|
||||||
|
|
||||||
|
request->send(response);
|
||||||
|
},
|
||||||
|
NULL, // upload handler is not used so it should be NULL
|
||||||
|
[](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
|
||||||
|
// log_d("Body: index: %u, len: %u, total: %u", index, len, total);
|
||||||
|
|
||||||
|
if (!index) {
|
||||||
|
// log_d("Start body parsing");
|
||||||
|
request->_tempObject = new String();
|
||||||
|
// cast request->_tempObject pointer to String and reserve total size
|
||||||
|
((String *)request->_tempObject)->reserve(total);
|
||||||
|
// set timeout 30s
|
||||||
|
request->client()->setRxTimeout(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
// log_d("Append body data");
|
||||||
|
((String *)request->_tempObject)->concat((const char *)data, len);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (triggerUART.length() && key == -1) {
|
||||||
|
Serial.println(triggerUART);
|
||||||
|
// log_d("Waiting for UART input...");
|
||||||
|
while (!Serial.available()) {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
key = Serial.read();
|
||||||
|
Serial.flush();
|
||||||
|
// log_d("UART input: %c", key);
|
||||||
|
triggerUART = emptyString;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
//
|
||||||
|
// https://github.com/ESP32Async/ESPAsyncWebServer/discussions/23
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP("esp-captive");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
request->send(200, "text/plain", "Hello, world");
|
||||||
|
});
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
Serial.println("begin() - run: curl -v http://192.168.4.1/ => should succeed");
|
||||||
|
delay(10000);
|
||||||
|
|
||||||
|
Serial.println("end()");
|
||||||
|
server.end();
|
||||||
|
server.begin();
|
||||||
|
Serial.println("begin() - run: curl -v http://192.168.4.1/ => should succeed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// not needed
|
||||||
|
void loop() {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
136
watering/lib/ESPAsyncWebServer/examples/Filters/Filters.ino
Normal file
136
watering/lib/ESPAsyncWebServer/examples/Filters/Filters.ino
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
//
|
||||||
|
// Shows how to use setFilter to route requests to different handlers based on WiFi mode
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <DNSServer.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
#include "ESPAsyncWebServer.h"
|
||||||
|
|
||||||
|
static DNSServer dnsServer;
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
|
||||||
|
class CaptiveRequestHandler : public AsyncWebHandler {
|
||||||
|
public:
|
||||||
|
bool canHandle(__unused AsyncWebServerRequest *request) const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleRequest(AsyncWebServerRequest *request) override {
|
||||||
|
AsyncResponseStream *response = request->beginResponseStream("text/html");
|
||||||
|
response->print("<!DOCTYPE html><html><head><title>Captive Portal</title></head><body>");
|
||||||
|
response->print("<p>This is out captive portal front page.</p>");
|
||||||
|
response->printf("<p>You were trying to reach: http://%s%s</p>", request->host().c_str(), request->url().c_str());
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
response->printf("<p>Try opening <a href='http://%s'>this link</a> instead</p>", WiFi.softAPIP().toString().c_str());
|
||||||
|
#endif
|
||||||
|
response->print("</body></html>");
|
||||||
|
request->send(response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool hit1 = false;
|
||||||
|
bool hit2 = false;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
server
|
||||||
|
.on(
|
||||||
|
"/", HTTP_GET,
|
||||||
|
[](AsyncWebServerRequest *request) {
|
||||||
|
Serial.println("Captive portal request...");
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
Serial.println("WiFi.localIP(): " + WiFi.localIP().toString());
|
||||||
|
#endif
|
||||||
|
Serial.println("request->client()->localIP(): " + request->client()->localIP().toString());
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
Serial.println("WiFi.type(): " + String((int)WiFi.localIP().type()));
|
||||||
|
#endif
|
||||||
|
Serial.println("request->client()->type(): " + String((int)request->client()->localIP().type()));
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
Serial.println(WiFi.localIP() == request->client()->localIP() ? "should be: ON_STA_FILTER" : "should be: ON_AP_FILTER");
|
||||||
|
Serial.println(WiFi.localIP() == request->client()->localIP());
|
||||||
|
Serial.println(WiFi.localIP().toString() == request->client()->localIP().toString());
|
||||||
|
#endif
|
||||||
|
request->send(200, "text/plain", "This is the captive portal");
|
||||||
|
hit1 = true;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.setFilter(ON_AP_FILTER);
|
||||||
|
|
||||||
|
server
|
||||||
|
.on(
|
||||||
|
"/", HTTP_GET,
|
||||||
|
[](AsyncWebServerRequest *request) {
|
||||||
|
Serial.println("Website request...");
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
Serial.println("WiFi.localIP(): " + WiFi.localIP().toString());
|
||||||
|
#endif
|
||||||
|
Serial.println("request->client()->localIP(): " + request->client()->localIP().toString());
|
||||||
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
Serial.println("WiFi.type(): " + String((int)WiFi.localIP().type()));
|
||||||
|
#endif
|
||||||
|
Serial.println("request->client()->type(): " + String((int)request->client()->localIP().type()));
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
Serial.println(WiFi.localIP() == request->client()->localIP() ? "should be: ON_STA_FILTER" : "should be: ON_AP_FILTER");
|
||||||
|
Serial.println(WiFi.localIP() == request->client()->localIP());
|
||||||
|
Serial.println(WiFi.localIP().toString() == request->client()->localIP().toString());
|
||||||
|
#endif
|
||||||
|
request->send(200, "text/plain", "This is the website");
|
||||||
|
hit2 = true;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.setFilter(ON_STA_FILTER);
|
||||||
|
|
||||||
|
// assert(WiFi.softAP("esp-captive-portal"));
|
||||||
|
// dnsServer.start(53, "*", WiFi.softAPIP());
|
||||||
|
// server.begin();
|
||||||
|
// Serial.println("Captive portal started!");
|
||||||
|
|
||||||
|
// while (!hit1) {
|
||||||
|
// dnsServer.processNextRequest();
|
||||||
|
// yield();
|
||||||
|
// }
|
||||||
|
// delay(1000); // Wait for the client to process the response
|
||||||
|
|
||||||
|
// Serial.println("Captive portal opened, stopping it and connecting to WiFi...");
|
||||||
|
// dnsServer.stop();
|
||||||
|
// WiFi.softAPdisconnect();
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.persistent(false);
|
||||||
|
WiFi.begin("IoT");
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
Serial.println("Connected to WiFi with IP address: " + WiFi.localIP().toString());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
|
||||||
|
// while (!hit2) {
|
||||||
|
// delay(10);
|
||||||
|
// }
|
||||||
|
// delay(1000); // Wait for the client to process the response
|
||||||
|
// ESP.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
@ -0,0 +1,107 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
//
|
||||||
|
// Shows how to serve a large HTML page from flash memory without copying it to heap in a temporary buffer
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
|
||||||
|
static const char *htmlContent PROGMEM = R"(
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Sample HTML</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Hello, World!</h1>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod
|
||||||
|
rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper
|
||||||
|
arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit
|
||||||
|
accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi.
|
||||||
|
Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo
|
||||||
|
dapibus elit, id varius sem dui id lacus.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
)";
|
||||||
|
|
||||||
|
static const size_t htmlContentLength = strlen_P(htmlContent);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP("esp-captive");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// curl -v http://192.168.4.1/
|
||||||
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
// need to cast to uint8_t*
|
||||||
|
// if you do not, the const char* will be copied in a temporary String buffer
|
||||||
|
request->send(200, "text/html", (uint8_t *)htmlContent, htmlContentLength);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// not needed
|
||||||
|
void loop() {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
//
|
||||||
|
// Show how to manipulate headers in the request / response
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
|
||||||
|
// request logger
|
||||||
|
static AsyncLoggingMiddleware requestLogger;
|
||||||
|
|
||||||
|
// filter out specific headers from the incoming request
|
||||||
|
static AsyncHeaderFilterMiddleware headerFilter;
|
||||||
|
|
||||||
|
// remove all headers from the incoming request except the ones provided in the constructor
|
||||||
|
AsyncHeaderFreeMiddleware headerFree;
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP("esp-captive");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
requestLogger.setEnabled(true);
|
||||||
|
requestLogger.setOutput(Serial);
|
||||||
|
|
||||||
|
headerFilter.filter("X-Remove-Me");
|
||||||
|
|
||||||
|
headerFree.keep("X-Keep-Me");
|
||||||
|
headerFree.keep("host");
|
||||||
|
|
||||||
|
server.addMiddlewares({&requestLogger, &headerFilter});
|
||||||
|
|
||||||
|
// x-remove-me header will be removed
|
||||||
|
//
|
||||||
|
// curl -v -H "X-Header: Foo" -H "x-remove-me: value" http://192.168.4.1/remove
|
||||||
|
//
|
||||||
|
server.on("/remove", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
// print all headers
|
||||||
|
for (size_t i = 0; i < request->headers(); i++) {
|
||||||
|
const AsyncWebHeader *h = request->getHeader(i);
|
||||||
|
Serial.printf("Header[%s]: %s\n", h->name().c_str(), h->value().c_str());
|
||||||
|
}
|
||||||
|
request->send(200, "text/plain", "Hello, world!");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Only headers x-keep-me and host will be kept
|
||||||
|
//
|
||||||
|
// curl -v -H "x-keep-me: value" -H "x-remove-me: value" http://192.168.4.1/keep
|
||||||
|
//
|
||||||
|
server
|
||||||
|
.on(
|
||||||
|
"/keep", HTTP_GET,
|
||||||
|
[](AsyncWebServerRequest *request) {
|
||||||
|
// print all headers
|
||||||
|
for (size_t i = 0; i < request->headers(); i++) {
|
||||||
|
const AsyncWebHeader *h = request->getHeader(i);
|
||||||
|
Serial.printf("Header[%s]: %s\n", h->name().c_str(), h->value().c_str());
|
||||||
|
}
|
||||||
|
request->send(200, "text/plain", "Hello, world!");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.addMiddleware(&headerFree);
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// not needed
|
||||||
|
void loop() {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
69
watering/lib/ESPAsyncWebServer/examples/Headers/Headers.ino
Normal file
69
watering/lib/ESPAsyncWebServer/examples/Headers/Headers.ino
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
//
|
||||||
|
// Query and send headers
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP("esp-captive");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// curl -v http://192.168.4.1
|
||||||
|
//
|
||||||
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
//List all collected headers
|
||||||
|
int headers = request->headers();
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < headers; i++) {
|
||||||
|
const AsyncWebHeader *h = request->getHeader(i);
|
||||||
|
Serial.printf("HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", "Hello World!");
|
||||||
|
|
||||||
|
//Add header to the response
|
||||||
|
response->addHeader("Server", "ESP Async Web Server");
|
||||||
|
|
||||||
|
//Add multiple headers with the same name
|
||||||
|
response->addHeader("Set-Cookie", "sessionId=38afes7a8", false);
|
||||||
|
response->addHeader("Set-Cookie", "id=a3fWa; Max-Age=2592000", false);
|
||||||
|
response->addHeader("Set-Cookie", "qwerty=219ffwef9w0f; Domain=example.com", false);
|
||||||
|
|
||||||
|
//Remove specific header
|
||||||
|
response->removeHeader("Set-Cookie", "sessionId=38afes7a8");
|
||||||
|
|
||||||
|
//Remove all headers with the same name
|
||||||
|
response->removeHeader("Set-Cookie");
|
||||||
|
|
||||||
|
request->send(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
//Sleep in the loop task to not keep the CPU busy
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
90
watering/lib/ESPAsyncWebServer/examples/Json/Json.ino
Normal file
90
watering/lib/ESPAsyncWebServer/examples/Json/Json.ino
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
|
// Copyright 2016-2025 Hristo Gochkov, Mathieu Carbou, Emil Muratov
|
||||||
|
|
||||||
|
//
|
||||||
|
// Shows how to send and receive Json data
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#ifdef ESP32
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#elif defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
|
||||||
|
#include <RPAsyncTCP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
#if __has_include("ArduinoJson.h")
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <AsyncJson.h>
|
||||||
|
#include <AsyncMessagePack.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static AsyncWebServer server(80);
|
||||||
|
|
||||||
|
#if __has_include("ArduinoJson.h")
|
||||||
|
static AsyncCallbackJsonWebHandler *handler = new AsyncCallbackJsonWebHandler("/json2");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
WiFi.softAP("esp-captive");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include("ArduinoJson.h")
|
||||||
|
//
|
||||||
|
// sends JSON using AsyncJsonResponse
|
||||||
|
//
|
||||||
|
// curl -v http://192.168.4.1/json1
|
||||||
|
//
|
||||||
|
server.on("/json1", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
AsyncJsonResponse *response = new AsyncJsonResponse();
|
||||||
|
JsonObject root = response->getRoot().to<JsonObject>();
|
||||||
|
root["hello"] = "world";
|
||||||
|
response->setLength();
|
||||||
|
request->send(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Send JSON using AsyncResponseStream
|
||||||
|
//
|
||||||
|
// curl -v http://192.168.4.1/json2
|
||||||
|
//
|
||||||
|
server.on("/json2", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
|
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||||
|
JsonDocument doc;
|
||||||
|
JsonObject root = doc.to<JsonObject>();
|
||||||
|
root["foo"] = "bar";
|
||||||
|
serializeJson(root, *response);
|
||||||
|
request->send(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
// curl -v -X POST -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/json2
|
||||||
|
// curl -v -X PUT -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/json2
|
||||||
|
handler->setMethod(HTTP_POST | HTTP_PUT);
|
||||||
|
handler->onRequest([](AsyncWebServerRequest *request, JsonVariant &json) {
|
||||||
|
serializeJson(json, Serial);
|
||||||
|
AsyncJsonResponse *response = new AsyncJsonResponse();
|
||||||
|
JsonObject root = response->getRoot().to<JsonObject>();
|
||||||
|
root["hello"] = json.as<JsonObject>()["name"];
|
||||||
|
response->setLength();
|
||||||
|
request->send(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.addHandler(handler);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
server.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
// not needed
|
||||||
|
void loop() {
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user