我希望在Node中创建一个服务器,它将运行在我的Raspberry Pi上,以处理更改的GPIO引脚。(我对Node很陌生,但很高兴能学到新东西)
这些引脚控制喷淋阀继电器使用OpenSprinkler硬件,一次只能打开一个阀门。硬件不允许您查询阀门的状态,因此需要在软件中处理。
当网络请求传入时,类似于“操作站1 15分钟”,我需要能够完成该命令,并等待适当的分钟数,然后再将引脚设置为off。每次执行都应该能够停止自己,我不想依靠外部命令关闭水,以免软件故障把我的院子变成池塘。
如果第二个命令在第一个操作时到达,我希望第一个操作终止自身,然后允许第二个命令运行。此终止将提前停止操作,记录它运行了多少分钟,等等。
我已经在Python中使用线程和队列编写了这篇文章,但是我想看看是否可以在Node中更干净地完成它。
我很好奇,我应该看看线程,产卵子进程,还是其他什么东西来实现我想要的呢?我需要一些非阻塞的,长时间运行的执行,可以监听信号被打断。
这是我的想法的一个概念,但是operateSprinkler函数会阻塞,因此需要修改或重写它。
net = require('net');
function operateSprinkler(minutes, station) {
console.log('Operating Station ' + station + ' for ' + minutes + ' minutes.');
var ms = minutes * 60 * 1000;
var endTime = (new Date().getTime()) + ms;
// Manipulate gpio pin to turn on sprinkler (pseudo-code here)
gpio.on()
while(new Date().getTime() < futureTime) {
// Hang out until time expires
// Listen for a signal that interrupts this function
}
else {
gpio.off() // pseudo-code
}
console.log('Finished operating station.');
}
net.createServer(function(socket) {
socket.on('data', function(data) {
try {
var json = JSON.parse(data);
// Make sure "minutes" and "station" were passed
if (json.hasOwnProperty('minutes') && json.hasOwnProperty('station')) {
operateSprinkler(json['minutes'], json['station']);
}
}
catch(e) {
console.log('Error. Invalid command.');
}
socket.end();
});
}).listen(5000);
console.log("Server running at port 5000\n");发布于 2013-07-22 21:15:54
通常,您需要重新处理代码来处理事件,无论是从计时器还是从洒水控制器。
在您提供的示例中,使用setTimeout,存储返回的timeoutId、洒水站和任何其他您需要访问的数据,以便以后可以取消它。
然后,替换您的operateSprinkler逻辑如下所示:
/*
* current station is false if not running
*
* or {
* station: stationid,
* duration: time,
* start: Date.now(),
* timeoutId: timeoutId
* }
*/
var currentStation = false;
function operateSprinkler(minutes, station) {
if(currentStation) {
console.log('Cancelling station: ' + currentStation.station);
gpio.off(); // Will need some way to look up by station...
clearTimeout(currentStation.timeoutId);
}
var ms = minutes * 60 * 1000;
var endTime = (new Date().getTime()) + ms;
currentStation = {
station: station,
duration: ms,
start: Date.now();
};
console.log('Operating Station ' + station + ' for ' + minutes + ' minutes.');
// Manipulate gpio pin to turn on sprinkler (pseudo-code here)
gpio.on()
currentStation.timeoutId = setTimeout(function() {
gpio.off();
currentStation = false;
console.log('Stopping station ' + currentStation.stationid);
console.log('Finished operating station.');
}, ms);
}发布于 2013-07-22 20:59:00
只需使用setTimeout。
var timer = setTimeout(stopSprinkler, 15_minutes_in_seconds);您可以将这个计时器存储到一个变量中,如果/当另一个命令出现时,只需检查是否设置了这个变量。如果设置好了,您可以使用clearTimeout来停止计时器,并手动处理停止洒水器。
https://stackoverflow.com/questions/17797220
复制相似问题