/* * productionMode.cpp * * Created on: Apr 05, 2019 * Author: wn */ #include "defines.h" #define MQTT_MAX_PACKET_SIZE 256 #include #include #include #include #include // #include #include #ifdef WS2811 #define FASTLED_ESP8266_NODEMCU_PIN_ORDER #include #endif #ifdef PL9823 #include #endif #include "configuration.h" void callback(char* topic, byte* payload, unsigned int length); WiFiClientSecure espClient; PubSubClient client(espClient); #ifdef WS2811 CRGB leds[NUM_OF_LEDs]; #endif #ifdef PL9823 typedef struct { uint8_t r; uint8_t g; uint8_t b; } CRGB; Adafruit_NeoPixel pixels(NUM_OF_LEDs, PIXEL_PIN, NEO_RGB + NEO_KHZ400); #endif static CRGB evaluationColorWord(char* cmd) { uint8_t red = 0, green = 0, blue = 0; if ((! strcmp(cmd, "on")) || (! strcmp(cmd, "white"))) { red = 255; green = 255; blue = 255; } else if (! strcmp(cmd, "off")) { red = 0; green = 0; blue = 0; } else if (! strcmp(cmd, "red")) { red = 255; green = 0; blue = 0; } else if (! strcmp(cmd, "green")) { red = 0; green = 255; blue = 0; } else if (! strcmp(cmd, "blue")) { red = 0; green = 0; blue = 255; } else if (! strcmp(cmd, "purple")) { red = 255; green = 0; blue = 255; } else if (! strcmp(cmd, "yellow")) { red = 255; green = 255; blue = 0; } CRGB res; res.r = red; res.g = green; res.b = blue; return res; } void callback(char* topic, byte* payload, unsigned int length) { const uint8_t MAX_TOKENS = 5; const uint8_t BUFSIZE = 128; if ((length + 1) >= BUFSIZE) { // 1 for terminating NUL #ifdef DEBUG Serial.println("Received message too long, ignore it"); #endif } else { char buffer[BUFSIZE]; memcpy(buffer, payload, length); *(buffer + length) = 0; #ifdef DEBUG Serial.print("Received message: "); Serial.print(length); Serial.print(" "); Serial.print(topic); Serial.print(" "); Serial.println(buffer); #endif char *inbuf = buffer; char *tk = NULL; uint8_t tokenCnt = 0; char *tokens[MAX_TOKENS]; do { if (tokenCnt >= MAX_TOKENS) { break; } tk = strtok(inbuf, " "); inbuf = NULL; tokens[tokenCnt] = tk; if (tk) { tokenCnt++; #ifdef DEBUG Serial.print("TokenCnt: "); Serial.print(tokenCnt); Serial.println(); #endif } } while (tk); #ifdef DEBUG for (uint8_t i = 0; i < tokenCnt; i++) { Serial.print("Token "); Serial.print(i); Serial.print(": "); Serial.println(tokens[i]); } #endif if (! strcmp(topic, configBlock.mqttTopicCommand)) { int32_t n, b; CRGB pseudoColors; switch (tokenCnt) { case 1: // set brightness b = strtol(tokens[0], NULL, 10); for (uint8_t i = 0; i < NUM_OF_LEDs; i++) { #ifdef WS2811 leds[i].r = b; leds[i].g = b; leds[i].b = b; #endif #ifdef PL9823 pixels.setPixelColor(i, pixels.Color(b, b, b)); #endif } #ifdef WS2811 FastLED.show(); #endif #ifdef PL9823 pixels.show(); #endif break; case 2: // set brightness for one LED n = strtol(tokens[0], NULL, 10); b = strtol(tokens[1], NULL, 10); if (n >= 0 && n < NUM_OF_LEDs) { #ifdef WS2811 leds[n].r = b; leds[n].g = b; leds[n].b = b; FastLED.show(); #endif #ifdef PL9823 pixels.setPixelColor(n, pixels.Color(b, b, b)); pixels.show(); #endif } break; } } else if (! strcmp(topic, configBlock.mqttTopicColorCommand)) { int32_t n, red, green, blue; CRGB colors; switch (tokenCnt) { case 1: // on, off, color word for all LEDs colors = evaluationColorWord(tokens[0]); for (uint8_t i = 0; i < NUM_OF_LEDs; i++) { #ifdef WS2811 leds[i] = colors; #endif #ifdef PL9823 pixels.setPixelColor(i, pixels.Color(colors.r, colors.g, colors.b)); #endif } #ifdef WS2811 FastLED.show(); #endif #ifdef PL9823 pixels.show(); #endif break; case 2: // token0 = LED number, token1 = color n = strtol(tokens[0], NULL, 10); if (n >= 0 && n < NUM_OF_LEDs) { colors = evaluationColorWord(tokens[1]); #ifdef WS2811 leds[n] = colors; FastLED.show(); #endif #ifdef PL9823 pixels.setPixelColor(n, pixels.Color(colors.r, colors.g, colors.b)); pixels.show(); #endif } break; case 3: // token0 = red, token1 = green, token2 = blue red = strtol(tokens[0], NULL, 10); green = strtol(tokens[1], NULL, 10); blue = strtol(tokens[2], NULL, 10); for (uint8_t i = 0; i < NUM_OF_LEDs; i++) { #ifdef WS2811 leds[i].r = red; leds[i].g = green; leds[i].b = blue; #endif #ifdef PL9823 pixels.setPixelColor(i, pixels.Color(red, green, blue)); #endif } #ifdef WS2811 FastLED.show(); #endif #ifdef PL9823 pixels.show(); #endif break; case 4: // token0 = LED number, token1 = red, token2 = green, token3 = blue n = strtol(tokens[0], NULL, 10); if (n >= 0 && n < NUM_OF_LEDs) { red = strtol(tokens[1], NULL, 10); green = strtol(tokens[2], NULL, 10); blue = strtol(tokens[3], NULL, 10); #ifdef WS2811 leds[n].r = red; leds[n].g = green; leds[n].b = blue; FastLED.show(); #endif #ifdef PL9823 pixels.setPixelColor(n, pixels.Color(red, green, blue)); pixels.show(); #endif } break; } } } } void reconnect() { // Loop until we're reconnected while (!client.connected()) { #ifdef DEBUG Serial.print("Attempting MQTT connection..."); #endif // Attempt to connect //char clientId[128]; //snprintf(clientId, 127, "esp%s", WiFi.macAddress().c_str()); if (client.connect(configBlock.mqttClientId, configBlock.mqttUser, configBlock.mqttPass)) { #ifdef DEBUG Serial.println("connected"); #endif client.setCallback(callback); // Once connected, publish an announcement... client.publish(configBlock.mqttDebugTopic, "hello world"); client.publish(configBlock.mqttDebugTopic, WiFi.localIP().toString().c_str()); client.subscribe(configBlock.mqttTopicColorCommand); client.subscribe(configBlock.mqttTopicCommand); } else { #ifdef DEBUG Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); #endif // Wait 5 seconds before retrying delay(5000); } } } bool mqtt_connect() { bool reconnected = false; if (!client.connected()) { reconnect(); reconnected = true; } client.loop(); return reconnected; } void setupApplication() { client.setServer(configBlock.mqttBroker, configBlock.mqttPort); #ifdef WS2811 FastLED.addLeds(leds, NUM_OF_LEDs); #endif #ifdef PL9823 pixels.begin(); for (uint8_t i = 0; i < NUM_OF_LEDs; i++) { pixels.setPixelColor(i, pixels.Color(0,0,0)); } pixels.show(); #endif } void loopApplication() { bool reconnected = mqtt_connect(); static uint32_t reconnectTime = 0; if (reconnected) { reconnectTime = millis(); } }