【问题标题】:Raspberry RFSniffer read output with pythonRaspberry RFSniffer 使用 python 读取输出
【发布时间】:2014-11-15 17:52:01
【问题描述】:

我正在尝试运行 RFSniffer 进程以侦听传入的 433mhz 信号。

如果我运行该过程,它只会输出来自 433mhz 接收器的值。我想用 Python 读取此输出,以便执行特定操作。

我找到了很多方法来运行它并使用 Python 获取输出,但那些命令是自终止的 (ls -ial)。 RFSniffer 进程会一直运行,直到您手动停止为止。

这是我现在拥有的(不工作):

#!/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()

【问题讨论】:

  • 您能否更具体地说明什么不起作用?是不是你只得到了命令的部分输出?当您直接运行命令时(在 Python 之外),该命令的输出是什么样的?
  • 我没有得到任何输出,当我在 python 之外用完时输出是:收到 14446784 收到 14446640 收到 14446784 收到 14446784 收到 14446784
  • 您也可以编辑 RFSniffer.cpp 并重新编译它,这样它就可以直接写入文件或数据库中。

标签: python linux raspberry-pi


【解决方案1】:

这个解决方案应该有效:

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()

你可以把它放在一个while循环中不断扫描,直到找到一个参数。

这是我遇到的唯一一种可以将实时扫描(无限且不间断,不像 ls -l)输出到文件然后读取值的方法。

这是我使用蓝牙进行实时扫描的示例:

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"

【讨论】:

  • 不工作 :-( 语法错误:文件“test2.py”,readf 中的第 8 行 ^ SyntaxError:无效语法
  • 对不起,我在 for 语句之后错过了一个 :。我已经更新了代码。拼写错误我的错。
  • 脚本启动但没有将任何数据写入 output.txt,如果我在终端中直接使用 >output.txt 运行命令。 :(
  • 我更改了 RFSniffer.cpp 文件,以便它记录到一个文件中,现在它可以工作了,感谢您帮助我。
【解决方案2】:

如果它符合您的需求,您可以反过来做。我让我的 python 脚本从 RFSniffer 中调用,将信号作为参数传递。

我的 python 脚本类似于以下内容:

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:])

现在您需要编辑 RFSniffer.cpp 以在收到每个信号后调用您的 python 脚本。跟随 sn-p 连接在短时间内收到的所有信号代码,因为在遥控器上按一次有时会导致多个信号代码。因此,您的 python 脚本不是按信号而是按按钮调用的。 我不是 CPP 开发人员,所以请原谅我在这方面的笨拙做法(但是,嘿,它完成了它的工作;))

//[...]
#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());
          }
      }
      //[...]

所以它的作用是循环 10k 次以寻找新的“ReceivedValue”并等待 50 微秒。您可以根据需要调整这些参数。这意味着一个时间范围至少为半秒长,并且应该涵盖属于遥控器上单个按钮的所有信号。这些一对多的信号代码作为逗号分隔值传递给您的 python 脚本(参数 -s code1,code2,code3)。在脚本中随心所欲地使用它。 玩得开心。

【讨论】:

    【解决方案3】:

    由于@user1232869 没有分享他是如何修改RFSniffer.cpp 的,而且因为我对C++ 一点也不熟悉,所以我在分享它:)。您只需在文件中添加三行粗体即可。

    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();
    

    然后您可以正确使用@Jonathan Davies 的答案,因为&gt;output.txt 在我的 Pi 上也失败了。

    【讨论】:

      【解决方案4】:

      我使用了一个名为 pi-switch 的 python 库,它为 rc-switch C++ 库提供了一个包装器。 这个库可以在https://github.com/lexruee/pi-switch-python找到。

      rc-switch 是 RFSniffer 使用的库,因此使用 pi-switch 可以让您监听来自 python 的 433mhz 信号。

      我正在使用它来检测何时按下无线门铃。

      【讨论】:

      • 即使指向页面的链接很有用,但在 OP 问题的上下文中了解此类包装器的用法也会很有趣。
      • 谢谢,我已经修改了答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-10
      • 1970-01-01
      • 2022-10-21
      • 1970-01-01
      相关资源
      最近更新 更多