/*  Function: RGB LED lässt sich mit MQTT-Dashbord steuern:
              Subsribed wird auf Topic: BuM/Wokwitest/LED
              Die blaue und die grüne LEDs werden mit folgenden Payloads geschaltet:
              b_ein, b_aus, g_ein, g_aus
              Die rote LED reagiert mit PWM auf Zahlen zwischen 0...255
              Published wird ein aufsteigender Zahlenwert auf Topic: BuM/Wokwitest/pub
              Getestet wurde mit MQTT-Explorer
    Broker:   test.mosquitto.org oder broker.hivemq.com auf  PORT: 1883 
    Autor:    M.Busch, 3/2024
    Library:  PubSubClient.h einbinden mit Library Manager
    
*/

#include <PubSubClient.h>
#include <WiFi.h>

const char *WIFI_SSID = "Wokwi-GUEST";
const char *WIFI_PWD = "";
const char *MQTT_SERVER = "test.mosquitto.org";
const uint16_t MQTT_PORT = 1883;

char cstr[16];

WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);

#define LEDr 32     //rote  LED innerhalb der RGB_LED
#define LEDg 25     //grüne LED innerhalb der RGB_LED
#define LEDb 27     //blaue LED innerhalb der RGB_LED

uint8_t tx_data = 0;  //Sendedaten, exemplarisch aufsteigend

void setup() 
{
  Serial.begin(115200);
  pinMode(LEDr, OUTPUT);
  pinMode(LEDb, OUTPUT);
  pinMode(LEDg, OUTPUT);
  
  ConnectToWiFi();
  SetupMqtt();

  Serial.println("Ende Setup");
}

void loop() 
{
  static uint64_t last_time;
  uint64_t now = millis();
  if (now - last_time > 1000)
  {
    if (!mqttClient.connected())
    {
      ConnectToMqtt();
    }
    mqttClient.loop();

    // Publish and print the values.
    String str = String(tx_data);
    str.toCharArray(cstr,16);
    mqttClient.publish("BuM/Wokwitest/pub", cstr );  //cstr = Character-Array
    tx_data++;
    
    Serial.print("-");
    last_time = now;
  }
}

void CallbackMqtt(char* topic, byte* payload, unsigned int length)
{
  String myPayload;
  int intPayload = 0;
  uint8_t rotwert, zahl = 0;;
  Serial.print("Callback - ");
  Serial.print("Message:");
  for (int i = 0; i < length; i++)
  {
    Serial.print((char)payload[i]);
    //CharArray in String umwandeln:
    myPayload = myPayload + (char)payload[i]; 
    if(payload[i] > 47 && payload[i] < 58) zahl++; //Erkennen ob eine Zahl empfangen wurde
  }
  if(zahl == length)
  {
     intPayload = myPayload.toInt();
     rotwert = intPayload;
     analogWrite(LEDr, rotwert);
  }
  Serial.println(intPayload);
  Serial.println(myPayload);

  //Auswertung des erhaltenen Payloads; dieser wurde zuvor in einen String gewandelt:
  if(myPayload.equals("g_ein")==true) digitalWrite(LEDg, HIGH);
  if(myPayload.equals("g_aus")==true) digitalWrite(LEDg, LOW);
  if(myPayload.equals("b_ein")==true) digitalWrite(LEDb, HIGH);
  if(myPayload.equals("b_aus")==true) digitalWrite(LEDb, LOW);

  Serial.println();
}

void SetupMqtt()
{
  mqttClient.setServer(MQTT_SERVER, MQTT_PORT);
  // set the callback function
  mqttClient.setCallback(CallbackMqtt);
}


void ConnectToMqtt()
{
  Serial.println("Connecting to MQTT Broker...");
  while (!mqttClient.connected())
  {
    char clientId[100] = "\0";
    sprintf(clientId, "ESP32Client-BuM", random(0xffff));
    Serial.println(clientId);

    if (mqttClient.connect(clientId))
    {
      Serial.println("Connected to MQTT broker.");
      // subscribe to topic
      mqttClient.subscribe("BuM/Wokwitest/LED");
    }
  }
}

void ConnectToWiFi()
{
  Serial.print("Connecting to WiFi ");
  Serial.println(WIFI_SSID);

  WiFi.begin(WIFI_SSID, WIFI_PWD, 6);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(500);
  }
  Serial.print("\nConnected to ");
  Serial.println(WIFI_SSID);
}