Build the Logic Behind the Action

For this simple example, you will update the value of the Property state, once the Action of turning the lamp on/off is executed.

  1. Before coding your Function, get the Thing’s Client ID and Client Secret under the Interfaces tab and store the values under Space Settings > Secrets Storage.
  2. In User Functions > Function, choose to create + New Function.
  3. Enter a Function name (for example, toggle-logic).
  4. Choose to code using the template for Python3 and include the code below.
    1. Complete the following variables with your own values: SPACE and THING_UID
    2. Enter the name of your secrets to get them from the secrets storage and store their value in the variables CLIENT_ID and CLIENT_SECRET.
    from swx.auth.token import get_token, revoke_token
    import requests
    import json
    import function.secrets as secrets
    
    API_HOST = 'https://api.swx.altairone.com'
    
    SPACE ="EnterYourSpaceID"
    NAMESPACE = "{}/spaces/{}".format(API_HOST,SPACE)
    THING_UID="EnterYourThingUID"
    
    urlActionToggle = "{}/things/{}/actions/toggle".format(NAMESPACE, THING_UID)
    urlThingStatus = "{}/things/{}/properties".format(NAMESPACE, THING_UID)
    
    def handle(req):
    
    		action = json.loads(req.body.decode('utf-8'))
    		CLIENT_ID = secrets.get("EnterYourSecretsName")
    		CLIENT_SECRET = secrets.get("EnterYourSecretsName")
    	
    		with get_token(CLIENT_ID, CLIENT_SECRET, ["thing.read", "thing.update"]) as token:
    		    headers = {"Authorization": "Bearer " + token.access_token, "Prefer": "preview=2023.1"}
    		    href = action["toggle"]["href"]
    		    action_id = href.split('/')[-1]
    		    input_action = action["toggle"]["input"]["value"]
    		    urlUpdateAction = "{}/things/{}/actions/toggle/{}".format(NAMESPACE, THING_UID, action_id)
    		
    		    response = requests.request("GET", urlThingStatus, headers=headers)
    		    response_json = response.json()
    		    property_value = response_json["state"]
    		
    		    if input_action != property_value :
    		
    		        payload_property={
    		            "state" : input_action
    		        }
    		        update_property = requests.request("PUT", urlThingStatus , headers=headers, json = payload_property)
    		        payload_action = {
    		            "toggle": {
    		                "status": "Completed - Lamp State has been successfully updated."
    		            }
    		        }
    		        update_action = requests.request("PUT", urlUpdateAction , headers=headers, json = payload_action)
    		
    		    else:
    		        payload_action = {
    		            "toggle": {
    		                "status": "Completed - Lamp State Unchanged"
    		            }
    		        }
    		        update_action = requests.request("PUT", urlUpdateAction , headers=headers, json = payload_action)
    		
    		
    		return {
    		    "status_code": 200,
    		    "body": req.body.decode('utf-8')
    		}
  5. Under event Trigger, click + Add Topic. Complete YourSpaceIDand YourThingUID in the topic below with your own values and click Save:
    spaces/YourSpaceID/things/YourThingUID/actions/toggle 
    The logic behind the Function will update the state of the lamp if an Action is triggered. It will check that the input value of the Action is different from the state of the lamp and if so, the state of the lamp will be updated. If not, it will remain unchanged.

    Note that in a real implementation, you would add to the code the logic needed to actually execute the Action (typically, a request to a specific endpoint)

  6. In User Functions > Triggers, choose to add + New Trigger.
    A Trigger is a component that is capable of invoking serverless Functions from an event source. They work as a listener to a particular endpoint to convert incoming events to HTTP requests to asynchronously invoke all the Functions that match certain criteria.
  7. In this example, you need to define a Trigger to listen to the Event topic that will trigger the invocation of our Function:
    1. Choose type MQTT.
    2. Set the host as mqtt.swx.altairone.com
    3. Username and Password: MQTT credentials from our Thing.
    4. Topic: spaces/YourSpaceID/things/YourThingUID/actions/toggle
  8. Check the Function status is running, and proceed to test if it works as expected.