Finished JSON API
Added RV http api call Fixed CY,PA,PC,PX api calls Fixed CORS
This commit is contained in:
parent
66c224c954
commit
709ff7a701
@ -30,7 +30,7 @@ lib_deps_external =
|
||||
ESPAsyncTCP@1.2.0
|
||||
AsyncTCP@1.0.3
|
||||
EspAsyncWebServer@1.2.0
|
||||
ArduinoJson@5.13.5
|
||||
#ArduinoJson@5.13.5
|
||||
IRremoteESP8266@2.5.5
|
||||
#Time@1.5
|
||||
#Timezone@1.2.1
|
||||
|
@ -347,6 +347,7 @@ uint32_t WS2812FX::getColor(void) {
|
||||
uint32_t WS2812FX::getPixelColor(uint16_t i)
|
||||
{
|
||||
if (_reverseMode) i = _length- 1 -i;
|
||||
if (IS_REVERSE) i = SEGMENT.stop -1 -i - SEGMENT.start; //reverse just individual segment
|
||||
if (_skipFirstMode) i += LED_SKIP_AMOUNT;
|
||||
if (_cronixieMode)
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head><meta charset="utf-8"><meta name="theme-color" content="#fff">
|
||||
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico'/>
|
||||
<title>WLED 0.8.3</title>
|
||||
<title>WLED 0.8.4</title>
|
||||
<script>
|
||||
var d=document;
|
||||
var w=window.getComputedStyle(d.querySelector("html"));
|
||||
@ -43,8 +43,8 @@
|
||||
CV(0);
|
||||
setInterval(GIO, 5000);
|
||||
GIO();
|
||||
setTimeout(function(){fillfx(0);}, 500);
|
||||
setTimeout(function(){fillfx(1);}, 750);
|
||||
setTimeout(function(){fillfx(0);}, 200);
|
||||
setTimeout(function(){fillfx(1);}, 500);
|
||||
}
|
||||
function GIO()
|
||||
{
|
||||
@ -369,7 +369,7 @@
|
||||
{
|
||||
e="<option>Error loading list!</option>";
|
||||
el = fp?Cf.FP:Cf.TX;
|
||||
fetch(fp?'/json/palettes':'/json/effects')
|
||||
fetch(fp?'/json/pal':'/json/eff')
|
||||
.then(res => {
|
||||
if (!res.ok) {
|
||||
el.innerHTML=e;
|
||||
@ -378,13 +378,12 @@
|
||||
})
|
||||
.then(json => {
|
||||
var x="";
|
||||
var l=fp?json.palettes:json.effects;
|
||||
for (i in l) {
|
||||
x += "<option value=\""+i+"\">"+l[i]+" ("+i+")</option>";
|
||||
for (i in json) {
|
||||
x += "<option value=\""+i+"\">"+json[i]+" ("+i+")</option>";
|
||||
}
|
||||
el.innerHTML=x;
|
||||
el.selectedIndex=fp?fpi:fxi;
|
||||
if(!fp)fxn=l.length;
|
||||
if(!fp)fxn=json.length;
|
||||
UV();
|
||||
})
|
||||
.catch(function () {
|
||||
|
File diff suppressed because one or more lines are too long
100
wled00/data/jsontest.htm
Normal file
100
wled00/data/jsontest.htm
Normal file
@ -0,0 +1,100 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>JSON client</title>
|
||||
<style>
|
||||
:root {
|
||||
--bCol:#333;--cCol:#222;--dCol:#666;--tCol:#fff;
|
||||
}
|
||||
body {
|
||||
font-family: Verdana, sans-serif;
|
||||
text-align: center;
|
||||
background: var(--cCol);
|
||||
color: var(--tCol);
|
||||
margin: 20px;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
button {
|
||||
background: var(--cCol);
|
||||
color: var(--tCol);
|
||||
border: 0.3ch solid var(--cCol);
|
||||
display: inline-block;
|
||||
font-size: 20px;
|
||||
margin: 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
input {
|
||||
background: var(--cCol);
|
||||
color: var(--tCol);
|
||||
border: 0.5ch solid var(--cCol);
|
||||
width: 100%;
|
||||
}
|
||||
h1{
|
||||
margin: 0px;
|
||||
font-size: 20px;
|
||||
}
|
||||
h2{
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
form{
|
||||
background: var(--bCol);
|
||||
width: 500px;
|
||||
padding: 20px;
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
display: inline-block;
|
||||
}
|
||||
textarea{
|
||||
background: var(--cCol);
|
||||
color: var(--tCol);
|
||||
padding-top: 10px;
|
||||
width: 100%;
|
||||
font-family: monaco,monospace;
|
||||
font-size: 12px;
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form name="cf">
|
||||
<h1>JSON API test tool</h1>
|
||||
<h2>URL:</h2>
|
||||
<input name="cu" type="text" size="60" value="http://192.168.4.1/json">
|
||||
<div id="buttons">
|
||||
<button type="button" onclick="rq('GET')">GET</button>
|
||||
<button type="button" onclick="rq('POST')">POST</button>
|
||||
</div>
|
||||
<h2>Body:</h2>
|
||||
<textarea name="bd" rows="8" cols="100"></textarea>
|
||||
<h2>Response:</h2>
|
||||
<textarea name="rsp" rows="25" cols="100"></textarea>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
function rq(cm)
|
||||
{
|
||||
var h = new XMLHttpRequest();
|
||||
h.open(cm, document.cf.cu.value, true);
|
||||
h.onreadystatechange = function()
|
||||
{
|
||||
if(h.readyState == 4)
|
||||
{
|
||||
if(h.status==200)
|
||||
{
|
||||
document.cf.rsp.value="Bad JSON: "+h.responseText
|
||||
document.cf.rsp.value=JSON.stringify(JSON.parse(h.responseText), null, '\t');
|
||||
}
|
||||
else
|
||||
{
|
||||
document.cf.rsp.value="Error "+h.status+"\r\n\n"+h.responseText;
|
||||
}
|
||||
}
|
||||
}
|
||||
h.send(document.cf.bd.value);
|
||||
}
|
||||
</script>
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
2407
wled00/html_mobile.h
2407
wled00/html_mobile.h
File diff suppressed because it is too large
Load Diff
@ -72,8 +72,8 @@ const char PAGE_settings_leds[] PROGMEM = R"=====(<!DOCTYPE html>
|
||||
function B(){window.open("/settings","_self");}function S(){GetV();setTimeout(function(){fillfx(0);},200);setTimeout(function(){fillfx(1);},400);UI();}
|
||||
function UI(){var myC=document.querySelectorAll('.wc'),l=myC.length;for(i=0;i<l;i++){myC[i].style.display=(document.getElementById('rgbw').checked)?'inline':'none';}
|
||||
var val=Math.ceil((100+document.Sf.LC.value*55)/500)/2;val=(val>5)?Math.ceil(val):val;var s="";if(val<1.02){s="ESP 5V pin with 1A USB supply";}else{s="External 5V ";s+=val;s+="A supply connected to LEDs";}document.getElementById('psu').innerHTML=s;}
|
||||
function fillfx(pl){e="<option>Error loading list!</option>";el=pl?Sf.FP:Sf.FX;fetch(pl?'/json/palettes':'/json/effects').then(res=>{if(!res.ok){el.innerHTML=e;}
|
||||
return res.json();}).then(json=>{var x="";var l=pl?json.palettes:json.effects;for(i in l){x+="<option value=\""+i+"\">"+l[i]+" ("+i+")</option>";}
|
||||
function fillfx(pl){e="<option>Error loading list!</option>";el=pl?Sf.FP:Sf.FX;fetch(pl?'/json/pal':'/json/eff').then(res=>{if(!res.ok){el.innerHTML=e;}
|
||||
return res.json();}).then(json=>{var x="";for(i in json){x+="<option value=\""+i+"\">"+json[i]+" ("+i+")</option>";}
|
||||
el.innerHTML=x;el.selectedIndex=pl?p:f;}).catch(function(){el.innerHTML=e;})}function GetV(){var d=document;%CSS%%SCSS%</head>
|
||||
<body onload="S()">
|
||||
<form id="form_s" name="Sf" method="post">
|
||||
|
3429
wled00/src/dependencies/json/ArduinoJson-v5.h
Normal file
3429
wled00/src/dependencies/json/ArduinoJson-v5.h
Normal file
File diff suppressed because it is too large
Load Diff
138
wled00/src/dependencies/json/AsyncJson.h
Normal file
138
wled00/src/dependencies/json/AsyncJson.h
Normal file
@ -0,0 +1,138 @@
|
||||
// AsyncJson.h
|
||||
/*
|
||||
Original file at: https://github.com/me-no-dev/ESPAsyncWebServer/blob/master/src/AsyncJson.h
|
||||
Only changes are ArduinoJson lib path and removed content-type check
|
||||
|
||||
Async Response to use with ArduinoJson and AsyncWebServer
|
||||
Written by Andrew Melvin (SticilFace) with help from me-no-dev and BBlanchon.
|
||||
|
||||
--------------------
|
||||
Async Request to use with ArduinoJson and AsyncWebServer
|
||||
Written by Arsène von Wyss (avonwyss)
|
||||
*/
|
||||
#ifndef ASYNC_JSON_H_
|
||||
#define ASYNC_JSON_H_
|
||||
#include "ArduinoJson-v5.h"
|
||||
|
||||
constexpr char* JSON_MIMETYPE = "application/json";
|
||||
|
||||
/*
|
||||
* Json Response
|
||||
* */
|
||||
|
||||
class ChunkPrint : public Print {
|
||||
private:
|
||||
uint8_t* _destination;
|
||||
size_t _to_skip;
|
||||
size_t _to_write;
|
||||
size_t _pos;
|
||||
public:
|
||||
ChunkPrint(uint8_t* destination, size_t from, size_t len)
|
||||
: _destination(destination), _to_skip(from), _to_write(len), _pos{0} {}
|
||||
virtual ~ChunkPrint(){}
|
||||
size_t write(uint8_t c){
|
||||
if (_to_skip > 0) {
|
||||
_to_skip--;
|
||||
return 1;
|
||||
} else if (_to_write > 0) {
|
||||
_to_write--;
|
||||
_destination[_pos++] = c;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class AsyncJsonResponse: public AsyncAbstractResponse {
|
||||
private:
|
||||
DynamicJsonBuffer _jsonBuffer;
|
||||
JsonVariant _root;
|
||||
bool _isValid;
|
||||
public:
|
||||
AsyncJsonResponse(bool isArray=false): _isValid{false} {
|
||||
_code = 200;
|
||||
_contentType = JSON_MIMETYPE;
|
||||
if(isArray)
|
||||
_root = _jsonBuffer.createArray();
|
||||
else
|
||||
_root = _jsonBuffer.createObject();
|
||||
}
|
||||
~AsyncJsonResponse() {}
|
||||
JsonVariant & getRoot() { return _root; }
|
||||
bool _sourceValid() const { return _isValid; }
|
||||
size_t setLength() {
|
||||
_contentLength = _root.measureLength();
|
||||
if (_contentLength) { _isValid = true; }
|
||||
return _contentLength;
|
||||
}
|
||||
|
||||
size_t getSize() { return _jsonBuffer.size(); }
|
||||
|
||||
size_t _fillBuffer(uint8_t *data, size_t len){
|
||||
ChunkPrint dest(data, _sentLength, len);
|
||||
_root.printTo( dest ) ;
|
||||
return len;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<void(AsyncWebServerRequest *request, JsonVariant &json)> ArJsonRequestHandlerFunction;
|
||||
|
||||
class AsyncCallbackJsonWebHandler: public AsyncWebHandler {
|
||||
private:
|
||||
protected:
|
||||
const String _uri;
|
||||
WebRequestMethodComposite _method;
|
||||
ArJsonRequestHandlerFunction _onRequest;
|
||||
int _contentLength;
|
||||
int _maxContentLength;
|
||||
public:
|
||||
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) : _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {}
|
||||
void setMethod(WebRequestMethodComposite method){ _method = method; }
|
||||
void setMaxContentLength(int maxContentLength){ _maxContentLength = maxContentLength; }
|
||||
void onRequest(ArJsonRequestHandlerFunction fn){ _onRequest = fn; }
|
||||
|
||||
virtual bool canHandle(AsyncWebServerRequest *request) override final{
|
||||
if(!_onRequest)
|
||||
return false;
|
||||
|
||||
if(!(_method & request->method()))
|
||||
return false;
|
||||
|
||||
if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/")))
|
||||
return false;
|
||||
|
||||
request->addInterestingHeader("ANY");
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void handleRequest(AsyncWebServerRequest *request) override final {
|
||||
if(_onRequest) {
|
||||
if (request->_tempObject != NULL) {
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject));
|
||||
if (json.success()) {
|
||||
_onRequest(request, json);
|
||||
return;
|
||||
}
|
||||
}
|
||||
request->send(_contentLength > _maxContentLength ? 413 : 400, "{\"error\":\"Empty body\"}");
|
||||
} else {
|
||||
request->send(500);
|
||||
}
|
||||
}
|
||||
virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final {
|
||||
}
|
||||
virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final {
|
||||
if (_onRequest) {
|
||||
_contentLength = total;
|
||||
if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) {
|
||||
request->_tempObject = malloc(total);
|
||||
}
|
||||
if (request->_tempObject != NULL) {
|
||||
memcpy((uint8_t*)(request->_tempObject) + index, data, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual bool isRequestHandlerTrivial() override final {return _onRequest ? false : true;}
|
||||
};
|
||||
#endif
|
@ -40,8 +40,6 @@
|
||||
#endif
|
||||
|
||||
#include <ESPAsyncWebServer.h>
|
||||
#include <AsyncJson.h>
|
||||
#include <ArduinoJson.h> //please use v5.13.x!
|
||||
#include <EEPROM.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <DNSServer.h>
|
||||
@ -62,6 +60,8 @@
|
||||
#endif
|
||||
#include "src/dependencies/e131/E131.h"
|
||||
#include "src/dependencies/async-mqtt-client/AsyncMqttClient.h"
|
||||
#include "src/dependencies/json/AsyncJson.h"
|
||||
#include "src/dependencies/json/ArduinoJson-v5.h"
|
||||
#include "html_classic.h"
|
||||
#include "html_mobile.h"
|
||||
#include "html_settings.h"
|
||||
@ -89,7 +89,7 @@
|
||||
|
||||
|
||||
//version code in format yymmddb (b = daily build)
|
||||
#define VERSION 1903055
|
||||
#define VERSION 1903062
|
||||
char versionString[] = "0.8.4-dev";
|
||||
|
||||
|
||||
|
@ -588,8 +588,8 @@ bool handleSet(AsyncWebServerRequest *request, String req)
|
||||
}
|
||||
|
||||
//Segment reverse
|
||||
//pos = req.indexOf("SR=");
|
||||
//if (pos > 0) strip.getSegment().reverse = (req.charAt(pos+3) != '0');
|
||||
pos = req.indexOf("RV=");
|
||||
if (pos > 0) strip.getSegment(0).setOption(1, req.charAt(pos+3) != '0');
|
||||
|
||||
//deactivate nightlight if target brightness is reached
|
||||
if (bri == nightlightTargetBri) nightlightActive = false;
|
||||
@ -617,7 +617,7 @@ bool handleSet(AsyncWebServerRequest *request, String req)
|
||||
pos = req.indexOf("CY=");
|
||||
if (pos > 0)
|
||||
{
|
||||
presetCyclingEnabled = req.charAt(pos+3 != '0');
|
||||
presetCyclingEnabled = (req.charAt(pos+3) != '0');
|
||||
presetCycCurr = presetCycleMin;
|
||||
}
|
||||
|
||||
@ -628,13 +628,13 @@ bool handleSet(AsyncWebServerRequest *request, String req)
|
||||
}
|
||||
|
||||
pos = req.indexOf("PA="); //apply brightness from preset
|
||||
if (pos > 0) presetApplyBri = req.charAt(pos+3 != '0');
|
||||
if (pos > 0) presetApplyBri = (req.charAt(pos+3) != '0');
|
||||
|
||||
pos = req.indexOf("PC="); //apply color from preset
|
||||
if (pos > 0) presetApplyCol = req.charAt(pos+3 != '0');
|
||||
if (pos > 0) presetApplyCol = (req.charAt(pos+3) != '0');
|
||||
|
||||
pos = req.indexOf("PX="); //apply effects from preset
|
||||
if (pos > 0) presetApplyFx = req.charAt(pos+3 != '0');
|
||||
if (pos > 0) presetApplyFx = (req.charAt(pos+3) != '0');
|
||||
|
||||
pos = req.indexOf("PS="); //saves current in preset
|
||||
if (pos > 0) savePreset(getNumVal(&req, pos));
|
||||
|
@ -6,6 +6,8 @@ void initServer()
|
||||
{
|
||||
//CORS compatiblity
|
||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
|
||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods", "*");
|
||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "*");
|
||||
|
||||
//settings page
|
||||
server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
|
@ -4,18 +4,23 @@
|
||||
|
||||
void deserializeState(JsonObject& root)
|
||||
{
|
||||
bri = root["bri"] | briLast;
|
||||
|
||||
bool on = root["on"] | (bri > 0);
|
||||
if (!on != !bri) toggleOnOff();
|
||||
|
||||
briLast = root["bri"] | briLast;
|
||||
if (bri > 0) bri = briLast;
|
||||
|
||||
if (root.containsKey("transition"))
|
||||
{
|
||||
transitionDelay = root["transition"];
|
||||
transitionDelay *= 100;
|
||||
}
|
||||
|
||||
int ps = root["ps"] | -1;
|
||||
if (ps >= 0) applyPreset(ps);
|
||||
|
||||
int cy = root["pl"] | -1;
|
||||
presetCyclingEnabled = (cy >= 0);
|
||||
|
||||
JsonObject& nl = root["nl"];
|
||||
nightlightActive = nl["on"] | nightlightActive;
|
||||
nightlightDelayMins = nl["dur"] | nightlightDelayMins;
|
||||
@ -92,6 +97,9 @@ void serializeState(JsonObject& root)
|
||||
root["bri"] = briLast;
|
||||
root["transition"] = transitionDelay/100; //in 100ms
|
||||
|
||||
root["ps"] = -1; //
|
||||
root["pl"] = (presetCyclingEnabled) ? 0: -1;
|
||||
|
||||
JsonObject& nl = root.createNestedObject("nl");
|
||||
nl["on"] = nightlightActive;
|
||||
nl["dur"] = nightlightDelayMins;
|
||||
@ -111,14 +119,20 @@ void serializeSegment(JsonObject& root)
|
||||
{
|
||||
WS2812FX::Segment seg = strip.getSegment(0);
|
||||
|
||||
//root["i"] = i;
|
||||
//root["id"] = i;
|
||||
root["start"] = seg.start;
|
||||
root["stop"] = seg.stop;
|
||||
root["len"] = seg.stop - seg.start;
|
||||
|
||||
JsonArray& colarr = root.createNestedArray("col");
|
||||
|
||||
for (uint8_t i = 0; i < 3; i++)
|
||||
//temporary
|
||||
JsonArray& c0 = colarr.createNestedArray();
|
||||
c0.add(col[0]); c0.add(col[1]); c0.add(col[2]); if (useRGBW) c0.add(col[3]);
|
||||
JsonArray& c1 = colarr.createNestedArray();
|
||||
c1.add(colSec[0]); c1.add(colSec[1]); c1.add(colSec[2]); if (useRGBW) c1.add(colSec[3]);
|
||||
//set i back to 0 once temporary is removed!
|
||||
for (uint8_t i = 2; i < 3; i++)
|
||||
{
|
||||
JsonArray& colX = colarr.createNestedArray();
|
||||
colX.add((seg.colors[i] >> 16) & 0xFF);
|
||||
@ -217,7 +231,7 @@ void serveJson(AsyncWebServerRequest* request)
|
||||
return;
|
||||
}
|
||||
else if (url.length() > 6) { //not just /json
|
||||
request->send( 500, "application/json", "{\"error\":\"Not implemented\"}");
|
||||
request->send( 501, "application/json", "{\"error\":\"Not implemented\"}");
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user