You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派中通过Python subprocess运行JS脚本并获取返回值方法问询

How to Retrieve Sensor Data from a Node.js Script in Python

Hey there! Since you can't rewrite your Node.js sensor script (thanks to that exclusive Node.js library), let's go through practical ways to get those sensor readings into your Python code. Here are the most reliable approaches:

1. Pass Data via Standard Output (stdout) – Simplest Approach

This is the easiest method for one-off sensor reads. The idea is to have your Node.js script output sensor data as a JSON string (easy to parse in Python), then capture that output in your Python script.

Step 1: Modify Your test.js to Output JSON

Update your script to print the sensor data to stdout after converting it to JSON. This ensures Python can easily parse it:

const sensorLib = require('your-exclusive-sensor-library');

// Async function to read sensor data
async function fetchSensorData() {
  try {
    // Replace with your actual sensor reading logic
    const sensorReading = await sensorLib.getSensorData();
    
    // Output JSON to stdout (Python will capture this)
    console.log(JSON.stringify(sensorReading));
  } catch (err) {
    // Send errors to stderr (Python can catch this too)
    console.error(`Sensor read error: ${err.message}`);
    process.exit(1); // Non-zero exit code signals failure to Python
  }
}

fetchSensorData();

Step 2: Capture and Parse Output in Python

Instead of subprocess.check_call, use subprocess.check_output to capture the stdout from the Node.js script, then parse the JSON:

import subprocess
import json

def get_sensor_reading():
    try:
        # Run the npm script and capture stdout
        raw_output = subprocess.check_output(
            ['npm', 'run', 'test'],
            stderr=subprocess.STDOUT,  # Include stderr in output for debugging
            text=True  # Return string instead of bytes
        )
        # Parse the JSON output
        sensor_data = json.loads(raw_output.strip())
        return sensor_data
    except subprocess.CalledProcessError as e:
        print(f"Failed to run Node.js script: {e.output}")
        return None
    except json.JSONDecodeError:
        print("Failed to parse sensor data (invalid JSON)")
        return None

# Example usage
sensor_reading = get_sensor_reading()
if sensor_reading:
    print(f"Got sensor data: {sensor_reading}")

2. Stream Real-Time Sensor Data

If you need continuous, real-time readings (e.g., polling the sensor every second), use subprocess.Popen to keep the Node.js process running and read its output line by line.

Modified test.js for Streaming

const sensorLib = require('your-exclusive-sensor-library');

async function streamSensorData() {
  try {
    while (true) {
      const sensorReading = await sensorLib.getSensorData();
      console.log(JSON.stringify(sensorReading));
      await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second between reads
    }
  } catch (err) {
    console.error(`Stream error: ${err.message}`);
    process.exit(1);
  }
}

streamSensorData();

Python Code to Stream Data

import subprocess
import json

def stream_sensor_data():
    try:
        # Start the Node.js process with persistent stdout
        process = subprocess.Popen(
            ['npm', 'run', 'test'],
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1,  # Line-buffered output
            universal_newlines=True
        )
        
        # Read output line by line
        for line in process.stdout:
            cleaned_line = line.strip()
            if cleaned_line:
                try:
                    sensor_data = json.loads(cleaned_line)
                    yield sensor_data
                except json.JSONDecodeError:
                    print(f"Invalid JSON line: {cleaned_line}")
        
        # Check if process exited unexpectedly
        process.wait()
        if process.returncode != 0:
            print(f"Stream process exited with code: {process.returncode}")
    except Exception as e:
        print(f"Failed to start stream: {e}")

# Example usage: iterate over real-time readings
for reading in stream_sensor_data():
    print(f"Real-time sensor reading: {reading}")

3. Use a Local HTTP Server (For More Complex Workflows)

If you need bidirectional communication or want to integrate with other tools, spin up a lightweight HTTP server in Node.js and have Python send requests to fetch data.

Node.js HTTP Server (test.js)

const sensorLib = require('your-exclusive-sensor-library');
const http = require('http');

const PORT = 3000;
const server = http.createServer(async (req, res) => {
    // Handle GET requests to /sensor-data
    if (req.method === 'GET' && req.url === '/sensor-data') {
        try {
            const sensorReading = await sensorLib.getSensorData();
            res.writeHead(200, {'Content-Type': 'application/json'});
            res.end(JSON.stringify(sensorReading));
        } catch (err) {
            res.writeHead(500, {'Content-Type': 'application/json'});
            res.end(JSON.stringify({error: 'Failed to read sensor'}));
        }
        return;
    }
    
    // Handle invalid routes
    res.writeHead(404);
    res.end('Not found');
});

server.listen(PORT, () => {
    console.log(`Sensor data server running on http://localhost:${PORT}`);
});

Python Code to Fetch Data via HTTP

import requests

def get_sensor_data_via_http():
    try:
        response = requests.get('http://localhost:3000/sensor-data')
        response.raise_for_status()  # Raise error for HTTP status codes >=400
        return response.json()
    except requests.exceptions.RequestException as e:
        print(f"HTTP request failed: {e}")
        return None

# Example usage
sensor_data = get_sensor_data_via_http()
if sensor_data:
    print(f"Sensor data from HTTP server: {sensor_data}")

Note: You'll need to start the Node.js server first (either manually or via Python using subprocess.Popen before making requests).

Which Approach Should You Choose?

  • One-off reads: Go with the stdout/JSON method (it's lightweight and requires no extra dependencies).
  • Real-time streaming: Use the Popen line-reading method or the HTTP server.
  • Complex interactions: The HTTP server or other IPC methods (like Unix sockets) are better suited.

内容的提问来源于stack exchange,提问作者Samuel Vergeiner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:42:24