0

GPIO ピンの変更を処理するために、Raspberry Pi で実行されるノードでサーバーを作成しようとしています。(私は Node を初めて使用しますが、新しいことを学ぶことに興奮しています)

これらのピンは、OpenSprinkler ハードウェアを使用してスプリンクラー バルブ リレーを制御します。一度に開くことができるバルブは 1 つだけです。ハードウェアではバルブの状態を照会できないため、ソフトウェアで処理する必要があります。

「ステーション 1 を 15 分間操作する」のようなネットワーク リクエストが届いた場合、そのコマンドを実行し、ピンをオフに戻す前に適切な時間待機できるようにする必要があります。各実行は自動的に停止できる必要があります。ソフトウェアの不具合によって庭が池にならないように、外部コマンドに頼って水を止めたくありません。

最初のコマンドの実行中に 2 番目のコマンドが到着した場合、最初の操作を終了してから、2 番目のコマンドの実行を許可します。この終了により、操作が早期に停止され、実行された時間 (分) が記録されます。

スレッドとキューを使用して Python で既にこれを作成しましたが、Node.js でよりきれいに実行できるかどうかを確認したいと考えています。

私が探しているものを達成するために、スレッドを調べたり、子プロセスを生成したり、何か他のものを見たりする必要があるかどうか興味がありますか? 信号が中断されるのをリッスンできる、ある種のノンブロッキングで長時間実行される実行が必要です。

これは私のアイデアの概念ですが、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");
4

2 に答える 2

1

通常、タイマーまたはスプリンクラー コントローラーからのイベントを処理するようにコードを修正する必要があります。

提供した例では、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-22T21:15:54.130 に答える