-
Notifications
You must be signed in to change notification settings - Fork 116
How to create a virtual device
Virtual Device (Vdev) is an instance of a VirtualDevice class' descendant which
exposes set of metrics
and commands
(according to it's type/subtype).
Virtual devices are the only runtime instances which is controllable and
observable throuh the ZAutomation API.
Technically, VDev is a VirtualDevice subclass which concretize, overrides or extends superclass' methods.
Class definition can be stored in a separate .js-file or reside in an
index.js
of it's module. It doesn't matter. To load external .js-file you
should call executeFile()
function.
// ...part of the BateryPolling.init()
executeFile(this.moduleBasePath()+"/BatteryPollingDevice.js");
Every AutomationModule has this.moduleBasePath()
which returns String which
contains module's exact folder name. This is neccessary due to executeFile()
is capable of loading any desired .js-file inside of the ZAutomation folder.
// Important: constructor SHOULD always be successful
BatteryPollingDevice = function (id, controller) {
// Always call superconstructor first
BatteryPollingDevice.super_.call(this, id, controller);
// Define VDevs properties
this.deviceType = "virtual";
this.deviceSubType = "batteryPolling";
this.widgetClass = "BatteryStatusWidget";
// Setup some additional metrics (many of them is setted up in a base class)
this.setMetricValue("someMetric", "someValue");
}
inherits(BatteryPollingDevice, VirtualDevice);
Number of VDev properties is mandatory, others is optional.
VDev class SHOULd always fill in the deviceType
property and often fill in
the deviceSubType
property.
If the particular VDev class can be controller by the client-side widget, it
SHOULD define widget's class name in the widgetClass
property.
BatteryPollingDevice.prototype.performCommand = function (command) {
var handled = true;
if ("update" === command) {
for (var id in zway.devices) {
zway.devices[id].Battery && zway.devices[id].Battery.Get();
}
} else {
handled = false;
}
return handled ? true : BatteryPollingDevice.super_.prototype.performCommand.call(this, command);
}
VDev itself mostly needed to handle commands, triggered by the events, system or the API.
In the example above you could see, that this VDev is capable of performing "update" command. But base class can be capable of performing some othe commands, so the last line calls superclass' performCommand() method if the particular command wasn't handled by the VDev itself.
This extensibility provides the possibility to create a VDev class tree. Take a
look at ZWaveGate
module as an example of such tree.
// ...part of the BatteryPolling.init() method
executeFile(this.moduleBasePath()+"/BatteryPollingDevice.js");
this.vdev = new BatteryPollingDevice("BatteryPolling", this.controller);
this.controller.registerDevice(this.vdev);
First line of code is loads and executes apropriate .js-file which provides BatteryPollingDevice class.
Secnd line instantiates this class.
The last line calls controller's registerDevice
method to register and VDev
instance.
It's that simple =)