-
Notifications
You must be signed in to change notification settings - Fork 114
How Drivers Work
Let's create our state machine for use in Zetta. When drawn out with state machine notation, our LED should look a little like this:
{:.zoom}
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
.
Our driver will have 4 major parts, all dictated by Zetta:
- Dependencies
- The constructor function
- An init function to define our state machine
- Transition functions
First we'll require all the necessary libraries
- We'll need the Device class to create our driver
- We'll need the util module for inheritance functionality
- We'll need bonescript for actually interacting with hardware on the BeagleBone
Add this to your empty /devices/led/index.js
file:
var Device = require('zetta-device');
var util = require('util');
var bone = require('bonescript');
Now we'll setup the constructor for our LED. Here you set parameters and initialize different things about the device.
Continue by adding this code to your /devices/led/index.js
file:
var Led = module.exports = function(pin) {
Device.call(this);
this.pin = pin || 'P9_41';
};
util.inherits(Led, Device);
- Line 3 tells the driver to use the pin you specify in
.use()
function inserver.js
, or uses the default of P9_41 - On line 6, we inherit from the
Device
class withutil.inherits()
to get functionality for API generation.
Next we'll implement the init function. This is where you'll implement your state machine.
-
.state()
sets the initial state of your device. We're starting in the off state -
.type()
sets what the type of the device is. In our case it'sled
. -
.name()
sets a human readable name for our device. It's an optional parameter. -
.when()
sets up what transitions are available based on the state of the device.-
when
our device is in state"on"
it can only use the"turn-off"
and"toggle"
transitions -
when
our device is in state"off"
it can only use the"on"
and"toggle"
transitions
-
-
.map()
will setup the functions that will be called for particular transitions. Whenever a transition occurs the function it is mapped to will be called.- when the
"on"
transition is called we will call theturnOn
function of this particular class - when the
"off"
transition is called we will call theturnOff
function of this particular class - when the
"toggle"
transition is called we will call thefunction
function of this particular class
- when the
Continue by adding this code to your /devices/led/index.js
file:
Led.prototype.init = function(config) {
config
.state('off')
.type('led')
.name('LED')
.when('on', { allow: ['turn-off', 'toggle'] })
.when('off', { allow: ['turn-on', 'toggle'] })
.map('turn-on', this.turnOn)
.map('turn-off', this.turnOff)
.map('toggle', this.toggle);
//Everything is off to start
bone.pinMode(this.pin, bone.OUTPUT);
bone.digitalWrite(this.pin, 0);
};
TIP Any setup you have to do for your device (such as line 14, which turns the LED off by default) should go inside it's init function, not the constructor
Finish up by adding the transition functions.
-
turnOn
will actually turn on the LED on the BeagleBone. It is provided a callback that you should call once the transition has completed. -
turnOff
will actually turn off the LED on the BeagleBone. It is provided a callback that you should call once the transition has completed. -
toggle
will change the led to off if it is currently on, or on if it is currently off. It is provided a callback that you should call once the transition has completed.
Your final /devices/led/index.js
file should look like this:
var Device = require('zetta').Device;
var util = require('util');
var bone = require('bonescript');
var Led = module.exports = function(pin) {
Device.call(this);
this.pin = "P9_41";
};
util.inherits(Led, Device);
Led.prototype.init = function(config) {
config
.state('off')
.type('led')
.name('LED')
.when('on', { allow: ['turn-off', 'toggle'] })
.when('off', { allow: ['turn-on', 'toggle'] })
.map('turn-on', this.turnOn)
.map('turn-off', this.turnOff)
.map('toggle', this.toggle);
//Everything is off to start
bone.pinMode(this.pin, bone.OUTPUT);
bone.digitalWrite(this.pin, 0);
};
Led.prototype.turnOn = function(cb) {
var self = this;
bone.digitalWrite(this.pin, 1, function() {
self.state = 'on';
cb();
});
};
Led.prototype.turnOff = function(cb) {
var self = this;
bone.digitalWrite(this.pin, 0, function() {
self.state = 'off';
cb();
});
};
Led.prototype.toggle = function(cb) {
if (this.state === 'on') {
this.call('turn-off', cb);
} else {
this.call('turn-on', cb);
}
};
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