I read a lot of posts on people having trouble with controlling neopixels or RGB LED’s from OpenHab so for beginners ( I am still a beginner too) I will include some simple files here of a working system.
Using a Colorpicker
The sitemap and items file are fairly easy, just using a Colorpicker. I will describe some additions, but the basic files are quite simple
itemsfile
Group All
Color RGBLed "NeoPixel Color" (All)
String RGBLedColor (All) {mqtt=">[mosquitto:OpenHab/RGB:command:*:default]"}
There are 2 items here. One item contains the HSB value, coming from the colorpicker, The other item, that will not be visible on the screen, will contain the calculated RGB code that will be sent out via MQTT.
sitemap file is as follows:
sitemap NeoPixel label="NeoPixel"
{
Frame label="NeoPixel" {
Colorpicker item=RGBLed icon="slider"
}
}
The colorpicker sends an HSB (Hue, Saturation, Brightness) code, but that isnt anything a regular Neopixel LED or regular RGB LED can use, so I set up a rule that triggers on any change of the RGB item to change the HSB code into a regular RGB code. That RGBcode is joined in 1 string called ’ color’. The rule then assigns that ‘color’ string to a new item called “RGBLedColor”
rules file
import org.openhab.core.library.types.*
rule "Set HSB value of item RGBLed to RGB color value"
when
Item RGBLed changed
then
val hsbValue = RGBLed.state as HSBType
val brightness = hsbValue.brightness.intValue
val redValue = ((((hsbValue.red.intValue * 255) / 100) *brightness) /100).toString
val greenValue = ((((hsbValue.green.intValue * 255) / 100) *brightness) /100).toString
val blueValue = ((((hsbValue.blue.intValue * 255) / 100) *brightness) /100).toString
val color = redValue + "," + greenValue + "," + blueValue
sendCommand( RGBLedColor, color)
end
//part of Neopixel conf files
On the receiving end, there is a Wemos D1 mini that controls a NeoPix strip. The ‘color’ string is split in its separate RGB values. As such it could also be used for an RGB LED or seperate Red, Green, Blue Led’s.
The code is reacting to one MQTT topic, basically switching the entire strip at one go in the desired color and brightness, but I added a structure catching some other MQTT topics that now go to empty routines but that could be used for patterns like a breathing light or a moving pattern. As illustration I added a simple red-blue pattern that responds to MQTT “OpenHab/RGB/scene” with payload “2” (Edit, new code now has 3 scenes built in, all with topic “OpenHab/RGB/scene” and payloads 1 to 3) I am using the broker name ‘mosquitto’, if your broker has a different name you needto modify that.
I have to say though that this is not the most efficient way of adding topics, but for beginners it is easiest to follow.
A much more efficient way is to keep the topics of one specified length with only say the last 2 or 3 characters defining the desired action and then only checking for those last characters. A good example of this is for instance in the gateway or sonoff code on https://github.com/computourist/ESP8266-MQTT-client. For readability sake however, in this example I have chosen to use a more traditional approch and as long as you just want to control some LEDs it is easier.
The ESP8266 code does send some information back: it returns the software version, the IP number and the RSSI.
With regard to the software version and IP number… if you have several ESP8266’s and or Arduino’s in your system, it is easy to lose track which one does what and with what software.
The ESP8266 code is OTA updateable
I have used a fork of the O’Leary PubSub library that makes it easier to send variables as the MQTT payload without having to resort to setting up buffer space and using c_string. Library is here: https://github.com/Imroy/pubsubclient.
If you already have the O’Leary PubSub library installed, you will need to put the library files in your sketch folder and change #include <PubSubClient.h> into #include “PubSubClient.h”
Sending predefined colors
If next to the Colorpicker you also want to be able to send predefined colors via a button, then you only need to add some lines in the items and sitemap file:
add to itemsfile:
Switch NEO_RED "Red" <red> {mqtt=">[mosquitto:OpenHab/RGB:command:ON:255,0,0]"}
Switch NEO_YELLOW "Yellow" <yellow> {mqtt=">[mosquitto:OpenHab/RGB:command:ON:100,96,0]"}
Switch NEO_BLUE "Blue" <darkblue>{mqtt=">[mosquitto:OpenHab/RGB:command:ON:0,0,255]"}
add to the sitemap:
Switch item=NEO_RED mappings=[ON="ON"]
Switch item=NEO_YELLOW mappings=[ON="ON"]
Switch item=NEO_BLUE mappings=[ON="ON"]
As it can be a bit of a bother to find and type all the codes for the colors you may want, I added for download some 160 predefined color settings to pick and add to your sitemap and itemsfile, including some simple icons. As these items already send an R,G,B, code they do not need the rulesfile, only the colorpicker does.
How about Sliders
Perhaps you do not want to use a colorpicker but just individual sliders for Red, Green and Blue.
That is quite easy too.
add the following to your itemsfile:
Dimmer NEO_SLIDERRED "Neopixel Red [%d %%]" <red> {mqtt=">[mosquitto:OpenHab/RGB/RED:command:*:default]"}
Dimmer NEO_SLIDERGREEN "Neopixel Green [%d %%]" <green> {mqtt=">[mosquitto:OpenHab/RGB/GREEN:command:*:default]"}
Dimmer NEO_SLIDERBLUE "Neopixel Blue [%d %%]" <blue> {mqtt=">[mosquitto:OpenHab/RGB/BLUE:command:*:default]"}
and this to your sitemap
Slider item=NEO_SLIDERRED
Slider item=NEO_SLIDERGREEN
Slider item=NEO_SLIDERBLUE
Normally that would be enough already, but our ESP8266 program is expecting one input rather than seperate RGB inputs. That is because the colorpicker we used before sends one string of info.
Ofcourse we could add topics to the ESp8266 program to respond to individual RG and B values (and that is what the MQTT topics OpenHab/RGB/RED, OpenHab/RGB/GREEN, and OpenHab/RGB/Blue would be for), but it might be easier to combine those and send as one. For that we need a new rule.
add this to your rules file:
rule "Send RGB items from slider"
when
Item NEO_SLIDERRED changed or
Item NEO_SLIDERGREEN changed or
Item NEO_SLIDERBLUE changed
then
val redValue= Math::round(2.55* (NEO_SLIDERRED.state as DecimalType).intValue)
val greenValue= Math::round(2.55* (NEO_SLIDERGREEN.state as DecimalType).intValue) //
val blueValue= Math::round(2.55* (NEO_SLIDERBLUE.state as Number).intValue)
val color = redValue + "," + greenValue + "," + blueValue
sendCommand( RGBLedColor, color)
end
While we are at it
If you want the Filename, IP number and RSSI to show up, add the following to your items file:
Number W_RSSI "RSSI [%d dbm]" <signal> {mqtt="<[mosquitto:home/nb/weer/RSSI:state:default]"}
String W_IP "IP [%s]" <network> {mqtt="<[mosquitto:home/nb/weer/IP:state:default]"}
String W_version "Software versie [%s]" <version> {mqtt="<[mosquitto:home/nb/weer/version:state:default]"}
String W_MAC "MAC [%s]" <mac> (Wweather) {mqtt="<[mosquitto:home/nb/weer/mac:state:default]"}
Number W_IP_Uptime "Uptime [%d min]" <clock> (Wweather) {mqtt="<[mosquitto:home/nb/weer/uptime:state:default]"}
and the following lines to your sitemap:
Text item=W_RSSI
Text item=W_IP
Text item=W_version
Text item=W_MAC
Text item=W_IP_Uptime
Although I tried on a Wemos D1 mini, I presume this will also work perfectly on the ESP8266-01. Perhaps a great way to use those if you still have on your scrapheap as this is typically a minimal pin project.
The ESP8266 program
The Esp8266 program is rather self explanatory and going into it too deep might fall outside the openhab scope a bit, but in brief, you will find several ino files and a userconfig.h file. These all should be in the same directory and it is sufficient to open the NeopixelOpenhab_vx.ino file in your IDE. The other files will then open up too.
You need to make a few modifications in the userdata.h file.
The essential changes are your password, your SSID and the address of your MQTT server. The other options are indeed ‘optional’, can leave them as is.
the Filename is sent back to openhab as an MQTT message, so in the future you will still know what file it was you put in your ESP8266. obviously you would need to fill out the correct filename. Maybe there is a possibility to automatically pull the filename from the system but if it is, then I haven’t found out about it yet