last updated: 19/06/20
Song of this chapter: Madness > Our house
In the market of IoT devices we have many proprietary solutions. To understand how automation software for buildings work we will lock in depth into one software designed for homes that is powerful in combining many proprietary protocols. The software is called openHAB, is open source and thus helps to understand the principles of building automation in depth. The documentation of openHAB is excellent, and there exists a big supporting community.
OpenHAB is easily extendable and regroups other home automation systems, devices and different technologies like KNX, HomeMatic, Phillips Hue and protocols or interfaces like MQTT or XBEE into a single solution.
OpenHAB provides also a uniform user interface and a common automation rules across the entire system. This regardless of the number of manufacturers and sub-systems involved.
OpenHAB does not need an external cloud, so the data can be secured in an local subsystem.
OpenHAB stands for open Home Automation Bus and is developed in Java, so it runs an all platforms. The newest Version is 2.4 and to distinguish from the former 1.x versions it is often called openHAB. The documentation can be found in openhab.org/docs.
OpenHAB is very powerful and flexible but has a steep learning curve. So let's start :)
We will install openHAB on a Raspberry Pi. This facilitates the installation procedure and the Raspberry Pi is a cheap and powerful possibility to use openHAB. Naturally it is also possible to install openHAB on a NAS or server or PC.
The Raspberry Pi is our openHAB server. Now we want to connect our devices (called Things in openHAB) with the openHAB server to be able to manage them.
Devices need a "driver" called a Binding in openHAB. Bindings integrate physical hardware, web services and external systems in openHAB. In the first version of openHAB they were called "Add-ons", and some add-ons don't still exist exist in a 2.x version. All Bindings and add-ons can be found on: https://www.openhab.org/addons/.
A Binding is installed by using an graphical interface called PaperUI.

This interface is accessed with an internet browser on port 8080 of your Raspberry Pi (e.g.: 192.168.1.100:8080).

Things in the openHAB language are physical entities like devices, but also web services or information sources. Devices like actuators, sensors, cameras, lamps etc.. can sometimes be connected directly, but often they use proprietary (wireless protocols) and connect with these protocols to a bridge (also named gateway or hub). The bridge is then connected to openHAB (e.g. Homematic, Philips Hue, LoRaWan).
After the installation of the Binding, we can add our Things in PaperUI. This can be done in by using the + sign in Configuration > Things. New detected Things are shown in Inbox and are then added by clicking on the check mark ✓.

In the same window we can edit and delete Things.
A Thing has often more than one possibility to interact. In openHAB these possibilities are called Channels. E. g. an integrated motion sensor has 5 Channels: a switch notifying motion, a temperature sensor, a luminance sensor an alarm switch and a battery level indicator.

Each Thing has a status object. This helps to identify possible problems. The following statuses are possible: UNINITIALIZED, INITIALIZING, UNKNOWN, ONLINE, OFFLINE, REMOVING and REMOVED. The status object has a status detail object witch gives even more information. More infos on status transition and the status objects can be found here.
Bindings and Things belong to the the physical world. The whole concept of the application openHAB is built around the notion of Items. Items are decoupled from the physical things and play on a virtual layer. Items can be strings, numbers, switches and can be compared with base variable data types of a programming language.
Items have always have a state and some of them can be manipulated through events. They represent all properties and capabilities of the user’s home automation.
Through a Binding an Item can e.g. be connected with a concrete Channel of a Sitemap. So the Item does not only store information set by software (e.g., ON, 247 or "Hello") but can also take action on the physical level. Items can be represented in sitemaps and can be grouped to create new logical items (group items). Al the rules in openHAB will be based on items and their status changes.
Items can be manipulated in PaperUI, but only with the newer 2.0 bindings and are then stored in JsonDB files (/var/lib/openhab), that are difficult to read and change. We will use the text-based configuration files with the extension .items under /etc/openhab2/items.
Example for an items file:

To create such a rough skeleton of an items files we can use the help of the HomeBuilder utility (copy/paste the text). This utility is also accessed with an internet browser on port 8080 of your Raspberry Pi (e.g.: 192.168.1.100:8080).
Items can be represented in Sitemaps was stated above. An important feature of openHAB is to interact with the user and provide infos in a modern and pleasant way on tablets, smartphones or PC's.
Sitemaps are used to compose a user-oriented presentation of items for various User Interfaces (UIs) like e.g. BasicUI or the openHAB app for Android.
Sitemaps are also text files with the extension .sitemap and are stored under /etc/openhab2/sitemaps. The Sitemap name (inside the Sitemap file) should match the name of the text file.
Here an example of such a text file and the representation in the application BasicUI:


To create such a Sitemap file we can use also use HomeBuilder (copy/paste the text) and than change the file according our needs.
In the file above a label (Frame label="Some Items from Room SC4") was added to the second frame.
The result of our Sitemap can be viewed with the application BasicUI (accessible with an internet browser on port 8080 of your Raspberry Pi (e.g.: 192.168.1.100:8080).)
| Bindings (Add-Ons): | a sort of "drivers" needed to communicate with the devices (Things) |
| Things: | your physical devices represented in openHAB |
| Channels: | your physical devices represented in openHAB |
| Items: | properties and capabilities linked to Channels of your Things |
| Groups: | collections or categories containing Items |
| Sitemaps: | user-defined front-end interfaces to arrange Groups, Items, ... |
| Transformations: | helper functions to transform your data |
| Persistence: | services to store data over time |
| Rules | automation logic, the “smart” in your Smart Home! |
More infos in https://www.openhab.org/docs/installation/linux.html.
We could use openHABian on our Raspberry Pi (see MQTT). This would be the easiest solution. To be more flexible with the platform, let's do it on a Debian based Linux system (package repo with apt).
OpenHAB is written in Java, so we first need a JAVA platform. As suggested we use Zulu. We add the repository of Zulu and install the package with the following commands:
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9
echo 'deb http://repos.azulsystems.com/debian stable main' | \
sudo tee /etc/apt/sources.list.d/zulu.list
sudo apt update
sudo apt install zulu-embedded-8
The first command imports the needed public key and the second command adds the repository.
The backslash in the second line means that the command from line 2 continues in line 3. In the terminal you have to type the command in one line and remove the backslash.
After an update we can install the package.
Now we will install the openHAB stable release:
wget -qO - 'https://bintray.com/user/downloadSubjectPublicKey?username=openhab' | sudo apt-key add -
sudo apt-get install apt-transport-https
echo 'deb https://dl.bintray.com/openhab/apt-repo2 stable main' | \
sudo tee /etc/apt/sources.list.d/openhab2.list
sudo apt update
sudo apt install openhab2
Now we can start openHAB by and test if its running:
sudo systemctl start openhab2.service
sudo systemctl status openhab2.service
Quit with ctrl-c.
To start on installation, execute the following commands to configure openHAB to start automatically using systemd:
sudo systemctl daemon-reload
sudo systemctl enable openhab2.service
Upgrade openHAB:
sudo apt update
sudo apt upgrade
Command Line interface (CLI) to use in terminal:
openhab-cli backup [--full] [filename] -- Stores the current configuration of openHAB.
openhab-cli clean-cache -- Cleans the openHAB temporary folders.
openhab-cli console -- Opens the openHAB console.
openhab-cli info -- Displays distribution information.
openhab-cli reset-ownership -- Gives openHAB control of its own directories.
openhab-cli restore filename -- Restores the openHAB configuration from a backup.
openhab-cli showlogs -- Displays the log messages of openHAB.
openhab-cli start [--debug] -- Starts openHAB in the terminal.
openhab-cli status -- Checks status (openHAB running?)
openhab-cli stop -- Stops any running instance of openHAB.
To be able to access our openHAB installation files from our local PC we will set up a Samba network share. More infos in the openHAB documentation. We begin with installing samba:
sudo apt install samba samba-common-bin
Next we have to edit the samba configuration file smb.conf.
sudo nano /etc/samba/smb.conf
Add the following to the bottom of the file:
[openHAB2-userdata]
comment=openHAB2 userdata
path=/var/lib/openhab2
browseable=Yes
writeable=Yes
only guest=no
public=no
create mask=0777
directory mask=0777
[openHAB2-conf]
comment=openHAB2 site configuration
path=/etc/openhab2
browseable=Yes
writeable=Yes
only guest=no
public=no
create mask=0777
directory mask=0777
[openHAB2-logs]
comment=openHAB2 logs
path=/var/log/openhab2
browseable=Yes
writeable=Yes
only guest=no
public=no
create mask=0777
directory mask=0777
Next, we need to set up a user and a password for our Samba share. Run the following command to create the user "pi" and set a password.
sudo smbpasswd -a pi
Change the ownership of the openHAB files to "pi" with:
sudo chown -hR pi:pi /etc/openhab2
Restart the server:
sudo systemctl restart smbd
Now you are able to access the files from your PC. On Linux and Mac you can use:
smb://samba_server_ip_address/sambashare (e.g. smb://192.168.178.110/openHAB2-conf)
In Windows:
\\samba_server_ip_address/sambashare (e.g. \\192.168.178.110/openHAB2-logs)
The openHAB console offers the option to monitor the log in real time and to execute runtime commands. So it may be good to know it exists.
The connection is only allowed from localhost (machine running openHAB) due to security concerns (default password is: habopen). We access the console with
openhab-cli console
The most useful command is help (q to quit). It lists all the other commands. When finished with the console you get out with logout.
Example to view all active add-ons using MQTT:
bundle:list |grep -i MQTT
To view the log in real-time:
log:tail
In /etc/default we find the config file openhab2. In this file we find the links to the openHAB default paths:
OPENHAB_HTTP_PORT=8080
OPENHAB_HTTPS_PORT=8443
OPENHAB_BACKUPS=/var/lib/openhab2/backups
OPENHAB_HOME=/usr/share/openhab2
OPENHAB_CONF=/etc/openhab2
OPENHAB_RUNTIME=/usr/share/openhab2/runtime
OPENHAB_USERDATA=/var/lib/openhab2
OPENHAB_LOGDIR=/var/log/openhab2
Use your favourite web-browser to access openHAB on port 8080 (e.g.: 192.168.1.100:8080). We land on a page saying "Welcome to openHAB 2 - Initial Setup". Choose the standard setup.

The new screen shows 4 apps:
HomeBuilder:
Home Builder is a getting-started generator for the building. It helps to generates a Sitemap file by classifying objects within rooms, adding icons and tags, and creating groups for the objects.
PaperUI:
Is needed for for system administration. With PaperUI we can e.g. install or uninstall openHAB Bindings (add-ons).
BasicUI:
is a web UI for mobile devices.
HABPanel:As we need to configure openHAB partially using text files, we need an editor. We can use nano with openHAB highlighting on the pi, but it is more comfortable to use an editor on the local machine and work on the pi via network share.
The best support for the moment is offered by "openHAB VS Code", an extension for Visual Studio Code. More infos on editors can be found on in the documentation of openHAB.
Download Visual Studio Code on your PC and install the openHAB extension (icon Extensions). Go to File > Preferences > Settings > Extensions > openHAB Configuration click on "Edit in settings.json". Add the following lines to the json file:
"openhab.host": "192.168.xxx.xxx",
"openhab.port": 8080,
"openhab.karafCommand": "ssh pi@%openhabhost% -p 8101 -t 'log:tail'",
More infos are on the github page of the extension.
Install openHAB and a samba network share on a Raspberry Pi. Test the openHAB karaf console (document this with a screenshot).
Install the "openHAB VS Code" extension for Visual Studio Code (VSC) and test it by creating a simple demo house Sitemap (2 floors, 4 rooms) with HomeBuilder and editing the Sitemap file with VSC (document the text file and the BasicUI screen).
Z-Wave is a wireless communications protocol operating with a throughput up to 40 kbit/s in the unlicensed Industrial, Scientific, and Medical (ISM) band of 868 MHz in Europe. It is a mesh network using low-energy radio waves used primarily for home automation. In the mesh network, mains powered nodes can route messages between battery driven nodes. The network supports hop distances of up to four hops. Communication distance between two nodes is about 30 meters. more about Z-Wave in the openHAB documentation.
Z-Wave allows interoperability between home control systems of different manufacturers (2.600 products by 2019). A wide range of devices are supported and the Z-Wave certification guarantees that certified devices will be compatible with each other and the network. OpenHAB supports 941 things from 132 manufacturers.
The Z-wave Binding uses a standard Z-Wave serial USB stick to communicate with the Z-Wave devices. There are many sticks available, and they all support the same interface so the Binding does not distinguish between them.
Open PaperUI, go to Add-ons > Bindings and install the Z-Wave Binding. Before the Binding can be used, the serial adapter (Thing!) must be added. We use a Z-Wave USB stick on the Raspberry Pi. We need to provide the used serial port to openHAB. Go to Configuration > Things and click on +. After two further clicks we are able to add the serial port. Normally this is /dev/ttyACM0. If you are not sure, insert the stick and use the command dmesg to acquire the information about the used serial port.
Next we must add the openHAB user to the dialout group with:
sudo usermod -a -G dialout openhab
To detect our Z-Wave devices we use the + sign in Configuration > Things. new detected devices are shown in Inbox. They are added by clicking on the check mark ✓.
Add a Z-wave USB stick to your Raspberry Pi. Add the Binding and configure the stick (screenshot).
Now we will add Z-Wave Things to openHAB. This will be an MT02647 Motion Sensor from Devolo, an LC-13 Living Connect Z Thermostat from Danfoss and a 09813 Home Control Smoke Detector from Devolo. Read the inclusion and exclusion information in the in the openHAB Z-Wave documentation and the 3 documentations on the devices.
Tipp: First start the search for the Sitemap (+). Then for the motion sensor you have to press the switch on the back 3 times in 1.5 s, and for the thermostat a short press on the middle button after inserting the batteries will do. Document the PaperUI Things screen after a successful inclusion.
Let's have a closer look to items. An Item has different fields with a defined order. The two first fields itemtype and itemname are obligatory. The other fields are optional. Fields may be separated by one or more spaces, or tabs and the Item definition may use multiple lines.

itemtype (blue) and itemname (green):
In the screenshot we see two items with the types Switch and Number (blue) and their corresponding names "SC4""Light" and "SC4Temperature".
"itemlabel [stateformat]" (brown):
The Item label text (Temperature, Light) will be displayed in the Sitemap. The state format in square brackets defines the format of e.g the temperature, a float number to one-tenth of a degree in Celsius (ex. 22.5 °C). Both are contained in double quotes.
<iconname> (white):
Defines the icon that should be used in the Sitemap (in angle brackets). You can create your own icons (png,svg) and save them under /etc/openhab2/icons/classic.
(group1, group2, ...) (green):
The Item belongs to these groups (contained in round brackets). E. g. the Item SC4_Light belongs to the groups SC4 (the room) and gLight (all the lights).
["tag1", "tag2", ...] (brown):
E. g. the first Item is tagged as a lightning with the ability to be switched. Tags in double quotes contained in square brackets.
{bindingconfig} (purple):
Item is bound to the openHAB Binding. E.g. {channel="zwave:device:22fb1a7c:node5:sensor_luminance"}.
So for us the most interesting field is {bindingconfig}. Here we add our channels to the Item.
Let's create a Sitemap and an Item text file with HomeBuilder (copy/paste). It should contain only one classroom, but all the channels available from our Z-Wave Things.
Tip: If objects are not available, you can create one by typing in the text box. Document the created files. The Sitemap name (inside the Sitemap file) should match the name of the text file.
Modify the Sitemap and Item text files to match our needs. Document the modified files and the BasicUI screen.
As we built our own IoT devices publishing and subscribing by using MQTT we naturally want to add them to openHAB.
More infos can be found in the openHAB doc on Bindings. The MQTT Binding allows to configure connections to brokers via openHAB Things.
As for the Z-Wave Binding we first install the Binding (PaperUI, Add-ons > Bindings). Search for MQTT (mqtt-binding - 2.4.0) and click on "INSTALL".
Now we can add MQTT Things in the Configuration > Things menu: Click on + , choose the MQTT Binding. Our first Sitemap to add will be the broker. As we want to use an external MQTT broker (server) we click on MANUALLY ADD THING.
It is a good idea to give the server a Name that is not cryptic, but readable. We name the broker Sitemap "mosquitto-sc1". OpenHAB needs to know at least the IP address (field "Broker Hostname/IP") of our mosquitto server. Under SHOW MORE we can specify e.g. a password. If we specify a location (not necessary), we will find the broker later under this name in the Control window.

Now it may be necessary to restart openHAB, to take the changes in account (known bug in 2.4.0). Ssh to your server and use the following command:
sudo systemctl restart openhab2.service
If all went well we will see the following in /var/log/openhab2/openhab.log:
Starting MQTT broker connection to ...
Use this procedure also if you account problems as not connected devices.
(OpenHAB has also an embedded simple MQTT server (less features especially on security than mosquitto) if you don't want to use an external broker (Configuration > Things > + > Mqtt Binding > ADD MANUALLY > System MQTT Broker)).
Now we are ready to add an MQTT device. For each MQTT device we create a Sitemap and for each Sitemap there are the channels which are the different input and outputs of the MQTT device. Each Channel has an Item so we can control or read the Channel.
There are two methods for defining Things:
It is not always clear what is the best way, and it depends on the Binding used. We will first use the discovery way. More infos can be found here.
We need a device with a variable input and output to test MQTT on openHAB, so let's quickly built one.
A 10 kΩ potentiometer (variable resistance) will be connected to 3.3 V and deliver a voltage between 0 V and 3.3 V. The ADC of the ESP32 (GPIO 35) will convert this voltage with 12 bit in a value between 0 and 4095.
The actuator will be a servo. The value for the servo ranges from 0 to 180 corresponding to an angle of 0° to 180°. We need the PubSubClient library and the ESP32servo library. Install both with the Tools > Manage libraries... .
Use this circuit and sketch:
// mqtt_esp32_servo_pot.ino weigu.lu
// Using ESP32Servo (install with lib manager)
// https://github.com/jkb-git/ESP32Servo
#include <WiFi.h>
#include <PubSubClient.h>
#include <ESP32Servo.h>
// WiFi and network settings
const char* WIFI_SSID = "***";
const char* WIFI_PASS = "***";
// MQTT settings
const short MQTT_PORT = 1883; // clear text = 1883
const char *MQTT_SERVER = "192.128.1.10";
const char *MQTT_CLIENT_ID = "gen_mqtt_pot_servo_1";
const char *MQTT_TOPIC_OUT = "gen_mqtt_1/pot";
const char *MQTT_TOPIC_OUT2 = "gen_mqtt_1/pot_json";
const char *MQTT_TOPIC_IN = "gen_mqtt_1/servo";
const byte PIN_POT = 35;
const byte PIN_SERVO = 16;
const unsigned long DELAY_MS = 3000; // time between sends in ms
char char_buffer[50];
unsigned short pot_value = 0;
int servo_pos = 0; // 0-180° variable to store the servo position
WiFiClient espClient;
PubSubClient mqtt_client(espClient);
Servo My_Servo;
void setup() {
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
My_Servo.setPeriodHertz(50); // see lib example
My_Servo.attach(PIN_SERVO, 1000, 2000); // see lib example
Serial.begin(115200);
setup_wifi();
mqtt_client.setServer(MQTT_SERVER, MQTT_PORT);
mqtt_client.setCallback(mqtt_callback);
}
void loop() {
if (WiFi.status() != WL_CONNECTED) // reconnect if no more WIFI present
setup_wifi();
if (!mqtt_client.connected()) { // reconnect client if not yet connected
mqtt_reconnect();
}
mqtt_client.loop(); // make mqtt client live
if (non_blocking_delay(DELAY_MS)) {
pot_value = analogRead(PIN_POT);
snprintf (char_buffer, 50, "%ld", pot_value);
mqtt_client.publish(MQTT_TOPIC_OUT, char_buffer); // value only
snprintf (char_buffer, 50, "{\"Pot_value\":\"%ld\"}", pot_value);
Serial.print("Publish message: ");
Serial.println(char_buffer);
mqtt_client.publish(MQTT_TOPIC_OUT2, char_buffer); // value in JSON string
}
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message on topic \"");
Serial.print(topic);
Serial.print("\": value = ");
servo_pos = atoi((char *)payload);
Serial.print(servo_pos);
Serial.println();
My_Servo.write(servo_pos);
}
void mqtt_reconnect() {
while (!mqtt_client.connected()) { // Loop until we're reconnected
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (mqtt_client.connect(MQTT_CLIENT_ID)) {
Serial.println("connected");
mqtt_client.publish(MQTT_TOPIC_OUT, "reconnected");
mqtt_client.subscribe(MQTT_TOPIC_IN);// ... and resubscribe
} else {
Serial.print("failed, rc=");
Serial.print(mqtt_client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
bool non_blocking_delay(unsigned long milliseconds) {
static unsigned long nb_delay_prev_time = 0;
if(millis() >= nb_delay_prev_time + milliseconds) {
nb_delay_prev_time += milliseconds;
return true;
}
return false;
}
Now we will add a the Generic MQTT Thing. Go to Inbox menu and click on SEARCH FOR THINGS. Choose the MQTT binding, click on MANUALLY ADD THING and then on Generic MQTT Thing.
Give it a meaningful name (e.g. MyGenericDevice1_pot_servo) and the bridge will be our MQTT server. If you gave a location to the broker, it is a good idea to use here the same location. This helps to find the device later in the Control window. After this, click on the blue check mark ✓.

Next we need channels to define our topics. Click on the blue +. Each Channel has a Channel type. Possible types are:
For our device we will use two channels, one for input (poti) and one for output.
The values of the potentiometer will be the input. The values are between 0 and 4095 and clearly are numbers, so we choose the number type. Choose a clear name for the Channel id. We will use "MGD1_potentiometer". Add a Label. This will show up in your Sitemap (e.g. MGD1 Potentiometer).
As we will only receive something on this Channel, we will only define the state topic (what we receive). This is the output topic of our device: "gen_mqtt_1/pot"". Add the min and max values. Click on SAVE.

The values for the servo will be the output. The values are between 0 and 180 and we choose the number type. Channel id will be "MGD1_sevo" and the Label "MGD1 Servo".
As we will only send something on this Channel, we will only define the command topic (what we send). This is the input topic of our device: "gen_mqtt_1/servo"". Add also the min and max values. Click on SAVE.

As seen everything in openHAB is happening through items. So we need to link our channels to items. To do this we click on the blue circle ◯ before a Channel and in "Please select the item to link" we choose Create new item....


In the Link Channel window we give the Item a name (e.g. MyGenericDevice1_Potentiometer), a Label (e.g MGD1 Potentiometer) and assign the Item to a Category (e.g. Potentiometer).

In the overview window we see that the e blue circle ◯ changed to a fisheye ◉ to indicate that the Channels are linked to items.

Go to the Control menu. Here we are now able to see the potentiometer value and to manipulate the servo.

gen_mqtt_1/pot_json. As we get a json string, we need a transformation to a number. To do so, click on SHOW MORE while configuring the Channel. Under "Incoming Value Transformations" add the following line to transform the json string to a number:JSONPATH:$.Pot_value
mappings=[0="Open", 90="Half", 180="Close"]
What would life be without rules :))
In an home automation system we want to automate things, so we need rules to do so. In openHAB the rules are defined in the .rules files. These files use a Domain Specific Language (DSL) near to Xtend, a general-purpose high-level programming language for the Java Virtual Machine. So if you want to dig deeper it is a goof idea to look here.
As in most programming languages we can import missing things and use our own variables, but for most things it suffices to program some instructions.
Let's look at a simple instruction line. Every rule begins with the keyword rule and has a minimum of one condition (when) and one or more instructions if the condition is fulfilled (then).
rule "<RULE_NAME>"
when
<TRIGGER_CONDITION> [or <TRIGGER_CONDITION2> [or ...]]
then
<SCRIPT_BLOCK>
end
Triggering a rule can mainly be:
As events can hardly occur at the exact same time we don't use logic AND combinations, but only OR combinations.
In the when block we use a trigger condition. Item based trigger conditions use the following syntax:
Item <item> received command [<command>]
Item <item> received update [<state>]
Item <item> changed [from <state>] [to <state>]
The then block includes a script to perform things we need. The language used is the same that is used in the Xtend language.
Let's cook a little rule. Our potentiometer should control the servo, but only in the range from 1000 to 2800, where 1000 = 0° and 2800 = 180°. The when is clear, as we need to react on a change of the potentiometer.

An now we code a little bit. The value of the pot object is to be found in the state variable. To facilitate the code we create our own integer variable to hold the value. For this we must cast the state to a number (as Number) and convert the number to an integer (.intValue). For the rest the xtend code is very similar to Arduino code (C++) and easily readable. More infos on the syntax can be found here. Use Visual Studio Code and a samba share to the log files to get help in the syntax and to control the outputs.

An important thing when handling data is the visualisation. Humans can much easier interpret behaviour of IoT devices from graphs than from columns and rows of data numbers.
But the first step of drawing graphs is to store data over time called persistence. OpenHAB persists Item states in a database. Most popular databases are supported and openHAB can even use multiple databases in parallel.
First we have to install a persistence. In PaperUI > Add-ons > PERSISTANCE we choose the RRD4j Persistence. This is a based on a round-robin database. A round-robin database does not grow in size. This is accomplished by saving a fixed amount of data points and by doing data compression, which means that the older the data is, the less values are available. To use this database in openHAB it is important to save data minimum once a minute.
If you can't install the Persistance, ssh in your raspi, and change the ownership of the /etc/openhab2 folder to user openhab:
sudo chown -hR openhab:openhab /etc/openhab2
This is necessary because we get here an older Binding (v 1.9) and it needs this ownership to write files to the right folder.
After installing we can revert to our user needed for the samba share:
sudo chown -hR weigu:weigu /etc/openhab2
First it is now important to select a default persistence service even if only one persistence add-on installed. Do this in PaperUI > Configuration > System. Don't forget to save.
Now the data is available, and we can add a graph to our sitemap.
Add the following lines to your sitemap. The period is 2 days (2D) and the graph is refreshed once a minute (60000 ms)

Here we see the result:



As stated, there exist two ways. Let's lock how to do it the hard way :) using text files. Text files are often better for big projects, because it is easier to duplicate Channels or Items.
More help can be found here.
We need a configuration text file for the Thing in /etc/openhab2/things/ with the ending .things (e.g. mymqtt.things).
Here an example:

\ marks a continuation of the lineIn the first line we find our broker. As the broker has a preconfigured ID (I forgot to give it a meaningful ID) we have to live with the cryptic numbers. Look for your ID in PaperUI.
Bridge mqtt:broker:6ff76698 [ host="192.168.1.60", secure=false ]
Next we configure our thing.
Thing topic MyGenericDevice2_pot_servo "MyGenericDevice2_pot_servo" @ "Luxembourg_LAM_SC"
The label and location ("MyGenericDevice2potservo" @ "LuxembourgLAMSC") are optional.
For the channels we need the Type and the Channel ID and in square brackets the topics (min and max are optional). If needed we can add a JSON transformation.
Channels:
Type number:MGD2_potentiometer "MGD2 Potentiometer" [stateTopic="gen_mqtt_2/pot",min=0,max=4095]
Type number:MGD2_potentiometer_j "MGD2 Potentiometer_j" [stateTopic="gen_mqtt_2/pot_json", \
min=0,max=4095,transformationPattern="JSONPATH:$.Pot_value"]
Type number:MGD2_servo "MGD2 Servo" [ commandTopic="gen_mqtt_2/servo", min=0, max=180]
Ass all MQTT things use the same server, they have to be declared in the same things file!
Link to openHAB doc on Things: https://www.openhab.org/docs/configuration/things.html.
We need a configuration text file for the Items in /etc/openhab2/items/ with the ending .items (e.g. mymqtt.items).
Here an example:

\ marks a continuation of the lineThe syntax for items is:
itemtype itemname "labeltext [stateformat]" <iconname> (group1, ...)["tag1", ...] {bindingconfig}
Fields must be entered in the order shown, itemtype and itemname are mandatory and all other fields are optional. Fields may be separated by one or more spaces, or tabs and an Item definition may span multiple lines.
The labeltext with the stateformat and the iconname are helpful for the sitemap and should be added. It is also important to add the right stateformat! If you get e.g. a float number and don't specify the %f you don't see a number in PaperUI Configuration or your Sitemap!
The most important part for mqtt binding is to link to the right channel ({bindingconfig}). Fortunately we can get the channel name from PaperUI! We find even an icon to copy the name.

Link to openHAB doc on Items: https://www.openhab.org/docs/configuration/items.html.
Change the topics (number 2 instead of 1) and reprogram your ESP. Create the Things and the Items config file as shown. Test the device in PaperUI control. Document the PaperUI control screen.
const char *MQTT_CLIENT_ID = "gen_mqtt_pot_servo_2";
const char *MQTT_TOPIC_OUT = "gen_mqtt_2/pot";
const char *MQTT_TOPIC_OUT2 = "gen_mqtt_2/pot_json";
const char *MQTT_TOPIC_IN = "gen_mqtt_2/servo";
When programming a home automation system, it is important to ask feedback from the people using the building! and to consider their wishes.
Without the people the automation will not work!
And don't forget to always add a manual override if possible.
If you want to create more complex charts or dashboards, with a database and the powerful graphics software Grafana, look here at the end of the page:
http://weigu.lu/sb-computer/sb_home_server/index.html.