Added v2 usermods API

This commit is contained in:
cschwinne 2020-05-28 02:20:02 +02:00
parent a4e093159e
commit 696e438df7
18 changed files with 443 additions and 38 deletions

View File

@ -2,6 +2,13 @@
### Development versions after 0.10.0 release
#### Build 2005280
- Added v2 usermod API
- Added v2 example usermod `usermod_v2_example` in the usermods folder as prelimary documentation
- Added DS18B20 Temperature usermod with Info page support
- Disabled MQTT on ESP01 build to make room in flash
#### Build 2005230
- Fixed TPM2

View File

@ -74,6 +74,8 @@ arduino_core_develop = https://github.com/platformio/platform-espressif8266#deve
arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage
# Platform to use for ESP8266
platform_wled_default = ${common.arduino_core_2_7_1}
# We use 2.7.0+ on analog boards because of PWM flicker fix
platform_latest = ${common.arduino_core_2_7_1}
# ------------------------------------------------------------------------------
@ -180,51 +182,51 @@ lib_ignore =
[env:nodemcuv2]
board = nodemcuv2
platform = ${common.platform_latest}
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266}
[env:esp01]
board = esp01
platform = ${common.platform_latest}
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_512k}
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK
-D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED
-D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED -D WLED_DISABLE_MQTT
[env:esp01_1m_ota]
board = esp01_1m
platform = ${common.platform_latest}
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_1m0m}
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED -D WLED_DISABLE_MQTT
[env:esp01_1m_full]
board = esp01_1m
platform = ${common.platform_latest}
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_1m0m}
build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA
[env:esp07]
board = esp07
platform = ${common.platform_latest}
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266}
[env:d1_mini]
board = d1_mini
platform = ${common.platform_latest}
platform = ${common.platform_wled_default}
upload_speed = 921600
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266}
[env:heltec_wifi_kit_8]
board = d1_mini
platform = ${common.platform_latest}
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266}
[env:h803wf]
board = d1_mini
platform = ${common.platform_latest}
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266} -D LEDPIN=1 -D WLED_DISABLE_INFRARED
@ -267,7 +269,7 @@ build_flags = ${common.build_flags_esp8266} -D WLED_USE_ANALOG_LEDS -D WLED_USE_
[env:d1_mini_debug]
board = d1_mini
build_type = debug
platform = ${common.platform_latest}
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266} ${common.debug_flags}
@ -276,7 +278,7 @@ board = d1_mini
upload_protocol = espota
# exchange for your WLED IP
upload_port = "10.10.1.27"
platform = ${common.platform_latest}
platform = ${common.platform_wled_default}
board_build.ldscript = ${common.ldscript_4m1m}
build_flags = ${common.build_flags_esp8266}

View File

@ -0,0 +1,10 @@
# Usermods API v2 example usermod
In this usermod file you can find the documentation on how to take advantage of the new version 2 usermods!
## Installation
Copy `usermod_v2_example.h` to the wled00 directory.
Uncomment the corresponding lines in `usermods_list.h` and compile!
_(You shouldn't need to actually install this, it does nothing useful)_

View File

@ -0,0 +1,119 @@
#pragma once
#include "wled.h"
/*
* Usermods allow you to add own functionality to WLED more easily
* See: https://github.com/Aircoookie/WLED/wiki/Add-own-functionality
*
* This is an example for a v2 usermod.
* v2 usermods are class inheritance based and can (but don't have to) implement more functions, each of them is shown in this example.
* Multiple v2 usermods can be added to one compilation easily.
*
* Creating a usermod:
* This file serves as an example. If you want to create a usermod, it is recommended to use usermod_v2_empty.h from the usermods folder as a template.
* Please remember to rename the class and file to a descriptive name.
* You may also use multiple .h and .cpp files.
*
* Using a usermod:
* 1. Copy the usermod into the sketch folder (same folder as wled00.ino)
* 2. Register the usermod by adding #include "usermod_filename.h" in the top and registerUsermod(new MyUsermodClass()) in the bottom of usermods_list.cpp
*/
//class name. Use something descriptive and leave the ": public Usermod" part :)
class MyExampleUsermod : public Usermod {
private:
//Private class members. You can declare variables and functions only accessible to your usermod here
unsigned long lastTime = 0;
public:
//Functions called by WLED
/*
* setup() is called once at boot. WiFi is not yet connected at this point.
* You can use it to initialize variables, sensors or similar.
*/
void setup() {
//Serial.println("Hello from my usermod!");
}
/*
* connected() is called every time the WiFi is (re)connected
* Use it to initialize network interfaces
*/
void connected() {
//Serial.println("Connected to WiFi!");
}
/*
* loop() is called continuously. Here you can check for events, read sensors, etc.
*
* Tips:
* 1. You can use "if (WLED_CONNECTED)" to check for a successful network connection.
* Additionally, "if (WLED_MQTT_CONNECTED)" is available to check for a connection to an MQTT broker.
*
* 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds.
* Instead, use a timer check as shown here.
*/
void loop() {
if (millis() - lastTime > 1000) {
//Serial.println("I'm alive!");
lastTime = millis();
}
}
/*
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
* Below it is shown how this could be used for e.g. a light sensor
*/
/*
void addToJsonInfo(JsonObject& root)
{
int reading = 20;
//this code adds "u":{"Light":[20," lux"]} to the info object
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
JsonArray lightArr = user.createNestedArray("Light"); //name
lightArr.add(reading); //value
lightArr.add(" lux"); //unit
}
*/
/*
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
void addToJsonState(JsonObject& root)
{
//root["user0"] = userVar0;
}
/*
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients
*/
void readFromJsonState(JsonObject& root)
{
userVar0 = root["user0"] | userVar0; //if "user0" key exists in JSON, update, else keep old value
//if (root["bri"] == 255) Serial.println(F("Don't burn down your garage!"));
}
/*
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
* This could be used in the future for the system to determine whether your usermod is installed.
*/
uint16_t getId()
{
return USERMOD_ID_EXAMPLE;
}
//More methods can be added in the future, this example will then be extended.
//Your usermod will remain compatible as it does not need to implement all methods from the Usermod base class!
};

View File

@ -0,0 +1,40 @@
# Temperature usermod
Based on the excellent `QuinLED_Dig_Uno_Temp_MQTT` by srg74!
This usermod will read from an attached DS18B20 temperature sensor (as available on the QuinLED Dig-Uno)
The temperature is displayed both in the Info section of the web UI as well as published to the `/temperature` MQTT topic if enabled.
This usermod will be expanded with support for different sensor types in the future.
## Installation
Copy `usermod_temperature.h` to the wled00 directory.
Uncomment the corresponding lines in `usermods_list.h` and compile!
If this is the only v2 usermod you plan to use, you can alternatively replace `usermods_list.h` in wled00 with the one in this folder.
## Project link
* [QuinLED-Dig-Uno](https://quinled.info/2018/09/15/quinled-dig-uno/) - Project link
### PlatformIO requirements
You might have to uncomment `DallasTemperature@~3.8.0`,`OneWire@~2.3.5 under` `[common]` section in `platformio.ini`:
```ini
# platformio.ini
...
[platformio]
...
; default_envs = esp07
default_envs = d1_mini
...
[common]
...
lib_deps_external =
...
#For use SSD1306 OLED display uncomment following
U8g2@~2.27.3
#For Dallas sensor uncomment following 2 lines
DallasTemperature@~3.8.0
OneWire@~2.3.5
...
```

View File

@ -0,0 +1,79 @@
#pragma once
#include "wled.h"
#include <DallasTemperature.h> //DS18B20
//Pin defaults for QuinLed Dig-Uno
#ifdef ARDUINO_ARCH_ESP32
#define TEMPERATURE_PIN 18
#else //ESP8266 boards
#define TEMPERATURE_PIN 14
#endif
#define TEMP_CELSIUS // Comment out for Fahrenheit
#define MEASUREMENT_INTERVAL 60000 //1 Minute
OneWire oneWire(TEMPERATURE_PIN);
DallasTemperature sensor(&oneWire);
class UsermodTemperature : public Usermod {
private:
//set last reading as "40 sec before boot", so first reading is taken after 20 sec
unsigned long lastMeasurement = UINT32_MAX - 40000;
float temperature = 0.0f;
public:
void getReading() {
sensor.requestTemperatures();
#ifdef TEMP_CELSIUS
temperature = sensor.getTempCByIndex(0);
#else
temperature = sensor.getTempFByIndex(0);
#endif
}
void setup() {
sensor.begin();
sensor.setResolution(9);
}
void loop() {
if (millis() - lastMeasurement > MEASUREMENT_INTERVAL)
{
getReading();
if (WLED_MQTT_CONNECTED) {
char subuf[38];
strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/temperature");
mqtt->publish(subuf, 0, true, String(temperature).c_str());
}
lastMeasurement = millis();
}
}
void addToJsonInfo(JsonObject& root) {
JsonObject user = root["u"];
if (user.isNull()) user = root.createNestedObject("u");
JsonArray temp = user.createNestedArray("Temperature");
if (temperature == DEVICE_DISCONNECTED_C) {
temp.add(0);
temp.add(" Sensor Error!");
return;
}
temp.add(temperature);
#ifdef TEMP_CELSIUS
temp.add("°C");
#else
temp.add("°F");
#endif
}
uint16_t getId()
{
return USERMOD_ID_TEMPERATURE;
}
};

View File

@ -0,0 +1,25 @@
#include "wled.h"
/*
* Register your v2 usermods here!
*/
/*
* Add/uncomment your usermod filename here (and once more below)
* || || ||
* \/ \/ \/
*/
//#include "usermod_v2_example.h"
#include "usermod_temperature.h"
//#include "usermod_v2_empty.h"
void registerUsermods()
{
/*
* Add your usermod class name here
* || || ||
* \/ \/ \/
*/
//usermods.add(new MyExampleUsermod());
usermods.add(new UsermodTemperature());
//usermods.add(new UsermodRenameMe());
}

View File

@ -7,7 +7,7 @@ If you have created an usermod that you believe is useful (for example to suppor
In order for other people to be able to have fun with your usermod, please keep these points in mind:
- Create a folder in this folder with a descriptive name (for example `usermod_ds18b20_temp_sensor_mqtt`)
- Include your custom `usermod.cpp` file
- Include your custom files
- If your usermod requires changes to other WLED files, please write a `readme.md` outlining the steps one has to take to use the usermod
- Create a pull request!
- If your feature is useful for the majority of WLED users, I will consider adding it to the base code!
@ -15,4 +15,7 @@ In order for other people to be able to have fun with your usermod, please keep
While I do my best to not break too much, keep in mind that as WLED is being updated, usermods might break.
I am not actively maintaining any usermod in this directory, that is your responsibility as the creator of the usermod.
For new usermods, I would recommend trying out the new v2 usermod API, which allows installing multiple usermods at once and new functions!
You can take a look at `EXAMPLE_v2` for some documentation and at `Temperature` for a completed v2 usermod!
Thank you for your help :)

View File

@ -10,6 +10,15 @@
#define DEFAULT_AP_PASS "wled1234"
#define DEFAULT_OTA_PASS "wledota"
//increase if you need more
#define WLED_MAX_USERMODS 4
//Usermod IDs
#define USERMOD_ID_RESERVED 0 //Unused. Might indicate no usermod present
#define USERMOD_ID_UNSPECIFIED 1 //Default value for a general user mod that does not specify a custom ID
#define USERMOD_ID_EXAMPLE 2 //Usermod "usermod_v2_example.h"
#define USERMOD_ID_TEMPERATURE 3 //Usermod "usermod_temperature.h"
//Access point behavior
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
#define AP_BEHAVIOR_NO_CONN 1 //Open when no connection (either after boot or if connection is lost)

View File

@ -139,6 +139,40 @@ void realtimeLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC);
void handleNotifications();
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
//um_manager.cpp
class Usermod {
public:
virtual void loop() {}
virtual void setup() {}
virtual void connected() {}
virtual void addToJsonState(JsonObject& obj) {}
virtual void addToJsonInfo(JsonObject& obj) {}
virtual void readFromJsonState(JsonObject& obj) {}
virtual uint16_t getId() {return USERMOD_ID_UNSPECIFIED;}
};
class UsermodManager {
private:
Usermod* ums[WLED_MAX_USERMODS];
byte numMods = 0;
public:
void loop();
void setup();
void connected();
void addToJsonState(JsonObject& obj);
void addToJsonInfo(JsonObject& obj);
void readFromJsonState(JsonObject& obj);
bool add(Usermod* um);
byte getModCount();
};
//usermods_list.cpp
void registerUsermods();
//usermod.cpp
void userSetup();
void userConnected();
@ -174,8 +208,8 @@ String dmxProcessor(const String& var);
void serveSettings(AsyncWebServerRequest* request);
//xml.cpp
char* XML_response(AsyncWebServerRequest *request, char* dest = nullptr);
char* URL_response(AsyncWebServerRequest *request);
void XML_response(AsyncWebServerRequest *request, char* dest = nullptr);
void URL_response(AsyncWebServerRequest *request);
void sappend(char stype, const char* key, int val);
void sappends(char stype, const char* key, char* val);
void getSettingsJS(byte subPage, char* dest);

View File

@ -168,6 +168,8 @@ bool deserializeState(JsonObject root)
}
}
usermods.readFromJsonState(root);
colorUpdated(noNotification ? NOTIFIER_CALL_MODE_NO_NOTIFY : NOTIFIER_CALL_MODE_DIRECT_CHANGE);
//write presets to flash directly?
@ -233,6 +235,8 @@ void serializeState(JsonObject root)
root["pss"] = savedPresets;
root["pl"] = (presetCyclingEnabled) ? 0: -1;
usermods.addToJsonState(root);
//temporary for preset cycle
JsonObject ccnf = root.createNestedObject("ccnf");
ccnf["min"] = presetCycleMin;
@ -363,6 +367,8 @@ void serializeInfo(JsonObject root)
root["freeheap"] = ESP.getFreeHeap();
root["uptime"] = millis()/1000 + rolloverMillis*4294967;
usermods.addToJsonInfo(root);
byte os = 0;
#ifdef WLED_DEBUG
os = 0x80;

View File

@ -76,7 +76,7 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
void publishMqtt()
{
doPublishMqtt = false;
if (mqtt == nullptr || !mqtt->connected()) return;
if (!WLED_MQTT_CONNECTED) return;
DEBUG_PRINTLN("Publish MQTT");
char s[10];

23
wled00/um_manager.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "wled.h"
/*
* Registration and management utility for v2 usermods
*/
//Usermod Manager internals
void UsermodManager::loop() { for (byte i = 0; i < numMods; i++) ums[i]->loop(); }
void UsermodManager::setup() { for (byte i = 0; i < numMods; i++) ums[i]->setup(); }
void UsermodManager::connected() { for (byte i = 0; i < numMods; i++) ums[i]->connected(); }
void UsermodManager::addToJsonState(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->addToJsonState(obj); }
void UsermodManager::addToJsonInfo(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->addToJsonInfo(obj); }
void UsermodManager::readFromJsonState(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->readFromJsonState(obj); }
bool UsermodManager::add(Usermod* um)
{
if (numMods >= WLED_MAX_USERMODS || um == nullptr) return false;
ums[numMods] = um;
numMods++;
}
byte UsermodManager::getModCount() {return numMods;}

18
wled00/usermod_v2_empty.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include "wled.h"
//This is an empty v2 usermod template. Please see the file usermod_v2_example.h in the EXAMPLE_v2 usermod folder for documentation on the functions you can use!
class UsermodRenameMe : public Usermod {
private:
public:
void setup() {
}
void loop() {
}
};

26
wled00/usermods_list.cpp Normal file
View File

@ -0,0 +1,26 @@
#include "wled.h"
/*
* Register your v2 usermods here!
* (for v1 usermods using just usermod.cpp, you can ignore this file)
*/
/*
* Add/uncomment your usermod filename here (and once more below)
* || || ||
* \/ \/ \/
*/
//#include "usermod_v2_example.h"
//#include "usermod_temperature.h"
//#include "usermod_v2_empty.h"
void registerUsermods()
{
/*
* Add your usermod class name here
* || || ||
* \/ \/ \/
*/
//usermods.add(new MyExampleUsermod());
//usermods.add(new UsermodTemperature());
//usermods.add(new UsermodRenameMe());
}

View File

@ -51,6 +51,7 @@ void WLED::loop()
handleDMX();
#endif
userLoop();
usermods.loop();
yield();
handleIO();
@ -94,35 +95,29 @@ void WLED::loop()
initMqtt();
}
// DEBUG serial logging
#ifdef WLED_DEBUG
if (millis() - debugTime > 9999) {
DEBUG_PRINTLN("---DEBUG INFO---");
DEBUG_PRINT("Runtime: ");
DEBUG_PRINTLN(millis());
DEBUG_PRINT("Unix time: ");
DEBUG_PRINTLN(now());
DEBUG_PRINT("Free heap: ");
DEBUG_PRINTLN(ESP.getFreeHeap());
DEBUG_PRINT("Wifi state: ");
DEBUG_PRINTLN(WiFi.status());
DEBUG_PRINT("Runtime: "); DEBUG_PRINTLN(millis());
DEBUG_PRINT("Unix time: "); DEBUG_PRINTLN(now());
DEBUG_PRINT("Free heap: "); DEBUG_PRINTLN(ESP.getFreeHeap());
DEBUG_PRINT("Wifi state: "); DEBUG_PRINTLN(WiFi.status());
if (WiFi.status() != lastWifiState) {
wifiStateChangedTime = millis();
}
lastWifiState = WiFi.status();
DEBUG_PRINT("State time: ");
DEBUG_PRINTLN(wifiStateChangedTime);
DEBUG_PRINT("NTP last sync: ");
DEBUG_PRINTLN(ntpLastSyncTime);
DEBUG_PRINT("Client IP: ");
DEBUG_PRINTLN(WiFi.localIP());
DEBUG_PRINT("Loops/sec: ");
DEBUG_PRINTLN(loops / 10);
DEBUG_PRINT("State time: "); DEBUG_PRINTLN(wifiStateChangedTime);
DEBUG_PRINT("NTP last sync: "); DEBUG_PRINTLN(ntpLastSyncTime);
DEBUG_PRINT("Client IP: "); DEBUG_PRINTLN(WiFi.localIP());
DEBUG_PRINT("Loops/sec: "); DEBUG_PRINTLN(loops / 10);
loops = 0;
debugTime = millis();
}
loops++;
#endif // WLED_DEBU
#endif // WLED_DEBUG
}
void WLED::setup()
@ -156,6 +151,7 @@ void WLED::setup()
int heapPreAlloc = ESP.getFreeHeap();
DEBUG_PRINT("heap ");
DEBUG_PRINTLN(ESP.getFreeHeap());
registerUsermods();
strip.init(EEPROM.read(372), ledCount, EEPROM.read(2204)); // init LEDs quickly
strip.setBrightness(0);
@ -174,6 +170,7 @@ void WLED::setup()
loadSettingsFromEEPROM(true);
beginStrip();
userSetup();
usermods.setup();
if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0)
showWelcomePage = true;
WiFi.persistent(false);
@ -449,6 +446,7 @@ void WLED::handleConnection()
DEBUG_PRINTLN(WiFi.localIP());
initInterfaces();
userConnected();
usermods.connected();
// shut down AP
if (apBehavior != AP_BEHAVIOR_ALWAYS && apActive) {

View File

@ -8,7 +8,7 @@
*/
// version code in format yymmddb (b = daily build)
#define VERSION 2005230
#define VERSION 2005280
// ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS).
@ -25,7 +25,9 @@
//#define WLED_DISABLE_CRONIXIE // saves 3kb
//#define WLED_DISABLE_HUESYNC // saves 4kb
//#define WLED_DISABLE_INFRARED // there is no pin left for this on ESP8266-01, saves 12kb
#define WLED_ENABLE_MQTT // saves 12kb
#ifndef WLED_DISABLE_MQTT
#define WLED_ENABLE_MQTT // saves 12kb
#endif
#define WLED_ENABLE_ADALIGHT // saves 500b only
//#define WLED_ENABLE_DMX // uses 3.5kb (use LEDPIN other than 2)
@ -491,6 +493,9 @@ WLED_GLOBAL bool e131NewData _INIT(false);
// led fx library object
WLED_GLOBAL WS2812FX strip _INIT(WS2812FX());
// Usermod manager
WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager());
// debug macro variable definitions
#ifdef WLED_DEBUG
WLED_GLOBAL unsigned long debugTime _INIT(0);
@ -502,6 +507,7 @@ WLED_GLOBAL WS2812FX strip _INIT(WS2812FX());
#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED)
#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0)
#define WLED_MQTT_CONNECTED (mqtt != nullptr && mqtt->connected())
// append new c string to temp buffer efficiently
bool oappend(const char* txt);

View File

@ -5,7 +5,7 @@
*/
//build XML response to HTTP /win API request
char* XML_response(AsyncWebServerRequest *request, char* dest)
void XML_response(AsyncWebServerRequest *request, char* dest)
{
char sbuf[(dest == nullptr)?1024:1]; //allocate local buffer if none passed
obuf = (dest == nullptr)? sbuf:dest;
@ -100,9 +100,9 @@ char* XML_response(AsyncWebServerRequest *request, char* dest)
if (request != nullptr) request->send(200, "text/xml", obuf);
}
char* URL_response(AsyncWebServerRequest *request)
void URL_response(AsyncWebServerRequest *request)
{
char sbuf[256]; //allocate local buffer if none passed
char sbuf[256];
char s2buf[100];
obuf = s2buf;
olen = 0;