Automated dimming light by TV status in kitchen

Hello all,

I’d like to share one of the idea, which can do our lives happier. At the end of year 2019 there was a project in my house to build a brand-new kitchen. Everything went well, my wife is satisfied and now I can think about some improvements here.

Once I had a coffee time with my wife, we enjoyed that time a lot, but there was one disturbing element which we found that time. When we sit at the table and looking on the TV, which is placed on the wall, the light from chandelier causing light pollution and it’s not really very comfortable. In other words, my eyes are focusing on the light so much and I must squint them. Ok, there is no way to replace light because of kitchen design and happy marriage, so then some skills and automation must come.

But how to achieve that? Let’s have look what possibilities are in the place. The TV is quite old LG “smart” with WebOS v2 – so nothing too much smart and quick. For turning on the TV from OpenHAB I’m using ESP8266 Arduino with IR LED here already. (no way to turn the TV by LAN because when TV is off, also network adapter is off and serial interface is not working here due to inexplicable reason). In addition to the already functional solution of OpenHAB and some Loxone hardware there was an unused Finder dimming module. Hurray, the idea climbs up.

Main idea:

1, Use dimmer for chandelier. Dimmer has native fade in and fade out function and I have a plus points here, because this effect is very nice. Also, this dimmer can be switched to dim classical bulbs (used now, because I like that warm light) or LEDs. The relay is Finder 15.11.8.230.0400 and it can be controlled with 0-10V from Loxone 0-10V analog output.

2, In normal use, the light always goes to 100% when turned on. In special cases I can use dimmer from OH or dim +/- from wall switch (Loxone one button dimming feature).

3, When the light is on and TV is off, no change there. When the TV is turned on, light will dim to 60% and goes up to 100% when the TV goes off. But in the meantime, someone turns off the light when watching the TV, no change for the light will be there after turning the TV off.

Trigger for OH when the TV is ON or OFF.

As seen from picture, there are 3 USB ports on the TV.

I realize to use 5V out as a trigger. Documentation says, that ESP8266 has 5V intolerant input and I have to create simple level converter. The wiring connection is easy. Someone tested that 5V is OK, but who know, how long …

5V converter

Wiring in real life, I know that I will not win a prize for design :blush:

From USB and Arduino to Loxone and OH

When ESP8266 detects signal on input, it sends a UDP message to Loxone miniserver. The message is “IRblaster01 1 1” for ON and “IRblaster01 1 0” for OFF. Syntax:

<ESPNAME><DIGITAL INPUT NUMBER><STATUS>.

I use Loxone for parsing UDP messages and transofrm it to switch status, which is connected to OH by Loxone binding. Yes, this can be done by OH, but in this case it’s prepared for some Loxone ideas in future.

UDP message:


Loxone config:

Arduino source code:

At first I didn’t even want to share the code, but then I wondered why not. In this code is also IR solution for remoting the TV (but it’s another story). So shame on me because of the code, but that’s the life, I’m not experienced programmer, only scripting guy.

// libraries
#include <ESP8266WiFi.h>        
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>

const uint16_t kIrLed = 14;  // IR LED GPIO pin to use (D5).
IRsend irsend(kIrLed);  // Set the GPIO to be used to sending the message.

const char* ssid     = "WIFI SID";         // The SSID (name) of the Wi-Fi network you want to connect to
const char* password = "WIFI PASSWORD";     // The password of the Wi-Fi network
//
WiFiClient espClient;
PubSubClient client(espClient);

void setup()
{
  //set clkPin,dePin,swPin as INPUT
      pinMode(kIrLed, OUTPUT);    // LED pin as output.
  //serial out
      //Serial.begin(115200); 
  //Wifi
      WiFi.begin(ssid, password);  
      WiFi.mode(WIFI_STA);           
      //Serial.print("Connecting to ");
      //Serial.print(ssid); //Serial.println(" ...");
      int i = 0;
      while (WiFi.status() != WL_CONNECTED) 
        { // Wait for the Wi-Fi to connect
          delay(1000);
          //Serial.print(++i); //Serial.print(' ');
        }
      //Serial.println('\n');
      //Serial.println("Connection established!");  
     // Serial.print("IP address:\t");
     // Serial.println(WiFi.localIP());        
  //Wifi end

  //mosquito
      client.setServer(mqtt_server, 1883);
      client.setCallback(callback);
  //mosquito end
}

void loop()
{
  //mosquito
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  //mosquito end
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    //Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    // If you do not want to use a username and password, change next line to
    // if (client.connect("ESP8266Client")) {
    if (client.connect("ESP8266Client_3", mqtt_user, mqtt_password)) {
      //Serial.println("connected");
      client.subscribe("pracovna/LGTV");
            } else {
      //Serial.print("failed, rc=");
      //Serial.print(client.state());
      //Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void callback(String topic, byte* message, unsigned int length) {
  //Serial.print("Message arrived on topic: ");
  //Serial.print(topic);
  //Serial.print(". Message: ");
  String messageTemp;
  for (int i = 0; i < length; i++) {
    //Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  //Serial.println();
  //Serial.println("-----------------------");
  
  // Feel free to add more if statements to control more GPIOs with MQTT
  // If a message is received on the topic room/lamp, you check if the message is either on or off. Turns the lamp GPIO according to the message
  //LGTV
  if (topic == "pracovna/LGTV") {
    //Serial.print("TV IR: ");
    if (messageTemp == "ON") {
      //Serial.print("ON");
      irsend.sendNEC(0x20DF23DC, 32); //ON-OFF code
      }
    else if (messageTemp == "OFF") {
      //Serial.print("OFF");
      irsend.sendNEC(0x20DFA35C, 32); //ON-OFF code
    }
     else if (messageTemp == "VOLUP") {
      //Serial.print("VOLUP");
      irsend.sendNEC(0x20DF40BF, 32); //ON-OFF code
    }
    else if (messageTemp == "VOLDN") {
      //Serial.print("VOLDN");
      irsend.sendNEC(0x20DFC03F, 32); //ON-OFF code
    }
    else if (messageTemp == "HDMI1") {
      //Serial.print("HDMI1");
      irsend.sendNEC(0x20DF738C, 32); //ON-OFF code
    }
    else if (messageTemp == "HDMI2") {
      //Serial.print("HDMI2");
      irsend.sendNEC(0x20DF33CC, 32); //ON-OFF code
    }
     else if (messageTemp == "LIVETV") {
      //Serial.print("LIVETV");
      irsend.sendNEC(0x20DF6B94, 32); //ON-OFF code
    }
     else if (messageTemp == "CHANUP") {
      //Serial.print("CHANUP");
      irsend.sendNEC(0x20DF00FF, 32); //ON-OFF code
    }
     else if (messageTemp == "CHANDN") {
      //Serial.print("CHANDN");
      irsend.sendNEC(0x20DF807F, 32); //ON-OFF code
    }
     else if (messageTemp == "MUTE") {
      //Serial.print("MUTE");
      irsend.sendNEC(0x20DF906F, 32); //ON-OFF code
    }
      else if (messageTemp == "1") {
      //Serial.print("1");
      irsend.sendNEC(0x20DF8877, 32); //ON-OFF code
    }
      else if (messageTemp == "2") {
      //Serial.print("2");
      irsend.sendNEC(0x20DF48B7, 32); //ON-OFF code
    }
      else if (messageTemp == "3") {
      //Serial.print("3");
      irsend.sendNEC(0x20DFC837, 32); //ON-OFF code
    }
      else if (messageTemp == "4") {
      //Serial.print("4");
      irsend.sendNEC(0x20DF28D7, 32); //ON-OFF code
    }
      else if (messageTemp == "5") {
      //Serial.print("5");
      irsend.sendNEC(0x20DFA857, 32); //ON-OFF code
    }
      else if (messageTemp == "6") {
      //Serial.print("6");
      irsend.sendNEC(0x20DF6897, 32); //ON-OFF code
    }
      else if (messageTemp == "7") {
      //Serial.print("7");
      irsend.sendNEC(0x20DFE817, 32); //ON-OFF code
    }
      else if (messageTemp == "8") {
      //Serial.print("8");
      irsend.sendNEC(0x20DF18E7, 32); //ON-OFF code
    }
      else if (messageTemp == "9") {
      //Serial.print("9");
      irsend.sendNEC(0x20DF9867, 32); //ON-OFF code
    }
      else if (messageTemp == "0") {
      //Serial.print("0");
      irsend.sendNEC(0x20DF08F7, 32); //ON-OFF code
    }    
  }
  //LGTV

} //end  
 

Some basic config in OH

As seen from the OH code, there is basic linking from Loxone thing to items and one extra switch, which is enabler of the dimming function. I have these “enablers” on lot of functions used in OH.

Switch which is the trigger for OH, that TV is ON or OFF

Switch IRblaster01 "IRblaster01" {channel="loxone:miniserver:504F941192A3:14B07EB9-02E9-83AB-FFFF8AF06CA4E88A"}

Ligth configuration.
Switch CentDimmer5_1: OH switch / wallswitch for light
Dimmer CentDimmer5: dimmer for that light
Switch CentDimmer5_dimming: enabler for automatic dimming

Switch CentDimmer5_1 {channel="loxone:miniserver:504F941192A3:14AE2A2F-02AC-5879-FFFF8AF06CA4E88A"}
Dimmer CentDimmer5   {channel="loxone:miniserver:504F941192A3:14AE2679-031E-9749-FFFFE51BF6A4CFE0"}
Switch CentDimmer5_dimming

Now, when there is a solution from TV to OH I’m using few rules, which are causing dimming the light.

rule "dimmer when TV goes ON"
when Item IRblaster01 changed from OFF to ON
then
	logInfo("TVKITCHEN:","Change here!")
	if (CentDimmer5.state != 0 && CentDimmer5_dimming.state === ON)
{
	logInfo("TVKITCHEN:","dimming DOWN")
sendCommand(CentDimmer5, "60")
}

end

rule "dimmer when TV goes OFF"
when Item IRblaster01 changed from ON to OFF
then

	logInfo("TVKITCHEN:","Change here!")
	if (CentDimmer5.state != 0 && CentDimmer5_dimming.state === ON)
{
	logInfo("TVKITCHEN:","dimming UP")
sendCommand(CentDimmer5, "100")
}

end

rule "dimmer when TV is ON"
when
Item CentDimmer5_1 changed from OFF to ON
then
if (IRblaster01.state === ON && CentDimmer5_dimming.state === ON)
{
	logInfo("TVKITCHEN:","Setting light to 60% because TV is ON")
sendCommand(CentDimmer5, "60")
}
end

That’s it. I hope that I just ispired someone.

And finally the video here: https://youtu.be/ENhhTkMs8EA, sorry for my english :slight_smile:

5 Likes

Just my curiosity, why didn’t you use the networkbinding to ping your TV? Pingable -> TV ON else OFF

Beacause I do not want ping my TV every second. Also as you can see, Arduino was in place already for IR remoting. And finally it’s ready for some Loxone stuuf in future.
EDIT: And this should be inspiration for someone, who has really dumb TV without network adapter :slight_smile:

1 Like

I use the ping method, but have it set to ping every 15 seconds and timeout after 60 seconds. So, the lights don’t dim immediately and don’t turn back on for “little while” (at least a minute). There have also been some times that, since my TV is connected via Wifi, network congestion will cause the TV to falsely report “off” (4 missed pings), so the lights turn on mid-movie.

Your method has a distinct advantage of being faster to react to TV on/off events and less susceptible to network congestion. Thank you for the writeup!

1 Like