Skip to content

Commit 71bf91c

Browse files
Revert "Feature/controller"
1 parent bd6d998 commit 71bf91c

File tree

21 files changed

+58
-1083
lines changed

21 files changed

+58
-1083
lines changed

README.md

+1-19
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ To install the library, simply clone this repository in the /libraries folder of
154154

155155
## API documentation
156156

157-
The API currently supports five type of commands: digital, analog, and mode, variables, and user-defined functions and api-extensions.
157+
The API currently supports five type of commands: digital, analog, and mode, variables, and user-defined functions.
158158

159159
### Digital
160160

@@ -189,24 +189,6 @@ You can also define your own functions in your sketch that can be called using t
189189
* `rest.function("led",ledControl);` declares the function in the Arduino sketch
190190
* `/led?params=0` executes the function
191191

192-
### API-Extensions
193-
194-
With api-extensions you have the possibility to extend the api by your own subcommands and customized responses.
195-
196-
You define your api extensions in your sketch that can be called using the REST API. To access an user-defined api-extension defined in your sketch, you have to declare it first, and then call it from with a REST call. Note that all api-extension functions need to have the following signature `void api_extension(aREST *arest, const String& name, const String& request_url)`. For example, if your aREST instance is called "rest" and the function "aquariumController":
197-
* `rest.api_extension("aquarium",aquariumController);` declares the api extension in the Arduino sketch
198-
* `/aquarium/water_limit/lower/set/65` executes the api-extension function and passes the value `"/aquarium/water_limit/lower/set/65"` as the third parameter (`request_url`) into the api-extension function
199-
* You can then customize your JSON result and extend it to something like this:
200-
```
201-
{
202-
"sensor-ids": ["100", "101", "102", "103", "104"],
203-
"id": "008",
204-
"name": "dapper_drake",
205-
"hardware": "arduino",
206-
"connected": true
207-
}
208-
```
209-
210192
### Get data about the board
211193

212194
You can also access a description of all the variables that were declared on the board with a single command. This is useful to automatically build graphical interfaces based on the variables exposed to the API. This can be done via the following calls:

aREST.h

+56-89
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ struct Handler {
192192
Handler() : include_into_root_answer{false} { }
193193
Handler(bool include) : include_into_root_answer{include} { }
194194

195-
virtual void addToBuffer(aREST *arest, const String& name, const String& request_url) const = 0;
195+
virtual void addToBuffer(aREST *arest, const String& name, const String& arguments) const = 0;
196196
};
197197

198198

@@ -201,7 +201,7 @@ struct Variable: Handler {
201201

202202
virtual void addToBuffer(aREST *arest) const = 0;
203203

204-
void addToBuffer(aREST *arest, const String& name, const String& request_url) const override {
204+
void addToBuffer(aREST *arest, const String& name, const String& arguments) const override {
205205
if (LIGHTWEIGHT) {
206206
addToBuffer(arest);
207207
} else {
@@ -231,8 +231,7 @@ struct FunctionHandler: Handler {
231231

232232
FunctionHandler(int (*f)(String)) : func{f} { }
233233

234-
void addToBuffer(aREST *arest, const String& name, const String& request_url) const override {
235-
String arguments = extractParams(name, request_url);
234+
void addToBuffer(aREST *arest, const String& name, const String& arguments) const override {
236235
int result = func(arguments);
237236

238237
if (!LIGHTWEIGHT) {
@@ -243,36 +242,6 @@ struct FunctionHandler: Handler {
243242
// arest->addToBufferF(F(" executed\", "));
244243
}
245244
}
246-
247-
String extractParams(const String& name, const String& request_url) const {
248-
// We're expecting a string of the form <handlerName>?xxxxx=<arguments>, where xxxxx can be almost anything as long as it's followed by an '='
249-
// Get command -- Anything following the first '=' in answer will be put in the arguments string.
250-
uint16_t header_length = name.length() + 1; // +1 for the '/' at the start
251-
if (request_url.substring(header_length, header_length + 1) == "?") {
252-
// Standard operation --> strip off anything preceeding the first "=", pass the rest to the handler
253-
if(AREST_PARAMS_MODE == 0) {
254-
uint16_t eq_position = request_url.indexOf('=', header_length); // Replacing 'magic number' 8 for fixed location of '='
255-
if (eq_position != -1)
256-
return request_url.substring(eq_position + 1, request_url.length());
257-
}
258-
// All params mode --> pass all parameters, if any, to the handler. Handler will be resonsible for parsing
259-
else if(AREST_PARAMS_MODE == 1) {
260-
return request_url.substring(header_length + 1, request_url.length());
261-
}
262-
}
263-
return String("");
264-
}
265-
};
266-
267-
268-
struct ApiHandler: Handler {
269-
void (*func)(aREST *, const String&, const String&);
270-
271-
ApiHandler(void (*f)(aREST *, const String&, const String&)) : func{f} { }
272-
273-
void addToBuffer(aREST *arest, const String& name, const String& request_url) const override {
274-
func(arest, name, request_url);
275-
}
276245
};
277246

278247
public:
@@ -313,13 +282,6 @@ void function(const char *name, int (*f)(String)) {
313282
}
314283

315284

316-
void api_extension(const char *name, void (*f)(aREST *, const String&, const String&)) {
317-
handlers[handlers_index] = new ApiHandler(f);
318-
handler_names[handlers_index] = name;
319-
handlers_index++;
320-
}
321-
322-
323285
private:
324286

325287
void initialize() {
@@ -495,7 +457,7 @@ void reset_status() {
495457

496458
reset();
497459
answer = "";
498-
request_url = "";
460+
arguments = "";
499461

500462
index = 0;
501463
//memset(&buffer[0], 0, sizeof(buffer));
@@ -1182,29 +1144,42 @@ void process(char c) {
11821144
// Handler request received ?
11831145
if (command == 'u') {
11841146

1185-
if (answer.endsWith(" HTTP/") || answer.endsWith("\r")) {
1186-
// Check if handler name is registered in array
1187-
for (uint8_t i = 0; i < handlers_index; i++) {
1188-
if (answer.startsWith(handler_names[i])) {
1189-
1190-
// End here
1191-
pin_selected = true;
1192-
state = 'x';
1193-
1194-
// Set state
1195-
command = 'h';
1196-
value = i;
1197-
1198-
answer.trim();
1199-
1200-
if (answer.endsWith(" HTTP/")) {
1201-
request_url = "/" + answer.substring(0, answer.length() - 6); // length of " HTTP/"
1202-
} else {
1203-
request_url = "/" + answer;
1147+
// Check if handler name is registered in array
1148+
for (uint8_t i = 0; i < handlers_index; i++) {
1149+
if (answer.startsWith(handler_names[i])) {
1150+
1151+
// End here
1152+
pin_selected = true;
1153+
state = 'x';
1154+
1155+
// Set state
1156+
command = 'h';
1157+
value = i;
1158+
1159+
answer.trim();
1160+
1161+
// We're expecting a string of the form <handlerName>?xxxxx=<arguments>, where xxxxx can be almost anything as long as it's followed by an '='
1162+
// Get command -- Anything following the first '=' in answer will be put in the arguments string.
1163+
arguments = "";
1164+
uint16_t header_length = strlen(handler_names[i]);
1165+
if (answer.substring(header_length, header_length + 1) == "?") {
1166+
uint16_t footer_start = answer.length();
1167+
if (answer.endsWith(" HTTP/"))
1168+
footer_start -= 6; // length of " HTTP/"
1169+
1170+
// Standard operation --> strip off anything preceeding the first "=", pass the rest to the handler
1171+
if(AREST_PARAMS_MODE == 0) {
1172+
uint16_t eq_position = answer.indexOf('=', header_length); // Replacing 'magic number' 8 for fixed location of '='
1173+
if (eq_position != -1)
1174+
arguments = answer.substring(eq_position + 1, footer_start);
1175+
}
1176+
// All params mode --> pass all parameters, if any, to the handler. Handler will be resonsible for parsing
1177+
else if(AREST_PARAMS_MODE == 1) {
1178+
arguments = answer.substring(header_length + 1, footer_start);
12041179
}
1205-
1206-
break; // We found what we're looking for
12071180
}
1181+
1182+
break; // We found what we're looking for
12081183
}
12091184
}
12101185

@@ -1239,23 +1214,19 @@ void process(char c) {
12391214
// Serial.print("Selected method: ");
12401215
// Serial.println(method);
12411216
// }
1242-
} else {
1243-
answer = "";
12441217
}
12451218

1246-
if (c == '\r' || answer.startsWith("GET /") || answer.startsWith("/")) {
1247-
answer = "";
1248-
}
1219+
answer = "";
12491220
}
12501221

12511222

1252-
// Modifies request_url in place
1253-
void urldecode(String &request_url) {
1223+
// Modifies arguments in place
1224+
void urldecode(String &arguments) {
12541225
char a, b;
12551226
int j = 0;
1256-
for(int i = 0; i < request_url.length(); i++) {
1257-
// %20 ==> request_url[i] = '%', a = '2', b = '0'
1258-
if ((request_url[i] == '%') && ((a = request_url[i + 1]) && (b = request_url[i + 2])) && (isxdigit(a) && isxdigit(b))) {
1227+
for(int i = 0; i < arguments.length(); i++) {
1228+
// %20 ==> arguments[i] = '%', a = '2', b = '0'
1229+
if ((arguments[i] == '%') && ((a = arguments[i + 1]) && (b = arguments[i + 2])) && (isxdigit(a) && isxdigit(b))) {
12591230
if (a >= 'a') a -= 'a'-'A';
12601231
if (a >= 'A') a -= ('A' - 10);
12611232
else a -= '0';
@@ -1264,17 +1235,17 @@ void urldecode(String &request_url) {
12641235
if (b >= 'A') b -= ('A' - 10);
12651236
else b -= '0';
12661237

1267-
request_url[j] = char(16 * a + b);
1238+
arguments[j] = char(16 * a + b);
12681239
i += 2; // Skip ahead
1269-
} else if (request_url[i] == '+') {
1270-
request_url[j] = ' ';
1240+
} else if (arguments[i] == '+') {
1241+
arguments[j] = ' ';
12711242
} else {
1272-
request_url[j] = request_url[i];
1243+
arguments[j] = arguments[i];
12731244
}
12741245
j++;
12751246
}
12761247

1277-
request_url.remove(j); // Truncate string to new possibly reduced length
1248+
arguments.remove(j); // Truncate string to new possibly reduced length
12781249
}
12791250

12801251

@@ -1474,19 +1445,15 @@ bool send_command(bool headers, bool decodeArgs) {
14741445
// Handler selected
14751446
if (command == 'h') {
14761447
if (decodeArgs) {
1477-
urldecode(request_url); // Modifies request_url
1448+
urldecode(arguments); // Modifies arguments
14781449
}
14791450
// Send feedback to client
14801451
if (LIGHTWEIGHT) {
1481-
addHandlerToBuffer(value, request_url);
1452+
addHandlerToBuffer(value, arguments);
14821453
} else {
14831454
addToBufferF(F("{"));
1484-
auto bufferPos = index;
1485-
addHandlerToBuffer(value, request_url);
1486-
if (bufferPos < index) {
1487-
// index has changed -> the handler added some stuff to the buffer
1488-
addToBufferF(F(", "));
1489-
}
1455+
addHandlerToBuffer(value, arguments);
1456+
addToBufferF(F(", "));
14901457
}
14911458
}
14921459

@@ -1901,8 +1868,8 @@ uint8_t esp_12_pin_map(uint8_t pin) {
19011868
}
19021869

19031870

1904-
void addHandlerToBuffer(uint8_t index, const String& request_url) {
1905-
handlers[index]->addToBuffer(this, String(handler_names[index]), request_url);
1871+
void addHandlerToBuffer(uint8_t index, const String& arguments) {
1872+
handlers[index]->addToBuffer(this, String(handler_names[index]), arguments);
19061873
}
19071874

19081875

@@ -1954,7 +1921,7 @@ void setMQTTServer(char* new_mqtt_server){
19541921

19551922
char name[NAME_SIZE];
19561923
String id;
1957-
String request_url;
1924+
String arguments;
19581925

19591926
// Output uffer
19601927
char buffer[OUTPUT_BUFFER_SIZE];

examples/BLE/BLE.ino

-57
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RD
2525
int temperature;
2626
int humidity;
2727

28-
// Declare functions to be exposed to the API
29-
int ledControl(String command);
30-
void aquariumController(aREST *arest, const String& name, const String& request_url);
31-
3228
void setup(void)
3329
{
3430
// Start Serial
@@ -46,9 +42,6 @@ void setup(void)
4642
// Function to be exposed
4743
rest.function("led",ledControl);
4844

49-
// API-Extension to be exposed
50-
rest.api_extension("aquarium", aquariumController);
51-
5245
// Give name & ID to the device (ID should be 6 characters long)
5346
rest.set_id("008");
5447
rest.set_name("ble_drake");
@@ -95,53 +88,3 @@ int ledControl(String command) {
9588
digitalWrite(7,state);
9689
return 1;
9790
}
98-
99-
void aquariumController(aREST *arest, const String& name, const String& request_url) {
100-
// check format of request_url
101-
if (request_url == F("/aquarium")
102-
|| request_url == F("/aquarium/")) {
103-
// Send feedback to client
104-
if (LIGHTWEIGHT) {
105-
bool isFirstSensor = true;
106-
auto count = 5;
107-
for (uint32_t i = 0; i < count; ++i) {
108-
if (isFirstSensor) {
109-
isFirstSensor = false;
110-
} else {
111-
arest->addToBufferF(F(","));
112-
}
113-
auto id = i + 100;
114-
arest->addToBuffer(id);
115-
}
116-
} else {
117-
arest->addToBufferF(F("\"sensor-ids\": ["));
118-
bool isFirstSensor = true;
119-
auto count = 5;
120-
for (uint32_t i = 0; i < count; ++i) {
121-
if (isFirstSensor) {
122-
isFirstSensor = false;
123-
} else {
124-
arest->addToBufferF(F(", "));
125-
}
126-
arest->addToBufferF(F("\""));
127-
auto id = i + 100;
128-
arest->addToBuffer(id);
129-
arest->addToBufferF(F("\""));
130-
}
131-
arest->addToBufferF(F("]"));
132-
}
133-
} else if (request_url.startsWith(F("/aquarium/water_limit/lower/set/"))) {
134-
String args = request_url.substring(32); // 32 = length of "/aquarium/water_limit/lower/set/"
135-
136-
// Send feedback to client
137-
if (!LIGHTWEIGHT) {
138-
arest->addToBufferF(F("\"message\": \"lower water limit set to "));
139-
arest->addToBuffer(args);
140-
arest->addToBufferF(F("cm\""));
141-
}
142-
} else {
143-
arest->addToBufferF(F("\"message\": \"Unknown request_url '"));
144-
arest->addToBuffer(request_url);
145-
arest->addToBufferF(F("'.\""));
146-
}
147-
}

0 commit comments

Comments
 (0)