zigbee-bridge

API

Major Classes

This module provides you with Bridge and Endpoint classes.

Bridge Class

Exposed by require('zigbee-bridge')


new Bridge(path[, opts])

Create a new instance of the Bridge class. The created instance is a ZigBee gateway that runs with node.js.

Arguments:

  1. path (String): A string that refers to system path of the serial port connecting to your ZNP (CC253X), e.g., '/dev/ttyUSB0'.
  2. opts (Object): This value-object has three properties sp, net and dbPath to configure the serial port, zigbee network settings and database file path.
    • sp (Object): An optional object to configure the seiralport. Default is { baudrate: 115200, rtscts: true }.
    • net (Object): An object to configure the network settings, and all properties in this object are optional. The descriptions are shown in the following table.
    • dbPath (String): Set database file path, default is __dirname + '/database/dev.db'.
Property Type Mandatory Description Default value
panId Number Optional Identify the ZigBee PAN. This id should be a value between 0 and 0x3FFF. You can also set it to 0xFFFF to let ZNP choose a random PAN-ID on its own. 0xFFFF
channelList Array Optional Pick possible channels for your ZNP to start a PAN with. If only a single channel is given, ZNP will start a PAN with the channel you’ve picked. [ 11 ]
precfgkey Array Optional This is for securing and un-securing packets. It must be an array with 16 uint8 integers. [ 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0D ]
precfgkeysEnable Boolean Optional To distribute the security key to all devices in the network or not. true
startoptClearState Boolean Optional If this option is set, the device will clear its previous network state. This is typically used during application development. false

Returns:

Examples:

const Bridge = require('zigbee-bridge');

const bridge = new Bridge('/dev/ttyUSB0', {
  sp: {
    baudrate: 115200,
    rtscts: true
  },
  net: {
    panId: 0x1234,
    channelList: [12, 14], // pick CH12 and CH14
    precfgkey: [
      0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
    ],
    precfgkeysEnable: true
  }
});

.start()

Connect to the ZNP and start bridge.

Returns:

Examples:

// promise style
bridge.start()
  .then(() => console.log('bridge is now running.'));

.stop()

Disconnect from the ZNP and stop bridge.

Returns:

Examples:

bridge.stop()
  .then(() => console.log('bridge is stopped.'));

.reset(mode)

Reset the ZNP.

Arguments:

  1. mode (String Number): Set to 'hard' or 0 to trigger the hardware reset (SoC resets), and set to 'soft' or 1 to trigger the software reset (zstack resets).

Returns:

Examples:

// hard reset
bridge.reset(0)
  .then(() => console.log('reset successfully.'));

// soft reset
bridge.reset('soft')
  .then(() => console.log('reset successfully.'));

.permitJoin(time[, type])

Allow or disallow devices to join the network. A permitJoining event will be fired every tick of countdown (per second) when bridge is allowing device to join its network.

Arguments:

  1. time (Number): Time in seconds for bridge to allow devices to join the network. This property accepts a value ranging from 0 to 255. Given with 0 can immediately close the admission and given with 255 will always allow devices to join in.
  2. type (String Number): Set it to 'coord' or 0 to let devices join the network through the coordinator, and set it to 'all' or 1 to let devices join the network through the coordinator or routers. The default value is 'all'.

Returns:

Examples:

bridge.on('permitJoining', (joinTimeLeft) => {
  console.log(joinTimeLeft);
});

// default is allow devices to join coordinator or routers
bridge.permitJoin(60)
  .then(() => console.log('ZNP is now allowing devices to join the network for 60 seconds.'));

// allow devices only to join coordinator
bridge.permitJoin(60, 'coord');

.info()

Returns bridge information.

Arguments:

  1. none

Returns:

Examples:

bridge.info();

/*
{
  enabled: true,
  net: {
    state: 'Coordinator',
    channel: 11,
    panId: '0x7c71',
    extPanId: '0xdddddddddddddddd',
    ieeeAddr: '0x00124b0001709887',
    nwkAddr: 0
  },
  startTime: 1473415541,
  joinTimeLeft: 49
}
*/

.mount(zApp, callback)

Mounts a zigbee application zApp that will be registered to the coordinator as a local endpoint, where zApp is an instance created by the ZCL framework zive. With zive, all you have to do is to plan your clusters well and zive itself will handle all ZCL messages for you.

Arguments:

  1. zApp (Object): instance of Zive class.
  2. callback (Function): function (err, epId) { }. When zApp mounts to coordinator successfully, bridge will return you a registered endpoint id. This epId is something that helps bridge route all messages going to the zApp.

Returns:

Examples:

const myZbApp = require('./lib/myZbApp.js'); // myZbApp is an instance of Zive

bridge.mount(myZbApp, (err, epId) => {
  if (!err) {
    console.log(epId);  // 12
  }
});

.list([ieeeAddrs])

Lists the information of devices managed by bridge. The argument accepts a single ieee address or an array of ieee addresses, and the output will always be an array of the corresponding records. All device records will be listed out if ieeeAddrs is not given.

Arguments:

  1. ieeeAddrs (String String[]): The ieee address(es) of device(s) you’d like to list.

Returns:

Examples:

bridge.list(); // list all

/*
[
  {
    type: 'Router',
    ieeeAddr: '0x00124b0001ce4beb',
    nwkAddr: 55688,
    status: 'online',
    joinTime: 1469528238,
    manufId: 0,
    epList: [ 8 ],
  },
  {
    type: 'EndDevice',
    ieeeAddr: '0x00124b0001ce3631',
    nwkAddr: 11698,
    status: 'offline',
    joinTime: 1469528238,
    manufId: 0,
    epList: [ 8 ],
  },
  ...
]
*/

bridge.list('0x00124b0001ce4beb'); // equivalent to bridge.list([ '0x00124b0001ce4beb' ]);

/*
[
  {
    type: 'Router',
    ieeeAddr: '0x00124b0001ce4beb',
    nwkAddr: 55688,
    ...
  }
]
*/

bridge.list('no_such_device'); // equivalent to bridge.list([ 'no_such_device' ]);

// [ undefined ]

bridge.list([ '0x00124b0001ce4beb', 'no_such_device', '0x00124b0001ce3631']);

/*
[
  {
    type: 'Router',
    ieeeAddr: '0x00124b0001ce4beb',
    nwkAddr: 55688,
    ...
  },
  undefined,
  {
    type: 'EndDevice',
    ieeeAddr: '0x00124b0001ce3631',
    nwkAddr: 11698,
    ...
  }
]
*/

.find(addr, epId)

Find an endpoint instance by address and endpoint id.

Arguments:

  1. addr (String Number): Find by ieee address if addr is given with a string, or find by network address if it is given with a number.
  2. epId (Number): The endpoint id to find with.

Returns:

Examples:

bridge.find('no_such_ieee_addr', 10);  // undefined, find no device by this ieee address
bridge.find('0x00124b0001ce4beb', 7);  // undefined, find no device by this endpoint id
bridge.find(1244, 10);                 // undefined, find no device by this network address
bridge.find(1200, 7);                  // undefined, find no device by this endpoint id

bridge.find(1200, 10);                 // object, the endpoint instance
bridge.find('0x00124b0001ce4beb', 10); // object, the endpoint instance

.lqi(ieeeAddr, callback)

Query the link quality index from a certain device by its ieee address.

Arguments:

  1. ieeeAddr (String): Ieee address of the device.
  2. callback (Function): function (err, data) { }. This method returns you the link quality index via data. An error occurs if device not found.

Returns:

Examples:

bridge.lqi('0x00124b0001ce4beb', (err, data) => {
  if (!err) {
    console.log(data);
    /*
    [
      {
        ieeeAddr: '0x00124b0001ce3631',
        lqi: 62
      },
      {
        ieeeAddr: '0x00124b00019c2ee9',
        lqi: 70
      }
    ]
    */
  }
});

.remove(ieeeAddr[, cfg][, callback])

Remove the device from the network.

Arguments:

  1. ieeeAddr (String): Ieee address of the device.
  2. cfg (Object):
    • reJoin (Boolean): Set to true if device is allowed for re-joining, otherwise false. Default is true.
    • rmChildren (Boolean): Set to true will remove all children of this device as well. Default is false.
  3. callback (Function): function (err) { }.

Returns:

Examples:

bridge.remove('0x00124b0001ce4beb', (err) => {
  if (!err) {
    console.log('Successfully removed!');
  }
});

// remove and ban [TODO: how to unban???]
bridge.remove('0x00124b0001ce4beb', { reJoin: false }, (err) => {
  if (!err) {
    console.log('Successfully removed!');
  }
});

.acceptDevIncoming(devInfo, callback)

Accept or reject the device join the network. Overridable.

Arguments:

  1. devInfo (Object): An object that contains the ieee address and endpoints of the device.
Property Type Description
ieeeAddr String Ieee address of the device.
endpoints Object[] An array of the endpoint instance.
  1. callback (Function): function (err, accepted) {}, the callback you should call and pass the accepted (Boolean) to it.

Returns:

Examples:

bridge.acceptDevIncoming = (devInfo, callback) => {
  if (devInfo.ieeeAddr === '0x00124b0001ce4beb') {
    callback(null, false);
  } else {
    callback(null, true);
  }
};

Event: ‘ready’

Listener: function () { }

Fired when Server is ready.


Event: ‘error’

Listener: function (err) { }

Fired when there is an error occurs.


Event: ‘permitJoining’

Listener: function (joinTimeLeft) {}

Fired when the Server is allowing for devices to join the network, where joinTimeLeft is number of seconds left to allow devices to join the network. This event will be triggered at each tick of countdown (per second).


Event: ‘ind’

Listener: function (msg) { }

Fired when there is an incoming indication message. The msg is an object with the properties given in the table:

Property Type Description
type String Indication type, can be 'devIncoming', 'devLeaving', 'devChange', 'devStatus', and 'attReport'.
endpoints Object[] | Number[] An array of the endpoint instance, except that when type === 'devLeaving', endpoints will be an array of the endpoint id (since endpoints have been removed)
data Depends Data along with the indication, which depends on the type of indication

Endpoint Class

This class provides you with methods to operate the remote endpoints or local endpoints. An instance of this class is denoted as ep in this document.


.getSimpleDesc()

Returns the simple descriptor of the endpoint.

Arguments:

  1. none

Returns:

Property Type Description
profId Number Profile id for this endpoint
epId Number Endpoint id
devId Number Device description id for this endpoint
inClusterList Array List of input cluster Ids
outClusterList Array List of output cluster Ids

Examples:

var ep = bridge.find('0x00124b0001ce4beb', 8);
ep.getSimpleDesc();

/*
{
  profId: 260,
  epId: 8,
  devId: 0,
  inClusterList: [ 0, 3 ],
  outClusterList: [ 3, 6 ]
}
*/

.getIeeeAddr()

Returns ieee address of the device holding this endpoint.

Arguments:

  1. none

Returns:

Examples:

ep1.getIeeeAddr();  // '0x00124b0001ce4beb'
ep2.getIeeeAddr();  // '0x00124b0001ce3631'

.getNwkAddr()

Returns network address of the device holding this endpoint.

Arguments:

  1. none

Returns:

Examples:

ep1.getNwkAddr();  // 55688
ep2.getNwkAddr();  // 11698

.foundation(cId, cmd, zclData[, cfg], callback)

Send ZCL foundation command to this endpoint. Response will be passed through second argument of the callback.

Arguments:

  1. cId (String Number): Cluster id, i.e. 'genBasic', 0, 'genOnOff', 6.
  2. cmd (String Number): ZCL foundation command id, i.e. 'read', 0, 'discover', 12.
  3. zclData (Object Array): zclData, which depends on the specified command.
  4. cfg (Object):
    • manufSpec (Number): Tells if this is a manufacturer-specific command. Default is 0.
    • disDefaultRsp (Number): Disable default response. Default is 0 to enable the default response.
  5. callback (Function): function (err, rsp) { }. Please refer to Payload in foundation command table to learn more about the rsp object.

Returns:

Examples:

ep.foundation('genBasic', 'read', [{ attrId: 3 }, { attrId: 4 }], (err, rsp) => {
  if (!err) {
    console.log(rsp);
    /*
    [
      {
        attrId: 3,     // hwVersion
        status: 0,     // success
        dataType: 32,  // uint8
        attrData: 0
      },
      {
        attrId: 4,     // manufacturerName
        status: 0,     // success
        dataType: 66,  // charStr
        attrData: 'TexasInstruments'
      }
    ]
    */
  }
});

.functional(cId, cmd, zclData[, cfg], callback)

Send ZCL functional command to this endpoint. The response will be passed to the second argument of the callback.

Arguments:

  1. cId (String Number): Cluster id.
  2. cmd (String Number): Functional command id.
  3. zclData (Object Array): zclData depending on the given command.
  4. cfg (Object):
    • manufSpec (Number): Tells if this is a manufacturer-specific command. Default is 0.
    • disDefaultRsp (Number): Disable default response. Default is 0 to enable the default response.
  5. callback (Function): function (err, rsp) { }. Please refer to Arguments in functional command table to learn more about the functional command rsp object.

Returns:

Examples:

// This example receives a 'defaultRsp'
ep.functional('genOnOff', 'toggle', {}, (err, rsp) => {
  if (!err) {
    console.log(rsp);
    /*
    {
      cmdId: 2,
      statusCode: 0
    }
    */
  }
});

.read(cId, attrIdOrDef, callback)

The shorthand to read a single attribute.

Arguments:

  1. cId (String Number): Cluster id.
  2. attrIdOrDef (String Number Object): Attribute id of which attribute you like to read or Attribute definition in format { id: Number, type: String } (useful for proprietary attributes).
  3. callback (Function): function (err, data) { }. This data is the attribute value.

Returns:

Examples:

// attribute id
ep.read('genBasic', 'manufacturerName', (err, data) => {
  if (!err) {
    console.log(data);  // 'TexasInstruments'
  }
});

// attribute definition (example for Xiaomi devices proprietary attribute)
ep.read('genBasic', { id: 65281, type: 'charStr' }, (err, data) => {
  if (!err) {
    console.log(data);  // 'j23nd10kokKSn94jb...'
  }
});


.write(cId, attrIdOrDef, data, callback)

The shorthand to write a single attribute.

Arguments:

  1. cId (String Number): Cluster id.
  2. attrIdOrDef (String Number Object): Attribute id of which attribute you like to write or Attribute definition in format { id: Number, type: String } (useful for proprietary attributes).
  3. data (String Number): Depends on the type of attribute.
  4. callback (Function): function (err, data) { }. This data is the attribute value.

Returns:

Examples:

// attribute id
ep.write('genBasic', 'locationDesc', 'office', (err, data) => {
  if (!err) {
    console.log(data);  // 'office'
  }
});

// attribute definition
ep.write('genBasic', { id: 47613, type: 'charStr' }, 'green', (err, data) => {
  if (!err) {
    console.log(data);  // 'green'
  }
});

.bind(cId, dstEpOrGrpId[, callback])

Bind this endpoint to the other endpoint or to a group with the specified cluster.

Arguments:

  1. cId (String Number): Cluster id.
  2. dstEpOrGrpId (Object Number): Bind this endpoint to the other endpoint if dstEpOrGrpId is given with an instance of the Endpoint class, or bind this endpoint to a group if it is given with a numeric id.
  3. callback (Function): function (err) { }. An error will occur if binding fails.

Returns:

Examples:

const ep1 = bridge.find('0x00124b0001ce4beb', 8);
const ep2 = bridge.find('0x00124b00014a7dd2', 12);

// bind ep1 to ep2
ep1.bind('genOnOff', ep2, (err) => {
  if (!err) {
    console.log('Successfully bind ep1 to ep2!');
  }
});

ep1.bind('genOnOff', 3, (err) => {
  if (!err) {
    console.log('Successfully bind ep1 to group of id 3.');
  }
});

.unbind(cId, dstEpOrGrpId[, callback])

Unbind this endpoint from the other endpoint or from a group with the specified cluster.

Arguments:

  1. cId (String Number): Cluster id.
  2. dstEpOrGrpId (Object Number): Unbind with endpoint if dstEpOrGrpId is given with an instance of the Endpoint class , or unbind this endpoint from a group if it is given with a numeric id.
  3. callback (Function): function (err) { }. An error will occur if unbinding fails.

Returns:

Examples:

ep1.unbind('genOnOff', ep2, (err) => {
  if (!err) {
    console.log('Successfully unbind ep1 from ep2!');
  }
});

ep1.unbind('genOnOff', 3, (err) => {
  if (!err) {
    console.log('Successfully unbind ep1 from group of id 3.');
  }
});

.report(cId, attrIdOrDef, minInt, maxInt[, repChange][, callback])

Set the report configuration of the attribute to endpoint.

Arguments:

  1. cId (String Number): Cluster id.
  2. attrIdOrDef (String Number Object): Attribute id of which attribute you like to report or Attribute definition in format { id: Number, type: String } (useful for proprietary attributes).
  3. minInt (Number): The minimum reporting interval, in seconds.
  4. maxInt (Number): The maximum reporting interval, in seconds.
  5. repChange (Number): Reportable change. The attribute should report its value when the value is changed more than this setting. If attributes with analog data type this argument is mandatory.
  6. callback (Function): function (err) { }. An error will occur if configure reporting fails.

Returns:

Examples:

// attribute id
ep1.report('msTemperatureMeasurement', 'measuredValue', 3, 5, 100, (err) => {
  if (!err) {
    console.log('Successfully configure ep1 report temperature attribute!');
  }
});

// attribute definition (example for Xiaomi devices proprietary attribute)
ep1.report('genBasic', { id: 65281, type: 'charStr' }, 1, 60, 100, (err) => {
  if (!err) {
    console.log('Successfully configure ep1 report proprietary attribute!');
  }
});

.dump()

Dump the endpoint record.

Arguments:

  1. none

Returns:

Property Type Description
profId Number Profile id for this endpoint
epId Number Endpoint id
devId Number Device description id for this endpoint
inClusterList Array List of input cluster Ids
outClusterList Array List of output cluster Ids
clusters Object Clusters information

Examples:

ep.dump();

/*
{
  profId: 260,
  epId: 8,
  devId: 0,
  inClusterList: [ 0, 3 ],
  outClusterList: [ 3, 6 ],
  clusters: {
    genBasic: {
      dir: { value: 1 },  // in Cluster
      attrs: {
        hwVersion: 0,
        manufacturerName: 'TexasInstruments',
        modelId: 'TI0001',
        dateCode: '20060831',
        powerSource: 1,
        locationDesc: '',
        physicalEnv: 0,
        deviceEnabled: 1
      }
    },
    genIdentify: {
      dir: { value: 3 },  // in and out Cluster
      attrs: {
        identifyTime: 0
      }
    },
    genOnOff:{
      dir: { value: 2 },  // out Cluster
      attrs: {
        onOff: 0
      }
    }
  }
}
*/