diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..822a4a8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +commands.json \ No newline at end of file diff --git a/README.md b/README.md index c31f524..ee2261d 100644 --- a/README.md +++ b/README.md @@ -52,12 +52,12 @@ in this video. 2. Download the retaliation.py script onto the system connected to your missile launcher. - 3. Modify your `COMMAND_SETS` in the `retaliation.py` script to define your targeting - commands for each one of your build-braking coders (their user ID as listed - in Jenkins). A command set is an array of move and fire commands. It is recommend - to start each command set with a "zero" command. This parks the launcher in a known - position (bottom-left). You can then use "up" and "right" followed by a time (in - milliseconds) to position your fire. + 3. Copy `commands-example.json` to `commands.json` (removing comments) and use it to + define your targeting commands for each one of your build-braking coders (their user + ID as listed in Jenkins). A command set is an array of move and fire commands. + It is recommend to start each command set with a "zero" command. This parks the + launcher in a known position (bottom-left). You can then use "up" and "right" + followed by a time (in milliseconds) to position your fire. You can test a set by calling retaliation.py with the target name. e.g.: @@ -85,6 +85,7 @@ in this video. It may work with other models but I've only tested with this one. * Python 2.6+ * Python PyUSB Support (on Mac use brew to "brew install libusb") + * ```pip install -r requirements.txt``` * Should work on Windows, Mac and Linux Thanks to the dev team at PaperCut (working on print diff --git a/commands-example.json b/commands-example.json new file mode 100644 index 0000000..db24851 --- /dev/null +++ b/commands-example.json @@ -0,0 +1,28 @@ +{ + "will" : [ + ["zero", 0], // Zero/Park to know point (bottom-left) + ["led", 1], // Turn the LED on + ["right", 3250], + ["up", 540], + ["fire", 4], // Fire a full barrage of 4 missiles + ["led", 0], // Turn the LED back off + ["zero", 0] // Park after use for next time + ], + "tom" : [ + ["zero", 0], + ["right", 4400], + ["up", 200], + ["fire", 4], + ["zero", 0] + ], + "chris" : [ // That's me - just dance around and missfire! + ["zero", 0], + ["right", 5200], + ["up", 500], + ["pause", 5000], + ["left", 2200], + ["down", 500], + ["fire", 1], + ["zero", 0] + ] +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1cd0447 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pyusb==1.0.0b1 diff --git a/retaliation.py b/retaliation.py index 763c829..485cf91 100755 --- a/retaliation.py +++ b/retaliation.py @@ -83,44 +83,22 @@ import usb.core import usb.util +import json +import os + ########################## CONFIG ######################### # -# Define a dictionary of "command sets" that map usernames to a sequence -# of commands to target the user (e.g their desk/workstation). It's -# suggested that each set start and end with a "zero" command so it's +# Json structure representing targets. +# It's suggested that each set start and end with a "zero" command so it's # always parked in a known reference location. The timing on move commands # is milli-seconds. The number after "fire" denotes the number of rockets # to shoot. # -COMMAND_SETS = { - "will" : ( - ("zero", 0), # Zero/Park to know point (bottom-left) - ("led", 1), # Turn the LED on - ("right", 3250), - ("up", 540), - ("fire", 4), # Fire a full barrage of 4 missiles - ("led", 0), # Turn the LED back off - ("zero", 0), # Park after use for next time - ), - "tom" : ( - ("zero", 0), - ("right", 4400), - ("up", 200), - ("fire", 4), - ("zero", 0), - ), - "chris" : ( # That's me - just dance around and missfire! - ("zero", 0), - ("right", 5200), - ("up", 500), - ("pause", 5000), - ("left", 2200), - ("down", 500), - ("fire", 1), - ("zero", 0), - ), -} +curr_dir = os.path.dirname(os.path.realpath(__file__)) +json_data = open(curr_dir + '/commands.json') +COMMAND_SETS = json.load(json_data) +json_data.close() # # The UDP port to listen to Jenkins events on (events are generated/supplied @@ -181,7 +159,7 @@ def usage(): def setup_usb(): # Tested only with the Cheeky Dream Thunder # and original USB Launcher - global DEVICE + global DEVICE global DEVICE_TYPE DEVICE = usb.core.find(idVendor=0x2123, idProduct=0x1010) @@ -195,7 +173,7 @@ def setup_usb(): else: DEVICE_TYPE = "Thunder" - + # On Linux we need to detach usb HID first if "Linux" == platform.system(): @@ -259,9 +237,8 @@ def run_command(command, value): def run_command_set(commands): - for cmd, value in commands: - run_command(cmd, value) - + for cmd in commands: + run_command(cmd[0], cmd[1]) def jenkins_target_user(user): match = False @@ -291,7 +268,7 @@ def read_url(url): def jenkins_get_responsible_user(job_name): # Call back to Jenkins and determin who broke the build. (Hacky) # We do this by crudly parsing the changes on the last failed build - + changes_url = JENKINS_SERVER + "/job/" + job_name + "/lastFailedBuild/changes" changedata = read_url(changes_url) @@ -327,7 +304,7 @@ def jenkins_wait_for_event(): jenkins_target_user(target) except: pass - + def main(args):