Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* XML Measure Support * XML Command Support * Run prettier * Remove irrelevant comment
- Loading branch information
Showing
8 changed files
with
71 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,131 +1,101 @@ | ||
// Connect to an IoT Agent and use fallback values if necessary | ||
|
||
|
||
const IoTDevices = require('../devices'); | ||
const DEVICE_API_KEY = process.env.DUMMY_DEVICES_API_KEY || '1234'; | ||
|
||
const debug = require('debug')('tutorial:xml'); | ||
|
||
const xmlParser = require('xml-parser'); | ||
|
||
// A series of constants used by our set of devices | ||
const OK = ' OK'; | ||
const NOT_OK = ' NOT OK'; | ||
|
||
const OK = 'success'; | ||
const NOT_OK = 'error'; | ||
|
||
/* global MQTT_CLIENT */ | ||
|
||
// | ||
// Splits the deviceId from the command sent. | ||
// | ||
function getXMLCommand(string) { | ||
const command = string.split('@'); | ||
if (command.length === 1) { | ||
command.push(''); | ||
function getResult(status, command, id, info) { | ||
if (info) { | ||
return '<' + status + ' command="' + command + '" device="' + id + '">' + info + '</' + status + '/>'; | ||
} | ||
return command[1]; | ||
return '<' + status + ' command="' + command + '" device="' + id + '"/>'; | ||
} | ||
|
||
// This processor sends XML payload northbound to | ||
// the southport of the IoT Agent and sends measures | ||
// for the motion sensor, door and lamp. | ||
|
||
// XML 2.0 is a lightweight text based protocol aimed to constrained | ||
// devices and communications | ||
// where the bandwidth and device memory may be limited resources. | ||
// | ||
// A device can report new measures to the IoT Platform using an HTTP GET request to the /iot/d path with the following query parameters: | ||
// | ||
// i (device ID): Device ID (unique for the API Key). | ||
// k (API Key): API Key for the service the device is registered on. | ||
// t (timestamp): Timestamp of the measure. Will override the automatic IoTAgent timestamp (optional). | ||
// d (Data): XML 2.0 payload. | ||
// | ||
// At the moment the API key and timestamp are unused by the simulator. | ||
|
||
class XMLCommand { | ||
// The bell will respond to the "ring" command. | ||
// this will briefly set the bell to on. | ||
// The bell is not a sensor - it will not report state northbound | ||
actuateBell(req, res) { | ||
|
||
|
||
debug(req.body) | ||
|
||
|
||
const keyValuePairs = req.body.split('|') || ['']; | ||
const command = getXMLCommand(keyValuePairs[0]); | ||
const deviceId = 'bell' + req.params.id; | ||
const result = keyValuePairs[0] + '| ' + command; | ||
const data = xmlParser(req.body); | ||
const deviceId = data.root.attributes.device; | ||
const command = data.root.name; | ||
|
||
if (IoTDevices.notFound(deviceId)) { | ||
return res.status(404).send(result + NOT_OK); | ||
return res.status(404).send(getResult(NOT_OK, command, deviceId, 'not found')); | ||
} else if (IoTDevices.isUnknownCommand('bell', command)) { | ||
return res.status(422).send(result + NOT_OK); | ||
return res.status(422).send(getResult(NOT_OK, command, deviceId, 'unknown command')); | ||
} | ||
|
||
// Update device state | ||
IoTDevices.actuateDevice(deviceId, command); | ||
return res.status(200).send(result + OK); | ||
return res.status(200).send(getResult(OK, command, deviceId)); | ||
} | ||
|
||
// The door responds to "open", "close", "lock" and "unlock" commands | ||
// Each command alters the state of the door. When the door is unlocked | ||
// it can be opened and shut by external events. | ||
actuateDoor(req, res) { | ||
const keyValuePairs = req.body.split('|') || ['']; | ||
const command = getXMLCommand(keyValuePairs[0]); | ||
const deviceId = 'door' + req.params.id; | ||
const result = keyValuePairs[0] + '| ' + command; | ||
const data = xmlParser(req.body); | ||
const deviceId = data.root.attributes.device; | ||
const command = data.root.name; | ||
|
||
if (IoTDevices.notFound(deviceId)) { | ||
return res.status(404).send(result + NOT_OK); | ||
return res.status(404).send(getResult(NOT_OK, command, deviceId, 'not found')); | ||
} else if (IoTDevices.isUnknownCommand('door', command)) { | ||
return res.status(422).send(result + NOT_OK); | ||
return res.status(422).send(getResult(NOT_OK, command, deviceId, 'unknown command')); | ||
} | ||
|
||
// Update device state | ||
IoTDevices.actuateDevice(deviceId, command); | ||
return res.status(200).send(result + OK); | ||
return res.status(200).send(getResult(OK, command, deviceId)); | ||
} | ||
|
||
// The lamp can be "on" or "off" - it also registers luminosity. | ||
// It will slowly dim as time passes (provided no movement is detected) | ||
actuateLamp(req, res) { | ||
const keyValuePairs = req.body.split('|') || ['']; | ||
const command = getXMLCommand(keyValuePairs[0]); | ||
const deviceId = 'lamp' + req.params.id; | ||
const result = keyValuePairs[0] + '| ' + command; | ||
const data = xmlParser(req.body); | ||
const deviceId = data.root.attributes.device; | ||
const command = data.root.name; | ||
|
||
if (IoTDevices.notFound(deviceId)) { | ||
return res.status(404).send(result + NOT_OK); | ||
return res.status(404).send(getResult(NOT_OK, command, deviceId, 'not found')); | ||
} else if (IoTDevices.isUnknownCommand('lamp', command)) { | ||
return res.status(422).send(result + NOT_OK); | ||
return res.status(422).send(getResult(NOT_OK, command, deviceId, 'unknown command')); | ||
} | ||
|
||
// Update device state | ||
IoTDevices.actuateDevice(deviceId, command); | ||
return res.status(200).send(result + OK); | ||
return res.status(200).send(getResult(OK, command, deviceId)); | ||
} | ||
|
||
// cmd topics are consumed by the actuators (bell, lamp and door) | ||
processMqttMessage(topic, message) { | ||
const path = topic.split('/'); | ||
if (path.pop() === 'cmd') { | ||
const keyValuePairs = message.split('|') || ['']; | ||
const command = getXMLCommand(keyValuePairs[0]); | ||
const deviceId = path.pop(); | ||
const result = keyValuePairs[0] + '| ' + command; | ||
const data = xmlParser(message); | ||
const deviceId = data.root.attributes.device; | ||
const command = data.root.name; | ||
|
||
if (!IoTDevices.notFound(deviceId)) { | ||
IoTDevices.actuateDevice(deviceId, command); | ||
const topic = '/' + DEVICE_API_KEY + '/' + deviceId + '/cmdexe'; | ||
MQTT_CLIENT.publish(topic, result + OK); | ||
MQTT_CLIENT.publish(topic, getResult(OK, command, deviceId)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
module.exports = XMLCommand; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.