Reading Raspberry RFSniffer with python

I am trying to start the RFSniffer process to listen for incoming 433 MHz signals.

If I run the process, it just outputs the values ​​from the 433 MHz receiver. I want to read this output using Python so that I can perform certain actions.

I found many ways to run it and get output using Python, but the one where the commands that were completed by user ( ls -ial

). The RFSniffer process runs until you manually stop it.

This is what I have (doesn't work):

#!/usr/bin/python
# -*- coding: utf-8 -*-
import subprocess, time, os, sys

cmd = ["sudo", "/home/pi/433Utils/RPi_utils/RFSniffer"]

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=1)
for line in iter(p.stdout.readline, b''):
    print line,
p.stdout.close()
p.wait()

      

+3


source to share


4 answers


This solution should work:

os.system("sudo /home/pi/433Utils/RPi_utils/RFSniffer >output.txt & pkill --signal SIGINT RFSniffer")
f = open("output.txt","r")
readf = f.read()
for line in readf:
    print line,
#close file
if f.closed == "False":
    f.close()

      

You can put it in a while loop to scan continuously until a parameter is found.



This is the only way you can output the realtime scan (infinite and not stopping, not ls -l) to a file and then read the values.

Here is an example of one of my realtime scans using bluetooth:

sensortag=0
while sensortag != "B4:99:4C:64:33:E0":
    #call the command and write to scan.txt file and then fill the process.
    #loop to find if the MAC address given is available
    os.system("hcitool lescan> scan.txt & pkill --signal SIGINT hcitool")
    scan = open("scan.txt","r")
    readscan = scan.read()
    if "B4:99:4C:64:33:E0" in readscan:
        print "SensorTag found."
        sensortag = "B4:99:4C:64:33:E0"

      

+1


source


If it suits your needs, you can do it the other way around. I will let my python script be called from RFSniffer, passing signals as arguments.

My python script looks something like this:

import sys, getopt
import uuid

fileEnding = "txt"
fileFolder = "./sniffed"

def main(argv):
    opts, args = getopt.getopt(argv,"s:")

    for opt, arg in opts:
        if opt == '-s':
            filename = fileFolder + "/" + str(uuid.uuid4()) + "." + fileEnding
            with open(filename, 'w') as outfile:
                outfile.write(arg)

if __name__ == "__main__":
    main(sys.argv[1:])

      



Now you need to edit RFSniffer.cpp to call your python-script after every signal received. Once the code snippet is agreed, all signal codes received in a short amount of time, like one press on your remote, sometimes result in more than one signal code. This way your python script is not called for every signal, but for a button click. I'm not a CPP developer, so excuse my clumsy approach to this (but hey, it gets the job done;))

//[...]
#include <iostream>
#include <string>
#include <sstream>
#include <unistd.h>
//[...]
while(1) {
          int count = 0;
          std::string signals;
          signals = "";

          while (count < 10000) {
              if (mySwitch.available()) {
                    int value = mySwitch.getReceivedValue();

                    if (value == 0) {
                        printf("Unknown encoding\n");
                    } else {
                        std::string signal;
                        std::stringstream signalStream;
                        signalStream << value;
                        signal = signalStream.str();

                        if (signals.length() > 0) {
                            signals.append(",");
                        }
                        else {
                            // first receive, so reset timeframe here
                            count = 0;
                        }
                        signals.append(signal);
                        printf("Received %s\n", signal.c_str() );
                    }
                    mySwitch.resetAvailable();
              }
              usleep(50);
              count += 1;
          }
          if (signals.length() > 0) {
            std::string command;
            command.append("python3 /home/pi/your_script.py -s ");
            command.append(signals);
            printf("Call %s\n", command.c_str());
            system(command.c_str());
          }
      }
      //[...]

      

So what it does is it loops 10k times looking for a new "ReceivedValue" and waits for 50 microseconds. You can tweak these settings if you like. This means that one timeframe is at least half a second long and must cover all signals belonging to one button press on the remote. These to many signal codes are passed as comma separated values ​​to your python-script (argument -s code1, code2, code3). Do whatever you want inside your script. Have fun.

+1


source


Since @ user1232869 did not share how he did it to change RFSniffer.cpp

, and since it cost me a little time because I am not familiar with C ++ at all, I am sharing it :). You just need to add three highlighted lines to your file.

if (value == 0) {
      printf("Unknown encoding");
    } else {    

      printf("Received %i\n", mySwitch.getReceivedValue() );
      // These lines are the lines which interest you! :)
      FILE* pFile = fopen("/home/pi/logs.txt", "a");
      fprintf(pFile, "%i\n",mySwitch.getReceivedValue());
      fclose(pFile);
    }

    mySwitch.resetAvailable();

      

And then you can use @ Jonathan Davies' answer correctly because it >output.txt

failed on my Pi too.

0


source


I used a python library called pi-switch which provides a wrapper around the C ++ rc-switch library. This library can be found at https://github.com/lexruee/pi-switch-python

rc-switch is the library that RFSniffer uses, so with pi-switch you can listen for 433 MHz signals from python.

I use it to detect when a wireless doorbell has been pressed.

-1


source







All Articles