Table of Contents
Integrate rtl_433 sensors into openHAB via MQTT
Since rtl_433 now has the ability to directly publish sensor data to a MQTT broker, it's reasonably easy to integrate with MQTT-enabled automation solutions.
This HowTo could serve as a blueprint for integrating two different types of sensors into home automation solution openHAB
We focus here on the rtl_433 side and assume you are familiar with openHAB and its basic concepts (Things, Channels, Items ...
) and that you have a MQTT broker (preferably Mosquitto) running.
1. Getting the devices received by rtl_433
When starting with rtl_433 the first thing to check is whether the device is already "known" to rtl_433 and has a dedicated decoder implemented. If so, we can simply read values from this device by specifying the right protocol.
As an example of this kind of devices we use a Globaltronic GT-WT02
, a simple temperature/humidity transmitter sold with different weather stations.
To gather data from it, we can simply start rtl_433
while specifying the right protocol to receive - -R 25
in this case:
# rtl_433 -R 25
<---OUTPUT OMITTED---->
Tuner gain set to Auto.
Tuned to 433.920MHz.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time : 2019-08-30 13:48:12
model : GT-WT02 ID Code : 215
Channel : 1 Battery : OK Button : 0 Temperature: 26.3 C Humidity : 54 % Integrity : CHECKSUM
^CSignal caught, exiting!
The second type of device is not directly supported by the rtl_433 and has no built-in decoder yet. Fortunately, many such devices can be decoded by a so-called "flex decoder".
Our example here is a cheap EV1527-base motion detector. To get notifications from it, we specify a flex decoder specification like this:
-R 0 -X n=EV1527-PIR,m=OOK_PWM,s=400,l=1200,g=1500,r=12000,repeats>=4,rows=25,unique
# rtl_433 -R 0 -X "n=EV1527-PIR,m=OOK_PWM,s=400,l=1200,g=1500,r=12000,repeats>=4,rows=25,unique"
<---OUTPUT OMITTED>
Tuner gain set to Auto.
Tuned to 433.920MHz.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time : 2019-08-30 14:00:30
model : EV1527-PIR count : 25 num_rows : 25 len : 25 data : 1234567
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
time : 2019-08-30 14:00:39
model : EV1527-PIR count : 25 num_rows : 25 len : 25 data : 1234567
^CSignal caught, exiting!
Good. Messages from "unsupported" motion detector can be received too.
2. Publish output to MQTT
MQTT is the "swiss army knife" to integrate IoT components via simple attribute/value peers ("topics"). These topics are published to an "MQTT broker".
Clients interested in these topics can subscribe to them.
We choose the MQTT output by the -F mqtt://....
option, e.g.:
-F mqtt://localhost:1883,retain=0,devices=sensors/rtl_433/
and check whether the output is sent to the broker:
#rtl_433 -R 0 -X "n=EV1527-PIR,m=OOK_PWM,s=400,l=1200,g=1500,r=12000,repeats>=4,rows=25,unique" -F mqtt://localhost:1883,retain=0,devices=sensors/rtl_433/
<---OUTPUT OMITTED--->
Tuner gain set to Auto.
Tuned to 433.920MHz.
MQTT Connected...
MQTT Connection established.
On a second terminal screen we subscribe to sensors/#
to observe incoming topics starting with "sensors/
":
# mosquitto_sub -v -t sensors/#
sensors/rtl_433//time 2019-08-30 14:14:38
sensors/rtl_433//count 25
sensors/rtl_433//num_rows 25
sensors/rtl_433//len 25
sensors/rtl_433//data 1234567
Well - works too. We get topics created for our motion sensor....
3. Prettifying the output
To simplify the consumption of the published content by openHAB (as well as by other MQTT clients) it helps a lot if we slightly modify or format the topics:
-F mqtt://localhost:1883,retain=0,devices=sensors/rtl_433/P[protocol:255]/C[channel:0] -M newmodel -M protocol -M time:iso
This does the following:
-M newmodel
... use revised model names and MQTT topics (will become default some day)
-M protocol
... outputs the protocol number along with the other output
[protocol:255]
... placeholder for the protocol number if defined, otherwise set to "255"
[channel:0]
... placeholder for the channel ID if defined, otherwise set to "0"
-M time:iso
... generate time topics which can be directly sent to openHAB's DateTime
items
Putting this all together in one command line gives us:
rtl_433 -R 25 -X "n=EV1527-PIR,m=OOK_PWM,s=400,l=1200,g=1500,r=12000,repeats>=4,rows=25,unique" -F mqtt://localhost:1883,retain=0,devices=sensors/rtl_433/P[protocol:255]/C[channel:0] -M newmodel -M protocol -M time:iso
which generates these pretty topics at the broker:
# mosquitto_sub -v -t sensors/#
sensors/rtl_433/P25/C3/time 2019-08-30T14:23:25
sensors/rtl_433/P25/C3/protocol 25
sensors/rtl_433/P25/C3/id 20
sensors/rtl_433/P25/C3/channel 3
sensors/rtl_433/P25/C3/battery_ok 1
sensors/rtl_433/P25/C3/button 0
sensors/rtl_433/P25/C3/temperature_C 28.400000
sensors/rtl_433/P25/C3/humidity 38.000000
sensors/rtl_433/P25/C3/mic CHECKSUM
sensors/rtl_433/P255/C0/time 2019-08-30T14:23:25
sensors/rtl_433/P255/C0/count 25
sensors/rtl_433/P255/C0/num_rows 25
sensors/rtl_433/P255/C0/len 1
sensors/rtl_433/P255/C0/data 8
sensors/rtl_433/P255/C0/time 2019-08-30T14:23:26
sensors/rtl_433/P255/C0/count 25
sensors/rtl_433/P255/C0/num_rows 25
sensors/rtl_433/P255/C0/len 25
sensors/rtl_433/P255/C0/data 1234567
So for the GT-WT-02 we get for example:
sensors/rtl_433/P25/C3/temperature_C 28.400000
Protocol==25
Channel == 3 (set by the tiny switch at the back of the sensor)
Temperature == 28.4 degree celsius
4. Convert the settings to a configuration file
The command line got pretty long meanwhile. This is neither easy to read nor to change if needed.
Luckily we can put all that configuration stuff into a configuration file. A sample is provided along with the rtl_433.
Rtl_433 looks for it (rtl_433.conf
) by default in different locations.
If we put our configfile in one of these default locations, we don't even need to specify the file at launch, rtl_433 will honor it. If you store it somewhere else or use a different name you can pass it by the -c <path/configfile>
.
Let's copy the sample config file to /etc/rtl_433/rtl_433.conf :
cp conf/rtl_433.example.conf /etc/rtl_433/rtl_433.conf
and add, uncomment and/or modify the following lines:
# to get the "protocol"-token available in output and set the time output to ISO
report_meta protocol
report_meta time:iso
# specify MQTT output and formatting
output mqtt://localhost:1883,retain=0,devices=sensors/rtl_433/P[protocol:255]/C[channel:0]
# enable the needed protocol (25 in our example)
protocol 25 # GT-WT-02 Sensor
# create the flex decoder specification
decoder {
n=EV1527-PIR,
m=OOK_PWM,
s=400,
l=1200,
g=1500,
r=12000,
repeats>=4,
rows=25,
get=@0:{25}:channel:[1234567:10 2345678:20],
get=@0:{1}:command:[0:OPEN 1:OPEN],
unique
}
You may have noticed the two get=
statements in the flex decoder which have been added compared to the former command line. This is the idea behind:
get=@0:{25}:channel:[1234567:10 2345678:20]
sets a channel
-token to 10
or 20
based on the unique EV1527-ID in the data
get=@0:{1}:command:[0:OPEN 1:OPEN]
adds a command
-topic with value always set to OPEN
to assist openHAB integration
7. Make rtl_433 controlled by systemd
You certainly want to have rtl_433 starting automatically every time your system boots. Systemd can do this for us...
Create the /etc/systemd/system/rtl_433-mqtt.service with this content:
# more /etc/systemd/system/rtl_433-mqtt.service
[Unit]
Description=rtl_433 to MQTT publisher
After=network.target
[Service]
ExecStart=/usr/local/bin/rtl_433
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Make it automatically start at system start:
#systemctl enable rtl_433-mqtt.service
Start the service:
#systemctl start rtl_433-mqtt.service
6. Create your openHAB MQTT things
In the openHAB thing configuration folder, we create a MQTT bridge definition along with channels matching our MQTT topics from above:
/etc/openhab2/things/mqtt.things:
Bridge mqtt:broker:MY-MQTT "MQTT Broker" @ "Central functions" [
host="192.168.x.y",
secure=false,
port=1883,
qos=0,
retain=false,
clientid="Oh2Mqtt2Thing",
keep_alive_time=30000,
reconnect_time=60000
]
{
Thing topic RTL_433 "433MHz receiver" @ "Central functions" {
Channels:
Type number : temp [ stateTopic="sensors/rtl_433/P25/C3/temperature_C" ]
Type number : hum [ stateTopic="sensors/rtl_433/P25/C3/humidity" ]
Type switch : batt [ stateTopic="sensors/rtl_433/P25/C3/battery_ok"]
Type contact: motion1 [ stateTopic="sensors/rtl_433/P255/C10/command" ]
Type datetime: motion1_time [ stateTopic="sensors/rtl_433/P255/C10/time" ]
}
}
Now you likely see why we publish a command==OPEN
when motion is detected:
The motion1-channel is of type contact
which supports just the two states OPEN
and CLOSED
.
Directly sending OPEN
makes it easy to configure without any further logic to translate (see: transformations) other values to OPEN
.
You might need to restart the MQTT binding at this point.
7. Configure the matching openHAB items
Now we are going to link the configured channels to the real items which we can use in rules or UIs:
Number Temp1 "Temperature [%.1f °C]" <temperature> { channel="mqtt:topic:MY-MQTT:RTL_433:temp"}
Number Hum1 "Humidity [%d %%rH]" <humidity> { channel="mqtt:topic:MY-MQTT:RTL_433:hum"}
Switch Bat1 "Battery o.k." { channel="mqtt:topic:MY-MQTT:RTL_433:batt"}
Contact Motion1 "Motion" <lock> { channel="mqtt:topic:MY-MQTT:RTL_433:motion1", expire="10s, state=CLOSED" }
DateTime Motion1_time "last detection" <motion> { channel="mqtt:topic:OGV-MQTT:RTL_433:motion1_time" }
8. Observe the log
Start the openHAB logviewer and look for the just created items getting populated:
2019-08-30 15:17:23.895 [vent.ItemStateChangedEvent] - Temp1 changed from UNDEF to 26.600000
2019-08-30 15:17:23.903 [vent.ItemStateChangedEvent] - Hum1 changed from UNDEF to 52.000000
2019-08-30 15:18:00.555 [vent.ItemStateChangedEvent] - Motion1 changed from CLOSED to OPEN
2019-08-30 15:18:11.470 [vent.ItemStateChangedEvent] - Motion1 changed from OPEN to CLOSED
Have fun ;-)