From 286b32d15174bd64ea35b3d021363b13b9e0e985 Mon Sep 17 00:00:00 2001 From: Greg Maslowski Date: Wed, 13 Nov 2019 13:20:08 +0100 Subject: [PATCH 1/3] Small refactorings to OO. --- .vscode/settings.json | 6 ++- Esp8266PinBasedLedStripAdapter.cpp | 14 +++++++ Esp8266PinBasedLedStripAdapter.h | 13 ++++++ LedStrip.cpp | 26 ++++++++++++ LedStrip.h | 22 ++++++++++ LedStripAdapter.h | 9 +++++ controller.ino | 13 ++++-- led.h | 4 +- led.ino | 65 ++++++++---------------------- wledimir.ino | 1 - 10 files changed, 119 insertions(+), 54 deletions(-) create mode 100644 Esp8266PinBasedLedStripAdapter.cpp create mode 100644 Esp8266PinBasedLedStripAdapter.h create mode 100644 LedStrip.cpp create mode 100644 LedStrip.h create mode 100644 LedStripAdapter.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 8d5b32a..289b028 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,5 +8,9 @@ "arduino.additionalUrls": [ "http://arduino.esp8266.com/stable/package_esp8266com_index.json" ], - "arduino.defaultBaudRate": 115200 + "arduino.defaultBaudRate": 115200, + "files.associations": { + "istream": "cpp", + "streambuf": "cpp" + } } \ No newline at end of file diff --git a/Esp8266PinBasedLedStripAdapter.cpp b/Esp8266PinBasedLedStripAdapter.cpp new file mode 100644 index 0000000..0568efa --- /dev/null +++ b/Esp8266PinBasedLedStripAdapter.cpp @@ -0,0 +1,14 @@ +#include "Arduino.h" +#include "Esp8266PinBasedLedStripAdapter.h" + +Esp8266PinLedStripAdapter::Esp8266PinLedStripAdapter(byte gpioPin) +{ + _gpioPin = gpioPin; + pinMode(gpioPin, OUTPUT); + analogWrite(_gpioPin, 0); +} + +void Esp8266PinLedStripAdapter::changeLight(byte value) +{ + analogWrite(_gpioPin, value * 10); +}; \ No newline at end of file diff --git a/Esp8266PinBasedLedStripAdapter.h b/Esp8266PinBasedLedStripAdapter.h new file mode 100644 index 0000000..8c67f3f --- /dev/null +++ b/Esp8266PinBasedLedStripAdapter.h @@ -0,0 +1,13 @@ +#pragma once + +#include "LedStripAdapter.h" + +class Esp8266PinLedStripAdapter : public LedStripAdapter +{ +public: + Esp8266PinLedStripAdapter(byte gpioPin); + virtual void changeLight(byte value); + +private: + byte _gpioPin; +}; \ No newline at end of file diff --git a/LedStrip.cpp b/LedStrip.cpp new file mode 100644 index 0000000..8972141 --- /dev/null +++ b/LedStrip.cpp @@ -0,0 +1,26 @@ +#include "LedStrip.h" + +LedStrip::LedStrip() : LedStrip::LedStrip(0, NULL) +{ +} + +LedStrip::LedStrip(byte initialValue, LedStripAdapter *adapter) +{ + _adapter = adapter; + _currentValue = initialValue; +} + +void LedStrip::manipulate(byte value, String effect) +{ + _toBeValue = value; + _effect = effect; +} + +void LedStrip::controlLight() +{ + if (_currentValue != _toBeValue) + { + _currentValue = _toBeValue > _currentValue ? _currentValue + 1 : _currentValue - 1; + _adapter->changeLight(_currentValue); + } +} diff --git a/LedStrip.h b/LedStrip.h new file mode 100644 index 0000000..8f77ef0 --- /dev/null +++ b/LedStrip.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include "LedStripAdapter.h" + +class LedStrip +{ + +public: + LedStrip(); + LedStrip(byte initialValue, LedStripAdapter *adapter); + + void manipulate(byte value, String effect); + void controlLight(); + +private: + volatile byte _toBeValue = 0; + volatile byte _currentValue = 0; + String _effect = "dim"; + + LedStripAdapter *_adapter; +}; diff --git a/LedStripAdapter.h b/LedStripAdapter.h new file mode 100644 index 0000000..1a388e6 --- /dev/null +++ b/LedStripAdapter.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +class LedStripAdapter +{ +public: + virtual void changeLight(byte value) = 0; +}; diff --git a/controller.ino b/controller.ino index d0f96c3..ef07055 100644 --- a/controller.ino +++ b/controller.ino @@ -20,12 +20,11 @@ void setupWebServer() server.begin(); } -void loopWebServer() +void loopWebServer() { - server.handleClient(); + server.handleClient(); } - void handleRoot() { server.send(SUC_CODE, APP_JSON, "{\"app\": \"Wledimir\"}"); @@ -70,6 +69,14 @@ void handlePost() succeedWith(message); } +void validate(byte led) +{ + if (led != 1 && led != 2) + { + failWith(ERR_CODE, "You can only choose 1 or 2 for led number"); + } +} + void succeedWith(char message[]) { server.send(SUC_CODE, APP_JSON, "{\"message\": \"" + String(message) + "\"}"); diff --git a/led.h b/led.h index 9bcb5c4..4865a4d 100644 --- a/led.h +++ b/led.h @@ -1,4 +1,6 @@ -void manipulateLed(int led, byte value, String effect); +#include + +void manipulateLed(byte led, byte value, String effect); void setupLed(); diff --git a/led.ino b/led.ino index ae8f3fe..8eaf6bf 100644 --- a/led.ino +++ b/led.ino @@ -1,70 +1,39 @@ #include +#include "LedStrip.h" +#include "LedStripAdapter.h" +#include "Esp8266PinBasedLedStripAdapter.h" -#define led1 0 -#define led2 2 -#define DELAY 10 +#define LED_1_GPIO 0 +#define LED_2_GPIO 2 -volatile int led1_toBeValue = 0; -volatile int led1_currentValue = 0; -volatile int led2_toBeValue = 0; -volatile int led2_currentValue = 0; +#define DELAY 5 + +LedStrip ledStrip1; +LedStrip ledStrip2; void setupLed() { - pinMode(led1, OUTPUT); - pinMode(led2, OUTPUT); - - analogWrite(led1, 0); - analogWrite(led2, 0); + ledStrip1 = LedStrip((byte)0, new Esp8266PinLedStripAdapter(LED_1_GPIO)); + ledStrip2 = LedStrip((byte)0, new Esp8266PinLedStripAdapter(LED_2_GPIO)); } void loopLed() { - byte delayMs = 0; - - if (led1_currentValue != led1_toBeValue) - { - if (led1_toBeValue > led1_currentValue) - { // more light - led1_currentValue = led1_currentValue + 1; - } - else - { // less light - led1_currentValue = led1_currentValue - 1; - } - delayMs = DELAY; - analogWrite(led1, led1_currentValue); - } - - if (led2_currentValue != led2_toBeValue) - { - if (led2_toBeValue > led2_currentValue) - { // more light - led2_currentValue = led2_currentValue + 1; - } - else - { // less light - led2_currentValue = led2_currentValue - 1; - } - delayMs = DELAY; - analogWrite(led2, led2_currentValue); // analogWrite values from 0 to 255 - } + ledStrip1.controlLight(); + ledStrip2.controlLight(); - delay(delayMs); + delay(DELAY); } -// value might be from 0 to 100 -// led might be eiter 1 or 2 -void manipulateLed(int led, byte value, String effect) +void manipulateLed(byte led, byte value, String effect) { if (led == 1) { - led1_toBeValue = value * 10; + ledStrip1.manipulate(value, effect); } if (led == 2) { - led2_toBeValue = value * 10; + ledStrip2.manipulate(value, effect); } - return; } diff --git a/wledimir.ino b/wledimir.ino index 177568f..ea8f0e4 100644 --- a/wledimir.ino +++ b/wledimir.ino @@ -6,7 +6,6 @@ void setup() { - // put your setup code here, to run once: Serial.begin(115200); setupLed(); From 29771126517ee8eb079141aff6c2dc896687226f Mon Sep 17 00:00:00 2001 From: Greg Maslowski Date: Wed, 13 Nov 2019 14:02:03 +0100 Subject: [PATCH 2/3] Extracted payload validator. --- RestPayloadValidator.cpp | 47 ++++++++++++++++++++++++++++++++++++++++ RestPayloadValidator.h | 17 +++++++++++++++ controller.ino | 43 +++++++++++++++++++++++------------- 3 files changed, 92 insertions(+), 15 deletions(-) create mode 100644 RestPayloadValidator.cpp create mode 100644 RestPayloadValidator.h diff --git a/RestPayloadValidator.cpp b/RestPayloadValidator.cpp new file mode 100644 index 0000000..926eee0 --- /dev/null +++ b/RestPayloadValidator.cpp @@ -0,0 +1,47 @@ +#include "RestPayloadValidator.h" + +#define ERR_CODE 400 +#define SUC_CODE 200 + +#define JSON_LED "led" +#define JSON_VALUE "value" +#define JSON_EFFECT "effect" + +RestPayloadValidator::RestPayloadValidator() +{ +} + +struct RestPayloadValidationResult RestPayloadValidator::validate(StaticJsonDocument<150> json, DeserializationError error) +{ + + struct RestPayloadValidationResult result; + result.faulty = false; + result.message = "OK."; + result.httpErrorCode = SUC_CODE; + + if (error) + { + result.faulty = true; + result.message = "Cannot parse message."; + result.httpErrorCode = ERR_CODE; + return result; + } + + if (json[JSON_LED] != 1 && json[JSON_LED] != 2) + { + result.faulty = true; + result.message = "The led number has to be either 1 or 2."; + result.httpErrorCode = ERR_CODE; + return result; + } + + if (json[JSON_VALUE] < 0 || json[JSON_VALUE] > 100) + { + result.faulty = true; + result.message = "The value has to be in range <0,100>."; + result.httpErrorCode = ERR_CODE; + return result; + } + + return result; +} diff --git a/RestPayloadValidator.h b/RestPayloadValidator.h new file mode 100644 index 0000000..1d336f3 --- /dev/null +++ b/RestPayloadValidator.h @@ -0,0 +1,17 @@ +#include +#include + +class RestPayloadValidator +{ +public: + RestPayloadValidator(); + + struct RestPayloadValidationResult validate(StaticJsonDocument<150> StaticJsonDocument, DeserializationError error); +}; + +struct RestPayloadValidationResult +{ + boolean faulty = false; + String message; + short httpErrorCode; +}; diff --git a/controller.ino b/controller.ino index ef07055..23a9491 100644 --- a/controller.ino +++ b/controller.ino @@ -2,6 +2,7 @@ #include #include "led.h" #include "controller.h" +#include "RestPayloadValidator.h" #define PORT 8080 #define ERR_CODE 400 @@ -9,8 +10,13 @@ #define PLAIN "plain" #define APP_JSON "application/json" +#define JSON_LED "led" +#define JSON_VALUE "value" +#define JSON_EFFECT "effect" + ESP8266WebServer server(PORT); StaticJsonDocument<150> json; +RestPayloadValidator payloadValidator = RestPayloadValidator(); void setupWebServer() { @@ -47,42 +53,49 @@ void handleNotFound() */ void handlePost() { - if (server.hasArg(PLAIN) == false) { failWith(ERR_CODE, "Body not received."); return; } - auto error = deserializeJson(json, server.arg(PLAIN)); + RestPayloadValidationResult validationResult = payloadValidator.validate(json, deserializeJson(json, server.arg(PLAIN))); - if (error) + if (validationResult.faulty) { - failWith(ERR_CODE, "Cannot parse message."); + failWith(validationResult.httpErrorCode, validationResult.message); delay(1000); return; } - - manipulateLed(json["led"], json["value"], json["effect"]); - - char message[] = "OK."; - succeedWith(message); + else + { + manipulateLed(json[JSON_LED], json[JSON_VALUE], json[JSON_EFFECT]); + succeedWith(validationResult.message); + } } -void validate(byte led) +boolean validate(byte led, int value) { + boolean retVal = true; if (led != 1 && led != 2) { - failWith(ERR_CODE, "You can only choose 1 or 2 for led number"); + failWith(ERR_CODE, "The led number has to be either 1 or 2."); + retVal = false; + } + if (value < 0 || value > 100) + { + failWith(ERR_CODE, "The value has to be in range <0,100>."); + retVal = false; } + return retVal; } -void succeedWith(char message[]) +void succeedWith(String message) { - server.send(SUC_CODE, APP_JSON, "{\"message\": \"" + String(message) + "\"}"); + server.send(SUC_CODE, APP_JSON, "{\"message\": \"" + message + "\"}"); } -void failWith(int code, char message[]) +void failWith(int code, String message) { - server.send(code, APP_JSON, "{\"error\": \"" + String(message) + "\"}"); + server.send(code, APP_JSON, "{\"error\": \"" + message + "\"}"); } From daa944325da1e0da401916a032b8e367b2f3b1a8 Mon Sep 17 00:00:00 2001 From: Greg Maslowski Date: Wed, 13 Nov 2019 14:04:48 +0100 Subject: [PATCH 3/3] Remove obsolete method. --- controller.ino | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/controller.ino b/controller.ino index 23a9491..2f2af58 100644 --- a/controller.ino +++ b/controller.ino @@ -74,22 +74,6 @@ void handlePost() } } -boolean validate(byte led, int value) -{ - boolean retVal = true; - if (led != 1 && led != 2) - { - failWith(ERR_CODE, "The led number has to be either 1 or 2."); - retVal = false; - } - if (value < 0 || value > 100) - { - failWith(ERR_CODE, "The value has to be in range <0,100>."); - retVal = false; - } - return retVal; -} - void succeedWith(String message) { server.send(SUC_CODE, APP_JSON, "{\"message\": \"" + message + "\"}");