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/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 d0f96c3..2f2af58 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() { @@ -20,12 +26,11 @@ void setupWebServer() server.begin(); } -void loopWebServer() +void loopWebServer() { - server.handleClient(); + server.handleClient(); } - void handleRoot() { server.send(SUC_CODE, APP_JSON, "{\"app\": \"Wledimir\"}"); @@ -48,34 +53,33 @@ 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 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 + "\"}"); } 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();