Skip to content

how can I add custom actions to ambit? #4

Open
@jafny

Description

@jafny

Let me start by saying thanks for this great repo, really excited to play around with it! One question I have is where can I register callbacks to execute when I get an Input? I see that I can use actionmaps for the executeCommand action when I receive input...but I was curious where I can define those callbacks.

Such as the below example: "rotation_left": { "action": "adjustTemperature", "behavior": "delta", "invert": true }

Where can I define what the adjustTemperature string argument maps to a callback function?

Activity

added
documentationImprovements or additions to documentation
questionFurther information is requested
on Jan 13, 2022
changed the title Probably Silly Question how can I add custom actions to ambit? on Jan 13, 2022
khimaros

khimaros commented on Jan 13, 2022

@khimaros
Owner

hello @jafny -- this is a completely reasonable question!

the callback system is not quite as extensible/modular as i'd like and requires modifying a few different parts of the core ambit code in order to add a new native action. this is suboptimal and will require you to maintain patches against ambit and possibly deal with merge conflicts as the core code evolves. however, for posterity, the places are:

in the meantime, your best bet might actually be to use executeCommand with an external program written in any language of your choice. there are some examples of this in the included layouts: https://github.com/khimaros/ambit/tree/master/ambit/resources/layouts/multifunction-buttons

the executeCommand action is documented at https://github.com/khimaros/ambit/blob/master/docs/CONFIG.md#executecommand and usage would look something like:

{ "action": "executeCommand", "argv": [ "./example/scripts/temperature.sh" ], "limits": [50, 80] }

with the accompanying external program at https://github.com/khimaros/ambit/blob/master/example/scripts/temperature.sh

if you are interested in writing native modules in python or executeCommand doesn't fit your needs, please let me know. i can prioritize adding a plugin based system for this, as it was already on the roadmap.

pinned this issue on Jan 13, 2022
khimaros

khimaros commented on Jan 14, 2022

@khimaros
Owner

i can envision a few ways to support defining custom actions in ambit, i'm interested to hear your thoughts on these.

regardless, i'd like the end result to support using custom external actions in the layout like:

{ "action": "externalAction", "data": {"somekey": "somevalue"}, "limits": [50, 80] }

option 1: enable plugins in config file

this would allow loading of modules entirely from the config and would not require writing any python code except for the module. it would also make it easier to use community made modules. loading the plugin in the layout config would look like:

{
    "action_plugins": ["/path/to/external_action.py"],
    "module_mappings": {...}
}

and the module itself would look like:

class Behavior:
    items = [...]

class Actions:
    def externalAction(self, ctrl, value, data):
        ctrl.screen_string('E: %s %s' % (value, data['somekey']))

option 2: subclass ambit controller

this option would require creating a new main entrypoint like bin/ambit and executing that instead of the upstream bin. a downside is that this would require making your own copy of any such upstream you use such as bin/ambit_demoscene. it also means making more of the core ambit API stable across releases.

class CustomController(ambit.Controller):
    @ambit.Callback('externalAction')
    def external_action_callback(self, value, data):
        self.screen_string('E: %s %s' % (value, data['somekey']))

def main():
    config = ambit.StandardConfiguration()
    ctrl = CustomController(config)
    ...

option 3: register callbacks procedurally

same limitations as option 2.

def external_action_callback(ctrl, value, data):
   ctrl.screen_string('E: %s %s' % (value, data['somekey']))

def main():
    config = ambit.StandardConfiguration()
    ctrl = ambit.Controller(config)
    ctrl.register_external_action('externalAction', external_action_callback, items=[...])
    ...

arguably, we could have some combination of these, but curious which you'd prefer. in terms of ease of implementation for me, the order would be: option 3, 2, 1

jafny

jafny commented on Jan 18, 2022

@jafny
Author

Sorry for the delayed response! If I am picturing the easy option 3 I think it will work well for my use case. At it's most basic, I want to create a method of interfacing with a websocket API where an ambitt powered MonogramCC is my UI. If I can write all my websocket interactions as modules, and then use the proposed "register_external_action" callback to inject that into a button push or knob dial....that feels like it would work great.

khimaros

khimaros commented on Feb 9, 2022

@khimaros
Owner

@jafny thank you for the feedback. i just want to confirm: does executeCommand fit your needs in the short term or is there something you'd like to do that isn't supported there?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationquestionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      how can I add custom actions to ambit? · Issue #4 · khimaros/ambit