简体   繁体   中英

How to automatically start and stop a python script in nodejs?

I am developing a temperature monitoring application in a hen house with a web interface. I use two arduinos and a Raspberry.

Arduino 1 : I connected a temperature / humidity sensor and an RF433Mhz transmitter.

Arduino 2 : An RF433Mhz receiver is connected to it. It receives data from Arduino 1 .

Raspberry : Arduino 2 is connected to my raspberry which reads the data received in the serial monitor and send them to the web page via the websockets (package ws of nodejs).

At first I wanted to read this data directly with Nodejs, but I had some problems with the installation of the serial port package.

So I changed my approach: I read the data in the serial monitor with python, write it in files, and Nodejs reads these files and sends the data to the web page.

here are the two codes I use:

Phyton script

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 Script

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"));
});

for now I have to launch both scripts separately. I would like to run my python script directly from nodejs when I start the node server, and stop it when I stop my nodejs code (CTRL + C).

Do you have an idea of ​​how to do it?

What you want to achieve is spawn a new process in which you execute something from either a Node app or a Python app:

NodeJS approach: Child process

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

Python approach: Subprocess

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

EDIT

Regarding catching the INTERRUPT (CTRL+C) signal, this can also be done in both languages; and leveraged to kill the process you spawned:

With NodeJS:

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

With Python:

import sys

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM