RFSniffer, 433MHz receiver RPI and MQTT


(Josar) #1

I just wrote a small program which publishes the received codes from a 433Mhz receiver to a MQTT broker.

It is based on RFSniffer from ninjablocks and is best place besides RFSniffer in RPI_utils as there is a relative depency for the RCSwitch.h.

My setup has mosquitto installed on the rpi and also the MQTT binding in OpenHAB.

Using is as simple as usig the RPI_Utils. Follow the instructions from the readme or this thread help getting everything in place.

Then download the RFmqtt place it into the folder RPI_Utils, change the Makefile, and compile it.
(Follow the instruction in the Github folder.)

Then you can run the “RFmqtt”

Following the Instructions configuring the OpenHAB MQTT binding to use the default FRmqtt values.
mqtt.cfg

mymosquitto.url=tcp://localhost:1883
mymosquitto.user=admin
mymosquitto.pwd=password

setting up some items
.items

String MQTT_data "MQTT says: [%s]" {mqtt="<[mymosquitto:433MHz:state:default]"}
Switch MQTT_Remote

and something on my sitemap to see the received data.
.sitemap

Text item=MQTT_data 
Switch item= MQTT_Remote 

E viola pressing my remote i recieve the data on my sitemap.
(On my smartphone as somehow my Firefox still does not update the view, Edge does, Chrome alos doesn’t)

As i don`t know jet how to get e.g a swtich trigger when a spicific code was received, i take the route over a rule.
.rules

rule "433MHz RX"
  when
    Item MQTT_data changed
 then
    switch MQTT_data.state {
      case "1328465": MQTT_Remote.postUpdate(ON)
      case "1328468": MQTT_Remote.postUpdate(OFF)
    }
 end

If you only have one code which is send multiple times it will not trigger the rule multiple times as openhab only forwards changed statuses. At least i think so. So just reset the MQTT_data in the rule.

.rules

rule "433MHz RX"
  when
    Item MQTT_data changed
 then
    switch MQTT_data.state {
      case "1328465": MQTT_Remote.postUpdate(ON)
      case "1328468": MQTT_Remote.postUpdate(OFF)
    }
    if(MQTT_data.state.toString !="") MQTT_data.postUpdate("")
 end

Maybe this helps other people having fun with openhab.


Receiving 433mhz and send to sonoff switch
OpenHAB Exec Binding explained in detail on 433MHz radio transmitter example
RF Receiver (XY-MK-5V 433Mhz) and RF Remote
Item changed fast (1s) but only last change is seen by rule?
(Ramy Rutu) #2

FIRST of all thanks a lot and much appreciated for your time Josar
i tried everything and nothing really change. I thing I have a problem because of the Door Sensor type I’m using ?!
here is what my files look like :

String MQTT_data "MQTT says: [%s]" {mqtt="<[mymosquitto:433MHz:state:default]"}


and my rules :

rule "433MHz RX"
  when
    Item MQTT_data received update
then
    switch MQTT_data.state {
      case "14756833": MQTT_Remote.postUpdate(ON)
      case "14756823": MQTT_Remote.postUpdate(OFF)
    }
end

my sitemaps :

sitemap home label="DoorSensor"

{
       Frame label="doorsensor"
       {
           Switch item=MQTT_Remote
           Text item=MQTT_data

       }
}

pi@raspberrypi:~/433Utils/RPi_utils $ ls
codesend  codesend.cpp  codesend.o  Makefile  README.md  RFmqtt.cpp  RFSniffer  RFSniffer.cpp  RFSniffer.o  send  send.cpp  send.o  wiringPi
pi@raspberrypi:~/433Utils/RPi_utils $


this is the door sensor I’m using : https://www.banggood.com/SONOFF-DW1-433Mhz-Door-Window-Sensor-Compatible-With-RF-Bridge-For-Smart-Home-Alarm-Security-p-1227800.html?gmcCountry=CA&currency=CAD&createTmp=1&cur_warehouse=CN&utm_source=googleshopping&utm_medium=cpc_elc&utm_content=zouzou&utm_campaign=pla-ca-elc2-pc-en&gclid=Cj0KCQiAnuDTBRDUARIsAL41eDo_otAuoYXgKRWfkFoHXfpPGJUAZfZYg8Q-OdfknEc-PqaPDN7VXuUaAiGZEALw_wcB

I checked the sensor in terminal and its working, its connected to gpio 27. I don’t have an off or on code I only have one code to receive when the door sensor magnet is not in place, code = 14756833


(Josar) #3

Do you receive data when running RFsniffer?

./RFSniffer

Do you recieve data when running RFmqtt?

./RFmqtt

If not you have to check you setup. You need the cables connected to the PI, VCC, GND and BMC27/WiringPi2.

Then did you set up Mosquitto and tried to send data from a client to a server in the commandline?

Did you set up the MQTT binding an can send something to the MQTT_data ? Can you see the MQTT binding receiving data in the log?

I miss MQTT_Remote in your items.

If this works, then you will need a rule which triggers on the command you receive.

rule "433MHz RX"
  when
    Item MQTT_data received update
then
    switch MQTT_data.state {
      case "14756833": MQTT_Remote.postUpdate(ON)
    }
end

Will the code be send in intervalls as long as it is open? Or only once?
Will the code be send when the door opens and closes?
Depending on this you will have to desing the rule.


(Ramy Rutu) #4

i do receive data when running RFSniffer

when I run RFmqtt I get this error :

pi@raspberrypi:~ $ sudo systemctl status rfmqtt.service
● rfmqtt.service - RF 433MHz to MQTT bridge
Loaded: loaded (/etc/systemd/system/rfmqtt.service; disabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Wed 2018-02-07 22:33:37 UTC; 30min ago
Main PID: 28309 (code=exited, status=203/EXEC)

Feb 07 22:33:36 raspberrypi systemd[1]: rfmqtt.service: Unit entered failed state.
Feb 07 22:33:36 raspberrypi systemd[1]: rfmqtt.service: Failed with result ‘exit-code’.
Feb 07 22:33:37 raspberrypi systemd[1]: rfmqtt.service: Service hold-off time over, scheduling
Feb 07 22:33:37 raspberrypi systemd[1]: Stopped RF 433MHz to MQTT bridge.
Feb 07 22:33:37 raspberrypi systemd[1]: rfmqtt.service: Start request repeated too quickly.
Feb 07 22:33:37 raspberrypi systemd[1]: Failed to start RF 433MHz to MQTT bridge.
Feb 07 22:33:37 raspberrypi systemd[1]: rfmqtt.service: Unit entered failed state.
Feb 07 22:33:37 raspberrypi systemd[1]: rfmqtt.service: Failed with result ‘exit-code’.
lines 1-13/13 (END)

I don’t know how to compile and when I try to use make or cmake I get this error : Makefile:7: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.

MOSQUITTO its running and I have tested already using MQttfx for Windows
MQTT binding its installed

I think my compiling not done and I don’t know how and when I try to follow the steps on GitHub I get the error above when I use make


(Josar) #5

First, when you copy the makefile content make sure to have a tab instead of spaces. Then the compilation should work.

RFmqtt: ../rc-switch/RCSwitch.o RFmqtt.o
[This are no spaces it´s a tab]$(CXX) $(CXXFLAGS) $(LDFLAGS) $+ -o $@ -lwiringPi -lmosquitto

(Ramy Rutu) #7

Hey,
so I have been trying to solve my issue but I’m only getting more errors…

First : when I try to compile and install Cmake or make after going to bunch of missing librs, when I click make install I get this error here

-- Install configuration: ""
-- Up-to-date: /usr/local/doc/cmake-3.10.2/Copyright.txt
CMake Error at cmake_install.cmake:41 (file):
  file INSTALL cannot set permissions on
  "/usr/local/doc/cmake-3.10.2/Copyright.txt"


Makefile:73: recipe for target 'install' failed
make: *** [install] Error 1

``
that's after loading to 100%
than when I navigate to 433Utils/RPi_utils and than CD BUILD than 
cmake -GNinja .. i get this error 

CMake Error at CMakeLists.txt:4:
Parse error. Expected a newline, got identifier with text “set”.

– Configuring incomplete, errors occurred!

i am lost in this ... should i start again from scratch ?

here is what my files look like : 

pi@raspberrypi:~/433Utils/RPi_utils $ ls
build codesend README.md RFmqtt.o send
CMakeCache.txt codesend.cpp RFmqtt RFSniffer send.cpp
CMakeFiles codesend.o RFmqtt.cpp RFSniffer.cpp send.o
CMakeLists.txt Makefile rfmqtt.git RFSniffer.o wiringPi

pi@raspberrypi:~ $ ls
433Utils
blanktest.py
cmake-3.10.2
cmake-3.10.2.tar.gz
config.yaml
Desktop
Documents
Downloads
led.py
mosquitto
mosquitto-repo.gpg.key
motoplotlib
Music
paho.mqtt.python
pberrypi:~ $ sudo systemctl status rfmqtt.service
Pictures
Public
python_games
RandomStuff
recieve.py
rfmqtt.git
RGBREMOTE.lircd.conf
rpitx
send.py
service
SONY.lircd.conf
SourceCode
Templates
TV.lircd.conf
udo systemctl daemon-reload
Videos
wiringPi
ystemctl enable openhab2.service

(Josar) #8

@ramy_rutu please have a look at your post, i think there is something wrong with your markdown (definition of how the post should look like).

Mostly the bad format comes from copy code and then add the fences by pressing the button. Always first set the code fence and then copy the code into it.

  1. Can you download and the standart 433Utils/RPi_utils and compile with make?
  2. Can your run ./send xxx or ./RFSniffer ?
  3. Then copy the RFmqtt.cpp to the folder RPi_utils and add the additional line to the makefile.
  4. install the libraries sudo apt-get install libmosquitto-dev
  5. execute make

Please comment each of these steps and what result you get.


(Olaf Roehnert) #9

Hi Josar,
first of all thanks for great work. After install I will received signals from door sensor. In my rule I will send it to mail when state going on, and here is my Problem the sensor send the code 3 to 5 times and I received for every an email. My sensor send the code only when contact is broken. Do you have an idea that only the first received logged?
Greets Olaf


(Josar) #10

So i don’t know your setting and rule but ussually the item receiving the command do not change mutliple times. Use a rule which reacts on changed this wil prevent the rule to trigger multiple times.

So when you have a item which collects teh RF data use a rule that distributes the recieved commands to different sensor items your problem should not occur.

String MQTT_data "MQTT stest says: [%s]" {mqtt="<[mymosquitto:433MHz:state:default]"}
Group RfSensors
String MQTT_sensor_1 (RfSensors)
String MQTT_sensor_2 (RfSensors)
String MQTT_sensor_3 (RfSensors)
rule "433MHz rx"
  when
    Item MQTT_data changed
 then
    switch MQTT_data.state {
      case "1328465": MQTT_sensor_1.postUpdate(ON)
      case "1328468": MQTT_sensor_2.postUpdate(ON)
      case "1328491": MQTT_sensor_3.postUpdate(ON)
    }
    // This makes the item MQTT_data change again when the same command is recieved.
    if(MQTT_data.state.toString !="") MQTT_data.postUpdate("")
end
rule "Email Notification"
  when
    Member of RfSensors changed
    // This rule trigger works only since openhab 2.3.0 Build #1212.
    // But you can use multiple trigger for know untill you update
    // Item MQTT_sensor_1 changed or 
    // Item MQTT_sensor_2 changed or
    // Item MQTT_sensor_3 changed
 then
   // Trigger your email
    logInfo("RuleExamples", "The item " + triggeringItem.name +  " changed state from " 
                            + previousState +  " to " + triggeringItem.state)
end

If you only have one sensor and receive the data to one item in this case MQTT_data then there should be no multiple changes on your item.

But you could also post different Topics from the c code dependend from the received code.


OpenHAB Exec Binding explained in detail on 433MHz radio transmitter example
(Mark Lavercombe) #11

Great job, @Josar. Thanks for sharing. I have it working really well.

I do have a query though: I would like to do some processing of the received signals before sending them to mqtt, as I want to receive temperature/humidity sensors and they have encoded values.

The code I use on arduino to interpret the signals is as follows:

/* v0.1
 * Jaakko Ala-Paavola
 * 2011-02-27
 */

#define TIMEOUT 1000
#define BIT0_LENGTH 2000
#define BIT1_LENGTH 1000
#define VARIATION 500
#define DATA_LENGTH 5
#define SENSOR_COUNT 4
#define NETWORK_COUNT 1
#define MSGLENGTH 36

struct sensor {
  unsigned char humidity;
  signed char   temp_int;
  unsigned char temp_dec;
};

unsigned long time;
unsigned char bitcount = 0;
unsigned char bytecount = 0;
unsigned char second_half = 0;
unsigned char data[DATA_LENGTH];
struct sensor measurement[NETWORK_COUNT][SENSOR_COUNT];

/* This function is executed when state change occurs in external interrupt 0 */
void receive()
{
    unsigned char i;
    unsigned char bit;
    unsigned long current = micros();
    unsigned long diff = current-time;
    time=current;
      
    if ( diff < BIT0_LENGTH + VARIATION && diff > BIT0_LENGTH - VARIATION )
     {
        bit = 0;
        second_half = 0;
     }
     else if ( diff < BIT1_LENGTH + VARIATION && diff > BIT1_LENGTH - VARIATION )
     {
       if (second_half)
       {
         bit = 1;
         second_half = 0;  
       }
       else
       {
         second_half = 1;
         return;
       }
     }
     else 
     {
      goto reset;
     }
     
     data[bitcount/8] = data[bitcount/8]<<1;
     data[bitcount/8] |= bit;
     bitcount++;
     
     if ( bitcount == 4 )
     {
       if ( data[0] != 0x0c )
         goto reset;
       bitcount = 8;
     }

     if ( bitcount >= MSGLENGTH )
     {
       unsigned char net, id;
       int t_int;
       unsigned char rh, t_dec;

       Serial.print("ID:");
       id = 0x03 & (data[1]>>2);
       Serial.print(id, DEC);
       Serial.print(" RH:");
       rh = data[2];
       Serial.print(rh, DEC);
       Serial.print(" T:");
       t_int = data[3]-50;
       Serial.print(t_int, DEC);
       t_dec = data[4]>>1;
       Serial.print('.');
       Serial.print(t_dec,DEC);     
       Serial.print("\r\n");
            
       if ( net <= NETWORK_COUNT )
       {
         measurement[net][id].temp_int = t_int;
         measurement[net][id].temp_dec = t_dec;
         measurement[net][id].humidity = rh;
        }
       goto reset;  
     }
    return;

reset: 
  for (i=0; i<DATA_LENGTH; i++)
    data[i] = 0;

   bytecount = 0;
   bitcount = 0;
   second_half = 0;
   return;
}

void setup()
{
  unsigned char i,j;
  unsigned long t_epoch;
  
  Serial.begin(115200);
  Serial.println("Info: Starting Wireless Sensors Gateway");
  
  for (j=0; j<NETWORK_COUNT; j++)
  {
    for (i=0; i<SENSOR_COUNT; i++)
    {
      measurement[j][i].temp_int = 0;
      measurement[j][i].temp_dec = 0;
      measurement[j][i].humidity = 0;
    }
  }

  Serial.println("Info: IO initialization");
  attachInterrupt(0,receive,CHANGE);
  
  time = micros();
  Serial.println("Info: ### Setup done. Ready for operation. ###");
}

#define BUFFER_SIZE 6
void loop()
{
}

Are you able to give me any suggestions on how to insert this into the RFmqtt.cpp file? Obviously the void setup and loop sections can go, but any other suggestions would be appreciated.
Thanks in advance!


(Josar) #12

You want to send some data with a 433 transciever from an arduino to the RPi and split this telegram into two mqtt messages? Did i understand this right?

Or do you get a 433 RF signal which you used to decode with an arduino but now you like to decode it with the RPI?

Can you receive the message with the RPI? And how does this look like when you receive it?


(Vlad Martin) #13

@Josar, thanks for the cpp hack! I compiled it nicely and when I run locally i can see the rf messages received and dropped to STDOUT. However for some reason I cannot publish to the mqtt queue… any ideas? (my mqtt config does not have user or password)

the run line looks like this:
./RFmqtt -t “433receiver” -h 192.168.xxxx.xxx -w 400

Also, I do not see the -w having any effect…

Thanks for your work!

EDIT

Fixed: around line 144

 ret = mosquitto_publish (mosq, NULL, &MQTT_TOPIC[0u], strlen (valueStr), valueStr, 0, false);

change &MQTT_TOPIC[0u] to topic

 ret = mosquitto_publish (mosq, NULL, topic, strlen (valueStr), valueStr, 0, false);

(Josar) #14

Seems there are still some minor bugs. Thanks for pointing this out.


(Nico H) #15

Is it possible to use the RFSniffer with a NanoCul-USB-Stick ?

Thanks in advance