diff --git a/README.md b/README.md index 81583d8..0c7ecd8 100644 --- a/README.md +++ b/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 diff --git a/config.json b/config.json new file mode 100644 index 0000000..deb02ff --- /dev/null +++ b/config.json @@ -0,0 +1,31 @@ +{ + "inputs":{ + "buttons":{ + "restart":{ + "pin": 2, + "when_pressed": "restart" + } + } + }, + + "outputs":{ + "leds":[ + {"name":"1", + "pin": 21, + "target": 3 + }, + { "name":"2", "pin":20, "target":"4", "defaults": { "state":0,"brightness":1.0}}, + { "name":"3", "pin":16, "target":"5"}, + { "name":"4", "pin":12, "target":"6"}, + { "name":"5", "pin":5, "target":"7"}], + + "defaults":{ + "led":{ + "brightness": 1.0, + "colour": 1.0 , + "state": 0 + } + } + } +} + diff --git a/osc_client.py b/osc_client.py index d3722c9..38ee74b 100755 --- a/osc_client.py +++ b/osc_client.py @@ -24,13 +24,14 @@ def cmd_stop(): osc_msg_send("/stop","i",1) def cmd_restart(): - stop() + cmd_stop() osc_msg_send("/gotomarker","i",1) - play() + cmd_play() parser = argparse.ArgumentParser(description='OSC controller for REAPER') -parser.add_argument('command', action='store',choices=[cmd.replace("cmd_",'') for cmd in globals() if 'cmd_' in cmd],help='Command to send via OSC') +if __name__ == '__main__': + parser.add_argument('command', action='store',choices=[cmd.replace("cmd_",'') for cmd in globals() if 'cmd_' in cmd],help='Command to send via OSC') parser.add_argument('--debug-osc',action='store_true',default=False,help='Debug OSC messages') parser.add_argument('--server',action='store',default='127.0.0.1:8000',help="Server to connect to :. Defaults to localhost:8000",metavar='server:port') args=parser.parse_args() diff --git a/osc_server.py b/osc_server.py index 716a783..026058c 100755 --- a/osc_server.py +++ b/osc_server.py @@ -8,12 +8,16 @@ from pprint import pprint import argparse import colorsys import gpiozero +import osc_client +import json # Set up basic vars and logging logging.basicConfig(format='%(asctime)s - %(threadName)s ΓΈ %(name)s - ' '%(levelname)s - %(message)s') -log = logging.getLogger("osc") +log = logging.getLogger("ledserver") log.setLevel(logging.INFO) +osc_log=logging.getLogger("osc") +osc_log.setLevel(logging.WARNING) clientname="ledserver" # Get the normalised RGB values for the HSV (i.e, the colour float designating hue from OSC) @@ -43,21 +47,24 @@ class LED: state=False # The pin number of the LED pin=None + # The OSC target FX param + target=0 + name="" # List for logging state mode=["off","on"] # Initialize the object, set up GPIO - def __init__(self,pin): + def __init__(self,pin,target): self.pin=pin + self.target=target 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)) + log.info("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): @@ -82,19 +89,68 @@ class LED: # 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) + for name,led in leds.items(): + led.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): - for led in leds: + for name,led in leds.items(): 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)) - - + target=addr.split("/")[6] + for led in [led for name,led in leds.items() if led.target==target]: + led.toggle_state(bool(value)) + +def btn_restart(): + initialise() + osc_client.cmd_restart() + +def btn_play(): + osc_client.cmd_play() + +def btn_stop(): + osc_client.cmd_stop() + +def initialise(filename='config.json'): + global config + global leds + global buttons + config=json.load(open(filename)) + + log.info("Creating LEDs...") + + # Create LEDs + if 'leds' in globals(): + del leds + leds={led['name']:LED(led['pin'],led['target']) for led in config['outputs']['leds']} + for led in config['outputs']['leds']: + if "defaults" not in led: + led['defaults']={} + for i in config['outputs']['defaults']['led'].keys(): + led['defaults'][i]=config['outputs']['defaults']['led'][i] + + state=led['defaults']["state"] if "state" in led["defaults"] else config['outputs']["defaults"]['led']["state"] + colour=led['defaults']['colour'] if 'colour' in led['defaults'] else config['outputs']['defaults']['led']['colour'] + brightness=led['defaults']['brightness'] if 'brightness' in led['defaults'] else config['outputs']['defaults']['led']['brightness'] + + + leds[led['name']].set_state(bool(state)) + leds[led['name']].set_colour(colour) + leds[led['name']].set_brightness(brightness) + # Don't re-initialise buttons, specifically because we expect this to be called by a button + # And unassigning the calling button will probably break things + if 'buttons' not in globals(): + buttons={} + for name,button in config['inputs']['buttons'].items(): + log.info('Binding button {} to pin {}'.format(name,button['pin'])) + buttons[name]=gpiozero.Button(button['pin']) + log.info('Binding button {} when_pressed to {}'.format(name,button['when_pressed'])) + buttons[name].when_pressed=globals()['btn_'+button['when_pressed']] + pprint(buttons[name].when_pressed) + + # 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',help="Listen on a specific IP/port. Defaults to 127.0.0,.1:9000") @@ -108,7 +164,7 @@ log.info("Starting OSC...") # Log OSC stuff if requested if args.debug_osc: - osc_startup(logger=log) + osc_startup(logger=osc_log) else: osc_startup() @@ -129,10 +185,10 @@ 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 [16,20,21]] +initialise() +#restart_button=gpiozero.Button(2) +#restart_button.when_pressed=osc_client.cmd_restart # Do a massive loop listening for messages. This should really be cleaner...