2016-09-12 8 views
0

프로젝트 용 Homebridge 플러그인을 만드는 중입니다. Homebridge은 Apple HomeKit Bridge를 에뮬레이트하는 Raspberry Pi에서 실행되는 Node.JS 서버입니다. 흥미롭게도Node.JS에서 Python 함수를 호출하는 방법

var Service, Characteristic; 

var spawn = require('child_process').spawn; 
var py = spawn('python', ['/home/pi/Desktop/RFbulb/nRF24L01PLUS.py']); 
var data = [10,10,10]; 
var dataString = ''; 

var RFstatus = true; 

module.exports = function(homebridge) { 
    Service = homebridge.hap.Service; 
    Characteristic = homebridge.hap.Characteristic; 

    homebridge.registerAccessory("homebridge-RFbulb", "RFbulb", RFbulbAccessory); 
} 

function RFbulbAccessory(log, config) { 
    this.log = log; 
    this.config = config; 
    this.name = config["name"]; 
    this.address = config["address"]; 

    this.service = new Service.Lightbulb(this.name); 
    this.service 
     .getCharacteristic(Characteristic.On) 
     .on('get', this.getOn.bind(this)) 
     .on('set', this.setOn.bind(this)); 
} 

RFbulbAccessory.prototype.setOn = function(on, callback) { // This is the function throwing the error 
    var state = on ? "on": "off"; 
    if (state == "on") { 
     data = [1,parseInt(this.address, 10),100]; 
     dataString = ''; 
     py.stdout.on('data', function(data) { 
      dataString += data.toString(); 
     }); 
     py.stdout.on('end', function() { 
      console.log(dataString); 
     }); 
     py.stdin.write(JSON.stringify(data)); 
     py.stdin.end(); 
     RFstatus = true; 
    } 
    callback(null); 
} 

RFbulbAccessory.prototype.getServices = function() { 
    return [this.service]; 
} 

, 나는 setOn 기능을 처음 활성화 할 때 (예를 들어, 장치를 켜 :

this 링크를 사용하여, 나는 다음과 Node.js를 코드에서 파이썬 코드를 실행 할 수 있었다

events.js:141 
     throw er; // Unhandled 'error' event 
    ^

Error: write after end 
    at writeAfterEnd (_stream_writable.js:166:12) 
    at Socket.Writable.write (_stream_writable.js:211:5) 
    at Socket.write (net.js:642:40) 
    at RFbulbAccessory.setOn (/usr/lib/node_modules/homebridge-RFbulb/index.js:47:12) 
    at emitThree (events.js:97:13) 
    at emit (events.js:175:7) 
    at Characteristic.setValue (/usr/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Characteristic.js:155:10) 
    at Bridge.<anonymous> (/usr/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Accessory.js:710:22) 
    at Array.forEach (native) 
    at Bridge.Accessory._handleSetCharacteristics (/usr/lib/node_modules/homebridge/node_modules/hap-nodejs/lib/Accessory.js:655:8) 

이 오류의 원인이 될 수있는 무엇 : 나는 다음과 같은 오류와 서버 종료를 얻을 수)) 그것을 잘 작동하지만, 나는 setOn 기능을 한 번 더 활성화 할 때 (장치를 해제 ? 특히이 함수는 일회용으로 잘 작동하는 것처럼 보입니다. 스트림이 종료 된 후

py.stdin.end(); 

, 당신은 더 이상 쓸 수없는 당신이 여기처럼 : 당신이 입력 스트림을 폐쇄하고 있기 때문에

+0

스트림을 종료 한 후에도 마찬가지입니다. 이 줄은 범인이다 :'py.stdin.end();' –

+0

''py.stdin.end(); ''를 사용할 필요가 없다고 할 수 있겠는가? 이것이 내가 만든 자식 프로세스를 닫은 선이라고 생각 했나요? – user3185748

+0

모두 다 다릅니다. 입력 스트림을 닫는 것입니다. 프로세스를 닫으려면 해당 프로그램을 다시 실행할 때마다 다시 열어야합니다. 그래서 당신의 파이썬 스크립트가 stdin을 통해 여러 명령을 취하는 지 아니면 하나를 처리 한 다음 종료하는지에 달려 있습니다. 이전 버전 인 경우'py.stdin.end()'를 제거하십시오. 후자의 경우, Python 프로그램을 실행할 때마다 프로세스를 다시 생성해야합니다. –

답변

1

당신은 그 오류를 받고있어

py.stdin.write(JSON.stringify(data)); 

실행중인 Python 프로그램이 STDIN보다 여러 명령을 허용하는 경우 py.stdin.end() 줄을 제거하면됩니다.

그러나 파이썬 프로그램이 한 번 실행되면 완료됩니다. 그렇다면 프로그램을 실행할 때마다 프로세스를 다시 생성해야합니다.

if (state === "on") { 
    py = spawn('python', ['/home/pi/Desktop/RFbulb/nRF24L01PLUS.py']); 
    ... 
} 
관련 문제