Actions

Actions can be called from any events within the Workflow like on button pressed, on received message etc.

Create an Action

self.addAction(Name, Group, FunctionToCall)

Example

def afterInit(self):
    self.addAction("Action Name", "Group name", self.onRunAction)
    
async def onRunAction(self, callback):
    print("Run Action")
    callback(None)

The Group is "optional" and helps within the menu to organize a larger amount of actions. Leave Group empty and the action will be found directly within the root of the plugin and won't be organized within folders.

self.addAction("Action Name", "", self.onRunAction)

Action with parameter

def afterInit(self):
    myAction = self.addAction("Action Name", "Group Name", self.onRunAction)
    
    myAction.addFloatParameter("Example Float", 0, 0, 100)

async def onRunAction(self, callback, floatParam)
    print(floatParam)
    callback(None)

Action with dynamic changeable data target parameter

If actions needs dynamic parameter its possible to use the entities data structure for these.

.addDataTargetParameter(Name, ".host/entities/data", Path, Value, Name)
def afterInit(self):
    myAction = self.addAction("Action Name", "Group Name", self.onRunAction)
    
    myAction.addDataTargetParameter("Name", ".host/entities/data", "/Path/", "/Value", "/Name")

Example:

def afterInit(self):
    myAction = self.addAction("Action Name", "Group Name", self.onRunAction)
    
myAction.addDataTargetParameter("ControlID", ".host/entities/data", "/Controls/Boolean/", "/Id", "/ControlName")

Action with multiple parameters

def afterInit(self):
        myAction = self.addAction("Action Name", "Group Name", self.onRunAction)
        
        myAction.addFloatParameter("Example Float", 0, 0, 100)
        myAction.addIntParameter("Example Int", 587, 1, 65535)
        myAction.addBoolParameter("ExampleBool", False)
        myAction.addStringParameter("Example String", "")
        myAction.addIPParameter("Example IP", False)
        myAction.addTriggerParameter("Example Trigger Button")
        myAction.addPointParameter("Example Point",0,0,-10,10,-10,10)
        myAction.addVectorParameter("Example Vector", 0, 0, 0, -100, 100, -100, 100, -100, 100)
        myAction.addColorParameter("Example Color")
        myAction.addDataTargetParameter("Example LinkPath", "FilterPath", "Value", "Label", "Something")
        myAction.addEnumParameter("Example Enum", 0, "Entry 1;Entry 2;Entry 3")
        myAction.addScriptTokens(["Token1", "Token2", "..."])
        myAction.addFileParameter("Example File","")

async def onRunAction(self, callback, floatParam, intParam, boolParam, stringParam, ipParam, pointParam, vectorParam, colorParam, dataParam, enumParam, fileParam):
        print(floatParam)
        print(intParam)
        print(boolParam)
        print(stringParam)
        print(ipParam)
        print(pointParam)
        print(vectorParam)
        print(colorParam)
        print(dataParam)
        print(enumParam)
        print(fileParam)
        callback(None)

Using data response within an Action

It´s possible, that an action returns data into the data workflow "pipeline".

A response need to be a sp.ValueTree():

def afterInit(self):
    myAction = self.addAction("Action Name", "Group Name", self.onRunAction)

async def onRunAction(self, callback):

    response = sp.ValueTree("root")
    response["someData"].value = 123
    response["moreData"].value = False

    callback(response)

Or sp.ValueTree.fromDict():

def afterInit(self):
    myAction = self.addAction("Action Name", "Group Name", self.onRunActionWithDict)

async def onRunActionWithDict(self, callback):

    someDict = {"someData": 123, "moreData", False}
    callback(sp.ValueTree.fromDict(someDict , "root"))

Force an Action to trigger the "failed" pin

If not other defined within the callback(), the Action will always trigger the "success" pin from your action, as long the plugin is enabled.

There are many reasons why an action will be not successful, like being not connected to the device etc.

In this cases the plugin should "catch" these behaviors and use callback(response, failed=True):

async def onRunAction(self, callback):
    if self.someProof:
        callback(None)
    else:
        callback(None, failed=True)

or like:

async def onRunAction(self, callback):
    try: 
        self.someFunction()
        callback(None)
    except:
        callback(None, failed=True)

Last updated