Compare commits

...

4 Commits

  1. 2
      README.md
  2. 51
      osc_server.py

2
README.md

@ -16,7 +16,7 @@ git clone https://git.sav.net.au/Public/osc_led.git
```
# Setup Reaper, load the template
Set up reaper to listen on port 9000 and send to port 8000.
Set up reaper to listen on port 8000 and send to port 9000.
Control surface mode: OSC
Mode: Configure device IP + local port
Device port: 9000

51
osc_server.py

@ -7,16 +7,20 @@ import logging
from pprint import pprint
import argparse
import colorsys
import gpiozero
# Set up basic vars and logging
logging.basicConfig(format='%(asctime)s - %(threadName)s ø %(name)s - '
'%(levelname)s - %(message)s')
log = logging.getLogger("osc")
log.setLevel(logging.INFO)
clientname="ledserver"
# Get the normalised RGB values for the HSV (i.e, the colour float designating hue from OSC)
def hsv2rgb(h,s,v):
return tuple(round(i*255) for i in colorsys.hsv_to_rgb(h,s,v))
# Some little helper methods to set colours in the terminal output
def termrgb(rgb):
return "\033[38;2;{};{};{}m".format(rgb[0],rgb[1],rgb[2])
def termendc():
@ -25,80 +29,113 @@ def output_led_colour(rgb):
return termrgb(rgb)+""+termendc()
# Our main class, the LED
class LED:
# These should be largely self-explanatory
# Float, from OSC FX param 2
brightness=0
# RGB array, currently as int 0-255, but will probably end up float 0-1.0, converted from hue
colour=[0,0,0]
#Float, from OSC FX param 1
hue=0
state=True
# Bool, Intial state, off. Should always align to whether the LED is on or off, brightness being >0
state=False
# The pin number of the LED
pin=None
# List for logging state
mode=["off","on"]
# Initialize the object, set up GPIO
def __init__(self,pin):
self.pin=pin
self.led=gpiozero.PWMLED(pin)
# Set the brightness, this only triggers on a delta threshold so that we don't go crazy
def set_brightness(self,value):
if abs(self.brightness-value) > .005:
self.brightness=value
self.led.value=self.state*self.brightness
print("Setting brightness for LED on pin {} to {}".format(self.pin, self.brightness))
# Set the colour, only on a delta threshold
def set_colour(self,value):
if abs(self.hue-value) > .01:
self.colour=hsv2rgb(value,1,1)
self.hue=value
log.info("Setting colour for LED on pin {} to {} ({})".format(self.pin,self.colour,output_led_colour(self.colour)))
# Set an absolute state, on or off. Brightness is set regardless, so we can turn it on with 40% brightness if desired
def set_state(self,value):
self.state=value
self.led.value=self.state*self.brightness
log.info("Turning LED {} {}".format(self.pin, self.mode[self.state]))
# Toggle on or off, edge detecting. I.e, send True to turn on, send True again to turn off. False is ignored
def toggle_state(self,value):
if (value):
self.state=not self.state
self.led.value=self.state*self.brightness
log.info("Turning LED {} {}".format(self.pin, self.mode[self.state]))
# Set the colour of the LEDs. This only does the first LED, but when the REAPER controls are finalised, it'll be more controllable
def led_colour(value):
leds[0].set_colour(value)
# Set the brightness of all LEDs. As above, when REAPER is finalised it'll be controllable (or everything, as required)
def led_brightness(value):
leds[0].set_brightness(value)
for led in leds:
led.set_brightness(value)
# Turn an individual LED on or off based on FX param 3+
def led_state(addr,value):
led=addr.split("/")[6]
leds[int(led)-3].toggle_state(bool(value))
# Set up command line arguments
parser = argparse.ArgumentParser(description='OSC listener for LEDs')
parser.add_argument('--listen',action='store',default='127.0.0.1:9000')
parser.add_argument('--debug-osc',action='store_true',default=False)
parser.add_argument('--listen',action='store',default='127.0.0.1:9000',help="Listen on a specific IP/port. Defaults to 127.0.0,.1:9000")
parser.add_argument('--debug-osc',action='store_true',default=False,help="Debug OSC messages. Very verbose")
args=parser.parse_args()
# Start the system.
log.info("Starting OSC...")
pprint(args)
# Log OSC stuff if requested
if args.debug_osc:
osc_startup(logger=log)
else:
osc_startup()
# Split up port/address from command line
listen_address=args.listen.split(':')[0]
listen_port=args.listen.split(':')[1]
# Start up the OSC server
osc_udp_server(listen_address,listen_port, clientname)
# Set up osc paths
# Each FX param has a callback function that is triggered whenever a message for that path is received
log.info("Binding targets...")
osc_method("/track/2/fx/1/fxparam/1/value",led_colour)
osc_method("/track/2/fx/1/fxparam/2/value",led_brightness)
osc_method("/track/2/fx/1/fxparam/[!12]/value",led_state,argscheme=OSCARG_ADDRESS+OSCARG_DATAUNPACK)
log.info("Creating LEDs...")
# Create LEDs
leds=[LED(i) for i in range(0,4)]
leds=[LED(i) for i in [16,20,21]]
# Do a massive loop listening for messages. This should really be cleaner...
finished=False
log.info("Starting loop")
while not finished:

Loading…
Cancel
Save