mirror of
https://github.com/1technophile/OpenMQTTGateway.git
synced 2026-02-19 16:21:44 +01:00
By building only the log level required into LOG_LEVEL Co-authored-by: Florian <1technophile@users.noreply.github.com>
240 lines
7.7 KiB
C++
240 lines
7.7 KiB
C++
/*
|
|
Theengs OpenMQTTGateway - We Unite Sensors in One Open-Source Interface
|
|
|
|
This gateway enables to use RGBLED strips like WS2812
|
|
|
|
Copyright: (c)
|
|
|
|
This file is part of OpenMQTTGateway.
|
|
|
|
OpenMQTTGateway is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
OpenMQTTGateway is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "User_config.h"
|
|
|
|
#ifdef ZactuatorFASTLED
|
|
|
|
# include <FastLED.h>
|
|
|
|
# include "config_FASTLED.h"
|
|
|
|
enum LEDState {
|
|
OFF,
|
|
FIRE,
|
|
GENERAL
|
|
};
|
|
LEDState currentLEDState;
|
|
long lastUpdate = 0;
|
|
long currentUpdate = 0;
|
|
CRGB leds[FASTLED_NUM_LEDS];
|
|
CRGB ledColorBlink[FASTLED_NUM_LEDS];
|
|
bool blinkLED[FASTLED_NUM_LEDS];
|
|
const long blinkInterval = 300;
|
|
const long fireUpdate = 10;
|
|
CRGBPalette16 gPal;
|
|
|
|
void Fire2012WithPalette();
|
|
|
|
void setupFASTLED() {
|
|
THEENGS_LOG_NOTICE(F("FASTLED_DATA_GPIO: %d" CR), FASTLED_DATA_GPIO);
|
|
THEENGS_LOG_NOTICE(F("FASTLED_NUM_LEDS: %d" CR), FASTLED_NUM_LEDS);
|
|
THEENGS_LOG_TRACE(F("actuatorFASTLED setup done " CR));
|
|
FastLED.addLeds<FASTLED_TYPE, FASTLED_DATA_GPIO>(leds, FASTLED_NUM_LEDS);
|
|
}
|
|
|
|
//returns the current step of the animation
|
|
int animation_step(int duration, int steps) {
|
|
int currentStep = ((currentUpdate % duration) / ((float)duration)) * steps;
|
|
return currentStep;
|
|
}
|
|
|
|
//returns the number of steps since the last update
|
|
int animation_step_count(int duration, int steps) {
|
|
long lastAnimationNumber = lastUpdate / duration;
|
|
long currentAnimationNumber = currentUpdate / duration;
|
|
int lastStep = ((lastUpdate % duration) / ((float)duration)) * steps;
|
|
int currentStep = ((currentUpdate % duration) / ((float)duration)) * steps;
|
|
|
|
return currentStep - lastStep + (currentAnimationNumber - lastAnimationNumber) * steps;
|
|
}
|
|
|
|
void FASTLEDLoop() {
|
|
lastUpdate = currentUpdate;
|
|
currentUpdate = millis();
|
|
|
|
if (currentLEDState == GENERAL) {
|
|
for (int i = 0; i < FASTLED_NUM_LEDS; i++) {
|
|
int count = animation_step_count(blinkInterval, 2);
|
|
int step = animation_step(blinkInterval, 2);
|
|
|
|
if (count > 0) {
|
|
if (blinkLED[i]) {
|
|
if (step == 0) {
|
|
leds[i] = ledColorBlink[i];
|
|
} else {
|
|
ledColorBlink[i] = leds[i];
|
|
leds[i] = CRGB::Black;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if (currentLEDState == FIRE) {
|
|
int count = animation_step_count(fireUpdate, 1);
|
|
if (count > 0) {
|
|
//random16_add_entropy( random(0)); //random() don't exists in ESP framework - workaround?
|
|
Fire2012WithPalette();
|
|
}
|
|
}
|
|
FastLED.show();
|
|
}
|
|
|
|
boolean FASTLEDtoX() {
|
|
return false;
|
|
}
|
|
# if jsonReceiving
|
|
void XtoFASTLED(const char* topicOri, JsonObject& jsonData) {
|
|
currentLEDState = GENERAL;
|
|
//trc(topicOri);
|
|
//number = (long)strtol(&datacallback[1], NULL, 16);
|
|
|
|
if (cmpToMainTopic(topicOri, subjectMQTTtoFASTLEDsetled)) {
|
|
THEENGS_LOG_TRACE(F("MQTTtoFASTLED JSON analysis" CR));
|
|
int ledNr = jsonData["led"];
|
|
THEENGS_LOG_NOTICE(F("Led numero: %d" CR), ledNr);
|
|
const char* color = jsonData["hex"];
|
|
THEENGS_LOG_NOTICE(F("Color hex: %s" CR), color);
|
|
|
|
long number = (long)strtol(color, NULL, 16);
|
|
bool blink = jsonData["blink"];
|
|
if (ledNr <= FASTLED_NUM_LEDS) {
|
|
THEENGS_LOG_NOTICE(F("Blink: %d" CR), blink);
|
|
blinkLED[ledNr] = blink;
|
|
leds[ledNr] = number;
|
|
}
|
|
}
|
|
}
|
|
# endif
|
|
|
|
# if simpleReceiving
|
|
void XtoFASTLED(const char* topicOri, const char* datacallback) {
|
|
THEENGS_LOG_TRACE(F("MQTTtoFASTLED: " CR));
|
|
currentLEDState = GENERAL;
|
|
long number = 0;
|
|
if (cmpToMainTopic(topicOri, subjectMQTTtoFASTLED)) {
|
|
number = (long)strtol(&datacallback[1], NULL, 16);
|
|
THEENGS_LOG_NOTICE(F("Number: %l" CR), number);
|
|
for (int i = 0; i < FASTLED_NUM_LEDS; i++) {
|
|
leds[i] = number;
|
|
}
|
|
FastLED.show();
|
|
} else if (cmpToMainTopic(topicOri, subjectMQTTtoFASTLEDsetbrightness)) {
|
|
number = (long)strtol(&datacallback[1], NULL, 16);
|
|
THEENGS_LOG_NOTICE(F("Number: %l" CR), number);
|
|
FastLED.setBrightness(number);
|
|
FastLED.show();
|
|
} else if (cmpToMainTopic(topicOri, subjectMQTTtoFASTLEDsetanimation)) {
|
|
String payload = datacallback;
|
|
THEENGS_LOG_NOTICE(F("Datacallback: %s" CR), datacallback);
|
|
if (strstr(datacallback, "fire") != NULL) {
|
|
currentLEDState = FIRE;
|
|
gPal = HeatColors_p;
|
|
} else {
|
|
currentLEDState = OFF;
|
|
}
|
|
} else {
|
|
currentLEDState = OFF;
|
|
}
|
|
if (currentLEDState == OFF) {
|
|
for (int i = 0; i < FASTLED_NUM_LEDS; i++) {
|
|
leds[i] = CRGB::Black;
|
|
}
|
|
}
|
|
}
|
|
# endif
|
|
// Fire2012 by Mark Kriegsman, July 2012
|
|
// as part of "Five Elements" shown here: http://youtu.be/knWiGsmgycY
|
|
////
|
|
// This basic one-dimensional 'fire' simulation works roughly as follows:
|
|
// There's a underlying array of 'heat' cells, that model the temperature
|
|
// at each point along the line. Every cycle through the simulation,
|
|
// four steps are performed:
|
|
// 1) All cells cool down a little bit, losing heat to the air
|
|
// 2) The heat from each cell drifts 'up' and diffuses a little
|
|
// 3) Sometimes randomly new 'sparks' of heat are added at the bottom
|
|
// 4) The heat from each cell is rendered as a color into the leds array
|
|
// The heat-to-color mapping uses a black-body radiation approximation.
|
|
//
|
|
// Temperature is in arbitrary units from 0 (cold black) to 255 (white hot).
|
|
//
|
|
// This simulation scales it self a bit depending on NUM_LEDS; it should look
|
|
// "OK" on anywhere from 20 to 100 LEDs without too much tweaking.
|
|
//
|
|
// I recommend running this simulation at anywhere from 30-100 frames per second,
|
|
// meaning an interframe delay of about 10-35 milliseconds.
|
|
//
|
|
// Looks best on a high-density LED setup (60+ pixels/meter).
|
|
//
|
|
//
|
|
// There are two main parameters you can play with to control the look and
|
|
// feel of your fire: COOLING (used in step 1 above), and SPARKING (used
|
|
// in step 3 above).
|
|
//
|
|
// COOLING: How much does the air cool as it rises?
|
|
// Less cooling = taller flames. More cooling = shorter flames.
|
|
// Default 55, suggested range 20-100
|
|
# define COOLING 55
|
|
|
|
// SPARKING: What chance (out of 255) is there that a new spark will be lit?
|
|
// Higher chance = more roaring fire. Lower chance = more flickery fire.
|
|
// Default 120, suggested range 50-200.
|
|
# define SPARKING 120
|
|
bool gReverseDirection = false;
|
|
|
|
void Fire2012WithPalette() {
|
|
// Array of temperature readings at each simulation cell
|
|
static byte heat[FASTLED_NUM_LEDS];
|
|
|
|
// Step 1. Cool down every cell a little
|
|
for (int i = 0; i < FASTLED_NUM_LEDS; i++) {
|
|
heat[i] = qsub8(heat[i], random8(0, ((COOLING * 10) / FASTLED_NUM_LEDS) + 2));
|
|
}
|
|
|
|
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
|
for (int k = FASTLED_NUM_LEDS - 1; k >= 2; k--) {
|
|
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2]) / 3;
|
|
}
|
|
|
|
// Step 3. Randomly ignite new 'sparks' of heat near the bottom
|
|
if (random8() < SPARKING) {
|
|
int y = random8(7);
|
|
heat[y] = qadd8(heat[y], random8(160, 255));
|
|
}
|
|
|
|
// Step 4. Map from heat cells to LED colors
|
|
for (int j = 0; j < FASTLED_NUM_LEDS; j++) {
|
|
// Scale the heat value from 0-255 down to 0-240
|
|
// for best results with color palettes.
|
|
byte colorindex = scale8(heat[j], 240);
|
|
CRGB color = ColorFromPalette(gPal, colorindex);
|
|
int pixelnumber;
|
|
if (gReverseDirection) {
|
|
pixelnumber = (FASTLED_NUM_LEDS - 1) - j;
|
|
} else {
|
|
pixelnumber = j;
|
|
}
|
|
leds[pixelnumber] = color;
|
|
}
|
|
}
|
|
|
|
#endif
|