bug_fix
- fixed bugs - Added file for custom WS2812FX animations in custom slots - Rename varaibles to be char instead of String - Added LED pixel count and PIN settings to WiFiManager
This commit is contained in:
parent
38d8f3f813
commit
8ff869ce7f
6 changed files with 226 additions and 79 deletions
|
@ -84,7 +84,7 @@ ESP8266HTTPUpdateServer httpUpdater;
|
|||
// ***************************************************************************
|
||||
// https://github.com/kitesurfer1404/WS2812FX
|
||||
#include <WS2812FX.h>
|
||||
// WS2812FX strip = WS2812FX(NUMLEDS, PIN, NEO_GRB + NEO_KHZ800);
|
||||
// WS2812FX strip = WS2812FX(NUMLEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
|
||||
WS2812FX* strip;
|
||||
|
||||
#if defined(USE_WS2812FX_DMA) or defined(USE_WS2812FX_UART1) or defined(USE_WS2812FX_UART2)
|
||||
|
@ -229,10 +229,13 @@ void saveConfigCallback () {
|
|||
// ***************************************************************************
|
||||
#include "request_handlers.h"
|
||||
|
||||
#ifdef CUSTOM_WS2812FX_ANIMATIONS
|
||||
#include "custom_ws2812fx_animations.h" // Add animations in this file
|
||||
#endif
|
||||
|
||||
// function to Initialize the strip
|
||||
void initStrip(uint16_t stripSize = WS2812FXStripSettings.stripSize, neoPixelType RGBOrder = WS2812FXStripSettings.RGBOrder, uint8_t pin = WS2812FXStripSettings.pin){
|
||||
if (strip) {
|
||||
if (strip->getLength() == stripSize && WS2812FXStripSettings.RGBOrder == RGBOrder && WS2812FXStripSettings.pin == pin) return;
|
||||
delete strip;
|
||||
WS2812FXStripSettings.stripSize = stripSize;
|
||||
WS2812FXStripSettings.RGBOrder = RGBOrder;
|
||||
|
@ -259,9 +262,13 @@ void initStrip(uint16_t stripSize = WS2812FXStripSettings.stripSize, neoPixelTyp
|
|||
#endif
|
||||
strip->setBrightness(brightness);
|
||||
strip->setSpeed(convertSpeed(ws2812fx_speed));
|
||||
//strip->setMode(FX_MODE_RAINBOW_CYCLE);
|
||||
//strip->setMode(ws2812fx_mode);
|
||||
strip->setColor(main_color.red, main_color.green, main_color.blue);
|
||||
#ifdef CUSTOM_WS2812FX_ANIMATIONS
|
||||
strip->setCustomMode(myCustomEffect);
|
||||
#endif
|
||||
strip->start();
|
||||
if(mode != HOLD) mode = SET_MODE;
|
||||
saveWS2812FXStripSettings.once(3, writeStripConfigFS);
|
||||
}
|
||||
|
||||
|
@ -339,10 +346,16 @@ void setup() {
|
|||
#endif
|
||||
WiFiManagerParameter custom_mqtt_host("host", "MQTT hostname", mqtt_host, 64);
|
||||
WiFiManagerParameter custom_mqtt_port("port", "MQTT port", mqtt_port, 6);
|
||||
WiFiManagerParameter custom_mqtt_user("user", "MQTT user", mqtt_user, 32);
|
||||
WiFiManagerParameter custom_mqtt_pass("pass", "MQTT pass", mqtt_pass, 32);
|
||||
WiFiManagerParameter custom_mqtt_user("user", "MQTT user", mqtt_user, 32, " maxlength=31");
|
||||
WiFiManagerParameter custom_mqtt_pass("pass", "MQTT pass", mqtt_pass, 32, " maxlength=31 type='password'");
|
||||
#endif
|
||||
|
||||
sprintf(strip_size, "%d", WS2812FXStripSettings.stripSize);
|
||||
sprintf(led_pin, "%d", WS2812FXStripSettings.pin);
|
||||
|
||||
WiFiManagerParameter custom_strip_size("strip_size", "Number of LEDs", strip_size, 3);
|
||||
WiFiManagerParameter custom_led_pin("led_pin", "LED GPIO", led_pin, 2);
|
||||
|
||||
//Local intialization. Once its business is done, there is no need to keep it around
|
||||
WiFiManager wifiManager;
|
||||
//reset settings - for testing
|
||||
|
@ -362,6 +375,9 @@ void setup() {
|
|||
wifiManager.addParameter(&custom_mqtt_pass);
|
||||
#endif
|
||||
|
||||
wifiManager.addParameter(&custom_strip_size);
|
||||
wifiManager.addParameter(&custom_led_pin);
|
||||
|
||||
WiFi.setSleepMode(WIFI_NONE_SLEEP);
|
||||
|
||||
// Uncomment if you want to restart ESP8266 if it cannot connect to WiFi.
|
||||
|
@ -394,6 +410,16 @@ void setup() {
|
|||
strcpy(mqtt_user, custom_mqtt_user.getValue());
|
||||
strcpy(mqtt_pass, custom_mqtt_pass.getValue());
|
||||
|
||||
strcpy(strip_size, custom_strip_size.getValue());
|
||||
strcpy(led_pin, custom_led_pin.getValue());
|
||||
|
||||
if(atoi(strip_size) != WS2812FXStripSettings.stripSize)
|
||||
WS2812FXStripSettings.stripSize = atoi(strip_size);
|
||||
uint8_t pin = atoi(led_pin);
|
||||
if ((pin == 16 or pin == 5 or pin == 4 or pin == 0 or pin == 2 or pin == 14 or pin == 12 or pin == 13 or pin == 15 or pin == 3 or pin == 1) and (pin != WS2812FXStripSettings.pin) )
|
||||
WS2812FXStripSettings.pin = pin;
|
||||
initStrip();
|
||||
|
||||
//save the custom parameters to FS
|
||||
#if defined(ENABLE_STATE_SAVE_SPIFFS) and (defined(ENABLE_MQTT) or defined(ENABLE_AMQTT))
|
||||
(writeConfigFS(shouldSaveConfig)) ? DBG_OUTPUT_PORT.println("WiFiManager config FS Save success!"): DBG_OUTPUT_PORT.println("WiFiManager config FS Save failure!");
|
||||
|
@ -474,9 +500,6 @@ void setup() {
|
|||
|
||||
#ifdef ENABLE_MQTT
|
||||
if (mqtt_host != "" && atoi(mqtt_port) > 0) {
|
||||
snprintf(mqtt_intopic, sizeof mqtt_intopic, "%s/in", HOSTNAME);
|
||||
snprintf(mqtt_outtopic, sizeof mqtt_outtopic, "%s/out", HOSTNAME);
|
||||
|
||||
DBG_OUTPUT_PORT.printf("MQTT active: %s:%d\n", mqtt_host, String(mqtt_port).toInt());
|
||||
|
||||
mqtt_client.setServer(mqtt_host, atoi(mqtt_port));
|
||||
|
@ -492,7 +515,7 @@ void setup() {
|
|||
amqttClient.setServer(mqtt_host, atoi(mqtt_port));
|
||||
if (mqtt_user != "" or mqtt_pass != "") amqttClient.setCredentials(mqtt_user, mqtt_pass);
|
||||
amqttClient.setClientId(mqtt_clientid);
|
||||
amqttClient.setWill(mqtt_will_topic.c_str(), 2, true, mqtt_will_payload, 0);
|
||||
amqttClient.setWill(mqtt_will_topic, 2, true, mqtt_will_payload, 0);
|
||||
|
||||
connectToMqtt();
|
||||
}
|
||||
|
@ -575,7 +598,7 @@ void setup() {
|
|||
json["pin"] = 2;
|
||||
#else
|
||||
json["animation_lib"] = "WS2812FX";
|
||||
json["pin"] = PIN;
|
||||
json["pin"] = LED_PIN;
|
||||
#endif
|
||||
json["number_leds"] = NUMLEDS;
|
||||
#ifdef ENABLE_BUTTON
|
||||
|
@ -682,7 +705,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK %") + String(brightness)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK %") + String(brightness)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK %") + String(brightness)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -711,7 +734,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK ?") + String(ws2812fx_speed)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ?") + String(ws2812fx_speed)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK ?") + String(ws2812fx_speed)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState);
|
||||
|
@ -749,12 +772,13 @@ void setup() {
|
|||
});
|
||||
|
||||
server.on("/pixels", []() {
|
||||
|
||||
bool updateStrip = false;
|
||||
if(server.hasArg("ct")){
|
||||
uint16_t pixelCt = server.arg("ct").toInt();
|
||||
if (pixelCt > 0) {
|
||||
if(strip->isRunning()) strip->stop();
|
||||
initStrip(pixelCt);
|
||||
if(mode != HOLD) mode = SET_MODE;
|
||||
WS2812FXStripSettings.stripSize = pixelCt;
|
||||
updateStrip = true;
|
||||
DBG_OUTPUT_PORT.printf("/pixels: Count# %d\n", pixelCt);
|
||||
}
|
||||
}
|
||||
|
@ -762,22 +786,28 @@ void setup() {
|
|||
String RGBOrder = server.arg("rgbo");
|
||||
DBG_OUTPUT_PORT.print("/pixels: RGB Order# ");
|
||||
if (RGBOrder == "grb") {
|
||||
initStrip(strip->getLength(), NEO_GRB);
|
||||
WS2812FXStripSettings.RGBOrder = NEO_GRB;
|
||||
updateStrip = true;
|
||||
DBG_OUTPUT_PORT.println(RGBOrder);
|
||||
} else if (RGBOrder == "gbr") {
|
||||
initStrip(strip->getLength(), NEO_GBR);
|
||||
WS2812FXStripSettings.RGBOrder = NEO_GBR;
|
||||
updateStrip = true;
|
||||
DBG_OUTPUT_PORT.println(RGBOrder);
|
||||
} else if (RGBOrder == "rgb") {
|
||||
initStrip(strip->getLength(), NEO_RGB);
|
||||
WS2812FXStripSettings.RGBOrder = NEO_RGB;
|
||||
updateStrip = true;
|
||||
DBG_OUTPUT_PORT.println(RGBOrder);
|
||||
} else if (RGBOrder == "rbg") {
|
||||
initStrip(strip->getLength(), NEO_RBG);
|
||||
WS2812FXStripSettings.RGBOrder = NEO_RBG;
|
||||
updateStrip = true;
|
||||
DBG_OUTPUT_PORT.println(RGBOrder);
|
||||
} else if (RGBOrder == "brg") {
|
||||
initStrip(strip->getLength(), NEO_BRG);
|
||||
WS2812FXStripSettings.RGBOrder = NEO_BRG;
|
||||
updateStrip = true;
|
||||
DBG_OUTPUT_PORT.println(RGBOrder);
|
||||
} else if (RGBOrder == "bgr") {
|
||||
initStrip(strip->getLength(), NEO_BGR);
|
||||
WS2812FXStripSettings.RGBOrder = NEO_BGR;
|
||||
updateStrip = true;
|
||||
DBG_OUTPUT_PORT.println(RGBOrder);
|
||||
} else {
|
||||
DBG_OUTPUT_PORT.println("invalid input!");
|
||||
|
@ -798,7 +828,8 @@ void setup() {
|
|||
#endif
|
||||
#else
|
||||
if (pin == 16 or pin == 5 or pin == 4 or pin == 0 or pin == 2 or pin == 14 or pin == 12 or pin == 13 or pin == 15 or pin == 3 or pin == 1) {
|
||||
initStrip(NULL, NULL, pin);
|
||||
WS2812FXStripSettings.pin = pin;
|
||||
updateStrip = true;
|
||||
DBG_OUTPUT_PORT.println(pin);
|
||||
} else {
|
||||
DBG_OUTPUT_PORT.println("invalid input!");
|
||||
|
@ -806,6 +837,16 @@ void setup() {
|
|||
#endif
|
||||
}
|
||||
|
||||
if(updateStrip)
|
||||
{
|
||||
ws2812fx_mode = strip->getMode();
|
||||
if(strip->isRunning()) strip->stop();
|
||||
initStrip();
|
||||
writeStripConfigFS();
|
||||
strip->setMode(ws2812fx_mode);
|
||||
strip->trigger();
|
||||
}
|
||||
|
||||
DynamicJsonDocument jsonBuffer(200);
|
||||
JsonObject json = jsonBuffer.to<JsonObject>();
|
||||
json["pixel_pount"] = WS2812FXStripSettings.stripSize;
|
||||
|
@ -828,7 +869,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =off").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =off").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =off").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = false;
|
||||
|
@ -851,7 +892,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =all").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =all").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =all").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -871,7 +912,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =wipe").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =wipe").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =wipe").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -890,7 +931,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =rainbow").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =rainbow").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =rainbow").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -909,7 +950,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =rainbowCycle").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =rainbowCycle").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =rainbowCycle").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -928,7 +969,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =theaterchase").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =theaterchase").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =theaterchase").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -947,7 +988,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =twinkleRandom").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =twinkleRandom").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =twinkleRandom").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -966,7 +1007,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =theaterchaseRainbow").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =theaterchaseRainbow").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =theaterchaseRainbow").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -985,7 +1026,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =e131").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =131").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =131").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -1005,7 +1046,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =tv").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =tv").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =tv").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -1029,7 +1070,7 @@ void setup() {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK /") + String(ws2812fx_mode)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK /") + String(ws2812fx_mode)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK /") + String(ws2812fx_mode)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -1055,7 +1096,7 @@ void setup() {
|
|||
// Choose one to begin listening for E1.31 data
|
||||
// if (e131.begin(E131_UNICAST)) // Listen via Unicast
|
||||
if (e131.begin(E131_MULTICAST, START_UNIVERSE, END_UNIVERSE)) // Listen via Multicast
|
||||
Serial.println(F("Listening for data..."));
|
||||
Serial.println(F("E1.31 mode setup complete."));
|
||||
else
|
||||
Serial.println(F("*** e131.begin failed ***"));
|
||||
#endif
|
||||
|
|
97
Arduino/McLighting/custom_ws2812fx_animations.h
Normal file
97
Arduino/McLighting/custom_ws2812fx_animations.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
|
||||
Example of adding the example: https://github.com/kitesurfer1404/WS2812FX/blob/master/examples/ws2812fx_custom_FastLED/ws2812fx_custom_FastLED.ino
|
||||
as a custom effect
|
||||
|
||||
More info on how to create custom aniamtions for WS2812FX: https://github.com/kitesurfer1404/WS2812FX/blob/master/extras/WS2812FX%20Users%20Guide.md#custom-effects
|
||||
|
||||
*/
|
||||
|
||||
#include <FastLED.h> //https://github.com/FastLED/FastLED
|
||||
|
||||
|
||||
/*
|
||||
* paste in the Fire2012 code with a small edit at the end which uses the
|
||||
* setPixelColor() function to copy the color data to the ws2812fx instance.
|
||||
*/
|
||||
|
||||
// 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 50, 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 Fire2012()
|
||||
{
|
||||
// Array of temperature readings at each simulation cell
|
||||
byte heat[WS2812FXStripSettings.stripSize];
|
||||
|
||||
// Step 1. Cool down every cell a little
|
||||
for( int i = 0; i < WS2812FXStripSettings.stripSize; i++) {
|
||||
heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / WS2812FXStripSettings.stripSize) + 2));
|
||||
}
|
||||
|
||||
// Step 2. Heat from each cell drifts 'up' and diffuses a little
|
||||
for( int k= WS2812FXStripSettings.stripSize- 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 < WS2812FXStripSettings.stripSize; j++) {
|
||||
CRGB color = HeatColor( heat[j]);
|
||||
int pixelnumber;
|
||||
if( gReverseDirection ) {
|
||||
pixelnumber = (WS2812FXStripSettings.stripSize-1) - j;
|
||||
} else {
|
||||
pixelnumber = j;
|
||||
}
|
||||
|
||||
strip->setPixelColor(pixelnumber, color.red, color.green, color.blue);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t myCustomEffect() {
|
||||
Fire2012();
|
||||
return (strip->getSpeed() / WS2812FXStripSettings.stripSize);
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
//#define USE_WS2812FX_DMA // PIN is ignored & set to RX/GPIO3 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
||||
//#define USE_WS2812FX_UART1 // PIN is ignored & set to D4/GPIO2 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
||||
//#define USE_WS2812FX_UART2 // PIN is ignored & set to TX/GPIO1 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
||||
//#define USE_WS2812FX_DMA // LED_PIN is ignored & set to RX/GPIO3 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
||||
//#define USE_WS2812FX_UART1 // LED_PIN is ignored & set to D4/GPIO2 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
||||
//#define USE_WS2812FX_UART2 // LED_PIN is ignored & set to TX/GPIO1 Uses WS2812FX, see: https://github.com/kitesurfer1404/WS2812FX
|
||||
|
||||
// Neopixel
|
||||
#define PIN 14 // PIN (14 / D5) where neopixel / WS2811 strip is attached
|
||||
#define LED_PIN 14 // LED_PIN (14 / D5) where neopixel / WS2811 strip is attached
|
||||
#define NUMLEDS 24 // Number of leds in the strip
|
||||
#define BUILTIN_LED 2 // ESP-12F has the built in LED on GPIO2, see https://github.com/esp8266/Arduino/issues/2192
|
||||
#define BUTTON 4 // Input pin (4 / D2) for switching the LED strip on / off, connect this PIN to ground to trigger button.
|
||||
|
||||
const char HOSTNAME[] = "McLighting01"; // Friedly hostname
|
||||
#define HOSTNAME "McLighting01" // Friedly hostname
|
||||
|
||||
#define HTTP_OTA // If defined, enable ESP8266HTTPUpdateServer OTA code.
|
||||
//#define ENABLE_OTA // If defined, enable Arduino OTA code.
|
||||
|
@ -62,30 +62,28 @@ uint32_t autoParams[][4] = { // color, speed, mode, duration (milliseconds)
|
|||
};
|
||||
|
||||
#if defined(ENABLE_MQTT) or defined(ENABLE_AMQTT)
|
||||
const String mqtt_will_topic = String(HOSTNAME) + "/status";
|
||||
|
||||
const char mqtt_will_topic[] = HOSTNAME "/status";
|
||||
const char mqtt_will_payload[] = "ONLINE";
|
||||
const char mqtt_intopic[] = HOSTNAME "/in";
|
||||
const char mqtt_outtopic[] = HOSTNAME "/out";
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
#define MQTT_MAX_PACKET_SIZE 512
|
||||
#define MQTT_MAX_RECONNECT_TRIES 4
|
||||
|
||||
int mqtt_reconnect_retries = 0;
|
||||
char mqtt_intopic[strlen(HOSTNAME) + 4 + 5]; // Topic in will be: <HOSTNAME>/in
|
||||
char mqtt_outtopic[strlen(HOSTNAME) + 5 + 5]; // Topic out will be: <HOSTNAME>/out
|
||||
uint8_t qossub = 0; // PubSubClient can sub qos 0 or 1
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_AMQTT
|
||||
String mqtt_intopic = String(HOSTNAME) + "/in";
|
||||
String mqtt_outtopic = String(HOSTNAME) + "/out";
|
||||
uint8_t qossub = 0; // AMQTT can sub qos 0 or 1 or 2
|
||||
uint8_t qospub = 0; // AMQTT can pub qos 0 or 1 or 2
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
String mqtt_ha = "home/" + String(HOSTNAME) + "_ha/";
|
||||
String mqtt_ha_state_in = mqtt_ha + "state/in";
|
||||
String mqtt_ha_state_out = mqtt_ha + "state/out";
|
||||
const char mqtt_ha_state_in[] = "home/" HOSTNAME "_ha/state/in";
|
||||
const char mqtt_ha_state_out[] = "home/" HOSTNAME "_ha/state/out";
|
||||
|
||||
const char* on_cmd = "ON";
|
||||
const char* off_cmd = "OFF";
|
||||
|
@ -99,7 +97,7 @@ uint32_t autoParams[][4] = { // color, speed, mode, duration (milliseconds)
|
|||
#ifdef ENABLE_MQTT_HOSTNAME_CHIPID
|
||||
char mqtt_clientid[64];
|
||||
#else
|
||||
const char* mqtt_clientid = HOSTNAME;
|
||||
const char mqtt_clientid[] = HOSTNAME;
|
||||
#endif
|
||||
|
||||
char mqtt_host[64] = "";
|
||||
|
|
|
@ -461,7 +461,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -492,7 +492,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -512,7 +512,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -537,7 +537,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -562,7 +562,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -580,7 +580,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -599,7 +599,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -624,7 +624,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
if(!ha_send_data.active()) ha_send_data.once(5, tickerSendState);
|
||||
|
@ -644,7 +644,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
|||
mqtt_client.publish(mqtt_outtopic, json.c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, json.c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, json.c_str());
|
||||
#endif
|
||||
} else {
|
||||
DBG_OUTPUT_PORT.print("WS: ");
|
||||
|
@ -671,7 +671,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
|||
//DBG_OUTPUT_PORT.printf("Result: %d / %d", res, json_modes.length());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, json.c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, json.c_str());
|
||||
#endif
|
||||
} else {
|
||||
DBG_OUTPUT_PORT.print("WS: ");
|
||||
|
@ -700,7 +700,7 @@ void checkpayload(uint8_t * payload, bool mqtt = false, uint8_t num = 0) {
|
|||
mqtt_client.publish(mqtt_outtopic, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String(String("OK ") + String((char *)payload)).c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -855,12 +855,12 @@ void checkForRequests() {
|
|||
serializeJson(root, buffer, sizeof(buffer));
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
mqtt_client.publish(mqtt_ha_state_out.c_str(), buffer, true);
|
||||
DBG_OUTPUT_PORT.printf("MQTT: Send [%s]: %s\n", mqtt_ha_state_out.c_str(), buffer);
|
||||
mqtt_client.publish(mqtt_ha_state_out, buffer, true);
|
||||
DBG_OUTPUT_PORT.printf("MQTT: Send [%s]: %s\n", mqtt_ha_state_out, buffer);
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_ha_state_out.c_str(), 1, true, buffer);
|
||||
DBG_OUTPUT_PORT.printf("MQTT: Send [%s]: %s\n", mqtt_ha_state_out.c_str(), buffer);
|
||||
amqttClient.publish(mqtt_ha_state_out, 1, true, buffer);
|
||||
DBG_OUTPUT_PORT.printf("MQTT: Send [%s]: %s\n", mqtt_ha_state_out, buffer);
|
||||
#endif
|
||||
new_ha_mqtt_msg = false;
|
||||
ha_send_data.detach();
|
||||
|
@ -965,7 +965,7 @@ void checkForRequests() {
|
|||
DBG_OUTPUT_PORT.printf("MQTT: Message arrived [%s]\n", payload);
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
if (strcmp(topic, mqtt_ha_state_in.c_str()) == 0) {
|
||||
if (strcmp(topic, mqtt_ha_state_in) == 0) {
|
||||
if (!processJson((char*)payload)) {
|
||||
return;
|
||||
}
|
||||
|
@ -977,7 +977,7 @@ void checkForRequests() {
|
|||
} else if (strcmp(topic, (char *)mqtt_intopic) == 0) {
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
} else if (strcmp(topic, mqtt_intopic.c_str()) == 0) {
|
||||
} else if (strcmp(topic, mqtt_intopic) == 0) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -1007,7 +1007,7 @@ void checkForRequests() {
|
|||
mqtt_client.subscribe(mqtt_intopic, qossub);
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
ha_send_data.detach();
|
||||
mqtt_client.subscribe(mqtt_ha_state_in.c_str(), qossub);
|
||||
mqtt_client.subscribe(mqtt_ha_state_in, qossub);
|
||||
ha_send_data.once(5, tickerSendState);
|
||||
#ifdef MQTT_HOME_ASSISTANT_SUPPORT
|
||||
DynamicJsonDocument jsonBuffer(JSON_ARRAY_SIZE(strip->getModeCount()) + JSON_OBJECT_SIZE(12) + 1500);
|
||||
|
@ -1099,13 +1099,13 @@ void checkForRequests() {
|
|||
char * message = new char[18 + strlen(HOSTNAME) + 1];
|
||||
strcpy(message, "McLighting ready: ");
|
||||
strcat(message, HOSTNAME);
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, message);
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, message);
|
||||
//Subscribe
|
||||
uint16_t packetIdSub1 = amqttClient.subscribe((char *)mqtt_intopic.c_str(), qossub);
|
||||
uint16_t packetIdSub1 = amqttClient.subscribe((char *)mqtt_intopic, qossub);
|
||||
DBG_OUTPUT_PORT.printf("Subscribing at QoS %d, packetId: ", qossub); DBG_OUTPUT_PORT.println(packetIdSub1);
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
ha_send_data.detach();
|
||||
uint16_t packetIdSub2 = amqttClient.subscribe((char *)mqtt_ha_state_in.c_str(), qossub);
|
||||
uint16_t packetIdSub2 = amqttClient.subscribe((char *)mqtt_ha_state_in, qossub);
|
||||
DBG_OUTPUT_PORT.printf("Subscribing at QoS %d, packetId: ", qossub); DBG_OUTPUT_PORT.println(packetIdSub2);
|
||||
ha_send_data.once(5, tickerSendState);
|
||||
#ifdef MQTT_HOME_ASSISTANT_SUPPORT
|
||||
|
@ -1182,7 +1182,7 @@ void checkForRequests() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =static white").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =static white").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =static white").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -1198,7 +1198,7 @@ void checkForRequests() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =off").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =off").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =off").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = false;
|
||||
|
@ -1218,7 +1218,7 @@ void checkForRequests() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =fire flicker").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =fire flicker").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =fire flicker").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -1237,7 +1237,7 @@ void checkForRequests() {
|
|||
mqtt_client.publish(mqtt_outtopic, String("OK =fireworks random").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_AMQTT
|
||||
amqttClient.publish(mqtt_outtopic.c_str(), qospub, false, String("OK =fireworks random").c_str());
|
||||
amqttClient.publish(mqtt_outtopic, qospub, false, String("OK =fireworks random").c_str());
|
||||
#endif
|
||||
#ifdef ENABLE_HOMEASSISTANT
|
||||
stateOn = true;
|
||||
|
@ -1412,6 +1412,7 @@ bool readStateFS() {
|
|||
main_color.green = json["green"];
|
||||
main_color.blue = json["blue"];
|
||||
|
||||
if(mode != OFF) stateOn = true;
|
||||
strip->setMode(ws2812fx_mode);
|
||||
strip->setSpeed(convertSpeed(ws2812fx_speed));
|
||||
strip->setBrightness(brightness);
|
||||
|
@ -1441,10 +1442,12 @@ bool readStateFS() {
|
|||
#endif
|
||||
|
||||
//Strip Config
|
||||
char strip_size[3], led_pin[2]; //needed for WiFiManager Settings
|
||||
|
||||
struct
|
||||
{
|
||||
uint16_t stripSize = NUMLEDS;
|
||||
uint16_t RGBOrder = NEO_GRB;
|
||||
uint8_t RGBOrder = NEO_GRB;
|
||||
#if defined(USE_WS2812FX_DMA) or defined(USE_WS2812FX_UART1) or defined(USE_WS2812FX_UART2)
|
||||
#ifdef USE_WS2812FX_DMA
|
||||
uint8_t pin = 3;
|
||||
|
@ -1456,7 +1459,7 @@ struct
|
|||
uint8_t pin = 1;
|
||||
#endif
|
||||
#else
|
||||
uint8_t pin = PIN;
|
||||
uint8_t pin = LED_PIN;
|
||||
#endif
|
||||
} WS2812FXStripSettings;
|
||||
|
||||
|
@ -1504,7 +1507,7 @@ bool readStripConfigFS(void) {
|
|||
void writeStripConfigFS(void){
|
||||
updateFS = true;
|
||||
//save the strip config to FS JSON
|
||||
DBG_OUTPUT_PORT.print("Saving cfg: ");
|
||||
DBG_OUTPUT_PORT.print("Saving Strip cfg: ");
|
||||
DynamicJsonDocument jsonBuffer(JSON_OBJECT_SIZE(4)+300);
|
||||
JsonObject json = jsonBuffer.to<JsonObject>();
|
||||
json["pixel_pount"] = WS2812FXStripSettings.stripSize;
|
||||
|
@ -1519,6 +1522,7 @@ void writeStripConfigFS(void){
|
|||
}
|
||||
serializeJson(json, DBG_OUTPUT_PORT);
|
||||
serializeJson(json, configFile);
|
||||
DBG_OUTPUT_PORT.println();
|
||||
configFile.close();
|
||||
updateFS = false;
|
||||
//end save
|
||||
|
|
|
@ -74,4 +74,7 @@
|
|||
* - Bump PIO core to 2.0.1
|
||||
* - Send HA state on MQTT connect, address https://github.com/toblum/McLighting/issues/349
|
||||
* - Add LWT for MQTT and AMQTT, address https://github.com/toblum/McLighting/issues/340
|
||||
* - Added file for custom WS2812FX animations in custom slots
|
||||
* - Rename varaibles to be char instead of String
|
||||
* - Added LED pixel count and PIN settings to WiFiManager
|
||||
*/
|
||||
|
|
|
@ -8,7 +8,7 @@ description = The ESP8266 based multi-client lighting gadget
|
|||
# ------------------------------------------------------------------------------
|
||||
# PLATFORM:
|
||||
# !! DO NOT confuse platformio's ESP8266 development platform with Arduino core for ESP8266
|
||||
# We use Arduino Core 2.4.2 (platformIO 1.8.0) as default
|
||||
# We use Arduino Core 2.5.0 (platformIO 2.0.1) as default
|
||||
#
|
||||
# arduino core 2.3.0 = platformIO 1.5.0
|
||||
# arduino core 2.4.0 = platformIO 1.6.0
|
||||
|
@ -45,7 +45,10 @@ lib_deps =
|
|||
WebSockets
|
||||
ESPAsyncE131
|
||||
ESPAsyncUDP
|
||||
PubSubClient
|
||||
;PubSubClient ;neede for #define ENABLE_MQTT
|
||||
;FastLED ;needed for #define CUSTOM_WS2812FX_ANIMATIONS
|
||||
targets_eum = erase, upload, monitor
|
||||
targets_um = upload, monitor
|
||||
|
||||
[env:esp01_1m]
|
||||
board = esp01_1m
|
||||
|
@ -68,4 +71,5 @@ build_flags =
|
|||
monitor_speed = ${common.monitor_speed}
|
||||
upload_speed = ${common.upload_speed}
|
||||
upload_resetmethod = ${common.upload_resetmethod}
|
||||
lib_deps = ${common.lib_deps}
|
||||
lib_deps = ${common.lib_deps}
|
||||
; targets = ${common.targets_um}
|
Loading…
Add table
Reference in a new issue