# Actions

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

<figure><img src="/files/4DyQ71tMnHyv12F0GaNk" alt=""><figcaption></figcaption></figure>

## Create an Action

```
self.addAction(Name, Group, FunctionToCall)
```

#### Example

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

{% hint style="info" %}
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.<br>

<pre class="language-python"><code class="lang-python"><strong>self.addAction("Action Name", "", self.onRunAction)
</strong></code></pre>

{% endhint %}

***

## Action with parameter

```python
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.&#x20;

{% hint style="info" %}
[Learn here more about entities](broken://pages/2N1Bck8Lx7FpcyShhXkg)
{% endhint %}

```
.addDataTargetParameter(Name, ".host/entities/data", Path, Value, Name)
```

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

Example:

<figure><img src="/files/mnkkPdHT9vEAgHxSR85U" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/eUxWQ1qVTedof51Vcpig" alt=""><figcaption></figcaption></figure>

***

## Action with multiple parameters

{% code fullWidth="false" %}

```python
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)
```

{% endcode %}

{% hint style="warning" %}
The order of adding parameters to the action is defining also the order for the parameters within the called function.
{% endhint %}

{% hint style="info" %}
[Click here to find out more about the different parameter types](broken://pages/WUv2UuCJy5N34VB1R1z3)
{% endhint %}

***

## Using data response within an Action

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

<figure><img src="/files/Nwu0WJUnov1ziUqLCfKB" alt=""><figcaption></figcaption></figure>

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

```python
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()`:

```python
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

<figure><img src="/files/YNugJHDMCYBiEAh9goP1" alt=""><figcaption></figcaption></figure>

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

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

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

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

or like:

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://stage-precision.gitbook.io/grid/extensions/actions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
