Skip to content

Instantly share code, notes, and snippets.

@jpswensen
Created January 4, 2025 07:25
Show Gist options
  • Select an option

  • Save jpswensen/cfc4398d927b6cd0ec5b5dfc6294cb81 to your computer and use it in GitHub Desktop.

Select an option

Save jpswensen/cfc4398d927b6cd0ec5b5dfc6294cb81 to your computer and use it in GitHub Desktop.
A templatized way of creating Arduino AsyncWebServer APIs
String getFreeHeapStr(AsyncWebServerRequest *request);
String resetSettings();
void setWifiPower(float wifipower);
void setupPageHandlers() {
Serial.println(F("Starting the page handlers"));
// Set up the static pages to be read from the LittleFS filesystem
server->serveStatic("/", FSDRV, "/").setDefaultFile("index.html");;
Serial.println(F("Done setting up static pages"));
server->on( PSTR("/listwebserverfiles.html"), HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(200, PSTR("application/json"), "OK");
listDir(FSDRV, "/", 3);
});
// This installs a handler that only has POST capability
install_raw_post_handler(PSTR("/heap"), getFreeHeapStr);
// This installs a handler that only has GET capability
install_raw_get_handler(PSTR("/resetsettings.html"), resetSettings);
// This installs a handler that has both GET and POST capability
install_page_handlers(PSTR("wifipower"), getWifiPower, setWifiPower);
Serial.println(F("Done setting up dynamics handlers"));
server->onNotFound(notFound);
}
String getFreeHeapStr(AsyncWebServerRequest *request)
{
return String(ESP.getFreeHeap());
}
String resetSettings()
{
Serial.println(F("RESET CONFIG FILE"));
// Set up the default values
ConfigManager::getInstance().initializeConfigStruct();
ConfigManager::getInstance().writeConfigFile();
ConfigManager::getInstance().printCurrentConfig();
return String(F("Success resetting settings"));
}
float getWifiPower(void)
{
// This won't compile for you because it is my custom ConfigManager class, but you get the idea
return ConfigManager::getInstance().get<float>("wifipower");
}
void setWifiPower(float wifipower)
{
// This won't compile for you because it is my custom ConfigManager class, but you get the idea
ConfigManager::getInstance().set<float>("wifipower", wifipower);
WiFi.setOutputPower(wifipower);
}
#include "WebFramework.h"
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// All the templating functions that make the installation of the various web handlers really easy.
// See usage in .cpp file for clarification.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
String nil_get() { return ""; }
void nil_post(String val) { return; }
// This is a raw post handler that doesn't follow the rules of a JSON key that exapands to the URL
// Instead, it just has a URL and the function that should be call when the post comes in.
template<typename OP_POST>
void install_raw_post_handler(String url, OP_POST post)
{
server->on( url.c_str(), HTTP_POST, [post](AsyncWebServerRequest *request) {
if (request->args() < 1)
return;
post(request);
request->send(200, TEXT_PLAIN, "OK");
});
}
// This is a raw get handler that lets the function being called take care of send data back
// This on is used particularly for the serving of large files using the chunkedSend function
// but could be used for other similar applications.
template<typename OP_GET>
void install_raw_get_handler_handlersend(String url, OP_GET get)
{
server->on( url.c_str(), HTTP_GET, [get](AsyncWebServerRequest *request) {
get(request);
});
}
// This ia a raw get handler the simply send the result of the get operation back from calling
// the prescribed function
template<typename OP_GET>
void install_raw_get_handler(String url, OP_GET get)
{
server->on( url.c_str(), HTTP_GET, [get](AsyncWebServerRequest *request) {
request->send(200, PSTR("application/json"), get() );
});
}
// This installed page handlers based on a key and two functions.
// These page handlers expect that the key is expanded into a URL of /<key>.json and
// that the key will be the primary contents of the URL response.
// The user can also specify the two functions that will handle both GET and POST
// operations for this json URL and the corresponding key content.
template<typename OP_GET, typename OP_POST>
void install_page_handlers(String key, OP_GET get, OP_POST post)
{
String url = "/" + key + ".json";
server->on( url.c_str(), HTTP_POST, [key,post](AsyncWebServerRequest *request) {
if (request->args() < 1)
return;
const String& json = request->arg( (size_t)0);
StaticJsonDocument<512> doc;
DeserializationError error = deserializeJson(doc, json);
if (error)
{
Serial.printf(PSTR("Error reading JSON %s post argument"), key.c_str());
//Serial.println(F("Error reading JSON changeWifiPower post argument"));
Serial.print(F(" Error: "));
Serial.println(error.c_str());
Serial.print(F(" Raw json: "));
Serial.println(json);
}
else
{
post(doc[key]);
Serial.printf(PSTR("POST: Set the %s\n"), key.c_str());
Serial.print(F(" Raw json: "));
Serial.println(json);
}
doc.clear();
request->send(200);
});
server->on( url.c_str(), HTTP_GET, [key,get](AsyncWebServerRequest *request) {
IRAM_HEAP_DIRECTIVE
auto value = get();
String valueStr;
valueStr = String("\"") + String(value) + String("\"");
String json = String(F("[{\"")) + key + String(F("\":")) + valueStr + String(F("}]"));
request->send(200, PSTR("application/json"), json);
});
}
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESPAsyncWebServer.h>
#include "FS.h"
#include <LittleFS.h>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// All the templating functions that make the installation of the various web handlers really easy.
// See usage in .cpp file for clarification.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
String nil_get();
void nil_post(String val);
template<typename OP_POST>
void install_raw_post_handler(String url, OP_POST post);
template<typename OP_GET>
void install_raw_get_handler_handlersend(String url, OP_GET get);
template<typename OP_GET>
void install_raw_get_handler(String url, OP_GET get);
template<typename OP_GET, typename OP_POST>
void install_page_handlers(String key, OP_GET get, OP_POST post);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment