如何在Node.js中自动启动和停止python脚本?

时间:2018-06-22 14:21:44

标签: python node.js

我正在通过Web界面在鸡舍中开发温度监控应用程序。我使用两个arduinos和一个Raspberry。

Arduino 1 :我连接了温度/湿度传感器和RF433Mhz变送器。

Arduino 2 :一个RF433Mhz接收器已连接到它。它从 Arduino 1 接收数据。

Raspberry Arduino 2 已连接到我的Raspberry,Raspberry读取串行监视器中接收的数据,并通过 websockets将其发送到网页 strong>(nodejs的软件包 ws )。

起初,我想直接使用Nodejs读取此数据,但是在安装串行端口软件包时遇到了一些问题。

所以我改变了方法:我使用python在串行监视器中读取数据,将其写入文件中,然后Nodejs读取这些文件并将数据发送到网页。

这是我使用的两个代码:

Phyton脚本

import serial
import time

ser = serial.Serial('/dev/ttyACM0', 9600)

while True:
    data = ser.readline()
    if data:
        t = data[0:2]
        h = data[6:8]

        #decode utf-8
        tc = t.decode("utf-8")
        hc = h.decode("utf-8")

        #write the temperature in the temp file
        fileTc=open('temp', 'w')
        fileTc.write(str(tc))
        fileTc.close

        #write the humidity in the hum file
        fileHc=open('hum', 'w')
        fileHc.write(str(hc))
        fileHc.close

        #sleep
        time.sleep(.1)

Nodejs脚本

var express = require("express");
const WebSocket = require('ws');
const wss = new WebSocket.Server({port: 4400});
var path = require("path");
var fs = require("fs");
var sys = require("util");
var exec = require("child_process").exec;

var tempcpu = 0;
var temp = 0;
var hum = 0;

var app = express();
app.set("port", process.env.PORT || 5500);

app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");

app.use('/', express.static('public'));

wss.on('connection', function connection(ws) {
    ws.on('message', function incoming(message) {
        console.log('received: %s', message);
});
setInterval(function(){
    child1 = exec("cat /sys/class/thermal/thermal_zone0/temp", 
             function(error, stdout,stderr){
                if (error !== null){
                    console.log('exec error: ' +error);
                } else{
                       tempcpu = parseFloat(stdout)/1000;
                }
    });
    child2 = exec("cat temp", function(error, stdout,stderr){
            if (error !== null){
                console.log('exec error: ' +error);
            } else{
                temp = parseFloat(stdout);
            }
    });
    child3 = exec("cat hum", function(error, stdout,stderr){
            if (error !== null){
                console.log('exec error: ' +error);
            } else{
                hum = parseFloat(stdout);
            }
    });
    var tempCPU = JSON.stringify(["cpu",tempcpu]);
    var temperature = JSON.stringify(["temp",temp]);
    var humidity = JSON.stringify(["hum",hum]);

    ws.send(tempCPU);
    ws.send(temperature);
    ws.send(humidity);

    }, 5000);
});

app.get("/", function(request, response) {
   response.render("dashboard");
});

app.listen(app.get("port"), function() {
    console.log("Server started at port " + app.get("port"));
});

现在我必须分别启动两个脚本。我想在启动节点服务器时直接从nodejs运行python脚本,并在停止nodejs代码(CTRL + C)时停止运行它。

您是否有想法?

1 个答案:

答案 0 :(得分:0)

您想要实现的是产生一个新的过程,在该过程中您可以从Node应用程序或Python应用程序执行某些操作:

NodeJS方法:Child process

const { spawn } = require('child_process');
const pythonApp = spawn('python', ['my_python_app.py']);

Python方法:Subprocess

import subprocess
node_app = subprocess.Popen(["node","my_node_app.js"], stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

编辑

关于捕获INTERRUPT(CTRL + C)信号,这也可以使用两种语言来完成。并利用它杀死您产生的过程:

使用NodeJS:

process.on('SIGINT', () => {
    console.log("Caught interrupt signal");
    if(pythonApp) pythonApp.exit();
});

使用Python:

import sys

try:
    # Your app here...
except KeyboardInterrupt:
    print("Caught interrupt signal")
    if node_app: node_app.kill()
    sys.exit()