我正在尝试获取一些传感器数据,以便将其放入 influxdb 中。 我们有非常旧的传感器,通过服务器上的 fifo 将其写入服务器。 我知道我可以读它(制作了一个快速程序):
# reader.py
import os
FIFO = '/var/axis/sensor1'
FIFO_PATH = FIFO
fifo_path = FIFO
print("about to "+fifo_path)
# Ensure the FIFO exists
if not os.path.exists(fifo_path):
raise IOError("The FIFO '{0}' does not exist. Please create it using 'mkfifo {0}'.".format(fifo_path))
print("Opening FIFO {0} for reading...".format(fifo_path))
fifo_fd = os.open(fifo_path, os.O_RDONLY)
fifo_file = os.fdopen(fifo_fd)
try:
while True:
line = fifo_file.read(1)
if not line:
break
# Print the line to the screen
print(line),
finally:
fifo_file.close()
print("FIFO Closed.")
因此,当我运行此命令并且传感器正在运行数据时,我会看到类似这样的内容滚动经过屏幕:
@eN?>??Y?n??A?)??[Z@?c
@eN?>??\?n??A?)??[Z@?(
@eN?>`?n??A?)??[Z@?? @eN?>33c?n??A?)??[Z@?? @eN?>fff?n??A?)??[Z@?? @eN?>??i?n??A?)??[Z@? @eN?>??l?n??A?)??[Z@? @eN?>p?n??A?)??[Z@? @eN?>33s?n??A?)??[Z@? @eN?>ffv?n??A?)??[Z@? @eN?>??y?n??A?)??[Z@? @eN?>??|?n??A?)??[Z@? @eN?>??n??A?)??[Z@? @eN?>33??n??A?)??[Z@? @eN?>ff??n??A?)??[Z@? @eN?>????n??A?)??[Z@? @eN?>?̌?n??A?)??[Z@? @eN?>??n??A?)??[Z@? @eN?>33??n??A?)??[Z@? @eN?>ff??n??A?)??[Z@? @eN?>????n??A?)??[Z@? @eN?>?̜?n??A?)??[Z@? @eN?>??n??A?)??[Z@? @eN?>33??n??A?)??[Z@? @eN?>ff??n??A?)??[Z@? @eN?>????n??A?)??[Z@? @eN?>?̬?n??A?)??[Z@? @eN?>??n??A?)??[Z@? @eN?>33??n??A?)??[Z@? @eN?>ff??n??A?)??[Z@? @eN?>????n??A?)??[Z@? @eN?>?̼?n??A?)??[Z@? @eN?>??n??A?)??[Z@? @eN?>33??n??A?)??[Z@? @eN?>ff??n??A?)??[Z@? @eN?>????n??A?)??[Z@? @eN?>????n??A?)??[Z@? @eN?>??n??A?)??[Z@? @eN?>33??n??A?)??[Z@? @eN?>ff??n??A?)??[Z@? @eN?>????n??A?)??[Z@? @eN?>????n??A?)??[Z@? @eN?>??n??A?)??[Z@? @eN?>33??n??A?)??[Z@@eN?>ff??n??A?)??[Z@? @eN?>????n??A?)??[Z@? @eN?>????n??A?)??[Z@? @eN?>??n??A?)??[Z@? @eN?>33??n??A?)??[Z@? @eN?>ff??n??A?)??[Z@? @eN?>????n??A?)??[Z@? @eN?>????n??A?)??[Z@P? @???z?>?n??A?)??[Z@?~
@???z?>33?n??A?)??[Z@?_
@???z?>ff?n??A?)??[Z@??
显然 readline 是错误的命令,我猜这个数据是二进制的? fifo总是二进制的吗? 如果它是二进制的,这意味着我必须找出这个旧系统/传感器是如何编写这个 fifo 的,才能知道如何加载和解析它?
我想知道我在读什么,所以我知道如何将其打包为 json 发送到 influxdb。
编辑:我相信我找到了一些读取数据结构示例的c代码,使用该结构我可以在python中读取它吗?
C 数据结构:
typedef struct axis_data {
double now;
double p;
double v;
double current;
double error;
} AXIS_DATA;
fifoList.fd = open("/var/axis/sensor1", O_RDONLY);
AXIS_DATA data;
rb=read(this->fifoList.fd, &data, sizeof(data));
data.p, data.v, data.current, data.error
当然是释义 C,我的 C 很生疏,但我相信我想做同样的事情,在 Python 中创建一个等效结构并将该结构大小读入结构本身。 不知何故,在Python中,我在下面的尝试(我不敢相信我从来没有在Python中真正做过二进制)
# reader.py
import os
from ctypes import *
class AXIS_DATA(Structure):
_fields_ = [('now', c_double),
('p', c_double),
('v', c_double),
('current', c_double),
('error', c_double)]
FIFO = '/var/axis/sensor1'
#FIFO = 'mytest'
FIFO_PATH = FIFO
fifo_path = FIFO
print("about to "+fifo_path)
# Ensure the FIFO exists
if not os.path.exists(fifo_path):
raise IOError("The FIFO '{0}' does not exist. Please create it using 'mkfifo {0}'.".format(fifo_path))
print("Opening FIFO {0} for reading...".format(fifo_path))
fifo_fd = os.open(fifo_path, os.O_RDONLY)
#fifo_file = os.fdopen(fifo_fd)
fifo_file = open(fifo_path)
try:
while True:
result = []
dat = AXIS_DATA()
# this just froze
while fifo_file.readinto(dat) == sizeof(dat):
result.append((dat.now, dat.p, dat.v, dat.current, dat.error))
if not line:
break
# Print the line to the screen
print(result),
finally:
fifo_file.close()
print("FIFO Closed.")
“fifo 总是二进制吗?”
他们对他们“携带”的数据不可知。 就像文件、套接字等一样。
您看到的乱码看起来像是被(错误地)读取为 UTF-8 编码文本的二进制数据。 (
?
字符很可能是无法转换为可打印字符的字节/字节序列的替代。)
将数据视为文本的方法不太可能起作用......因为
?
替换正在丢失信息。 看来您需要对传感器输出的二进制格式进行逆向工程。
一旦你弄清楚了二进制格式,你应该能够借助内置的 Python
struct
库来读取它。