Philips Hue Dimmable Light Remote Control via ESP8266 with LCD Keypad Shield (openHAB,B4R,MQTT)

Exploring openHAB & openHABian.
Site Admin
Posts: 224
Joined: 07 Oct 2017, 12:16

Philips Hue Dimmable Light Remote Control via ESP8266 with LCD Keypad Shield (openHAB,B4R,MQTT)

Postby rwblinn » 12 Feb 2018, 09:09

openHAB2 Experiment - Philips Hue Dimmable Light Remote Control via ESP8266 with LCD Keypad Shield (openHAB,B4R,MQTT)
Version 20180212

To control a Philips Hue dimmable light, via WiFi & MQTT, by using a LCD Keypad Shield on top of an ESP8266 WeMOS D1 (retired).


  • ESP8266 WeMOS D1 (retired)
  • LCD Keypad Shield DFRobot
  • Hue Dimmable Light (White Lamp E27)


The openHAB server is a Raspberry Pi 3 with openHABian, openHAB 2.2.0 and Mosquitto MQTT Broker.

The LCD Keypad Shield is placed on top of the WeMOS D1.
As an indicator, to ensure the shield is rightly placed, check the LCD Keypad Shield 5V pin is matching the WeMOS D1 5V pin slot.

No download - the openHAB configuration and the B4R source are listed below.

The Hue light brightness is remote controlled via MQTT.
When pressing a key on the LCD keypad, a MQTT topic with payload, containing the brightness value between 0 - 100, is send to the openHAB server.
An openHAB number item listens to the MQTT topic and if the value (=state) changes, an openHAB rules triggers setting the value of an openHAB item Dimmer assigned to the Hue Light Thing.
The Hue Light Thing is updated via its Hue Bridge Channel.
The other way around is also implemented, means if the Hue Light brightness is changed via the openHAB Basic-UI, the new value is displayed on the LCD Keypad Shield.

openHAB Configuration
For the Hue Dimmable Light, the items, sitemap and rules are extracted from a full openHAB installation.
The Things are defined using the openHAB Basic-UI.

The thing defined is named "Hue white lamp 1" with status ONLINE.
It is a Dimmable Light connected to Hue Bridge hue:0100:00178863da1d and has Light ID 1.

The Dimmer Item uses the brightness channel of the Thing "Hue white lamp 1".

Code: Select all

Dimmer aHA_MakeLab_HueLight1bsl "Brightness" <light> (gHA_MakeLab) { channel="hue:0100:00178863da1d:1:brightness" }

The Number Item contains the brightness by listening to the MQTT topic "homeautomation/makelab/huelight1/set" with payload between 0 - 100.

Code: Select all

Number nHA_MakeLab_HueLight1 { mqtt="<[openhabprod:homeautomation/makelab/huelight1/set:state:default:.*]" }

The sitemap snippets shows the Dimmer Item as a Slider.

Code: Select all

Frame label="Make Lab" {
   Slider  item=aHA_MakeLab_HueLight1bsl

MQTT Broker
The broker is defined in the file mqtt.cfg located on the Raspberry Pi openHAB server /etc/openhabs2/services.

Code: Select all

# Local Mosquitto Broker running on the Raspberry Pi

There are two rules handling the change if the Number Item and the Dimmer Item.

State Change Number Item nHA_MakeLab_HueLight1
As defined in the item, the state will change if the payload of the MQTT message with topic "homeautomation/makelab/huelight1/set" changes.
If a change is made, the Dimmer Item aHA_MakeLab_HueLight1bsl is updated with the value of the Number Item nHA_MakeLab_HueLight1.

Code: Select all

rule "HueLight1 Brightness Set"
   Item nHA_MakeLab_HueLight1 changed
   logInfo("HUELIGHT1", "*** Brightness set to " + nHA_MakeLab_HueLight1.state.toString)

State Change Dimmer Item aHA_MakeLab_HueLight1bsl
If the state of the Dimmer Item changes, by changing the position of the slider in the openHAB Basic-UI, a MQTT message is published with
Broker: openhabprod
Topic: homeautomation/makelab/huelight1
Payload: Value of the Dimmer Item aHA_MakeLab_HueLight1bsl between 0 - 100

Code: Select all

rule "HueLight1 Brightness Changed"
   Item aHA_MakeLab_HueLight1bsl changed
   // Publish the message to topic using the specified MQTT broker.
   publish("openhabprod", "homeautomation/makelab/huelight1", aHA_MakeLab_HueLight1bsl.state.toString)

B4R Solution
The ESP8266 connects to the WLAN followed by a connection to the MQTT broker.
MQTT Outbound:
When pressing a key on the LCD keypad shield, a MQTT message with the new brightness value is published to the MQTT broker running on the openHAB server:
Topic: "homeautomation/makelab/huelight1/set", Payload: 0 - 100. The LCD Keypad display is updated with the new brightness value.
MQTT Inbound:
If a new incoming MQTT message is received, the LCD Keypad display is updated with the new brightness value.

For more, see comments in the code.
Libraries used: rcore, resp8266wifi, rmqtt, rliquidcrystal, rrandomaccessfile

Code: Select all

Sub Process_Globals
   Public Version As String = "v20180211"
    Public Serial1 As Serial
    Public wifi As ESP8266WiFi
   Public wificlient As WiFiSocket

   Public LCD As LiquidCrystal
   Public LCDKeyPadPin As Pin
   Public LCDKeyPressed As Int = 0
   Public LCDAnalogValue As Int = 0
   Public LCDKeyRight As Int =  0
   Public LCDKeyUp As Int = 1
   Public LCDKeyDown As Int =  2
   Public LCDKeyLeft As Int = 3
   Public LCDKeySelect As Int = 4
   Public LCDKeyNone As Int =  5

   'Mosquitto MQTT Broker running on a Raspberry Pi openHAB Home Automation
   Public serverIP() As Byte = Array As Byte(192, 168, N, NN)
   Public serverPort As UInt = 1883

   Public mqtt As MqttClient
   Public mqttCO As MqttConnectOptions
   Public mqttConnected As Boolean = False   'ignore
   'Ensure to set a unique clientid in the network
   Public clientID As String = "HAHueRemoteControl"
   'Hue Lights
   'For each light define the MQTT topics and the brightness
   'MQTT Topics Getter (Subscribe to a Topic) and Setter (Publish a Topic)
   Public HueLight1GetTopic As String = "homeautomation/makelab/huelight1"
   Public HueLight1SetTopic As String = "homeautomation/makelab/huelight1/set"
   Public HueLight1Brightness As Int = 0
   'The number of hue lights
   Public HueLights As Int = 1
   'The selected hue light stareting at 1
   Public HueSelected As Int = 1
   Public bc As ByteConverter
End Sub

Public Sub AppStart
   Log("AppStart ", Version)
   'Init the PotMeterPin
   LCDKeyPadPin.Initialize(LCDKeyPadPin.A0, LCDKeyPadPin.MODE_INPUT)
   'Init LCD
   'Pin mapping D8=GPIO0, D9=GPIO2, D4=GPIO4,D5=GPIO14,D6=GPIO12,D7=GPIO13) resulting in 0,255,2,4,14,12,13
   LCD.Initialize(0,255,2, Array As Byte(4, 14, 12, 13))
   'Columns, Rows
   'Turn the backlight on (default is turned off)
   LCD.DisplayOn = True
   LCD.Write("Hue Control")
   'Connect with wifi by setting SSID and password
   If wifi.Connect2("SSID", "*****") Then
      Log("[INFO] Connected to wireless network with local IP ", wifi.LocalIp)
      Log("[ERROR] Failed to connect to wireless network. Check the network parameter.")
   End If
   'Init MQTT
   mqtt.Initialize(wificlient.Stream, serverIP, serverPort, clientID, "Mqtt_MessageArrived", "Mqtt_Disconnected")
   'Make a connection to the MQTT Broker - ensure its up and running
   'Add the looper which handles the button pressed.
End Sub

#Region MQTT
' Check if connected to mqtt. if not, then try again after 1 sec
Sub Mqtt_Connect(unused As Byte)
   mqttCO.Initialize("", "")
   If mqtt.Connect2(mqttCO) = False Then
      mqttConnected = False
      Log("[ERROR] Can not connect the MQTT broker. Trying again ...")
        CallSubPlus("Mqtt_Connect", 1000, 0)
   End If
   mqttConnected = True
   Log("MQTT: Connected to the broker")
   ' Subscribe to topics
   mqtt.Subscribe(HueLight1GetTopic, 0)
End Sub

'MQTT New Message arrived (NOT USED)
Sub Mqtt_MessageArrived (Topic As String, Payload() As Byte)
   Dim PayLoadStr As String = bc.StringFromBytes(Payload)
   Select Topic
      Case HueLight1GetTopic
         HueLight1Brightness = PayLoadStr
         UpdateLCD(1, PayLoadStr)
   End Select
End Sub

'MQTT disconnected. If the server is nor reachable, then MQTT is disconnected. To connect again, reset the ESP.
Sub Mqtt_Disconnected
   Log("[INFO] Disconnected")
End Sub
#End Region

'Keep on looping and check if the potentiometer value has changed.
Public Sub Looper1
   LCDKeyPressed = KeyPadHandler
   Select LCDKeyPressed
      Case LCDKeyUp
      Case LCDKeyDown
      Case LCDKeyLeft
      Case LCDKeyRight
      Case LCDKeySelect
         HueSelected = HueSelected + 1
         If HueSelected > HueLights Then HueSelected = 1
         LCD.Write("Make Lab Hue")
         LCD.Write("Selected: ")
   End Select
End Sub

'Set the Hue Light Brightness. Current only 1 Hue is defined.
Public Sub SetHueBrightness(LCDKey As Int)
   Dim HueLightBrightness As Int
   Dim pmvtopic As String
   Dim pmvpayload As String

   'Get the brightness for the selected hue
   Select HueSelected
      Case 1
         HueLightBrightness = HueLight1Brightness
   End Select

   'Adjust the brightness
   If LCDKey = LCDKeyLeft Then HueLightBrightness = 0
   If LCDKey = LCDKeyUp Then HueLightBrightness = HueLightBrightness + 1
   If LCDKey = LCDKeyDown Then HueLightBrightness = HueLightBrightness - 1
   If LCDKey = LCDKeyRight Then HueLightBrightness = 100

   'Check the brightness
   If HueLightBrightness > 100 Then HueLightBrightness = 100
   If HueLightBrightness < 0 Then HueLightBrightness = 0

   'Assign the new brightness to the hue selected and define the mqtt topic and payload
   Select HueSelected
      Case 1
         HueLight1Brightness = HueLightBrightness
         Dim pmvtopic As String = HueLight1SetTopic
         Dim pmvpayload As String = HueLight1Brightness
   End Select

   'Publish the new payload to update the hue
   If pmvtopic.Length = 0 Then Return
   mqtt.Publish(pmvtopic, pmvpayload.GetBytes)
   'It is not request to update the LCD as this is handled by Mqtt_MessageArrived using the Getter
   'UpdateLCD(HueSelected, HueLightBrightness)
End Sub

Public Sub UpdateLCD(Selected As String, Brightness As String)
   LCD.Write("Make Lab Hue ")
End Sub

'Handle the LCD Keypad Key Press.
'The delay has to be determined experimental. Check the step(s) change when pressing keys UP or DOWN.
Public Sub KeyPadHandler As Int
   LCDAnalogValue = LCDKeyPadPin.AnalogRead
   If LCDAnalogValue > 1023 Then Return LCDKeyNone
   If LCDAnalogValue < 60 Then Return LCDKeyRight
   If LCDAnalogValue < 250 Then Return LCDKeyUp
   If LCDAnalogValue < 500 Then Return LCDKeyDown
   If LCDAnalogValue < 790 Then Return LCDKeyLeft
   If LCDAnalogValue < 1023 Then Return LCDKeySelect
   Return LCDKeyNone
End Sub

  • Experiment completed.

  • 20180212

Return to “Experiments”

Who is online