Device : IoT device operation
This module is the EdgerOS Device service module. Applications can use this module to operate any IoT device connected to this EdgerOS machine.
EdgerOS supports various types of IoT devices. The supported protocols include: MQTT, MQTT-SN, CoAP, SDDC, Zigbee Home Automation, etc. SDDC devices and Zigbee Home Automation devices can be directly operated use Device
module. MQTT, MQTT-SN, CoAP devices can obtain related device resources and description through this module, and directly use MQTT
and CoAP
modules to operate the device.
Any IoT device connected to EdgerOS includes a devid
. This devid
is the globally unique identifier of the device. The App that operates this device must first have the operation permission of the corresponding device devid
before it can obtain the complete information of the device and operate the device.
User can use the following code to import the Device
module.
var Device = require('device');
Support
The following shows Device
module APIs available for each permissions.
User Mode | Privilege Mode | |
---|---|---|
Device | ● | ● |
Device.count | ● | ● |
Device.list | ● | ● |
Device.info | ● | ● |
Device.named | ● | ● |
Device.alias | ● | |
Device.discover | ● | |
Device.occupation | ● | |
device.request | ● | ● |
device.release | ● | ● |
device.address | ● | ● |
device.send | ● | ● |
Device.Connector | ● | ● |
connector.write | ● | ● |
connector.end | ● | ● |
connector.close | ● | ● |
connector.toJSON | ● | ● |
Device Class
new Device()
- Returns: {Object} Device object.
Create a device object.
Example
var device = new Device();
Device.count(join, callback)
join
{Boolean} Whether to list only devices that have joined the network.callback
{Function} Callback function.error
{Error} Indicate an error information when an error occurs.count
{Integer} Device count.
Get all device count currently discovered by the system. When join
is true
, only get device count that have been discovered and joined.
Example
Device.count(false, function(error, count) {
if (error) {
console.error('Device count error:', error.message);
} else {
console.log('Device count:', count);
}
});
Device.list(join, callback)
join
{Boolean} Whether to list only devices that have joined the network.callback
{Function} Callback function.error
{Error} Indicate an error information when an error occurs.list
{Array} devid and alias object list.
List all devices currently discovered by the system. When join
is true
, only list devices that have been discovered and joined.
Example
Device.list(false, function(error, list) {
if (error) {
console.error('Device list error:', error.message);
} else {
list.forEach(function(dev) {
console.log(dev.devid, dev.alias);
});
}
});
Device.info(devid, callback)
devid
{String} Device ID.callback
{Function} Callback function.error
{Error} Indicate an error information when an error occurs.info
{Object} Device information.
Get detailed information for the specified device. The device information includes two parts, report
: basic information reported by the device, and server
: device server information. If this device contains server information, such as a CoAP server, it can only be obtained after device.request()
succeeds, otherwise only the basic device information can be obtained.
info
The object contains the following members:
join
{Boolean} Whether the device has joined the network. Only devices that have been confirmed to join the network can operate.alias
{String} Device alias name.report
{Object} Basic information reported by the devicename
{String} Name of the current machine. Typically:'Printer'
,'Patch panel'
,'Air conditioning'
...type
{String} The type of the machine. Typically:'monitor'
,'edger'
,'device'
.excl
{Boolean} This device is App exclusive.desc
{String} Device description information.model
{String} Device model.vendor
{String} Device manufacturer.version
{Array} Device software version, optional.sn
{String} Device serial number. optional.
server
{Object} Server information.coap
{Array} All CoAP server information in this device. Each item of this array has the following information:desc
{String} Server description.port
{Integer} CoAP server port.
vsoa
{Array} All VSOA server information in this device. Each item of this array has the following information:desc
{String} Server description.port
{Integer} VSOA server port.
addr
{String} If it is a network device, it indicates the IP address of the target device. For example, a CoAP or VSOA device can use this IP address to access the device with the specified device service.probe
{Boolean} Only the ZigBee device contains this member, indicating whether this device is allowed to be probed. Ifprobe
istrue
, it means that EdgerOS can automatically sense the online and offline status of this device.
Example
Device.info(devid, function(error, info) {
if (error == undefined) {
console.log(info);
}
});
Device.named(callback)
callback
{Function} Callback function.error
{Error} Indicate an error information when an error occurs.list
{Array} All devices have been aliased.
Get a list of all devices in the system that have been aliased, regardless of whether the device is online.
Example
Device.named(function(error, list) {
if (!error) {
list.forEach(function(dev) {
console.log(dev.devid, dev.alias);
});
}
});
Device.alias(devid, alias[, callback[, token]])
devid
{String} Device ID.alias
{String} Alias name.callback
{Function} Callback function.error
{Error} Indicate an error information when an error occurs.
token
{String} If it is an encrypted communication device, an encrypted token can be set.
The system device management App can use this method to alias the device, allowing the EdgerOS device to invite this device to join the network.
Example
Device.alias(devid, '客厅空气净化器');
Device.discover([addr[, smartcfg[, callback]]])
addr
{String} Specify the search destination IP address. default: broadcast search.smartcfg
{Boolean} Whether to use Smart Configure technology to provide WiFi SSID and password for IoT devices. default: false.callback
{Function} Callback function.error
{Error} Indicate an error information when an error occurs.
The system device management App can use this method to search for peripheral devices now, or search for specified remote devices.
EdgerOS will automatically search for surrounding network devices every minute. Zigbee devices will only search when this function is called.
Example
Device.discover();
Device.occupation(devid, callback)
devid
{String} Device ID.callback
{Function} Callback function.error
{Error} Indicate an error information when an error occurs.list
{Array} Device occupation appid array.
Exclusive devices only allow one App to access at the same time, shared devices allow multiple apps to access at the same time, this function can get the list of apps that currently operate the specified device.
Example
Device.occupation(devid, function(error, list) {
if (Array.isArray(list)) {
list.forEach(function(appid) {
// List all apps occupying this device
});
}
});
Device Object
device.request(devid, callback)
devid
{String} Device ID.callback
{Function} Callback function.error
{Error} Indicate an error information when an error occurs.
Request control of specified device. First you need to use permission.device()
to check if you have permission to access this device.
When this device is an exclusive device and is being used by other app, you cannot get the operation permission.
Example
device.request(devid, function(error) {
if (error) {
console.error(error.message);
}
});
Example
if (device.devid) {
device.send(...);
}
device.release([callback[, removeAllListeners]])
callback
{Function} Callback function.error
{Error} Indicate an error information when an error occurs.
removeAllListeners
{Boolean} Whether to remove the previously installed event listener after the release is successful. This argument is added in EdgerOS 1.6.0 and later versions.
Release the previously requested device. When the operation of the device is completed, the device should be released immediately.
Example
device.request(devid, function(error) {
if (error == undefined) {
device.send({ hello: 'hello' });
device.release();
}
});
device.address(callback)
callback
{Function} Callback function.error
{Error} Indicate an error information when an error occurs.addr
{String} Device net address.
Sometimes we need to use some special protocols to access the device, such as CoAP, etc. We can use this function to get the network address of the requested device.
Example
device.address(function(error, addr) {
if (typeof addr === 'string') {
console.log('device:', devid, 'address:', addr);
}
});
device.send(msg[, callback[, retries[, urgent[, mark]]]])
msg
{Object} Message to send.callback
{Function} Callback function.error
{Error} Indicate an error information when an error occurs.
retries
{Integer} Number of automatic retries. default: 2.urgent
{Boolean} Whether it is an urgent message. default: false.mark
{Boolean} Whether to mark the current app tag in the data packet. default: true.
Send a message to the specified device. When retries
is 0, it means non-reliable sending. When retries
> 0, the device will delay retrying when device not confirm (depends on the implementation of the relevant link protocol).
Example
device.send({ hello: 'hello' }, undefined, 3);
If you need to send an urgent message, you can set urgent
to true
, preempt the current sending sequence, and immediately transmit the urgent message. Not all IoT connections support urgent messages. If the communication link does not support, this message will be transmitted as a normal message.
When the target device can be shared and used by multiple apps, the mark
function will indicate the ID of the App in the data packet sent to the device. Using this information, the current App can establish a session with the target device, so that the target device can send data directly to the current App, other apps can’t received. EdgerOS 1.5.8 and later versions support mark
.
Device Class Events
Device
class and device
objects both inherit from EventEmitter
, The following events are thrown in some specific situations.
found
A new device was found. Only privileged app can receive this event.
Example
Device.on('found', function(devid, info) {
console.log('A new device was found:', devid, 'report:', info.report);
});
join
The discovered device has successfully joined the network and can request.
Example
Device.on('join', function(devid, info) {
console.log('Device join in:', devid, 'report:', info.report);
});
update
Device information changes, such as IP address or server status.
Example
Device.on('update', function(devid, info) {
console.log('Device update:', devid, 'report:', info.report);
});
lost
The device is lost. The lost device can no longer be operated.
Example
Device.on('lost', function(devid) {
console.log('Device lost:', devid);
});
alias
The specified device alias is modified.
Example
Device.on('alias', function(devid, info) {
console.log('Device alias modified:', devid, 'alias:', info.alias);
});
refuse
Discovered device refuses to join the network.
Example
Device.on('refuse', function(devid) {
console.warn('Device refuse join network:', devid);
});
Device Object Events
message
Received a message from a device.
Example
device.on('message', function(msg) {
console.log('received a message:', msg);
});
lost
This device is lost. The lost device can no longer be operated.
Example
device.on('lost', function() {
// This device lost
});
Device.Connector Class
Many devices need to perform batch data network transmission. EdgerOS provides the Device.Connector
class specifically for this operation. This class can receive and send data. At the same time, it supports encrypted data transmission. Device.Connector
only supports network devices. Device.Connector
class inherits from Stream.Duplex
class (For details: Stream), developers can use stream operations to communicate with the device in both directions
new Device.Connector(device[, cipher[, timeout]])
device
{Object} Device object.cipher
{Boolean} Whether to use encrypted transmission. default: false.timeout
{Integer} Maximum quiet time, no data transmission after checking this time, the current connection will be closed. default: 6000ms.- Returns: {Object}
Device.Connector
object.
Create a Device.Connector
object for batch data transfer with the device. If cipher
is true
, the data transmission will use a random key for encrypted transmission.
Example
var device = new Device();
device.request(..., function(error) {
if (!error) {
var connector = new Device.Connector(device);
// ...
}
});
Device.Connector Object
connector.close()
Close the current object, this object can no longer be used for any data transfer.
connector.write(data[, encoding][, callback])
data
{String | Buffer} Data to write.encoding
{String} Only used when data is string. default: utf8.callback
{Function} Optional callback for when the socket is finished.error
{Error} Specify the error when writing an error.
- Returns: {Boolean} Whether this operation was successful.
Send data to the device. Before sending data, you must ensure that the Device.Connector
object has been linked with the device.
Like Writable
stream object, if the return value is false
, indicating that there is too much data in the sending buffer, and it is recommended that the remaining data continue to be sent in the drain
event.
Example
var chunk = Buffer.from(...);
connector.write(chunk);
connector.end([data[, encoding][, callback]])
data
{String | Buffer} Data to write. default: no data to send.encoding
{String} Only used when data is string. default: 'utf8'.callback
{Function} Optional callback for when the socket is finished.error
{Error} Specify the error when writing an error.
To end data transmission, the Device.Connector
object must call this function to end data transmission after sending data to the device.
Example
connector.write('hello', 'utf-8');
connector.end();
// Or:
connector.end('hello', 'utf-8');
connector.toJSON()
- Returns: {String} This connector network parameters.
This function can cooperate with the device.send()
operation to inform the device of connector
related transmission parameters, and the device actively connects to the current connector
for data communication according to this parameter.
Example
var device = new Device();
device.request(..., function(error) {
if (error) {
// request device error.
return;
}
var connector = new Device.Connector(device);
// connector.toJSON() will return: {"port":...,"token":"..."}
// Or {"port":...}
device.send({ cmd: 'get_picture', connector: connector });
var chunks = [];
connector.on('data', function(chunk) {
chunks.push(chunk);
});
connector.on('close', function() {
// Closed!
});
connector.on('error', function(error) {
// Error!
connector.close();
});
});
- Send data
var device = new Device();
var chunk = fs.readFile('./pic.jpg');
device.request(..., function(error) {
if (error) {
// request device error.
return;
}
var connector = new Device.Connector(device);
// connector.toJSON() will return: {"port":...,"token":"..."}
// Or {"port":...}
device.send({ cmd: 'put_picture', connector: connector, size: chunk.length });
connector.on('connect', function() {
connector.end(chunk);
}
connector.on('close', function() {
// Closed!
});
connector.on('error', function(error) {
// Error!
connector.close();
});
});
Device.Connector Object Events
connect
When a device is connected, this event will be generated. Only after this event occurs, data can be sent and receive.
timeout
This event will be generated when the connector has no device connection for a long time. The connection will be closed automatically.
drain
Emitted when the write buffer becomes empty. Can be used to throttle uploads.
error
error
{Error} Indicate an error. When a communication error occurs, this event will be generated and indicate an error. This event callback must be installed to handle this event.
data
chunk
{String} | {Buffer} Received data. This event will be generated when data from the device is received.
finish
When the data transmission is completed, this event will be generated.
close
When the connector
connection is closed, this event will be generated, and the connector
object can no longer be used.
Device.Connector Writable & Readable
The Device.Connector
object can support duplex communication with the device. When sending data, it can be used as a Writable object for readable.pipe()
operations.
Example
var device = new Device();
var readable = fs.createReadStream('./pic.jpg');
device.request(..., function(error) {
if (error) {
// request device error.
return;
}
var connector = new Device.Connector(device);
// connector.toJSON() will return: {"port":...,"token":"..."}
// Or {"port":...}
device.send({ cmd: 'put_picture', connector: connector, size: fs.size('./pic.jpg') });
connector.on('connect', function() {
readable.pipe(connector);
}
connector.on('close', function() {
// Closed!
});
connector.on('error', function(error) {
// Error!
connector.close();
});
});