-
Notifications
You must be signed in to change notification settings - Fork 114
Mock Device
In this tutorial we build upon the Quick Start project by adding a mock device driver to the Zetta hub. The mock driver models a simple state machine, designed to turn a mock LED on and off, as the following state machine notation shows:
According to the diagram when our LED is off
it can only transition to the on
state, and conversely when the state is on
it can only transition to off
.
To keep things simple, we've written this sample device driver for you and made it available to download. In this tutorial, we'll install this sample driver and add it to the Zetta server code.
This tutorial assumes you have completed the Quick Start tutorial and have the "Hello Zetta" project working.
-
If the Zetta server is still running, hit
Ctrl-c
to stop it. -
In the
hello-zetta
directory, install the mock driver using NPM:npm install zetta-led-mock-driver --save
Note: By convention, Zetta device driver names follow the pattern
zetta-[device name]-[platform name]-driver
. In this example, we're controlling an LED device on a "mock" platform. For example, a driver that controls an LED from an Intel Edison Board might be calledzetta-led-edison-driver
. -
Open
index.js
in a text editor. -
Add this require statement to line 2:
var LED = require('zetta-led-mock-driver');
-
Add this
use
statement to line 6:.use(LED)
-
Be sure the code looks like this, then save the file:
var zetta = require('zetta');
var LED = require('zetta-led-mock-driver');
zetta()
.name('Hello Zetta')
.use(LED)
.listen(1337, function(){
console.log('Zetta is running at http://127.0.0.1:1337');
});
Now we've configured the server to use the mock LED driver. Before we look at the driver, let's test it.
-
Start the server:
node index.js
-
Notice the terminal output has some new information that we didn't see before -- the LED device we added to the hub was discovered by something called a "scout". We'll discuss scouts in detail in another topic.
Oct-23-2015 10:02:24 [scout] Device (led) f826f6e0-ebb8-430a-9e1e-6efddebc42fc was discovered
Oct-23-2015 10:02:24 [server] Server (Hello Zetta) Hello Zetta listening on http://127.0.0.1:1337
Zetta is running at http://127.0.0.1:1337
Device discovery is an important Zetta concept. When Zetta discovers a device, the device information is automatically added to the API. In this case, you could write a very simple app that turns the LED on and off using this API. Let's see how that works.
-
Using cURL or in a REST app like Postman or Advanced REST client, call the root URL:
curl http://127.0.0.1:1337
-
Then, in the response, locate the
/servers/Hello%20Zetta
URL and call it:curl http://localhost:1337/servers/Hello%20Zetta
-
Notice that this time the entities element lists a device. This is the LED device driver we added to the server. The driver defines the current and possible state properties for the device. In the case of the LED, those properties are on and off. The current state (reflected in the
properties
attribute of the JSON response) isoff
.
{
"class": [
"server"
],
"properties": {
"name": "Hello Zetta"
},
"entities": [
{
"class": [
"device",
"led"
],
"rel": [
"http://rels.zettajs.io/device"
],
"properties": {
"id": "e6f5b480-e96e-4fdc-8718-91aeb0234c99",
"type": "led",
"state": "off"
},
"links": [
{
"rel": [
"self",
"edit"
],
"href": "http://localhost:1337/servers/Hello%20Zetta/devices/e6f5b480-e96e-4fdc-8718-91aeb0234c99"
},
{
"rel": [
"http://rels.zettajs.io/type",
"describedby"
],
"href": "http://localhost:1337/servers/Hello%20Zetta/meta/led"
},
{
"title": "Hello Zetta",
"rel": [
"up",
"http://rels.zettajs.io/server"
],
"href": "http://localhost:1337/servers/Hello%20Zetta"
}
]
}
],
"actions": [
{
"name": "query-devices",
"method": "GET",
"href": "http://localhost:1337/servers/Hello%20Zetta",
"type": "application/x-www-form-urlencoded",
"fields": [
{
"name": "ql",
"type": "text"
}
]
}
],
"links": [
{
"rel": [
"self"
],
"href": "http://localhost:1337/servers/Hello%20Zetta"
},
{
"rel": [
"http://rels.zettajs.io/metadata"
],
"href": "http://localhost:1337/servers/Hello%20Zetta/meta"
},
{
"rel": [
"monitor"
],
"href": "ws://localhost:1337/servers/Hello%20Zetta/events?topic=logs"
}
]
}
##Query the device capabilities
Now, let's follow the URL to the device itself. It looks something like this:
http://127.0.0.1:1337/servers/Hello%20Zetta/devices/a3bbdd2d-67fe-4fad-97b2-3851f18aae7e
Here we can discover what actions the actual device is capable of performing. This device has a "transition" action that lets you change its state. Because the current state, as we saw previously, is off
, the available action is turn-on
.
{
"class": [
"device",
"led"
],
"properties": {
"id": "e6f5b480-e96e-4fdc-8718-91aeb0234c99",
"type": "led",
"state": "off"
},
"actions": [
{
"class": [
"transition"
],
"name": "turn-on",
"method": "POST",
"href": "http://localhost:1337/servers/Hello%20Zetta/devices/e6f5b480-e96e-4fdc-8718-91aeb0234c99",
"fields": [
{
"name": "action",
"type": "hidden",
"value": "turn-on"
}
]
}
],
"links": [
{
"rel": [
"self",
"edit"
],
"href": "http://localhost:1337/servers/Hello%20Zetta/devices/e6f5b480-e96e-4fdc-8718-91aeb0234c99"
},
{
"title": "Hello Zetta",
"rel": [
"up",
"http://rels.zettajs.io/server"
],
"href": "http://localhost:1337/servers/Hello%20Zetta"
},
{
"rel": [
"http://rels.zettajs.io/type",
"describedby"
],
"href": "http://localhost:1337/servers/Hello%20Zetta/meta/led"
},
{
"title": "state",
"rel": [
"monitor",
"http://rels.zettajs.io/object-stream"
],
"href": "ws://localhost:1337/servers/Hello%20Zetta/events?topic=led%2Fe6f5b480-e96e-4fdc-8718-91aeb0234c99%2Fstate"
},
{
"title": "logs",
"rel": [
"monitor",
"http://rels.zettajs.io/object-stream"
],
"href": "ws://localhost:1337/servers/Hello%20Zetta/events?topic=led%2Fe6f5b480-e96e-4fdc-8718-91aeb0234c99%2Flogs"
}
]
}
You might have noticed the transition action includes an href
link. The link is an HTTP POST command that you can use to change the LED's state. To "turn the light on", you simply form the correct POST request.
"actions": [
{
"class": [
"transition"
],
"name": "turn-on",
"method": "POST",
"href": "http://localhost:1337/servers/Hello%20Zetta/devices/e511deee-a266-4431-8a42-eeef7f2412f9",
"fields": [
{
"name": "action",
"type": "hidden",
"value": "turn-on"
}
]
}
]
The POST request to turn on the light looks something like this (you'll need to use the link provided in your own response, which has the correct device ID):
curl -i -X POST -H http://127.0.0.1:1337/servers/Hello%20Zetta/devices/e6f5b480-e96e-4fdc-8718-91aeb0234c99 -d 'action=turn-on'
Tip: To produce nicely formatted JSON from cURL, you can pipe the cURL response to this Python command to pretty-format the response: python -m json.tool. For example:
curl -i -X POST http://127.0.0.1:1337/servers/Hello%20Zetta/devices/e6f5b480-e96e-4fdc-8718-91aeb0234c99 -d ‘action=turn-on | python -m json.tool
In the response, you can see that the state has been changed from off
to on
. Furthermore, the available action is changed to turn-off
. To turn the light off again, follow the same pattern by POSTing to the transition URL.
{
"class": [
"device",
"led"
],
"properties": {
"id": "e6f5b480-e96e-4fdc-8718-91aeb0234c99",
"type": "led",
"state": "on"
},
"actions": [
{
"class": [
"transition"
],
"name": "turn-off",
"method": "POST",
"href": "http://localhost:1337/servers/Hello%20Zetta/devices/e6f5b480-e96e-4fdc-8718-91aeb0234c99",
"fields": [
{
"name": "action",
"type": "hidden",
"value": "turn-off"
}
]
}
],
"links": [
{
"rel": [
"self",
"edit"
],
"href": "http://localhost:1337/servers/Hello%20Zetta/devices/e6f5b480-e96e-4fdc-8718-91aeb0234c99"
},
{
"title": "Hello Zetta",
"rel": [
"up",
"http://rels.zettajs.io/server"
],
"href": "http://localhost:1337/servers/Hello%20Zetta"
},
{
"rel": [
"http://rels.zettajs.io/type",
"describedby"
],
"href": "http://localhost:1337/servers/Hello%20Zetta/meta/led"
},
{
"title": "state",
"rel": [
"monitor",
"http://rels.zettajs.io/object-stream"
],
"href": "ws://localhost:1337/servers/Hello%20Zetta/events?topic=led%2Fe6f5b480-e96e-4fdc-8718-91aeb0234c99%2Fstate"
},
{
"title": "logs",
"rel": [
"monitor",
"http://rels.zettajs.io/object-stream"
],
"href": "ws://localhost:1337/servers/Hello%20Zetta/events?topic=led%2Fe6f5b480-e96e-4fdc-8718-91aeb0234c99%2Flogs"
}
]
}
In this topic, we added a sample "mock" device driver to a server, and then we traced the links provided in the server's JSON response to transition the state of the device.
The cool thing about Zetta APIs is that each response contains everything an app developer needs to navigate the API, discover its actions, and execute them.
Another thing to remember is that this pattern is central to Zetta development. You write the device driver for whatever device you want to access over HTTP, and Zetta provides a fully functional REST API for that device!
In the next part of the tutorial, we'll take a close look at the LED driver code.
Need help? Visit the Zetta Discuss List !
Need help? Visit the Zetta Discuss List ! |
---|
About Zetta
Videos and webcasts
- NEW! Building with Zetta
Tutorials
- NEW! Zetta tutorial series
- Quick start
- Configure a simple device
- Build a mock LED device
- Use the browser client
- Deploy a Zetta server to Heroku
Understanding Zetta
Writing Zetta drivers
- Finding Zetta device drivers
- Create a device driver from starter code
- More coming soon...
Using streams
Reference