diff --git a/.gitignore b/.gitignore index c882358..e77824c 100755 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # intellij, pycharm, webstorm... /.idea/* - +.vscode node_modules .*.swp +coverage diff --git a/EmberClient/EmberClient.js b/EmberClient/EmberClient.js index c1b33e9..40f8a6a 100755 --- a/EmberClient/EmberClient.js +++ b/EmberClient/EmberClient.js @@ -623,6 +623,39 @@ class EmberClient extends EventEmitter { }); } + /** + * + * @param {TreeNode} node + * @param {string|number} value + * @returns {Promise} + */ + setValueNoAck(node, value) { + // This function immediately finish & resolve so we can't get any timeouts ever + // This is a pretty ugly hack, but it doesn't look to bring + // any negative consequences regarding the execution and resolving of other + // functions. It´s needed this because if the node already has the value we are + // setting it too, it will cause a timeout. + return new Promise((resolve, reject) => { + if (!node.isParameter()) { + reject(new Errors.EmberAccessError('not a Parameter')); + return; + } + this.addRequest({node: node, func: error => { + if (error) { + this._finishRequest(); + reject(error); + return; + } + winston.debug('setValue sending ...', node.getPath(), value); + this._client.sendBERNode(node.setValue(value)); + + this._finishRequest(); + this._callback = null; + return resolve(node) + }}); + }) + } + /** * * @param {TreeNode} qnode diff --git a/EmberLib/StreamDescription.js b/EmberLib/StreamDescription.js index 53edb69..4915551 100755 --- a/EmberLib/StreamDescription.js +++ b/EmberLib/StreamDescription.js @@ -1,15 +1,17 @@ "use strict"; -const Element = require("./Element"); const BER = require('../ber.js'); const StreamFormat = require("./StreamFormat"); const Errors = require("../Errors"); -class StreamDescription extends Element{ +class StreamDescription { /** * + * @param {number} offset + * @param {StreamFormat} format */ - constructor() { - super(); + constructor(offset, format) { + this.offset = offset; + this.format = format; } /** diff --git a/EmberLib/index.js b/EmberLib/index.js index d3f10f8..9dc3813 100755 --- a/EmberLib/index.js +++ b/EmberLib/index.js @@ -32,6 +32,7 @@ const StringIntegerPair = require("./StringIntegerPair"); const StringIntegerCollection = require("./StringIntegerCollection"); const StreamFormat = require("./StreamFormat"); const StreamDescription = require("./StreamDescription"); +const StreamCollection = require("./StreamCollection"); const Template = require("./Template"); const TemplateElement = require("./TemplateElement"); const QualifiedTemplate = require("./QualifiedTemplate"); @@ -151,6 +152,7 @@ module.exports = { QualifiedTemplate, StreamFormat, StreamDescription, + StreamCollection, StringIntegerPair, StringIntegerCollection, Template, diff --git a/EmberServer/JSONParser.js b/EmberServer/JSONParser.js index 126164a..dfa5015 100755 --- a/EmberServer/JSONParser.js +++ b/EmberServer/JSONParser.js @@ -90,6 +90,15 @@ class JSONParser { else { emberElement.contents.access = ember.ParameterAccess.read; } + if (content.streamDescriptor != null) { + if (content.streamDescriptor.offset == null || content.streamDescriptor.format == null) { + throw new Error("Missing offset or format for streamDescriptor"); + } + emberElement.contents.streamDescriptor = new ember.StreamDescription(); + emberElement.contents.streamDescriptor.offset = content.streamDescriptor.offset; + emberElement.contents.streamDescriptor.format = ember.StreamFormat.get(content.streamDescriptor.format); + delete content.streamDescriptor; + } } else if (content.func != null) { emberElement = new ember.Function(number, content.func); diff --git a/package.json b/package.json index 3c39074..b46f60d 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-emberplus", - "version": "2.5.7", + "version": "2.5.8", "description": "Javascript implementation of the Ember+ automation protocol", "main": "index.js", "scripts": { diff --git a/serve.js b/serve.js new file mode 100755 index 0000000..9447250 --- /dev/null +++ b/serve.js @@ -0,0 +1,55 @@ +const yargs = require('yargs'); +const { EmberServer, Decoder } = require('./index'); +const { readFileSync } = require('fs'); + +const argv = yargs.options({ + host: { + alias: 'h', + description: 'host name|ip', + default: '0.0.0.0' + }, + + port: { + alias: 'p', + default: 9000, + type: 'number', + description: 'port', + demandOption: true + }, + + file: { + alias: 'f', + description: 'file containing the ber (default) or json tree', + demandOption: true + }, + + json: { + alias: 'j', + type: 'boolean', + description: 'file format is json' + }, + debug: { + alias: 'd', + type: 'boolean', + description: 'debug' + } + +}).help().argv; + +const main = async () => { + const data = readFileSync(argv.file); + const tree = argv.json ? EmberServer.JSONtoTree(JSON.parse(data.toString())) : Decoder(data); + const server = new EmberServer(argv.host, argv.port, tree); + server._debug = true; + console.log(Date.now(), 'starting server'); + if (argv.debug) { + server._debug = true; + } + try { + server.listen(); + } catch (e) { + console.log(e); + } +}; + +main(); diff --git a/test/Server.test.js b/test/Server.test.js index 458b29b..46b0107 100755 --- a/test/Server.test.js +++ b/test/Server.test.js @@ -19,9 +19,11 @@ describe("server", function() { const root = EmberServer.JSONtoTree(jsonTree); expect(root).toBeDefined(); expect(root.elements).toBeDefined(); - expect(root.elements.size).toBe(1); + expect(root.elements.size).toBe(jsonTree.length); expect(root.getElementByNumber(0).contents.identifier).toBe("scoreMaster"); expect(root.getElementByNumber(0).elements.size).toBe(jsonTree[0].children.length); + expect(root.getElementByNumber(1).contents.streamDescriptor instanceof EmberLib.StreamDescription).toBeTruthy(); + expect(root.getElementByNumber(1).contents.streamDescriptor.offset).toBe(jsonTree[1].streamDescriptor.offset); }); it("should throw an error if invalid matrix mode", function() { jsonTree[0].children[1].children[0].mode = "invalid"; diff --git a/test/utils.js b/test/utils.js index f776d62..9cca4a4 100755 --- a/test/utils.js +++ b/test/utils.js @@ -119,6 +119,19 @@ const init = function(_src,_tgt) { ] } ] + }, + { + identifier: "PeakValue_2", + type: 2, + streamIdentifier: 4, + streamDescriptor: { + format: "ieeeFloat32LittleEndian", + offset: 4 + }, + access: 1, + maximum: 20, + minimum: -200, + value: -200 } ]; }