2017-10-19 15:43:39 +00:00
|
|
|
#ifndef ESPUI_h
|
|
|
|
#define ESPUI_h
|
2017-05-18 22:05:32 +00:00
|
|
|
|
2018-07-03 15:43:58 +00:00
|
|
|
#define DEBUG_ESPUI true
|
2018-12-27 10:34:28 +00:00
|
|
|
#define WS_AUTHENTICATION false
|
2017-11-13 15:10:56 +00:00
|
|
|
|
2017-05-18 22:05:32 +00:00
|
|
|
#include "Arduino.h"
|
|
|
|
#include "ArduinoJson.h"
|
2017-11-14 11:09:52 +00:00
|
|
|
#include "stdlib_noniso.h"
|
2017-10-16 13:00:53 +00:00
|
|
|
|
2017-12-01 16:11:16 +00:00
|
|
|
#if defined(ESP32)
|
2019-03-24 17:18:08 +00:00
|
|
|
#include <AsyncTCP.h>
|
|
|
|
#include <ESPAsyncWebServer.h>
|
2022-01-04 10:35:43 +00:00
|
|
|
#include <LITTLEFS.h>
|
2017-05-18 22:05:32 +00:00
|
|
|
|
2020-09-28 08:40:31 +00:00
|
|
|
#include "WiFi.h"
|
|
|
|
|
2017-12-01 16:11:16 +00:00
|
|
|
#else
|
|
|
|
|
2018-11-26 17:25:10 +00:00
|
|
|
#include <ArduinoOTA.h>
|
2017-12-01 16:11:16 +00:00
|
|
|
#include <ESP8266WiFi.h>
|
|
|
|
#include <ESP8266mDNS.h>
|
|
|
|
#include <ESPAsyncTCP.h>
|
|
|
|
#include <ESPAsyncWebServer.h>
|
2018-11-26 17:25:10 +00:00
|
|
|
#include <Hash.h>
|
2020-09-28 08:40:31 +00:00
|
|
|
#include <LittleFS.h>
|
2017-12-01 16:11:16 +00:00
|
|
|
|
|
|
|
#define FILE_WRITE "w"
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2018-05-13 18:19:29 +00:00
|
|
|
// Message Types (and control types)
|
2018-05-27 09:47:53 +00:00
|
|
|
|
2020-08-26 20:13:21 +00:00
|
|
|
enum ControlType : uint8_t
|
|
|
|
{
|
2020-09-28 08:40:31 +00:00
|
|
|
// fixed controls
|
|
|
|
Title = 0,
|
|
|
|
|
|
|
|
// updatable controls
|
|
|
|
Pad,
|
|
|
|
PadWithCenter,
|
|
|
|
Button,
|
|
|
|
Label,
|
|
|
|
Switcher,
|
|
|
|
Slider,
|
|
|
|
Number,
|
|
|
|
Text,
|
|
|
|
Graph,
|
|
|
|
GraphPoint,
|
|
|
|
Tab,
|
|
|
|
Select,
|
|
|
|
Option,
|
|
|
|
Min,
|
|
|
|
Max,
|
|
|
|
Step,
|
|
|
|
Gauge,
|
|
|
|
Accel,
|
2022-01-08 20:58:22 +00:00
|
|
|
Separator,
|
2022-01-20 21:50:06 +00:00
|
|
|
Time,
|
2020-09-28 08:40:31 +00:00
|
|
|
|
|
|
|
UpdateOffset = 100,
|
|
|
|
UpdatePad = 101,
|
|
|
|
UpdatePadWithCenter,
|
|
|
|
ButtonButton,
|
|
|
|
UpdateLabel,
|
|
|
|
UpdateSwitcher,
|
|
|
|
UpdateSlider,
|
|
|
|
UpdateNumber,
|
|
|
|
UpdateText,
|
|
|
|
ClearGraph,
|
|
|
|
UpdateTab,
|
|
|
|
UpdateSelection,
|
|
|
|
UpdateOption,
|
|
|
|
UpdateMin,
|
|
|
|
UpdateMax,
|
|
|
|
UpdateStep,
|
|
|
|
UpdateGauge,
|
|
|
|
UpdateAccel,
|
2022-01-08 20:58:22 +00:00
|
|
|
UpdateSeparator,
|
2022-01-20 21:50:06 +00:00
|
|
|
UpdateTime,
|
2020-09-28 08:40:31 +00:00
|
|
|
|
|
|
|
InitialGui = 200,
|
2022-01-01 22:04:32 +00:00
|
|
|
Reload = 201,
|
|
|
|
ExtendGUI = 210
|
2019-03-03 20:13:45 +00:00
|
|
|
};
|
2018-05-27 09:47:53 +00:00
|
|
|
|
2019-03-24 15:06:35 +00:00
|
|
|
#define UI_INITIAL_GUI ControlType::InitialGui
|
2020-06-15 09:06:34 +00:00
|
|
|
#define UI_RELOAD ControlType::Reload
|
2022-01-01 22:04:32 +00:00
|
|
|
#define UI_EXTEND_GUI ControlType::ExtendGUI
|
2019-03-24 15:06:35 +00:00
|
|
|
|
|
|
|
#define UI_TITLE ControlType::Title
|
|
|
|
#define UI_LABEL ControlType::Label
|
|
|
|
#define UI_BUTTON ControlType::Button
|
|
|
|
#define UI_SWITCHER ControlType::Switcher
|
|
|
|
#define UI_PAD ControlType::Pad
|
|
|
|
#define UI_CPAD ControlType::Cpad
|
|
|
|
#define UI_SLIDER ControlType::Slider
|
|
|
|
#define UI_NUMBER ControlType::Number
|
|
|
|
#define UI_TEXT_INPUT ControlType::Text
|
|
|
|
#define UI_GRAPH ControlType::Graph
|
|
|
|
#define UI_ADD_GRAPH_POINT ControlType::GraphPoint
|
|
|
|
|
|
|
|
#define UPDATE_LABEL ControlType::UpdateLabel
|
|
|
|
#define UPDATE_SWITCHER ControlType::UpdateSwitcher
|
|
|
|
#define UPDATE_SLIDER ControlType::UpdateSlider
|
|
|
|
#define UPDATE_NUMBER ControlType::UpdateNumber
|
|
|
|
#define UPDATE_TEXT_INPUT ControlType::UpdateText
|
|
|
|
#define CLEAR_GRAPH ControlType::ClearGraph
|
2018-05-27 09:47:53 +00:00
|
|
|
|
2019-03-03 20:13:45 +00:00
|
|
|
// Colors
|
2020-08-26 20:13:21 +00:00
|
|
|
enum ControlColor : uint8_t
|
|
|
|
{
|
2020-09-28 08:40:31 +00:00
|
|
|
Turquoise,
|
|
|
|
Emerald,
|
|
|
|
Peterriver,
|
|
|
|
Wetasphalt,
|
|
|
|
Sunflower,
|
|
|
|
Carrot,
|
|
|
|
Alizarin,
|
|
|
|
Dark,
|
|
|
|
None = 0xFF
|
2020-08-26 20:13:21 +00:00
|
|
|
};
|
2019-03-24 15:06:35 +00:00
|
|
|
#define COLOR_TURQUOISE ControlColor::Turquoise
|
|
|
|
#define COLOR_EMERALD ControlColor::Emerald
|
|
|
|
#define COLOR_PETERRIVER ControlColor::Peterriver
|
|
|
|
#define COLOR_WETASPHALT ControlColor::Wetasphalt
|
|
|
|
#define COLOR_SUNFLOWER ControlColor::Sunflower
|
|
|
|
#define COLOR_CARROT ControlColor::Carrot
|
|
|
|
#define COLOR_ALIZARIN ControlColor::Alizarin
|
|
|
|
#define COLOR_DARK ControlColor::Dark
|
|
|
|
#define COLOR_NONE ControlColor::None
|
2019-03-03 20:13:45 +00:00
|
|
|
|
2020-08-26 20:13:21 +00:00
|
|
|
class Control
|
|
|
|
{
|
2019-03-24 17:18:08 +00:00
|
|
|
public:
|
2020-09-28 08:40:31 +00:00
|
|
|
ControlType type;
|
|
|
|
uint16_t id; // just mirroring the id here for practical reasons
|
|
|
|
const char* label;
|
|
|
|
void (*callback)(Control*, int);
|
|
|
|
String value;
|
|
|
|
ControlColor color;
|
2021-08-06 14:33:53 +00:00
|
|
|
bool visible;
|
2022-01-08 21:25:10 +00:00
|
|
|
bool wide;
|
2022-01-21 23:30:08 +00:00
|
|
|
bool vertical;
|
2022-01-31 21:43:09 +00:00
|
|
|
bool enabled;
|
2020-09-28 08:40:31 +00:00
|
|
|
uint16_t parentControl;
|
2022-01-02 21:56:32 +00:00
|
|
|
String panelStyle;
|
|
|
|
String elementStyle;
|
2020-09-28 08:40:31 +00:00
|
|
|
Control* next;
|
|
|
|
|
|
|
|
static constexpr uint16_t noParent = 0xffff;
|
|
|
|
|
|
|
|
Control(ControlType type, const char* label, void (*callback)(Control*, int), const String& value,
|
2021-08-01 16:54:50 +00:00
|
|
|
ControlColor color, bool visible = true, uint16_t parentControl = Control::noParent)
|
2020-09-28 08:40:31 +00:00
|
|
|
: type(type),
|
|
|
|
label(label),
|
|
|
|
callback(callback),
|
|
|
|
value(value),
|
|
|
|
color(color),
|
2021-08-01 16:54:50 +00:00
|
|
|
visible(visible),
|
2022-01-08 21:25:10 +00:00
|
|
|
wide(false),
|
2022-01-21 23:30:08 +00:00
|
|
|
vertical(false),
|
2020-09-28 08:40:31 +00:00
|
|
|
parentControl(parentControl),
|
|
|
|
next(nullptr)
|
|
|
|
{
|
|
|
|
id = idCounter++;
|
|
|
|
}
|
|
|
|
|
|
|
|
Control(const Control& control)
|
|
|
|
: type(control.type),
|
|
|
|
id(control.id),
|
|
|
|
label(control.label),
|
|
|
|
callback(control.callback),
|
|
|
|
value(control.value),
|
|
|
|
color(control.color),
|
2021-08-01 16:54:50 +00:00
|
|
|
visible(control.visible),
|
2020-09-28 08:40:31 +00:00
|
|
|
parentControl(control.parentControl),
|
|
|
|
next(control.next)
|
2020-09-24 19:56:32 +00:00
|
|
|
{ }
|
2019-03-24 17:18:08 +00:00
|
|
|
|
|
|
|
private:
|
2020-09-28 08:40:31 +00:00
|
|
|
static uint16_t idCounter;
|
2019-03-03 20:13:45 +00:00
|
|
|
};
|
2018-05-27 09:47:53 +00:00
|
|
|
|
2017-10-19 11:46:47 +00:00
|
|
|
// Values
|
|
|
|
#define B_DOWN -1
|
2017-11-14 11:09:52 +00:00
|
|
|
#define B_UP 1
|
2017-10-19 11:46:47 +00:00
|
|
|
|
|
|
|
#define P_LEFT_DOWN -2
|
|
|
|
#define P_LEFT_UP 2
|
|
|
|
#define P_RIGHT_DOWN -3
|
|
|
|
#define P_RIGHT_UP 3
|
|
|
|
#define P_FOR_DOWN -4
|
|
|
|
#define P_FOR_UP 4
|
|
|
|
#define P_BACK_DOWN -5
|
|
|
|
#define P_BACK_UP 5
|
|
|
|
#define P_CENTER_DOWN -6
|
|
|
|
#define P_CENTER_UP 6
|
2017-11-29 10:32:07 +00:00
|
|
|
|
2017-10-19 15:30:32 +00:00
|
|
|
#define S_ACTIVE -7
|
|
|
|
#define S_INACTIVE 7
|
2017-10-19 11:46:47 +00:00
|
|
|
|
2017-11-29 10:32:07 +00:00
|
|
|
#define SL_VALUE 8
|
2018-05-13 18:19:29 +00:00
|
|
|
#define N_VALUE 9
|
2018-11-26 17:25:10 +00:00
|
|
|
#define T_VALUE 10
|
2019-03-04 20:07:39 +00:00
|
|
|
#define S_VALUE 11
|
2022-01-20 21:50:06 +00:00
|
|
|
#define TM_VALUE 12
|
2017-10-19 11:46:47 +00:00
|
|
|
|
2020-08-26 20:13:21 +00:00
|
|
|
enum Verbosity : uint8_t
|
|
|
|
{
|
2020-09-28 08:40:31 +00:00
|
|
|
Quiet = 0,
|
|
|
|
Verbose,
|
|
|
|
VerboseJSON
|
2020-08-26 20:13:21 +00:00
|
|
|
};
|
2017-11-14 11:09:52 +00:00
|
|
|
|
2020-08-26 20:13:21 +00:00
|
|
|
class ESPUIClass
|
|
|
|
{
|
2019-03-24 17:18:08 +00:00
|
|
|
public:
|
2020-09-28 08:40:31 +00:00
|
|
|
ESPUIClass()
|
|
|
|
{
|
|
|
|
verbosity = Verbosity::Quiet;
|
|
|
|
jsonUpdateDocumentSize = 2000;
|
|
|
|
jsonInitialDocumentSize = 8000;
|
|
|
|
sliderContinuous = false;
|
|
|
|
}
|
|
|
|
unsigned int jsonUpdateDocumentSize;
|
|
|
|
unsigned int jsonInitialDocumentSize;
|
|
|
|
bool sliderContinuous;
|
|
|
|
|
|
|
|
void setVerbosity(Verbosity verbosity);
|
2021-10-29 17:20:20 +00:00
|
|
|
void begin(const char* _title, const char* username = nullptr, const char* password = nullptr,
|
|
|
|
uint16_t port = 80); // Setup server and page in Memorymode
|
|
|
|
void beginSPIFFS(const char* _title, const char* username = nullptr, const char* password = nullptr,
|
2022-01-04 10:35:43 +00:00
|
|
|
uint16_t port = 80); // Setup server and page in LITTLEFS mode (DEPRECATED, use beginLITTLEFS)
|
|
|
|
void beginLITTLEFS(const char* _title, const char* username = nullptr, const char* password = nullptr,
|
|
|
|
uint16_t port = 80); // Setup server and page in LITTLEFS mode
|
2020-09-28 08:40:31 +00:00
|
|
|
|
|
|
|
void prepareFileSystem(); // Initially preps the filesystem and loads a lot of
|
2022-01-04 10:35:43 +00:00
|
|
|
// stuff into LITTLEFS
|
|
|
|
void list(); // Lists LITTLEFS directory
|
2020-09-28 08:40:31 +00:00
|
|
|
|
|
|
|
uint16_t addControl(ControlType type, const char* label, const String& value = String(""),
|
|
|
|
ControlColor color = ControlColor::Turquoise, uint16_t parentControl = Control::noParent,
|
|
|
|
void (*callback)(Control*, int) = nullptr);
|
|
|
|
bool removeControl(uint16_t id, bool force_reload_ui = false);
|
|
|
|
|
|
|
|
// create Elements
|
|
|
|
uint16_t button(const char* label, void (*callback)(Control*, int), ControlColor color,
|
|
|
|
const String& value = ""); // Create Event Button
|
|
|
|
uint16_t switcher(const char* label, void (*callback)(Control*, int), ControlColor color,
|
|
|
|
bool startState = false); // Create Toggle Button
|
|
|
|
uint16_t pad(const char* label, void (*callback)(Control*, int),
|
|
|
|
ControlColor color); // Create Pad Control
|
|
|
|
uint16_t padWithCenter(const char* label, void (*callback)(Control*, int),
|
|
|
|
ControlColor color); // Create Pad Control with Centerbutton
|
|
|
|
|
|
|
|
uint16_t slider(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0,
|
|
|
|
int max = 100); // Create Slider Control
|
|
|
|
uint16_t number(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0,
|
|
|
|
int max = 100); // Create a Number Input Control
|
|
|
|
uint16_t text(const char* label, void (*callback)(Control*, int), ControlColor color,
|
|
|
|
const String& value = ""); // Create a Text Input Control
|
|
|
|
|
|
|
|
// Output only
|
|
|
|
uint16_t label(const char* label, ControlColor color,
|
|
|
|
const String& value = ""); // Create Label
|
|
|
|
uint16_t graph(const char* label, ControlColor color); // Create Graph display
|
|
|
|
uint16_t gauge(const char* label, ControlColor color, int value, int min = 0,
|
|
|
|
int max = 100); // Create Gauge display
|
2022-01-08 20:58:22 +00:00
|
|
|
uint16_t separator(const char* label); //Create separator
|
2020-09-28 08:40:31 +00:00
|
|
|
|
|
|
|
// Input only
|
|
|
|
uint16_t accelerometer(const char* label, void (*callback)(Control*, int), ControlColor color);
|
|
|
|
|
|
|
|
// Update Elements
|
|
|
|
|
|
|
|
Control* getControl(uint16_t id);
|
|
|
|
|
|
|
|
// Update Elements
|
|
|
|
void updateControlValue(uint16_t id, const String& value, int clientId = -1);
|
|
|
|
void updateControlValue(Control* control, const String& value, int clientId = -1);
|
|
|
|
|
|
|
|
void updateControl(uint16_t id, int clientId = -1);
|
|
|
|
void updateControl(Control* control, int clientId = -1);
|
|
|
|
|
|
|
|
void print(uint16_t id, const String& value);
|
|
|
|
void updateLabel(uint16_t id, const String& value);
|
2022-01-16 14:47:41 +00:00
|
|
|
void updateButton(uint16_t id, const String& value);
|
2020-09-28 08:40:31 +00:00
|
|
|
void updateSwitcher(uint16_t id, bool nValue, int clientId = -1);
|
|
|
|
void updateSlider(uint16_t id, int nValue, int clientId = -1);
|
|
|
|
void updateNumber(uint16_t id, int nValue, int clientId = -1);
|
|
|
|
void updateText(uint16_t id, const String& nValue, int clientId = -1);
|
|
|
|
void updateSelect(uint16_t id, const String& nValue, int clientId = -1);
|
|
|
|
void updateGauge(uint16_t id, int number, int clientId);
|
2022-01-20 21:50:06 +00:00
|
|
|
void updateTime(uint16_t id, int clientId = -1);
|
2020-09-28 08:40:31 +00:00
|
|
|
|
|
|
|
void clearGraph(uint16_t id, int clientId = -1);
|
|
|
|
void addGraphPoint(uint16_t id, int nValue, int clientId = -1);
|
|
|
|
|
2022-01-02 21:56:32 +00:00
|
|
|
void setPanelStyle(uint16_t id, String style, int clientId = -1);
|
|
|
|
void setElementStyle(uint16_t id, String style, int clientId = -1);
|
|
|
|
|
2022-01-08 21:25:10 +00:00
|
|
|
void setPanelWide(uint16_t id, bool wide);
|
2022-01-21 23:30:08 +00:00
|
|
|
void setVertical(uint16_t id, bool vert = true);
|
2022-01-31 21:43:09 +00:00
|
|
|
void setEnabled(uint16_t id, bool enabled = true, int clientId = -1);
|
|
|
|
|
2022-01-28 20:31:25 +00:00
|
|
|
void updateVisibility(uint16_t id, bool visibility, int clientId = -1);
|
2022-01-08 21:25:10 +00:00
|
|
|
|
2020-09-28 08:40:31 +00:00
|
|
|
// Variables
|
|
|
|
const char* ui_title = "ESPUI"; // Store UI Title and Header Name
|
|
|
|
Control* controls = nullptr;
|
|
|
|
void jsonReload();
|
2022-01-12 20:12:20 +00:00
|
|
|
void jsonDom(uint16_t startidx, AsyncWebSocketClient* client = nullptr);
|
2020-09-28 08:40:31 +00:00
|
|
|
|
|
|
|
Verbosity verbosity;
|
|
|
|
|
|
|
|
AsyncWebServer* server;
|
|
|
|
AsyncWebSocket* ws;
|
2019-12-27 14:36:24 +00:00
|
|
|
|
2019-03-24 17:18:08 +00:00
|
|
|
private:
|
2020-09-28 08:40:31 +00:00
|
|
|
const char* basicAuthUsername = nullptr;
|
|
|
|
const char* basicAuthPassword = nullptr;
|
|
|
|
bool basicAuth = true;
|
2022-01-01 22:04:32 +00:00
|
|
|
|
2022-01-12 20:12:20 +00:00
|
|
|
uint16_t controlCount = 0;
|
|
|
|
|
|
|
|
void prepareJSONChunk(AsyncWebSocketClient* client, uint16_t startindex, JsonArray* items);
|
2017-05-18 22:05:32 +00:00
|
|
|
};
|
|
|
|
|
2017-10-19 15:43:39 +00:00
|
|
|
extern ESPUIClass ESPUI;
|
2017-05-18 22:05:32 +00:00
|
|
|
#endif
|