Package: aitpi
AITPIArbitrary Input for Terminal or a Pi, or Aitpi (pronounced 'eight pi')GoalThe goal of this project is to provide a simple, but arbitrary, input
mechanism for use with a raspberry pi, or a terminal keyboard (maybe more SBCs in the future?!).This program can be configured with two simple json files.SupportedThe project supports:Simple 'buttons''1 to 1' gpio to button setup on a raspberry piNon interrupt based key inputInterrupt based key input (using pynput)Encoders'2 to 1' gpio to encoder setup on a raspberry piNon interrupt based 2 to 1 key inputInterrupt based 2 to 1 key input (using pynput)ExamplesTo configure your setup, you can create up to three types of json files:Command Registry:A registry of commands that will interact directly with your user program[
    {
        "type": "normal",
        "input_type": "button",
        "id": "1",
        "name": "command0"
    },
    {
        "id": "1",
        "input_type": "button",
        "path": "../temp/",
        "type": "presets",
        "name": "howdy"
    },
    {
        "id": "1",
        "input_type": "button",
        "path": "../temp/",
        "type": "presets",
        "name": "test"
    },
    {
        "id": "1",
        "input_type": "button",
        "path": "../temp/",
        "type": "presets",
        "name": "another.txt"
    }
]name: A UNIQUE identifier that is presented.id: The message id sent with each commandinput_type: The abstract functional representation i.e. (for now) a button or an encodertype: Category for each command. Must be defined, but is only used to sort commands usefullypath: Only used for foldered commands. Tells the file path of the represented file.Input listThe list of all 'input units' that your system uses[
    {
        "name": "Button0",
        "type": "button",
        "mechanism": "rpi_gpio",
        "trigger": "5",
        "reg_link": "commandName0"
    },
    {
        "name": "Encoder0",
        "type": "encoder",
        "mechanism": "rpi_gpio",
        "left_trigger": "17",
        "right_trigger": "24",
        "reg_link": "commandName2"
    }
]This is an array of depth 1, with all your 'input units' listed as dictionaries inside"name": specifies the name of the input unitValid names: Any string, must be unique among all input units"type": specifies what type of input this unit isValid types: 'button', 'encoder'"mechanism": This tells Aitpi by what mechanism the input will be watchedValid mechanisms: 'key_interrupt', 'key_input', 'rpi_gpio'key_interrupt: Usespynputto set interrupts on your keyboard itselfkey_input: Manual in-code input through the function 'aitpi.takeInput'rpi_gpio: Raspberry pi GPIO input, all input units are assumed to be active low"trigger": The key string or gpio number that will trigger input for a buttonNOTE: This is only needed if 'type' equals 'button'Valid triggers: Any string, or any valid unused gpio number on a raspberry piNote strings of more than one char will not work with key_interrupt (pynput)"left_trigger" and "right_trigger: The key string or gpio numbers that will act as a left or right for an encoderNOTE: These are only needed if 'type' equals 'encoder'Valid left_triggers and right_triggers: Any string, or any valid unused gpio number on a raspberry piNote strings of more than one char will not work with key_interrupt (pynput)"reg_link": This corrosponds to a command from the command registry and will determine what message is sent to your user programFoldered CommandsFoldered commands allows you to consider all the files in a folder as a 'command' in the registry.
This uses thewatchdogpython package to monitor folders and update on the fly.
All commands added will be deleted and reloaded upon program startup.[
    {
        "name": "Folder0",
        "path": "/path/to/your/folder",
        "type": "<registry_type>",
        "id": "3",
        "input_type": "button"
    },
    {
        "name": "Folder1",
        "path": "/another/path",
        "type": "<registry_type>",
        "id": "4",
        "input_type": "encoder"
    }
]This is an array of depth 1 that lists all the folders you want to add"name": Gives a name that you can use to access the json using 'getFolderedCommands'Valid names: Any string"path": Specifies the folder that will be watchedValid paths: Any valid folder on your system"type": This will tell Aitpi where to insert the commands from the folder into your command registryValid types: Any string"id": When a command is added from the folder, this id will be the command registry 'id' valueValid ids: Any positive int, negative ints are reserved for Aitpi and could produce bad side effects"input_type": When a command is added from the folder, this directly corrosponds to the command registry's 'input_type'Example usage:# import the base aitpiimportaitpifromaitpiimportrouter# In order to receive messages can either make an object with a consume(message) function# or just provide a function `def consume(message)`classWatcher():defconsume(self,message):print("Got command:%s"%message.name)print("On event:%s"%message.event)print("All attributes:%s"%message.attributes)watcher=Watcher()# Here we add a consumer that will receive commands with ids 0,1,2,3,4, these ids are the same# as defined in your registry json filerouter.addConsumer([0,1,2,3,4],watcher)# We must first initialize our command registry before we can start getting inputaitpi.addRegistry("<path_to_json>/command_reg.json","<path_to_json>/foldered_commands.json")# We can add multiple registries, and do not need the foldered commandsaitpi.addRegistry("<path_to_json>/another_reg.json")# Once we initialize our system, all interrupt based commands can be sent imediately.# Therefore, make sure you are ready to handle any input in your functions before calling this.aitpi.initInput("<path_to_json>/example_input.json")# For synchronous input (not interrupt based) using the 'key_input' input mechanism is desireable# You can setup a custom progromatic form of input using this (If it is good enough, add it to AITPI!)while(True):aitpi.takeInput(input())