Node.js implementation of HDL SmartBus protocol http://hdlautomation.com.
When someone creates something great, why re-invent the wheel? The original creator (caligo-mentis) has done a great job of this library - but I needed some additional functionality which we couldn't agree on how it was implemented. The vast majority of caligo-mentis/smart-bus repo is untouched apart from:
sendAs
function - A function that adds the ability to send a message on the bus as any address simply by passing the first argulment as a string (eg1.50
). This is useful when crafting replies to physical bus devices that must appear to come from a different device - my original use for this was the HDL Dali module didn't correctly send status updates - so I usedsendAs
to impersonate the Dali module and send the status updates. Yes, this could be achieved with the new multi-bus approach, but I wanted a simple in-line ability to send as anything.0x0033
parser to enable display of channel status requests0xE012
parser/encoder for panel brightness and lock commands0xE14E
parser/encoder for panel button colour.
Create instance of SmartBus connector
var SmartBus = require('smart-bus');
var bus = new SmartBus({
device: '1.50', // Connector address in HDL network (subnet.id)
gateway: '192.168.1.250', // HDL SmartBus gateway IP
port: 6000 // and port, default: 6000
});
Connector address could be defined either as string in device
property,
or as separate properties subnet
and id
. In addition to passing
configuration as an object, you can use a url string:
var bus = new SmartBus('hdl://1.50@192.168.1.250:6000');
HDL gateway port also would be used as listening port of udp server to receive broadcast messages.
If you have several physical HDL gateways create Bus
instance for each:
var firstGateway = new SmartBus('hdl://1.50@192.168.1.250:6000');
var secondGateway = new SmartBus('hdl://1.51@192.168.1.251:6000');
Alternatively UDP broadcasting can be used if gateways sharing same network.
To do this create Bus
instance with broadcast address as gateway IP and enable
broadcast mode:
// Bus instance with broadcast address as gateway IP
var bus = new SmartBus('hdl://1.50@192.168.1.255:6000');
bus.on('listening', function() {
bus.setBroadcast(true);
});
Add handler to intercept all commands across bus
bus.on('command', function(command) {
// Integer with command operation code
command.code;
// Device objects
command.sender;
command.target;
// Object with decoded data or raw buffer
// if data can not be parsed automatically
command.data;
});
Handlers can be added for broadcast messages or specific commands
bus.on('broadcast', function(command) { ... });
bus.on(0x0032, function(command) { ... });
Listen for commands from specific device
var sensor = bus.device('1.20');
sensor.on(0x1647, function(data, target) { ... });
Use connector to send commands
bus.send('1.4', 0x0004, function(err) { ... });
bus.send('1.4', 0x0031, { channel: 1, level: 100 }, function(err) { ... });
Or use device object
var logic = bus.device('1.10');
logic.send(0xE01C, { switch: 1, status: 1 }, function(err) { ... });
Both send
methods accepts raw Buffer
as data object. In case if
data object can not be encoded error will be passed into callback.
Initialize channel object
var dimmer = bus.device('1.4');
var spotlights = dimmer.channel(2);
Listen to channel status event
spotlights.on('status', function() {
console.log('Spotlights level is %s', spotlights.level);
});
Set device channel level value to 100 in 5 seconds
spotlights.control(100, { time: 5 }, function(err) { ... });
control
function will send 0x0031
command into bus.
Underlying UDP socket can be closed using close
method:
bus.on('close', function() {
console.log('HDL Bus is closed');
});
bus.close();
Bus
will close UDP socket on error automatically so it
would be useful to attach error
event handler and restart
process if needed.
var error;
bus.on('error', function(err) { error = err; });
bus.on('close', function() {
// Shutdown process with error code
process.exit(err ? 1 : 0);
});