[英]python-shell node, keep a python script running
如果您可以在從 Javascript 調用 python 腳本時保持運行,那么有人會知道使用 python-shell 嗎? 也許使用 python-shell 從 Javascript 從 Python class 調用方法?
例如,此代碼有效,但每次調用 Python 腳本時都會殺死它。
let {PythonShell} = require("python-shell");
let options = {
mode: "text",
args: ["read", "12345:2", "analogInput", "2"],
};
PythonShell.run("bac0Worker.py", options, function (err, results) {
if (err){
console.log(err)
console.log("An error happened")
}else{
// results is an array consisting of messages collected during execution
console.log("results: ", results);
console.log("Python Script Finished");
}
})
在 Python 方面,我正在試驗用於 BACnet 系統的稱為 BAC0 的 package。 我想要做的是弄清楚我是否可以保持 BAC0 腳本運行,我認為在 BAC0 的引擎蓋下有很多過程正在進行,如果腳本啟動/停止,它可能會在 BACnet 網絡上產生大量不必要的流量很多。
bac0Worker.py
import sys
import BAC0
BAC0.log_level('silence')
bacnet = BAC0.lite()
def do_things(address,object_type,object_instance):
try:
read_vals = f'{address} {object_type} {object_instance} presentValue'
read_result = bacnet.read(read_vals)
if isinstance(read_result, str):
pass
else:
read_result = round(read_result,2)
print(read_result)
except Exception as error:
print("read error")
def main():
# args from Javascript
first = sys.argv[1]
second = sys.argv[2]
third = sys.argv[3]
fourth = sys.argv[4]
# get sensor data
do_things(second, third, fourth)
# all done
bacnet.disconnect()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("bacnet app error")
bacnet.disconnect()
就像我提到的那樣,如果我從 Node 運行,代碼可以工作,我可以從 BACnet 網絡看到傳感器值 71.7 度。
C:\Program Files\nodejs\node.exe .\start.js
results: (1) ['71.7']
Python Script Finished
希望這是有道理的,對於這個奇怪的問題很抱歉,但很好奇是否有人有任何關於如何保持 Python 腳本運行的提示,然后我可以將值(傳感器和設備尋址信息)傳遞給 BAC0 腳本以請求從網絡。 如果我替換此文件,則在 Python 文件的主 function 中:
# all done
bacnet.disconnect()
和:
while True:
pass
這將使 Python 文件保持活動狀態我只是不知道如何使用 python-shell 將值傳遞給實時 Python 腳本。 感謝您提供的任何提示,而不是這里的最佳實踐。 Curious if I should change my do_things
function into a Python class with a method called do_things
where then this class could get called from Javascript?
.js
const { PythonShell } = require("python-shell");
let pyshell = new PythonShell("my_script.py");
pyshell.send("hello");
pyshell.on("message", function (message) {
console.log(message);
});
setTimeout(() => {
pyshell.send("Another Hello");
}, 3000);
const end = () => {
pyshell.end(function (err, code, signal) {
if (err) throw err;
console.log("finished");
});
};
// end();
.py
import sys
def log():
print('hello from python')
while True:
inp = input(" ")
if inp=="hello":
log()
這將使進程保持運行,除非您從 nodejs 調用end
方法或發生某些錯誤。 這可能會導致性能問題,因為 python 東西將與您的 nodejs 共享相同的資源。 更好的方法是使用微服務,例如部署一些 Rest Api 來處理 python 特定任務。
只是為了好玩我會發布我從@sandeep 學到的東西(謝謝一百萬順便說一句),這很有效。 我可以在 60 秒setInterval(pythonDo, 60000);
保持 Python 文件處於活動狀態:
C:\Program Files\nodejs\node.exe .\start.js
BAC0 start success
68.47
68.43
68.29
68.25
開始.js
const { PythonShell } = require("python-shell");
let pyshell = new PythonShell("bac0Worker.py");
function pythonDo() {
pyshell.send("read 12345:2 analogInput 2");
}
pyshell.on("message", function (message) {
console.log(message);
});
var data = setInterval(pythonDo, 60000);
bac0Worker.py
import sys
import BAC0
BAC0.log_level('silence')
bacnet = BAC0.lite()
print("BAC0 start success")
# available BACnet actions
SUBSTRING_READ = "read"
SUBSTRING_WRITE = "write"
SUBSTRING_RELEASE = "release"
def bac0_worker(action, BACnet_request, **kwargs):
value = kwargs.get('value', None)
priority = kwargs.get('priority', None)
if action == "read":
try:
read_vals = f'{BACnet_request} presentValue'
read_result = bacnet.read(read_vals)
if isinstance(read_result, str):
pass
else:
read_result = round(read_result,2)
print(read_result)
except Exception as error:
print("read error")
elif action == "write":
try:
write_vals = f'{BACnet_request} presentValue {value} - {priority}'
bacnet.write(write_vals)
print(write_vals)
except Exception as error:
print("write error")
elif action == "release":
try:
release_vals = f'{BACnet_request} presentValue null - {priority}'
bacnet.write(release_vals)
print(release_vals)
except Exception as error:
print("release error")
else:
return "server error on BACnet opts"
def main():
while True:
# from javascript
inp = input(" ")
for word in inp.split():
if SUBSTRING_READ == word:
stripped_string = inp.replace(SUBSTRING_READ + " ", "")
# do a BACnet READ request with BAC0
bac0_worker(SUBSTRING_READ,stripped_string)
if SUBSTRING_WRITE == word:
print("WRITE Match Found")
if SUBSTRING_RELEASE == word:
print("RELEASE Match Found")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("bacnet app error")
bacnet.disconnect()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.