是否有可能读出node.js中的物理键盘笔画?

我有一个运行在树莓派上的节点应用程序,可以跟踪一堆UPnP播放器(Sonos),我希望能够通过物理遥控器进行控制。 我有几个airmouses,有小键盘以及音量button,我想使用。

我试图掌握如何读取Linux机器上的物理按键,并得出结论,我需要从input设备读取事件,在我的情况下是这样的:

/dev/input/by-id/usb-Dell_Dell_QuietKey_Keyboard-event-kbd 

如何find这样的设备和东西不是一个问题,真正的问题是如何解读您从中读取的数据。

我知道你会收到一个C结构,像这样:

 struct input_event { struct timeval time; unsigned short type; unsigned short code; unsigned int value; }; 

但我不知道我会怎么去读这个节点。 如果我可以运行一个外部应用程序,它将从预定义的击键触发,然后调用一个HTTP请求对我的节点,这将是我的第二个select,一个Python脚本或一些本地守护进程。 然而,我看了一些热门的守护进程,但没有一个能够工作。

如果我能以某种方式将它包含在节点中,当然会很好。

编辑:所以我做了一些testing,并做了一个简单的片段:

 var fs = require('fs'); var buffer = new Buffer(16); fs.open('/dev/input/by-id/usb-HJT_Air_Mouse-event-kbd', 'r', function (err, fd) { while (true) { fs.readSync(fd, buffer, 0, 16, null); console.log(buffer) } }); 

这输出这样的东西(空间):

 <Buffer a4 3e 5b 51 ab cf 03 00 04 00 04 00 2c 00 07 00> <Buffer a4 3e 5b 51 c3 cf 03 00 01 00 39 00 01 00 00 00> <Buffer a4 3e 5b 51 cb cf 03 00 00 00 00 00 00 00 00 00> <Buffer a4 3e 5b 51 ba 40 06 00 04 00 04 00 2c 00 07 00> <Buffer a4 3e 5b 51 cd 40 06 00 01 00 39 00 00 00 00 00> <Buffer a4 3e 5b 51 d2 40 06 00 00 00 00 00 00 00 00 00> 

我意识到,前四个字节是某种时间戳,下面的3个字节可能是微/毫秒的东西。

另一个奇怪的是,并不是所有的按键都能产生输出,但是随后的按键可能会发送两倍的数据,而且大多数时候它会开始输出在随后的按键之后停止的数据(或大约20秒左右)。 我真的不知道如何解释。 我已经尝试阅读这个守护进程https://github.com/baskerville/shkd/blob/master的源代码,但C不是我最强的语言,我不能确定他是如何处理它(或者如果它甚至应该被处理)。 而这个守护进程甚至没有为我工作(编译在一个覆盆子pi)。

Solutions Collecting From Web of "是否有可能读出node.js中的物理键盘笔画?"

那么让我们来看看这个结构。

 struct input_event { struct timeval time; unsigned short type; unsigned short code; unsigned int value; }; 

struct timeval有这样的结构:

 struct timeval { __time_t tv_sec; /* Seconds. */ __suseconds_t tv_usec; /* Microseconds. */ }; 

这些时间类型的定义是

 typedef signed long time_t; typedef signed long suseconds_t; 

一个有signed long是4个字节(好吧,如果你只是按照规范,但实际上,这是),所以前8个字节是一个类型戳。 接下来,你有一个类型和一个代码。 两者都很short ,所以在实践中,它们每个都是2个字节。 现在只剩下值了,这又是一个int,它将是四个字节。 此外,编译器理论上可以在这里的字段之间添加填充,但是我确信他不会。

因此,首先将您读取的字节分成4+4+2+2+4=16个字节的块。 每个块都是一个事件。 这适合您的示例数据。 接下来,从缓冲区中提取值(作为小端值,因为您在ARM系统上 – 在普通PC上,您需要大端)并解释这些值。 有关如何操作的说明,请阅读http://www.mjmwired.net/kernel/Documentation/input/event-codes.txt 。 常量的值不会写在那里,但通常可以使用grep -R NAME_OF_CONSTANT /usr/include找到那些值。

我们砍了

 <Buffer a4 3e 5b 51 ab cf 03 00 04 00 04 00 2c 00 07 00> 

举个例子。

 <Buffer a4 3e 5b 51 ab cf 03 00 04 00 04 00 2c 00 07 00> | tv_sec | tv_usec |type |code | value | 

十六进制中的tv_sec0x515b3ea40x515b3ea4 ,因为它是小端),这是十进制的1364934308 。 一个简单的unix时间转换器报告,这意味着02.04.2013 - 22:25:08 。 看起来不错!

tv_usec0x0003cfab=249771 ,事实上,事件发生在249771微秒之后。

类型是0x0004=4/usr/include/linux/input.h告诉我们这是一个EV_MSC

给定类型,我们也可以看到代码0x0004=4 ,表示MSC_SCAN

值是0x0007002c 。 在input.h无处不在。 嗯。

我认为你在找什么是fs.createReadStream,所以你可以安装一些事件处理程序。

您可以使用Buffer.readX例程将输入事件解析为结构:

  var i = 0; while((buf.length-i) >= 16) { var event = { tssec: buf.readUInt32LE(i+0), tsusec: buf.readUInt32LE(i+4), type: buf.readUInt16LE(i+8), code: buf.readUInt16LE(i+10), value: buf.readUInt32LE(i+12) }; i += 16; }