我正在尝试为 Raspberry Pi 的 GPIO-Pins 创建自己的模块,但如果有什么变化(例如按下/释放按钮),我想接收.on('something', function() { })
事件。
python 脚本每 0.01 秒发送一次值,如 true 或 false。
模块.js
var PythonShell = require('python-shell');
module.exports = {
switch_live: function(pin) {
var status = false;
this.get = (function(){
return status;
});
var options = {
mode: 'text',
args: [pin],
pythonOptions: ['-u']
};
var pyshell = new PythonShell('./data/switch_loop.py', options);
pyshell.on('message', function(message) {
if (message == 'false') {
if (status) {
// EMIT: button released
}
status = false;
} else {
if (!status) {
// EMIT: button pressed
}
status = true;
}
});
return this.status;
},
some_other_funcs: function(pin) {
// ...
}
}
应用.js
var module = require('./module.js');
var button = new module.switch_live(10);
该模块可以显示按钮的状态:
// get status of button
var status = button.get(); // returns "true" or "false"
但我想要这样的东西:
button.on('pressed', function() {
// call this function every time when button is pressed
});
button.on('released', function() {
// call this function every time when button is released
});
谢谢:)
编辑:我没有找到解决方案,因为我需要"模块导出"中的函数。
我的解决方案
它是用于Linkerkit-Board的模块。
应用.js
var linkerkit = require('./linkerkit.js');
var button = new linkerkit.switch_live(20);
button.on('pressed', function() {
// call this function every time when button is pressed
console.log('press');
});
button.on('released', function() {
// call this function every time when button is released
console.log('release');
});
链接套件.js
var PythonShell = require('python-shell');
var EventEmitter = require('events');
var util = require('util');
var linkerkit = {
switch_live: function(pin) {
var self = this;
this.status = false;
this.pin = pin;
EventEmitter.call(this);
this.get = function() {
return this.status;
}
this._pyshell = new PythonShell('./data/switch_loop.py', {
mode: 'text',
args: [this.pin],
pythonOptions: ['-u']
});
this._pyshell.on("message", function(message) {
if (message === "false") {
if (this.status === true) {
// EMIT: button released
self.emit("released");
}
this.status = false;
}
else {
if (this.status === false) {
// EMIT: button pressed
self.emit("pressed");
}
this.status = true;
}
});
}
}
for (var key in linkerkit) {
util.inherits(linkerkit[key], EventEmitter);
}
module.exports = linkerkit;
我编辑了代码,因为它应该能够做这样的事情:
var button = linkerkit.switch(20);
button.get() // get status of button once, has no python loop
var button_live = linkerkit.switch_live(20);
button.get() // get status of button once, has a python loop
button.on('pressed', callback);
button.on('released', callback);
var led = linkerkit.led(10);
led.on();
led.off();
led.brightness(255); // digitalOutput - brightness
led.blink(200); // 100ms on, 100ms off
var ledcolor = linkerkit.led_rgb(12);
ledcolor.on(); // on -> color: white
ledcolor.off();
ledcolor.rgb([255, 0, 0]); // on -> color: red
还有更多功能...
你应该能够使用 Node 的内置EventEmitter
类来创建你自己的"按钮发射器":
模块.js
var PythonShell = require('python-shell');
var util = require('util');
var EventEmitter = require('events');
function ButtonEmitter(pinNumber) {
this.status = false;
this.pinNumber = pinNumber;
EventEmitter.call(this);
}
util.inherits(ButtonEmitter, EventEmitter);
ButtonEmitter.prototype.get = function() {
return this.status;
};
ButtonEmitter.prototype.switch_live = function() {
var options = {
mode: 'text',
args: [this.pinNumber],
pythonOptions: ['-u']
};
this._pyshell = new PythonShell('./data/switch_loop.py', options);
this._pyshell.on("message", this._handleMessage.bind(this));
return this.status;
};
ButtonEmitter.prototype._handleMessage = function(message) {
if (message === "false") {
if (this.status === true) {
// EMIT: button released
this.emit("pressed");
}
this.status = false;
} else {
if (this.status === false) {
// EMIT: button pressed
this.emit("released");
}
this.status = true;
}
};
module.exports = ButtonEmitter;
应用.js
var ButtonTrigger = require('./module.js');
var button = new ButtonTrigger(10);
button.on('pressed', function() {
// call this function every time when button is pressed
});
button.on('released', function() {
// call this function every time when button is released
});
button.swith_live();
解释
上面的代码利用了 Node 对"子类"EventEmitter
util.inherits
,以便任何使用你的类的人都可以访问.on()
、.off()
和其他事件方法。(注意:如果你的 Node 版本支持它,你也可以使用 ES6 class
和extends
语法)
然后,使用"子类",添加自己的switch_live
方法来启动"侦听"过程,并向其传递_handleMessage
回调。
当_handleMessage
回调运行时,它会将当前状态与传入状态进行比较,并使用您在问题中发布的事件名称触发.emit()
。同样,.emit()
可用是因为您是一个"子类化"EventEmitter
。