Skip to main content

Plan voor Home Assistant Lux sensor via MQTT

To modify the provided Arduino code for the ESP8266 Witty Cloud ESP-12F to allow switching the onboard RGB LED on and off via MQTT (while retaining the light sensor functionality), we need to:


1. **Control the RGB LED**:

- The Witty Cloud has an onboard RGB LED with pins:

- Red: GPIO 15

- Green: GPIO 12

- Blue: GPIO 13

- These LEDs are active-low (writing `LOW` turns them on, `HIGH` turns them off).

2. **Add MQTT Subscription**:

- Subscribe to an MQTT topic (e.g., `heldenhome/switch/esp8266_rgbled/set`) to receive commands (`ON` or `OFF`) from Home Assistant.

3. **Update Home Assistant Configuration**:

- Add a manual MQTT switch entity in `configuration.yaml` to control the RGB LED.

4. **Retain Light Sensor Functionality**:

- Keep the existing LDR sensor code to publish light intensity every 5 seconds.


Below is the updated Arduino code that adds RGB LED control via MQTT, along with a plan to integrate it with Home Assistant.


### Plan for RGB LED Control

1. **Modify Arduino Code**:

- Define pins for the RGB LED.

- Add an MQTT subscription to a topic for LED control.

- Implement a callback function to process `ON`/`OFF` commands.

- Turn all RGB LED pins on/off together for simplicity (treating it as a single white LED).

2. **Update Home Assistant**:

- Add an MQTT switch entity in `configuration.yaml` to control the LED.

3. **Test**:

- Verify LED control via Home Assistant and ensure light sensor data continues to work.


### Updated Arduino Code

The code below extends the original code to include RGB LED control. It subscribes to `heldenhome/switch/esp8266_rgbled/set` for `ON`/`OFF` commands and controls the RGB LED pins accordingly.


```x-arduino

#include <ESP8266WiFi.h>

#include <PubSubClient.h>

#include <ArduinoJson.h>


// WiFi en MQTT instellingen

const char* ssid = "ORBI09";

const char* password = "heldeninit";

const char* mqtt_server = "192.168.15.254";

const char* mqtt_user = "MQTTBroker";

const char* mqtt_password = "Helden#123";

const char* mqtt_client_id = "ESP8266_LightSensor";

const char* discovery_prefix = "heldenhome";


// MQTT topics

const char* light_state_topic = "heldenhome/sensor/esp8266_lightsensor/state";

const char* light_config_topic = "heldenhome/sensor/esp8266_lightsensor/config";

const char* led_command_topic = "heldenhome/switch/esp8266_rgbled/set";

const char* led_state_topic = "heldenhome/switch/esp8266_rgbled/state";


// LDR pin

#define LDR_PIN A0


// RGB LED pins (active-low)

#define LED_RED 15

#define LED_GREEN 12

#define LED_BLUE 13


// WiFi en MQTT clients

WiFiClient espClient;

PubSubClient client(espClient);


// Tijdbeheer

unsigned long lastMsg = 0;

const long interval = 5000; // 5 seconden interval


void setup_wifi() {

delay(10);

Serial.println("Verbinden met WiFi...");

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

}

Serial.println("");

Serial.println("WiFi verbonden");

Serial.println("IP adres: ");

Serial.println(WiFi.localIP());

}


void publish_discovery() {

// Maak een JSON object voor de lichtsensor discovery configuratie

StaticJsonDocument<512> config;

config["name"] = "ESP8266 Lichtsensor";

config["device_class"] = "illuminance";

config["unit_of_measurement"] = "lx";

config["state_topic"] = light_state_topic;

config["value_template"] = "{{ value_json.lux }}";

config["unique_id"] = "esp8266_lightsensor";

config["device"]["identifiers"] = "esp8266_lightsensor";

config["device"]["name"] = "ESP8266 Lichtsensor";

config["device"]["model"] = "Witty Cloud ESP-12F";

config["device"]["manufacturer"] = "Gizwits";


char buffer[512];

serializeJson(config, buffer);

client.publish(light_config_topic, buffer, true);

Serial.println("Lichtsensor discovery bericht verzonden");

}


void callback(char* topic, byte* payload, unsigned int length) {

// Verwerk inkomende MQTT berichten

String message;

for (unsigned int i = 0; i < length; i++) {

message += (char)payload[i];

}

Serial.print("Bericht ontvangen op topic [");

Serial.print(topic);

Serial.print("]: ");

Serial.println(message);


// Controleer of het bericht voor de LED is

if (String(topic) == led_command_topic) {

if (message == "ON") {

digitalWrite(LED_RED, LOW); // Active-low: LOW = aan

digitalWrite(LED_GREEN, LOW);

digitalWrite(LED_BLUE, LOW);

client.publish(led_state_topic, "ON", true);

Serial.println("RGB LED aangezet");

} else if (message == "OFF") {

digitalWrite(LED_RED, HIGH); // Active-low: HIGH = uit

digitalWrite(LED_GREEN, HIGH);

digitalWrite(LED_BLUE, HIGH);

client.publish(led_state_topic, "OFF", true);

Serial.println("RGB LED uitgezet");

}

}

}


void reconnect() {

while (!client.connected()) {

Serial.print("Verbinden met MQTT...");

if (client.connect(mqtt_client_id, mqtt_user, mqtt_password)) {

Serial.println("verbonden");

// Publiceer discovery bericht

publish_discovery();

// Abonneer op LED commando topic

client.subscribe(led_command_topic);

Serial.println("Geabonneerd op LED commando topic");

} else {

Serial.print("mislukt, rc=");

Serial.print(client.state());

Serial.println(" probeer opnieuw in 5 seconden");

delay(5000);

}

}

}


void setup() {

Serial.begin(115200);

// Initialiseer RGB LED pins

pinMode(LED_RED, OUTPUT);

pinMode(LED_GREEN, OUTPUT);

pinMode(LED_BLUE, OUTPUT);

// Zet LED uit bij opstarten

digitalWrite(LED_RED, HIGH);

digitalWrite(LED_GREEN, HIGH);

digitalWrite(LED_BLUE, HIGH);


setup_wifi();

client.setServer(mqtt_server, 1883);

client.setCallback(callback);

}


void loop() {

if (!client.connected()) {

reconnect();

}

client.loop();


unsigned long now = millis();

if (now - lastMsg > interval) {

lastMsg = now;


// Lees LDR waarde

int ldr_value = analogRead(LDR_PIN);

// Converteer naar een geschatte lux waarde

float lux = map(ldr_value, 0, 1023, 0, 1000);


// Maak JSON payload

StaticJsonDocument<200> doc;

doc["lux"] = lux;

char buffer[200];

serializeJson(doc, buffer);


// Publiceer de lichtsterkte

client.publish(light_state_topic, buffer, true);

Serial.print("Lichtsterkte gepubliceerd: ");

Serial.println(buffer);

}

}

```


### Changes Made to the Code

1. **Added RGB LED Pins**:

- Defined `LED_RED` (15), `LED_GREEN` (12), and `LED_BLUE` (13).

- Initialized as outputs in `setup()` and set to `HIGH` (off) at startup.

2. **Added MQTT Topics for LED**:

- `led_command_topic`: `heldenhome/switch/esp8266_rgbled/set` for receiving `ON`/`OFF` commands.

- `led_state_topic`: `heldenhome/switch/esp8266_rgbled/state` to publish the LED state.

3. **Added MQTT Callback**:

- Implemented `callback()` to process messages on `led_command_topic`.

- Turns all RGB LED pins on (`LOW`) or off (`HIGH`) based on `ON`/`OFF` commands.

- Publishes the LED state to `led_state_topic` for Home Assistant feedback.

4. **Subscribed to LED Topic**:

- Added `client.subscribe(led_command_topic)` in `reconnect()`.

5. **Kept Light Sensor Functionality**:

- The LDR reading and publishing to `heldenhome/sensor/esp8266_lightsensor/state` remain unchanged.


### Home Assistant Configuration

Since MQTT Discovery didn’t work previously, add the LED as a manual MQTT switch in `configuration.yaml` to match the manual sensor configuration. Update your `configuration.yaml` as follows:


```yaml

mqtt:

sensor:

- name: "ESP8266 Lichtsensor"

state_topic: "heldenhome/sensor/esp8266_lightsensor/state"

value_template: "{{ value_json.lux }}"

unit_of_measurement: "lx"

device_class: "illuminance"

unique_id: "esp8266_lightsensor"

switch:

- name: "ESP8266 RGB LED"

command_topic: "heldenhome/switch/esp8266_rgbled/set"

state_topic: "heldenhome/switch/esp8266_rgbled/state"

state_on: "ON"

state_off: "OFF"

payload_on: "ON"

payload_off: "OFF"

unique_id: "esp8266_rgbled"

```


- **Save** the file and **restart Home Assistant** (**Settings** > **System** > **Restart**).

- The switch will appear as `switch.esp8266_rgb_led` in Home Assistant.


### Setup and Testing

1. **Upload the Code**:

- Copy the updated code into Arduino IDE.

- Select the board (**NodeMCU 1.0 (ESP-12E Module)**) and port.

- Upload and open the Serial Monitor (115200 baud) to verify:

- WiFi connection (“WiFi verbonden”).

- MQTT connection (“Verbinden met MQTT…verbonden”).

- Subscription to LED topic (“Geabonneerd op LED commando topic”).

- Light intensity publishing (“Lichtsterkte gepubliceerd”).

2. **Test the LED**:

- In Home Assistant, go to **Settings** > **Devices & Services** > **Entities**.

- Find `switch.esp8266_rgb_led` and toggle it.

- The RGB LED should turn on (white light, as all colors are activated) or off.

- Check the Serial Monitor for messages like “RGB LED aangezet” or “RGB LED uitgezet”.

3. **Verify Light Sensor**:

- Ensure `sensor.esp8266_lichtsensor` still updates with lux values every 5 seconds.

4. **Test with MQTT Explorer** (optional):

- Publish `ON` or `OFF` to `heldenhome/switch/esp8266_rgbled/set`:

```bash

mosquitto_pub -h 192.168.15.254 -u MQTTBroker -P Helden#123 -t "heldenhome/switch/esp8266_rgbled/set" -m "ON"

```

- Verify the LED state and `heldenhome/switch/esp8266_rgbled/state` updates.


### Troubleshooting

- **LED Doesn’t Respond**:

- Check Serial Monitor for callback messages when toggling the switch.

- Ensure `led_command_topic` matches in the code and Home Assistant.

- Verify the MQTT broker is accessible and credentials are correct.

- **Sensor Stops Working**:

- Confirm the `light_state_topic` payload is still `{"lux": <value>}`.

- Check for MQTT connection errors in Serial Monitor (e.g., “rc=-2”).

- **Entity Not Found**:

- Verify `configuration.yaml` syntax (**Developer Tools** > **Check Configuration**).

- Ensure `unique_id` values (`esp8266_lightsensor`, `esp8266_rgbled`) are unique.

- Restart Home Assistant after configuration changes.


### Notes

- The RGB LED is treated as a single switch (all colors on/off together). To control individual colors, additional topics and logic can be added.

- If you want to revisit MQTT Discovery for the LED, add a discovery message in `publish_discovery()` similar to the sensor, but this requires troubleshooting why discovery failed previously.


Let me know if you need further modifications, like individual RGB color control or deep sleep integration!