Python libraries in Node Red Flows

Hi All,

I have a rotary encoder where the knob is illuminated by an RGB LED, both the encoder and the LED are controlled by a microcontroller connected to a Raspberry PI over i2c. The libraries supporting the rotary encoder are written in Python and are quite extensive. I would like to get input from the encoder and control the colour/brightness of the LED via a node red flow. I have installed the node-red-contrib-python3-function but this is now apparently un-supported by its author. All I am after is getting msg.topic and msg.payload into a node, manipulate it with the python library to control the LED and getting a msg.topic and msg.payload out of a node to send to the next node in the flow.

Any good ideas or pointers?

Kind regards,
Chris

The common recommendation for this is to integrate mqtt into your Python application. Mqtt is very easy to implement with tons of information within this forum and around the internet.

Yes, or implement an API wrapper that allows REST interaction. Depends on the requirements and the underlying modules.

Thanks for the answers.......

@Julian, I don't think my current skill level allows me to create an API wrapper. I am not familiar with Python, reading through a Python script to understand its logic isn't so much of a problem writing one from scratch is.
@Stephen, I am not sure using mqtt would solve my problem.

All I am after is the little bit of Python code to read the contents of a Node Red msg.payload (Numeric values for red, green and blue for example) into Python variables. And to form a msg.payload from Python variables to send on to the next node.

Below is my current flow which from a hardware perspective works, when I turn the encoder its LED changes colour. I would like to set its initial colour from a previous node msg and output the encoder status to the next node.

Kind regards,
Chris

[{"id":"c4190447.a2b178","type":"inject","z":"b3342e39.b521f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":200,"y":540,"wires":[["2ebf1281.991cce"]]},{"id":"2ebf1281.991cce","type":"python3-function","z":"b3342e39.b521f","name":"","func":"import time\nimport colorsys\nimport ioexpander as io\n\n\nPIN_RED = 1\nPIN_GREEN = 7\nPIN_BLUE = 2\n\nPOT_ENC_A = 12\nPOT_ENC_B = 3\nPOT_ENC_C = 11\n\nBRIGHTNESS = 0.5                # Effectively the maximum fraction of the period that the LED will be on\nPERIOD = int(255 / BRIGHTNESS)  # Add a period large enough to get 0-255 steps at the desired brightness\n\nioe = io.IOE(i2c_addr=0x0F, interrupt_pin=4)\n\nioe.enable_interrupt_out(pin_swap=True)\n\nioe.setup_rotary_encoder(1, POT_ENC_A, POT_ENC_B, pin_c=POT_ENC_C)\n\nioe.set_pwm_period(PERIOD)\nioe.set_pwm_control(divider=2)  # PWM as fast as we can to avoid LED flicker\n\nioe.set_mode(PIN_RED, io.PWM, invert=True)\nioe.set_mode(PIN_GREEN, io.PWM, invert=True)\nioe.set_mode(PIN_BLUE, io.PWM, invert=True)\n\n#print(\"Running LED with {} brightness steps.\".format(int(PERIOD * BRIGHTNESS)))\n\ncount = 0\nr, g, b, = 0, 0, 0\n\nwhile True:\n    if ioe.get_interrupt():\n        count = ioe.read_rotary_encoder(1)\n        ioe.clear_interrupt()\n\n    h = (count % 360) / 360.0\n    r, g, b = [int(c * PERIOD * BRIGHTNESS) for c in colorsys.hsv_to_rgb(h, 1.0, 1.0)]\n    ioe.output(PIN_RED, r)\n    ioe.output(PIN_GREEN, g)\n    ioe.output(PIN_BLUE, b)\n\n#    print(count, r, g, b)\n\n    time.sleep(1.0 / 30)","outputs":1,"x":390,"y":540,"wires":[[]]}]

Sure it would but if you dont want to go down that route, you could save the python as a py script & run it from an exec node, passing in the RBG values and have the script print to STDOUT the encoder values you want that you can grab and parse from the output of the exec node.

e.g...

ziCIXr9GQY

test.py...

import sys
print("You sent R:"+sys.argv[1] + ", G:"+sys.argv[2] + ", B:"+sys.argv[3])

whatever you print is sent to stdout & appears on pin 1 of the exec node

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.