Running python in node-red, passing back a msg

I've been all over google for a few days and this forum getting nowhere.
I'm working on a raspberry pi 4 8GB, running current Raspbian. Installed node-red and have simple flows working. Have a simple python3 program running in Thonny.
This flow is just trying to run this simple python program under node-red python3 function and returning 1 value(message). It looks like not able to load modules, so I've stripped this program down to "hello world", without much luck getting it to pass a msg back to debug window, where do I go next ?

pi@raspberrypi:~ $ which python3
/usr/bin/python3
pi@raspberrypi:~ $ 
[{"id":"1027ca0d.5e05b6","type":"debug","z":"53601e04.d3716","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":700,"y":100,"wires":[]}]

python code below

import os
import glob
import time
 
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
 
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
 
def read_temp_raw():
    f = open(device_file, 'r')
    lines = f.readlines()
    f.close()
    return lines
 
def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_c = float(temp_string) / 1000.0
        temp_f = temp_c * 9.0 / 5.0 + 32.0
        return temp_c, temp_f
   
msg.payload = temp_f
return msg.payload

Can you show us your flow?

I think some have decided it is easier to use an exec node rather than the python node. Give it the full path to the script.
Did you use the recommended method of installing node red as in the official getting started guide?

I have a better idea, that I use all the time. Add MQTT support to your python script as a client/publisher and a subscriber, so in effect your python script is a service, yes invoked under systemd. Then add a publisher node and subscriber node to flow. Then the flow can request data from python service, if you will, and the python script can return data all via MQTT.

I know this sounds like a lot of work, but in the long run, it is worth it, uses MQTT, which is much friendlier to NR.

If you need help doing this, but want to, just let me know. I can send you examples of what I do and how. :slight_smile:

Once I did this the first time, it became very easy to do it again. I have a LOT of python code that drives sensors that are not easy to integrate to NR (at least not yet) and I did not want to recreate the wheel in NR when I had good working python code, so I added MQTT support to my python scripts, run them as services. It made integrating the MQTT requests and responses from the python side dirt easy in NR.

Post to the forum and not even post the flow, rookie mistake, sorry about that, here it is

[{"id":"53601e04.d3716","type":"tab","label":"Flow 6","disabled":false,"info":""},{"id":"9128e965.3d89b8","type":"inject","z":"53601e04.d3716","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"13","payloadType":"num","x":140,"y":100,"wires":[["fc05db00.d26228"]]},{"id":"1027ca0d.5e05b6","type":"debug","z":"53601e04.d3716","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":700,"y":100,"wires":[]},{"id":"fc05db00.d26228","type":"python3-function","z":"53601e04.d3716","name":"/usr/bin/python3","func":"import os\nimport glob\nimport time\n \nos.system('modprobe w1-gpio')\nos.system('modprobe w1-therm')\n \nbase_dir = '/sys/bus/w1/devices/'\ndevice_folder = glob.glob(base_dir + '28*')[0]\ndevice_file = device_folder + '/w1_slave'\n \ndef read_temp_raw():\n    f = open(device_file, 'r')\n    lines = f.readlines()\n    f.close()\n    return lines\n \ndef read_temp():\n    lines = read_temp_raw()\n    while lines[0].strip()[-3:] != 'YES':\n        time.sleep(0.2)\n        lines = read_temp_raw()\n    equals_pos = lines[1].find('t=')\n    if equals_pos != -1:\n        temp_string = lines[1][equals_pos+2:]\n        temp_c = float(temp_string) / 1000.0\n        temp_f = temp_c * 9.0 / 5.0 + 32.0\n        return temp_c, temp_f\n    \nmsg.payload = temp_f\n\nreturn msg.payload","outputs":1,"x":410,"y":100,"wires":[["1027ca0d.5e05b6"]]}]

"give it the full path to the script", I've not tried that as the python3..... node looks like it allows you to just enter the code in the node.

installation was the recommended method with a few extra steps

sudo apt update
sudo apt upgrade
sudo apt install build-essential

bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)

MQTT, ...I'm an old mainframe programmer and everytime I see "MQ" I run. I made my living on IBM MQ messaging and never want to go back....LOL.
But seriously, I'll look over the MQTT support and see what is involved and would welcome your example.

I'll look into the exec node

ok, tried the exec, some of the same error's. It's like it's not finding python3 since it can't load the first line of the python code, I keep going back to the PATH problem.

How does node-red "know" where python3 is?

I agree with @Colin I've used the Exec node to great effect.

Where are you calling python3 in that exec node ?

yes, I thought I was. In the exec node, in the command field I've coded a complete path to the python code with this command "/home/pi/pishared/OperationalFiles/tempprobes1.py",
Now I"m guessing I need to add python3.exe to it somehow as it seems it doesn't know it's python code

Hi @jabrockert

It looks like your python code reads a file, searches for t=, gets the value following it, divides by 1000, then calculates Fahrenheit and Celsius values right?

Unless i am missing something (or this is academic) - why dont you just do with with the node-red nodes?

file in node - read the file
function node - scan the file or use a regular expression to get the value.

ok, now you got me thinking about how the python program work. Yes, constantly reads a file that contains the temperature from a probe. I've completely misunderstood this python program. The DS18B20 sensor is updating that file constantly by itself and the python code really isn't needed for it get the new temperature and update the w1_slave file. This can be done with node-red-nodes.
Thanks for pointing that out. Onward

@jabrockert
What a SMALL WORLD... I when I was in operational support part of my career, before becoming an engineer, I supported many IBM MQ servers (and candle and ceder variants). And man, you got it, if I had gotten a nickle for every time I had to resolve an MQ or even an SNA gateway issue, I could have retired sooner than later! LMAO.

As for the python sending and receiving MQTT, it was completely worth the time and effort for me, I was able to keep my extensive python code base and still integrate into NR with ease.

LOL...I'm converting this script over to just node-red since it a simple problem, but have already started looking at MQTT youtube video's because at some point I'm going to need a solid interface to python. MQ is a love/hate relationship...

How is that happening? You can probably read the sensor directly in node-red, depending on how it is connected.

The DS18B20 sensor is a temperature sensor with ADC built in. It is communicating to a raspberry pi on a 1-wire protocol, on default pi GPIO4. Yes, I'm converting it over to a node-red flow, and not using python, just some javascript

When you get to Python and MQTT... one KEY design goal... Make sure the client connection has a unique id, and make sure you have a publish retry loop. Publishers need to have the ability to keep sending until they get configuration of message received from the broker. I found that if I just kicked a single publish 99% of the time my broker got it solid. But every once in a while otherwise. I don't often use retain message feature (maybe I should) but the retry loop logic as easy to do, and got me to a 100% consistency. It is also considered a best practice by a few Python MQTT users out on the web to do this.

I am confused, you said the sensor was writing to a file, if you are reading the sensor directly in node-red where does the file come into the equation??