heidloff.net - Building is my Passion
Post
Cancel

How to invoke OpenWhisk Actions for certain IoT Device Events

Serverless Computing is often useful in event-driven Internet of Things (IoT) scenarios. For example when IoT sensors exceed a certain temperature actions are invoked to fix the issue.

OpenWhisk is IBM’s serverless computing offering in Bluemix. In order to implement a use case like above with the experimental OpenWhisk service, at this point you need to deploy a non-serverless application which receives MQTT events from IoT devices and invokes the appropriate OpenWhisk actions. While such a model seems to defeat the purpose of a serverless architecture, it allows developers to add their own filtering logic. For example rather than invoking hundreds of actions for hundreds of device events, you can invoke the potentially processing-intensive actions only for certain events, for example when the temperature is too hot.

Below is a simple sample how you could do this. Here is a sample action.

image

1
2
3
4
function main(params) {
   params = JSON.stringify(params);
   return { "message": "you sent me " + params };
}

For testing purposes you can invoke events via MQTT tools.

image

The following code shows a Node.js application that can be deployed via Cloud Foundry or Docker on Bluemix.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var cfenv = require("cfenv");
var appEnv = cfenv.getAppEnv();
var express = require('express');
var app = express();
app.get('/', function (req, res) {
   res.send('up');
});
app.listen(appEnv.port, appEnv.bind, function() {
   console.log('listening on port ' + appEnv.port);
});

var openwhisk = require('openwhisk');
var ow = openwhisk({ api: 'https://openwhisk.ng.bluemix.net/api/v1/', 
   api_key: 'xxx:xxx', 
   namespace: 'niklas_heidloff@de.ibm.com_dev' });

var Client = require("ibmiotf");
var appClientConfig = {
   "org" : "1o56n8",
   "id" : 'myapp',
   "auth-key" : "a-1o56n8-xxx",
   "auth-token" : "xxx"
}
var appClient = new Client.IotfApplication(appClientConfig);
appClient.connect();

appClient.on("connect", function () {
   // change this for the device events you're interested in   
   appClient.subscribeToDeviceEvents("TestDeviceType","+","+","json");
});

appClient.on("deviceEvent", function (deviceType, deviceId, eventType, format, payload) {
   // add your own filter logic here    
   payload = JSON.parse(payload);
   ow.actions.invoke({ actionName: "openwhisk",
      params: payload }).then(result => {
         console.log('success', result);
      })
});

The Node application uses iot-nodejs for the MQTT part and openwhisk as a convenience library to invoke actions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "name": "mqtt-to-openwhisk",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "dependencies": {
    "ibmiotf": "^0.2.12",
    "openwhisk": "2.0.0",
    "express": "4.13.4",
    "cfenv": "1.0.3"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node app.js"
  },
  "author": "",
  "license": ""
}

Invoked actions show up in the OpenWhisk dashboard.

image

As alternative to deploying a Node application you could also use Node-RED, the incoming IoT node and the openwhisk node.

Featured Blog Posts
Disclaimer
The postings on this site are my own and don’t necessarily represent IBM’s positions, strategies or opinions.
Trending Tags