Wemos D1 Mini - und WS2812 LEDs über MQTT über WLAN mit FHEM ansteuern

Begonnen von skydns, 26 Dezember 2017, 16:38:11

Vorheriges Thema - Nächstes Thema

skydns

Hallo,

ich möchte meine funktionierenden Codeschnipsel hier im Forum teilen, da ich zu fasziniert von der Technik bin und auch andere dran teilhaben lassen möchte. Gewachsen ist die Idee, da ich unser Vogelhaus beleuchten wollte. Es lässt sich jedoch noch besser für indirekte Beleuchtung im Innenraum anwenden.

Vorraussetzungen:
- Ein eingerichteter MQTT Broker, darauf möchte ich hier nicht genauer eingehen, dazu habe ich bereits hier etwas geschrieben:
https://forum.fhem.de/index.php/topic,35201.msg728636.html#msg728636
- WLAN
- Ein paar WS2812 LEDs (aus China 300 Stk. / 5m ca. 25€)
- Wemos D1 Mini (ca. 6€)
- Einfache Löt-Kenntnisse und allgemeine Kenntnisse, was man so für einfache Programmierung braucht.
- Kenntnisse, wie man Bibliotheken in Arduino IDE hinzufügt (bei mir fehlten ESP8266, MQTT und NEOPIXEL)
- Ardunio IDE https://www.arduino.cc/en/Main/Software
- Wemos Treiber https://wiki.wemos.cc/products:d1:d1_mini

Sobald die Verbindung zum Wemos D1 Mini hergestellt ist, kann man den folgenden Sketch anpassen und übertragen:

wemos.ino

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <MQTTClient.h>

const char* clientid = "VogelLED"; // MQTT-ClientID
const char* host = "192.168.10.4"; // MQTT-Broker
const char* ssid = "WLAN-NAME";
const char* password = "WLAN-PASSWORT";

unsigned long lastMillis = 0;

WiFiClient net;
MQTTClient client;

void connect();

// AB HIER NEOPIXEL
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

#define NEOPIN D3

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(10, NEOPIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

// --------------------------------
// LED Leiste
// --------------------------------
int Rainbow = 0;
int NEOcolor = 0;
int NEOoff = 1;

// Übermittelte Farbwerte
int LEDredValue = 50;
int LEDgreenValue = 50;
int LEDblueValue = 50;

// Gerade gesetzte Farbe
int LEDredCurrent = 0;
int LEDgreenCurrent = 0;
int LEDblueCurrent = 0;

// Timervariable für eine Verzögerung. Als alternative zu delay was die verarbeitung anhält.
int LEDtimer = 0;
int LEDendTimer = 50;


// =======================
void setup() {
// =======================

  Serial.begin(115200);
  Serial.println();
  Serial.println("Booting...");

  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);
//  WiFi.config(IPAddress(192,168,10,43), IPAddress(192,168,10,1), IPAddress(255,255,255,0), IPAddress(192,168,10,1));

// --------------------------------
// MQTT client
// --------------------------------

  client.begin(host, net);
  client.onMessage(messageReceived);

  connect();

  client.publish("/EG/Garten/VogelLED/RED", String(LEDredValue));
  client.publish("/EG/Garten/VogelLED/GREEN", String(LEDgreenValue));
  client.publish("/EG/Garten/VogelLED/BLUE", String(LEDblueValue));
  client.publish("/EG/Garten/VogelLED/NEOcolor", String(NEOcolor));
  client.publish("/EG/Garten/VogelLED/RAINBOW", String(Rainbow));
 
  Serial.println("Setup completed...");

  // AB HIER NEOPIXEL
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code


  strip.begin();
  strip.show(); // Initialize all pixels to 'off'


} // ENDE setup()

// =======================
void loop() {
// =======================

  client.loop();

  if (!client.connected()) {
    connect();
    delay(1000);
  }

// WATCHDOG
// publish a message roughly every 5 minutes.
if (millis() - lastMillis > 60000) {
  lastMillis = millis();
  client.publish("/EG/Garten/VogelLED/online", "online");
}

// --------------------------------
// LED Leiste
// --------------------------------

    if (String(Rainbow) == "1") {
    rainbow(20);
    delay(1000);
    }
    if (String(NEOcolor) == "1") {
    NEOPIXELcolor(strip.Color(LEDredValue, LEDgreenValue, LEDblueValue));
    delay(1000);
    }
    if (String(NEOoff) == "1") {
    NEOPIXELoff(0);
    delay(1000);
    }

// ======================
} // ENDE void loop()
// ======================

void connect() {
  while(WiFi.waitForConnectResult() != WL_CONNECTED) {
    WiFi.begin(ssid, password);
    Serial.println("WiFi connection failed. Retry.");
    delay(1000);
  }

  Serial.print("Wifi connection successful - IP-Address: ");
  Serial.println(WiFi.localIP());

  while (!client.connect(clientid, "try", "try")) {
    Serial.print(".");
    delay(1000);
  }

  Serial.println("MQTT connected!");

// Abonieren von Nachrichten mit den angegebenen Topics

client.subscribe("/EG/Garten/VogelLED/RGB");
client.subscribe("/EG/Garten/VogelLED/RED");
client.subscribe("/EG/Garten/VogelLED/GREEN");
client.subscribe("/EG/Garten/VogelLED/BLUE");
client.subscribe("/EG/Garten/VogelLED/NEOcolor");
client.subscribe("/EG/Garten/VogelLED/RAINBOW");

} // ENDE connect()


// ============================
// MQTT EMPFANG UND AUSWERTUNG
// ============================

void messageReceived(String &topic, String &payload) {
  Serial.println("incoming: " + topic + " - " + payload);

// Überprüfung des Topics und setzen der Farbe je nach übermittelten Topic
  if ((topic == "/EG/Garten/VogelLED/RGB") && (payload[0] == '#')) {            // we get single Color back
         uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16);
         LEDredValue = ((rgb >> 16) & 0xFF);
         LEDgreenValue = ((rgb >> 8) & 0xFF);
         LEDblueValue = ((rgb >> 0) & 0xFF);
  client.publish("/EG/Garten/VogelLED/RGBcolorpicker", String(&payload[1]));
  client.publish("/EG/Garten/VogelLED/RED", String(LEDredValue));
  client.publish("/EG/Garten/VogelLED/GREEN", String(LEDgreenValue));
  client.publish("/EG/Garten/VogelLED/BLUE", String(LEDblueValue));               
  }
if (topic == "/EG/Garten/VogelLED/RED") LEDredValue = round(payload.toInt());
if (topic == "/EG/Garten/VogelLED/GREEN") LEDgreenValue = round(payload.toInt());
if (topic == "/EG/Garten/VogelLED/BLUE") LEDblueValue = round(payload.toInt());
if ((topic == "/EG/Garten/VogelLED/RAINBOW") && (payload == "start")) {
  Rainbow = 1;
  NEOoff = 0;
  delay(0);
  }
  else if ((topic == "/EG/Garten/VogelLED/RAINBOW") && (payload == "stop")) {
  Rainbow = 0;
  NEOoff = 1;
  delay(0);
  }
if ((topic == "/EG/Garten/VogelLED/NEOcolor") && (payload == "start")) {
NEOcolor = 1;
NEOoff = 0;
delay(0);
}
else if ((topic == "/EG/Garten/VogelLED/NEOcolor") && (payload == "stop")) {
NEOcolor = 0;
NEOoff = 1;
delay(0);
}

} // ENDE MQTT messageReceived


// ========================
// AB HIER NEOPIXEL
// ========================

void NEOPIXELoff(uint8_t wait) {
  int i = 0;
  for(i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, 0, 0, 0);
    strip.show();
    delay(wait);
  }
}

void NEOPIXELcolor(uint32_t c) {
    for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    }
    yield();
}

void colorLED(uint32_t c) {
    strip.setPixelColor(0, c); // Nur LED 0
    strip.setPixelColor(3, c); // Nur LED 3
    strip.show();
    delay(5000);
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}


Wenn man es bis hier geschafft hat, ist der Rest eigentlich einfach. Es lassen sich so die Farben und LEDs über FHEM ansteuern, der entsprechende Eintrag in FHEM sieht bei mir so aus:


defmod Garten_VogelLED MQTT_DEVICE
attr Garten_VogelLED IODev Mosquitto
attr Garten_VogelLED publishSet_BLUE 0 50 127 255 /EG/Garten/VogelLED/BLUE
attr Garten_VogelLED publishSet_GREEN 0 50 127 255 /EG/Garten/VogelLED/GREEN
attr Garten_VogelLED publishSet_NEOcolor start stop /EG/Garten/VogelLED/NEOcolor
attr Garten_VogelLED publishSet_RAINBOW start stop /EG/Garten/VogelLED/RAINBOW
attr Garten_VogelLED publishSet_RED 0 50 127 255 /EG/Garten/VogelLED/RED
attr Garten_VogelLED publishSet_RGB /EG/Garten/VogelLED/RGB
attr Garten_VogelLED room Garten
attr Garten_VogelLED stateFormat LED Streifen: NEOcolor <BR> R: RED G: GREEN B: BLUE <BR>Regenbogen: RAINBOW
attr Garten_VogelLED subscribeReading_BLUE /EG/Garten/VogelLED/BLUE
attr Garten_VogelLED subscribeReading_GREEN /EG/Garten/VogelLED/GREEN
attr Garten_VogelLED subscribeReading_NEOcolor /EG/Garten/VogelLED/NEOcolor
attr Garten_VogelLED subscribeReading_RAINBOW /EG/Garten/VogelLED/RAINBOW
attr Garten_VogelLED subscribeReading_RED /EG/Garten/VogelLED/RED
attr Garten_VogelLED subscribeReading_RGBcolorpicker /EG/Garten/VogelLED/RGBcolorpicker
attr Garten_VogelLED subscribeReading_online /EG/Garten/VogelLED/online


Aktuell versuche ich noch den Colorpicker vom Tablet UI mit einzubinden, es funktioniert bereits, wenn man auf einem Android Smartphone "MQTT Dashboard" installiert hat und den MQTT Pfad /EG/Garten/VogelLED/RGB nutzt. Der MQTT Dashboard Colorpicker sendet den Farbcode mit #, der dahinter stehende Farbcode wird dann in die richtigen Farbwerte umgewandelt. Der Colorpicker vom Tablet UI sendet nur den Farbcode ohne #, somit werden die Farben nicht ausgewertet.

Ich würde mich freuen, wenn noch jemand den Code erweitert. Ich finde es genial, fürs Vogelhaus ist der Stromverbrauch leider zu hoch. Daher werde ich es wahrscheinlich für indirekte Beleuchtung verbauen. Sobald man ein 5V Netzteil hat (je nach Anzahl der LEDs mit entsprechend viel Leistung).

Technische Daten:
Der Strombedarf im Standby liegt bei nur 0,4W
10 LEDs im Betrieb ca. 1,5W
300 LEDs benötigen ca. 4-6A bei 5V (ca. 30W)
Die WS2812 arbeiten mit 5V nicht mit den sonst üblichen 12V!!!

Ich werde noch ein paar Screenshots anfügen. Das ganze passiert in Echtzeit, ich bin leider kein youtuber, sonst könnte ich das alles mal Filmen, habe jedoch nicht so viele Kameras.
Hier noch ein Video: https://youtu.be/9FczPpG5Q94

Viel Spaß damit, Marco


EDIT 27.12.17: Ich habe den wemos.ino Code noch mal überarbeitet, damit sind auch mehrere Wemos parallel im Einsatz möglich, vorher gab es Probleme da die ClientID immer gleich war, diese muss für jeden Wemos geändert werden, da der MQTT Broker sonst immer die Verbindung abbricht und neu herstellt. Da er eine Doppelverbindung vermutet.
NUC - CUL868Mhz V3 culfwV1.67 - nanoCUL 433MHz (nanoCUL) V 1.26.08 a-culfw - Zigbee - Ubuntu 22.04 - FHEM 6.1 zum Schalten von Licht+Steckdosen (Sonoff,Shelly,MQTT,433Mhz) und Überwachung von diversen Homematic/Homematic IP Kontakten/Sensoren mit Anwesenheitserkennung (G-TAGS)

skydns

Mit diesem Notify lässt sich auch der Colorpicker vom Tablet UI nutzen


Garten_VogelLED.RGB:.* {
my $ARGS = $EVTPART1;
fhem ("setreading $NAME RED".hex(substr($ARGS,0,2)));
fhem ("setreading $NAME GREEN".hex(substr($ARGS,2,2)));
fhem ("setreading $NAME BLUE".hex(substr($ARGS,4,2)));
fhem("setreading $NAME RGBcolorpicker $ARGS");
fhem("set Garten_VogelLED RGB #" . "$ARGS");
}


Die entsprechenden Zeilen im Tablet UI sehen bei mir so aus:


       <div class="top-space normal" data-type="colorwheel"
       data-device="Garten_VogelLED"
       data-get="RGBcolorpicker"
       data-set="RGB"
       class="roundIndicator"></div>
       <div data-type="switch"
       data-device="Garten_VogelLED"
       class="cell"
       data-get="NEOcolor"
       data-set="NEOcolor"
       data-get-on="start"
       data-get-off="stop">
       </div>
       <div class="" data-type="label">Vogelhaus</div>
NUC - CUL868Mhz V3 culfwV1.67 - nanoCUL 433MHz (nanoCUL) V 1.26.08 a-culfw - Zigbee - Ubuntu 22.04 - FHEM 6.1 zum Schalten von Licht+Steckdosen (Sonoff,Shelly,MQTT,433Mhz) und Überwachung von diversen Homematic/Homematic IP Kontakten/Sensoren mit Anwesenheitserkennung (G-TAGS)

skydns

Hier ist der Code verbessert:
-u.a. um den Akkubetrieb zu verlängern, dazu habe ich nun noch einen LDR bzw. eine Platine, die mir einen Digitalen Ausgang liefert hinzugefügt. Somit ist der Wemos nur im dunklen erreichbar
-Die wichtigen Änderungen im Quelltext kann man am Anfang über die Variablen machen
-Der Batteriestatus wird auch mit MQTT übermittelt, im dukeln alle 5 Minuten und im Deep Sleep alle 10 Minuten
-mehr Kommentare für besseres Verständnis


const char* topicpfad = "/EG/Garten/VogelLED/"; // Topicpfad (ohne Payload)
const char* clientid = "VogelLED"; // MQTT-ClientID
const char* host = "192.168.10.4"; // MQTT-Broker
const char* ssid = "wifiname"; // WiFi SSID
const char* password = "wifipasswort"; // WiFi Passwort

unsigned long lastMillis = 0; // für Watchdog

// WiFi
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
WiFiClient net;

// MQTT
#include <MQTTClient.h>
MQTTClient client;

void connect();

// Batteriemessung
#define BATTERIE A0

// Licht Sensor und Deep Sleep
#define LICHTPIN D1
#define POWERLICHTPIN D2

// NEOPIXEL
#include <Adafruit_NeoPixel.h>
#define NEOPIN D3

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(10, NEOPIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

// --------------------------------
// LED WS2812B
// --------------------------------
int Rainbow = 0;
int NEOcolor = 0;
int NEOoff = 1;

// Voreingestellte LED-Farbwerte
int LEDredValue = 50;
int LEDgreenValue = 50;
int LEDblueValue = 50;


// =======================
void setup() {
// =======================

  Serial.begin(115200);
  Serial.println();
  Serial.println("Starte Setup...");

  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);
  //  WiFi.config(IPAddress(192,168,10,43), IPAddress(192,168,10,1), IPAddress(255,255,255,0), IPAddress(192,168,10,1)); // Statische Netzwerkadresse

  // --------------------------------
  // MQTT client
  // --------------------------------

  client.begin(host, net);
  client.onMessage(messageReceived);

  connect();

  client.publish(String(topicpfad) + "online", "online");
  client.publish(String(topicpfad) + "ResetReason", ESP.getResetReason());
  client.publish(String(topicpfad) + "NEOcolor", String(NEOcolor));
  client.publish(String(topicpfad) + "RAINBOW", String(Rainbow));

  // AB HIER NEOPIXEL
  strip.begin();
  strip.show(); // Schalte alle LED-Pixel "AUS"

  // Batterie Messung
  pinMode(BATTERIE, INPUT);
  Batterie_Messung();
  delay(1000);
  Serial.println("Setup erfolgreich...");

  // Licht Messung und Deep Sleep
  pinMode(LICHTPIN, INPUT);
  pinMode(POWERLICHTPIN, OUTPUT);
  Licht_Messung();

} // ENDE setup()

// =======================
void loop() {
// =======================
  Licht_Messung();
  delay(1000);
 
  client.loop();

  if (!client.connected()) {
    connect();
    delay(1000);
  }

  // WATCHDOG
  // Sendet alle 5 Minuten einen Status.
  if (millis() - lastMillis > 300000) {
    lastMillis = millis();
    client.publish((String(topicpfad) + "online"), "online");
    Batterie_Messung();
  }

  // --------------------------------
  // LED WS2812B
  // --------------------------------

  if (Rainbow == 1) {
    rainbow(20);
    delay(1000);
  }
  if (NEOcolor == 1) {
    NEOPIXELcolor(strip.Color(LEDredValue, LEDgreenValue, LEDblueValue));
    delay(1000);
  }
  if (NEOoff == 1) {
    NEOPIXELoff(0);
    delay(1000);
  }

  // ======================
} // ENDE void loop()
// ======================

void connect() {
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    WiFi.begin(ssid, password);
    Serial.println("WiFi Verbindung Fehlgeschlagen. Verbinde erneut...");
    delay(1000);
  }

  Serial.print("Wifi Verbindung herrgestellt - IP-Addresse: ");
  Serial.println(WiFi.localIP());

// ClientID / Benutzername / Passwort
  while (!client.connect(clientid, "try", "try")) {
    Serial.print(".");
    delay(1000);
  }

  Serial.println("MQTT verbunden!");

// Abonieren von Nachrichten mit den angegebenen Topics
  client.subscribe(String(topicpfad) + "RGB");
  client.subscribe(String(topicpfad) + "RED");
  client.subscribe(String(topicpfad) + "GREEN");
  client.subscribe(String(topicpfad) + "BLUE");
  client.subscribe(String(topicpfad) + "NEOcolor");
  client.subscribe(String(topicpfad) + "RAINBOW");

} // ENDE connect()


// ============================
// BATTERIE MESSUNG
// ============================

void Batterie_Messung() {
  // 130kOhm werden für einen Messbereich bis 4,5V benötigt und die Formel muss 4.5/1024*A0 sein
  float Batteriespannung = analogRead(BATTERIE);
  Batteriespannung = 3.2 / 1024 * Batteriespannung; //3.2 ist ohne Widerstand
  Serial.print("Batteriespannung: ");
  Serial.print(Batteriespannung);
  Serial.println(" V");

  client.publish((String(topicpfad) + "Battery"), String(Batteriespannung));
}

// ============================
// LICHT MESSUNG und DEEP SLEEP
// ============================

void Licht_Messung() {
  digitalWrite(POWERLICHTPIN, HIGH);
  delay(10);
  int Lichtsensor = digitalRead(D1);
  Serial.print("Lichtsensor: ");
  Serial.print(Lichtsensor);
  Serial.println();

  digitalWrite(POWERLICHTPIN, LOW);

  // Lichtsensor 1 bei Dunkelheit
  if (Lichtsensor == 1) {
    Serial.println("Es ist dunkel, der Wemos bleib an...");
  }
  else if ((Lichtsensor == 0) && (Rainbow == 0) && (NEOcolor == 0)) {
    // Lichtsensor 0 bei Helligkeit
    // DEEP SLEEP für 10 Minuten
    // Brücke zwischen D0 und RST nicht vergessen
    client.disconnect(); // MQTT Verbindung trennen
    WiFi.disconnect(); // WiFi Verbindung trennen
    Serial.println("Es ist zu hell, beginne DEEP SLEEP für 10 Minuten um Strom zu sparen. Bis gleich...");
    delay(10);
    ESP.deepSleep(600e6); // 20e6 sind 20 Sekunden 600e6 = 10 Minuten
  }
}

// ============================
// MQTT EMPFANG UND AUSWERTUNG
// ============================

void messageReceived(String &topic, String &payload) {
  Serial.println("empfange: " + topic + " - " + payload);

  // Überprüfung des Topics und setzen der Farbe je nach übermittelten Topic
  if ((topic == (String(topicpfad) + "RGB")) && (payload[0] == '#')) {            // Empfange Farbwert mit # Bsp: #FFFFFF wird in R + G + B aufgelöst
    uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16);
    LEDredValue = ((rgb >> 16) & 0xFF);
    LEDgreenValue = ((rgb >> 8) & 0xFF);
    LEDblueValue = ((rgb >> 0) & 0xFF);
    client.publish(String(topicpfad) + "RGBcolorpicker", String(&payload[1]));
    client.publish(String(topicpfad) + "RED", String(LEDredValue));
    client.publish(String(topicpfad) + "GREEN", String(LEDgreenValue));
    client.publish(String(topicpfad) + "BLUE", String(LEDblueValue));
  }
  if (topic == String(topicpfad) + "RED") LEDredValue = round(payload.toInt());
  if (topic == String(topicpfad) + "GREEN") LEDgreenValue = round(payload.toInt());
  if (topic == String(topicpfad) + "BLUE") LEDblueValue = round(payload.toInt());
  if ((topic == String(topicpfad) + "RAINBOW") && (payload == "start")) {
    Rainbow = 1;
    NEOoff = 0;
    delay(0);
  }
  else if ((topic == String(topicpfad) + "RAINBOW") && (payload == "stop")) {
    Rainbow = 0;
    NEOoff = 1;
    delay(0);
  }
  if ((topic == String(topicpfad) + "NEOcolor") && (payload == "start")) {
    NEOcolor = 1;
    NEOoff = 0;
    delay(0);
  }
  else if ((topic == String(topicpfad) + "NEOcolor") && (payload == "stop")) {
    NEOcolor = 0;
    NEOoff = 1;
    delay(0);
  }

} // ENDE MQTT messageReceived


// ========================
// NEOPIXEL
// ========================

void NEOPIXELoff(uint8_t wait) {
  int i = 0;
  for (i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, 0, 0, 0);
    strip.show();
    delay(wait);
  }
}

void NEOPIXELcolor(uint32_t c) {
  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
  }
  yield();
}

void colorLED(uint32_t c) {
  strip.setPixelColor(0, c); // Nur LED 0
  strip.setPixelColor(3, c); // Nur LED 3
  strip.show();
  delay(5000);
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}


Im FHEM sieht es dazu so aus:

define Garten_VogelLED MQTT_DEVICE
attr Garten_VogelLED IODev Mosquitto
attr Garten_VogelLED alias Vogelhaus
attr Garten_VogelLED publishSet_BLUE 0 50 127 255 /EG/Garten/VogelLED/BLUE
attr Garten_VogelLED publishSet_GREEN 0 50 127 255 /EG/Garten/VogelLED/GREEN
attr Garten_VogelLED publishSet_NEOcolor start stop /EG/Garten/VogelLED/NEOcolor
attr Garten_VogelLED publishSet_RAINBOW start stop /EG/Garten/VogelLED/RAINBOW
attr Garten_VogelLED publishSet_RED 0 50 127 255 /EG/Garten/VogelLED/RED
attr Garten_VogelLED publishSet_RGB /EG/Garten/VogelLED/RGB
attr Garten_VogelLED room Garten
attr Garten_VogelLED stateFormat LED Streifen: NEOcolor <BR>Regenbogen: RAINBOW <BR> Batterie: Battery V
attr Garten_VogelLED subscribeReading_BLUE /EG/Garten/VogelLED/BLUE
attr Garten_VogelLED subscribeReading_Battery /EG/Garten/VogelLED/Battery
attr Garten_VogelLED subscribeReading_GREEN /EG/Garten/VogelLED/GREEN
attr Garten_VogelLED subscribeReading_NEOcolor /EG/Garten/VogelLED/NEOcolor
attr Garten_VogelLED subscribeReading_RAINBOW /EG/Garten/VogelLED/RAINBOW
attr Garten_VogelLED subscribeReading_RED /EG/Garten/VogelLED/RED
attr Garten_VogelLED subscribeReading_RGBcolorpicker /EG/Garten/VogelLED/RGBcolorpicker
attr Garten_VogelLED subscribeReading_ResetReason /EG/Garten/VogelLED/ResetReason
attr Garten_VogelLED subscribeReading_online /EG/Garten/VogelLED/online


Notify um über den Colorpicker vom FTUI oder Nodered die Farbe einzustellen:

define n_VogelLED_FTUIcolorpicker notify Garten_VogelLED.RGB:.* { \
my $ARGS = $EVTPART1;;\
fhem ("setreading $NAME RED ".hex(substr($ARGS,0,2)));;\
fhem ("setreading $NAME GREEN ".hex(substr($ARGS,2,2)));;\
fhem ("setreading $NAME BLUE ".hex(substr($ARGS,4,2)));;\
fhem("setreading $NAME RGBcolorpicker $ARGS");;\
fhem("set Garten_VogelLED RGB #" . "$ARGS");;\
}\
attr n_VogelLED_FTUIcolorpicker room Garten


Notify um um die LEDs zu aktivieren:

define n_VogelLED notify Kontakt_04.contact:.* {\
if($EVTPART1 eq "geöffnet") {\
fhem("set Garten_VogelLED NEOcolor start");;\
fhem("define at_VogelLED at +00:07:00 set Garten_VogelLED NEOcolor stop")\
}\
}
attr n_VogelLED room Garten


Notify um nach dem Reset den letzten Farbcode wiederherzustellen:

define n_VogelLED_Reset notify Garten_VogelLED:ResetReason:.* {\
my $RGBcolorpicker = ReadingsVal("Garten_VogelLED", "RGBcolorpicker", "7f0000");;\
fhem("sleep 1;; set Garten_VogelLED RGB $RGBcolorpicker");;\
}
attr n_VogelLED_Reset room Garten


Viel Spaß damit
Marco
NUC - CUL868Mhz V3 culfwV1.67 - nanoCUL 433MHz (nanoCUL) V 1.26.08 a-culfw - Zigbee - Ubuntu 22.04 - FHEM 6.1 zum Schalten von Licht+Steckdosen (Sonoff,Shelly,MQTT,433Mhz) und Überwachung von diversen Homematic/Homematic IP Kontakten/Sensoren mit Anwesenheitserkennung (G-TAGS)