cbuslibrary
Version:
Library to decode & encode CBUS messages
486 lines (462 loc) • 416 kB
JavaScript
const expect = require('chai').expect;
var itParam = require('mocha-param');
var winston = require('./config/winston_test.js');
const cbusLib = require('./../cbusLibrary.js')
function decToHex(num, len) {return parseInt(num & (2 ** (4*len) - 1)).toString(16).toUpperCase().padStart(len, '0');}
function stringToHex(string) {
// expects UTF-8 string
var bytes = new TextEncoder().encode(string);
return Array.from(
bytes,
byte => byte.toString(16).padStart(2, "0")
).join("");
}
function hexToString(hex) {
// returns UTF-8 string
const bytes = new Uint8Array(hex.length / 2);
for (let i = 0; i !== bytes.length; i++) {
bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
}
return new TextDecoder().decode(bytes);
}
describe('cbusMessage tests', function(){
before(function(done) {
winston.info({message: ' '});
winston.info({message: '======================================================================'});
winston.info({message: '------------------------ cbusMessage tests -------------------------'});
winston.info({message: '======================================================================'});
winston.info({message: ' '});
done();
});
beforeEach(function() {
winston.info({message: ' '}); // blank line to separate tests
// ensure expected CAN header is reset before each test run
cbusLib.setCanHeader(2, 123)
});
after(function() {
winston.info({message: ' '}); // blank line to separate tests
});
function GetTestCase_dec2hex () {
var testCases = [];
testCases.push({'number':-128, 'length': '2','expected':'80'});
testCases.push({'number':-1, 'length': '2','expected':'FF'});
testCases.push({'number':0, 'length': '2','expected':'00'});
testCases.push({'number':1, 'length': '2','expected':'01'});
testCases.push({'number':127, 'length': '2','expected':'7F'});
//
testCases.push({'number':-2048, 'length': '3','expected':'800'});
testCases.push({'number':-128, 'length': '3','expected':'F80'});
testCases.push({'number':-1, 'length': '3','expected':'FFF'});
testCases.push({'number':0, 'length': '3','expected':'000'});
testCases.push({'number':1, 'length': '3','expected':'001'});
testCases.push({'number':127, 'length': '3','expected':'07F'});
testCases.push({'number':2047, 'length': '3','expected':'7FF'});
//
testCases.push({'number':-32768, 'length': '4','expected':'8000'});
testCases.push({'number':-128, 'length': '4','expected':'FF80'});
testCases.push({'number':-1, 'length': '4','expected':'FFFF'});
testCases.push({'number':0, 'length': '4','expected':'0000'});
testCases.push({'number':1, 'length': '4','expected':'0001'});
testCases.push({'number':127, 'length': '4','expected':'007F'});
testCases.push({'number':32767, 'length': '4','expected':'7FFF'});
return testCases;
}
itParam("decToHex test ${JSON.stringify(value))", GetTestCase_dec2hex(), function (value) {
winston.info({message: 'cbusMessage test: BEGIN dec2hex test ' + JSON.stringify(value)});
var result = decToHex(value.number, value.length);
winston.info({message: 'cbusMessage test: Result ' + result});
expect(result).to.equal(value.expected, 'dec2hex test');
})
function GetTestCase_canHeader () {
var testCases = [];
for (MJ = 1; MJ < 4; MJ++) {
if (MJ == 1) MjPri = 0;
if (MJ == 2) MjPri = 1;
if (MJ == 3) MjPri = 3;
for (ID = 1; ID < 5; ID++) {
if (ID == 1) CAN_ID = 0;
if (ID == 2) CAN_ID = 1;
if (ID == 3) CAN_ID = 123;
if (ID == 4) CAN_ID = 127;
testCases.push({'MjPri':MjPri, 'CAN_ID':CAN_ID});
}
}
return testCases;
}
// MinPri is pre-defined for each opcode, and using RQNP has a MinPri of 3, so thats fixed and no need to test
// the tests for other opCodes test the changing of the MinPri value
itParam("canHeader test MjPri ${value.MjPri} CAN_ID ${value.CAN_ID}", GetTestCase_canHeader(), function (value) {
winston.info({message: 'cbusMessage test: BEGIN canHeader test ' + JSON.stringify(value)});
var identifier = parseInt(value.MjPri << 14) + parseInt(3 << 12) + parseInt(value.CAN_ID << 5)
expected = ":S" + decToHex(identifier, 4) + "N10" + ";";
cbusLib.setCanHeader(value.MjPri, value.CAN_ID)
var encode = cbusLib.encodeRQNP();
var canHeader = cbusLib.getCanHeader();
winston.info({message: 'cbusMessage test: canHeader encode ' + encode});
winston.info({message: 'cbusMessage test: canHeader decode ' + JSON.stringify(canHeader)});
expect(encode).to.equal(expected, 'encode test');
expect(canHeader.MjPri).to.equal(value.MjPri, 'MjPri test');
expect(canHeader.CAN_ID).to.equal(value.CAN_ID, 'CAN_ID test');
})
// Generic encode test cases
//
function GetTestCase_encode () {
var testCases = [];
testCases.push({'test':{'mnemonic': 'ACK'}, 'expected': ':SAF60N00;'});
testCases.push({'test':{'mnemonic': 'NAK'}, 'expected': ':SAF60N01;'});
testCases.push({'test':{'mnemonic': 'HLT'}, 'expected': ':S8F60N02;'});
testCases.push({'test':{'mnemonic': 'BON'}, 'expected': ':S9F60N03;'});
testCases.push({'test':{'mnemonic': 'TOF'}, 'expected': ':S9F60N04;'});
testCases.push({'test':{'mnemonic': 'TON'}, 'expected': ':S9F60N05;'});
testCases.push({'test':{'mnemonic': 'ESTOP'}, 'expected': ':S9F60N06;'});
testCases.push({'test':{'mnemonic': 'ARST'}, 'expected': ':S8F60N07;'});
testCases.push({'test':{'mnemonic': 'RTOF'}, 'expected': ':S9F60N08;'});
testCases.push({'test':{'mnemonic': 'RTON'}, 'expected': ':S9F60N09;'});
testCases.push({'test':{'mnemonic': 'RESTP'}, 'expected': ':S8F60N0A;'});
testCases.push({'test':{'mnemonic': 'RSTAT'}, 'expected': ':SAF60N0C;'});
testCases.push({'test':{'mnemonic': 'QNN'}, 'expected': ':SBF60N0D;'});
testCases.push({'test':{'mnemonic': 'RQNP'}, 'expected': ':SBF60N10;'});
testCases.push({'test':{'mnemonic': 'RQMN'}, 'expected': ':SAF60N11;'});
testCases.push({'test':{'mnemonic': 'GSTOP'}, 'expected': ':S9F60N12;'});
testCases.push({'test':{'mnemonic': 'KLOC', 'session': '1'}, 'expected': ':SAF60N2101;'});
testCases.push({'test':{'mnemonic': 'QLOC', 'session': '1'}, 'expected': ':SAF60N2201;'});
testCases.push({'test':{'mnemonic': 'DKEEP', 'session': '1'}, 'expected': ':SAF60N2301;'});
testCases.push({'test':{'mnemonic': 'DBG1', 'status': '1'}, 'expected': ':SAF60N3001;'});
testCases.push({'test':{'mnemonic': 'EXTC', 'Ext_OPC': '1'}, 'expected': ':SBF60N3F01;'});
testCases.push({'test':{'mnemonic': 'RLOC', 'address': '1'}, 'expected': ':SAF60N400001;'});
testCases.push({'test':{'mnemonic': 'QCON', 'conID': '1', 'index': '2'}, 'expected': ':SAF60N410102;'});
testCases.push({'test':{'mnemonic': 'SNN', 'nodeNumber': '1'}, 'expected': ':SBF60N420001;'});
testCases.push({'test':{'mnemonic': 'ALOC', 'session': '1', 'allocationCode': '2'}, 'expected': ':SAF60N430102;'});
testCases.push({'test':{'mnemonic': 'STMOD', 'session': '1', 'modeByte': '2'}, 'expected': ':SAF60N440102;'});
testCases.push({'test':{'mnemonic': 'PCON', 'session': '1', 'consistAddress': '2'}, 'expected': ':SAF60N450102;'});
testCases.push({'test':{'mnemonic': 'KCON', 'session': '1', 'consistAddress': '2'}, 'expected': ':SAF60N460102;'});
testCases.push({'test':{'mnemonic': 'DSPD', 'session': '1', 'speed': '2', 'direction':'Reverse'}, 'expected': ':SAF60N470102;'});
testCases.push({'test':{'mnemonic': 'DFLG', 'session': '1', 'flags': '2'}, 'expected': ':SAF60N480102;'});
testCases.push({'test':{'mnemonic': 'DFNON', 'session': '1', 'functionNumber': '2'}, 'expected': ':SAF60N490102;'});
testCases.push({'test':{'mnemonic': 'DFNOF', 'session': '1', 'functionNumber': '2'}, 'expected': ':SAF60N4A0102;'});
testCases.push({'test':{'mnemonic': 'SSTAT', 'session': '1', 'status': '2'}, 'expected': ':SBF60N4C0102;'});
testCases.push({'test':{'mnemonic': 'NNRSM', 'nodeNumber': '1'}, 'expected': ':SBF60N4F0001;'});
testCases.push({'test':{'mnemonic': 'RQNN', 'nodeNumber': '1'}, 'expected': ':SBF60N500001;'});
testCases.push({'test':{'mnemonic': 'NNREL', 'nodeNumber': '1'}, 'expected': ':SBF60N510001;'});
testCases.push({'test':{'mnemonic': 'NNACK', 'nodeNumber': '1'}, 'expected': ':SBF60N520001;'});
testCases.push({'test':{'mnemonic': 'NNLRN', 'nodeNumber': '1'}, 'expected': ':SBF60N530001;'});
testCases.push({'test':{'mnemonic': 'NNULN', 'nodeNumber': '1'}, 'expected': ':SBF60N540001;'});
testCases.push({'test':{'mnemonic': 'NNCLR', 'nodeNumber': '1'}, 'expected': ':SBF60N550001;'});
testCases.push({'test':{'mnemonic': 'NNEVN', 'nodeNumber': '1'}, 'expected': ':SBF60N560001;'});
testCases.push({'test':{'mnemonic': 'NERD', 'nodeNumber': '1'}, 'expected': ':SBF60N570001;'});
testCases.push({'test':{'mnemonic': 'RQEVN', 'nodeNumber': '1'}, 'expected': ':SBF60N580001;'});
testCases.push({'test':{'mnemonic': 'WRACK', 'nodeNumber': '1'}, 'expected': ':SBF60N590001;'});
testCases.push({'test':{'mnemonic': 'RQDAT', 'nodeNumber': '1'}, 'expected': ':SBF60N5A0001;'});
testCases.push({'test':{'mnemonic': 'RQDDS', 'nodeNumber': '1'}, 'expected': ':SBF60N5B0001;'});
testCases.push({'test':{'mnemonic': 'BOOTM', 'nodeNumber': '1'}, 'expected': ':SBF60N5C0001;'});
testCases.push({'test':{'mnemonic': 'ENUM', 'nodeNumber': '1'}, 'expected': ':SBF60N5D0001;'});
testCases.push({'test':{'mnemonic': 'NNRST', 'nodeNumber': '1'}, 'expected': ':SBF60N5E0001;'});
testCases.push({'test':{'mnemonic': 'EXTC1', 'Ext_OPC': '1', 'byte1':'2'}, 'expected': ':SBF60N5F0102;'});
testCases.push({'test':{'mnemonic': 'DFUN', 'session': '1', 'Fn1': '2', 'Fn2':'3'}, 'expected': ':SAF60N60010203;'});
testCases.push({'test':{'mnemonic': 'GLOC', 'address': '1', 'flags':'2'}, 'expected': ':SAF60N61000102;'});
testCases.push({'test':{'mnemonic': 'ERR', 'data1': '1', 'data2':'2', 'errorNumber': '3'}, 'expected': ':SAF60N63010203;'});
testCases.push({'test':{'mnemonic': 'SQU', 'nodeNumber': '1', 'capacityIndex':'2'}, 'expected': ':S8F60N66000102;'});
testCases.push({'test':{'mnemonic': 'CMDERR', 'nodeNumber': '1', 'errorNumber':'2'}, 'expected': ':SBF60N6F000102;'});
testCases.push({'test':{'mnemonic': 'EVNLF', 'nodeNumber': '1', 'EVSPC':'2'}, 'expected': ':SBF60N70000102;'});
testCases.push({'test':{'mnemonic': 'NVRD', 'nodeNumber': '1', 'nodeVariableIndex':'2'}, 'expected': ':SBF60N71000102;'});
testCases.push({'test':{'mnemonic': 'NENRD', 'nodeNumber': '1', 'eventIndex':'2'}, 'expected': ':SBF60N72000102;'});
testCases.push({'test':{'mnemonic': 'RQNPN', 'nodeNumber': '1', 'parameterIndex':'2'}, 'expected': ':SBF60N73000102;'});
testCases.push({'test':{'mnemonic': 'NUMEV', 'nodeNumber': '1', 'eventCount':'2'}, 'expected': ':SBF60N74000102;'});
testCases.push({'test':{'mnemonic': 'CANID', 'nodeNumber': '1', 'CAN_ID':'2'}, 'expected': ':SBF60N75000102;'});
testCases.push({'test':{'mnemonic': 'MODE', 'nodeNumber': '1', 'ModeNumber':'2'}, 'expected': ':SBF60N76000102;'});
testCases.push({'test':{'mnemonic': 'RQSD', 'nodeNumber': '1', 'ServiceIndex':'2'}, 'expected': ':SBF60N78000102;'});
testCases.push({'test':{'mnemonic': 'EXTC2', 'Ext_OPC': '1', 'byte1':'2', 'byte2':'3'}, 'expected': ':SBF60N7F010203;'});
testCases.push({'test':{'mnemonic': 'RDCC3', 'repetitions': '1', 'byte0':'2', 'byte1':'3', 'byte2':'4'}, 'expected': ':SAF60N8001020304;'});
testCases.push({'test':{'mnemonic': 'WCVO', 'session': '1', 'CV':'2', 'value':'3'}, 'expected': ':SAF60N8201000203;'});
testCases.push({'test':{'mnemonic': 'WCVB', 'session': '1', 'CV':'2', 'value':'3'}, 'expected': ':SAF60N8301000203;'});
testCases.push({'test':{'mnemonic': 'QCVS', 'session': '1', 'CV':'2', 'mode':'3'}, 'expected': ':SAF60N8401000203;'});
testCases.push({'test':{'mnemonic': 'PCVS', 'session': '1', 'CV':'2', 'value':'3'}, 'expected': ':SAF60N8501000203;'});
testCases.push({'test':{'mnemonic': 'RDGN', 'nodeNumber': '1', 'ServiceIndex':'2', 'DiagnosticCode':'3'}, 'expected': ':SBF60N8700010203;'});
testCases.push({'test':{'mnemonic': 'NVSETRD', 'nodeNumber': '1', 'nodeVariableIndex':'2', 'nodeVariableValue':'3'}, 'expected': ':SBF60N8E00010203;'});
testCases.push({'test':{'mnemonic': 'ACON', 'nodeNumber': '1', 'eventNumber':'2'}, 'expected': ':SBF60N9000010002;'});
testCases.push({'test':{'mnemonic': 'ACOF', 'nodeNumber': '1', 'eventNumber':'2'}, 'expected': ':SBF60N9100010002;'});
testCases.push({'test':{'mnemonic': 'AREQ', 'nodeNumber': '1', 'eventNumber':'2'}, 'expected': ':SBF60N9200010002;'});
testCases.push({'test':{'mnemonic': 'ARON', 'nodeNumber': '1', 'eventNumber':'2'}, 'expected': ':SBF60N9300010002;'});
testCases.push({'test':{'mnemonic': 'AROF', 'nodeNumber': '1', 'eventNumber':'2'}, 'expected': ':SBF60N9400010002;'});
testCases.push({'test':{'mnemonic': 'EVULN', 'nodeNumber': '1', 'eventNumber':'2'}, 'expected': ':SBF60N9500010002;'});
testCases.push({'test':{'mnemonic': 'NVSET', 'nodeNumber': '1', 'nodeVariableIndex':'2', 'nodeVariableValue':'3'}, 'expected': ':SBF60N9600010203;'});
testCases.push({'test':{'mnemonic': 'NVANS', 'nodeNumber': '1', 'nodeVariableIndex':'2', 'nodeVariableValue':'3'}, 'expected': ':SBF60N9700010203;'});
testCases.push({'test':{'mnemonic': 'ASON', 'nodeNumber': '1', 'deviceNumber':'2'}, 'expected': ':SBF60N9800010002;'});
testCases.push({'test':{'mnemonic': 'ASOF', 'nodeNumber': '1', 'deviceNumber':'2'}, 'expected': ':SBF60N9900010002;'});
testCases.push({'test':{'mnemonic': 'ASRQ', 'nodeNumber': '1', 'deviceNumber':'2'}, 'expected': ':SBF60N9A00010002;'});
testCases.push({'test':{'mnemonic': 'PARAN', 'nodeNumber': '1', 'parameterIndex':'2', 'parameterValue':'3'}, 'expected': ':SBF60N9B00010203;'});
testCases.push({'test':{'mnemonic': 'REVAL', 'nodeNumber': '1', 'eventIndex':'2', 'eventVariableIndex':'3'}, 'expected': ':SBF60N9C00010203;'});
testCases.push({'test':{'mnemonic': 'ARSON', 'nodeNumber': '1', 'deviceNumber':'2'}, 'expected': ':SBF60N9D00010002;'});
testCases.push({'test':{'mnemonic': 'ARSOF', 'nodeNumber': '1', 'deviceNumber':'2'}, 'expected': ':SBF60N9E00010002;'});
testCases.push({'test':{'mnemonic': 'EXTC3', 'Ext_OPC': '1', 'byte1':'2', 'byte2':'3', 'byte3':'4'}, 'expected': ':SBF60N9F01020304;'});
testCases.push({'test':{'mnemonic': 'RDCC4', 'repetitions': '1', 'byte0':'2', 'byte1':'3', 'byte2':'4', 'byte3':'5'}, 'expected': ':SAF60NA00102030405;'});
testCases.push({'test':{'mnemonic': 'WCVS', 'session': '1', 'CV':'2', 'mode':'3', 'value':'4'}, 'expected': ':SAF60NA20100020304;'});
testCases.push({'test':{'mnemonic': 'HEARTB', 'nodeNumber': '1', 'SequenceCount':'2', 'StatusByte1':'3', 'StatusByte2':'4'}, 'expected': ':SBF60NAB0001020304;'});
testCases.push({'test':{'mnemonic': 'SD', 'nodeNumber': '1', 'ServiceIndex':'2', 'ServiceType':'3', 'ServiceVersion':'4'}, 'expected': ':SBF60NAC0001020304;'});
testCases.push({'test':{'mnemonic': 'GRSP', 'nodeNumber': '1', 'requestOpCode':'02', 'serviceType':'3', 'result':'4'}, 'expected': ':SBF60NAF0001020304;'});
testCases.push({'test':{'mnemonic': 'ACON1', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3'}, 'expected': ':SBF60NB00001000203;'});
testCases.push({'test':{'mnemonic': 'ACOF1', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3'}, 'expected': ':SBF60NB10001000203;'});
testCases.push({'test':{'mnemonic': 'REQEV', 'nodeNumber': '1', 'eventNumber':'2', 'eventVariableIndex':'3'}, 'expected': ':SBF60NB20001000203;'});
testCases.push({'test':{'mnemonic': 'ARON1', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3'}, 'expected': ':SBF60NB30001000203;'});
testCases.push({'test':{'mnemonic': 'AROF1', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3'}, 'expected': ':SBF60NB40001000203;'});
testCases.push({'test':{'mnemonic': 'NEVAL', 'nodeNumber': '1', 'eventIndex':'2', 'eventVariableIndex':'3', 'eventVariableValue':'4'}, 'expected': ':SBF60NB50001020304;'});
testCases.push({'test':{'mnemonic': 'PNN', 'nodeNumber': '1', 'manufacturerId':'2', 'moduleId':'3', 'flags':'4'}, 'expected': ':SBF60NB60001020304;'});
testCases.push({'test':{'mnemonic': 'ASON1', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3'}, 'expected': ':SBF60NB80001000203;'});
testCases.push({'test':{'mnemonic': 'ASOF1', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3'}, 'expected': ':SBF60NB90001000203;'});
testCases.push({'test':{'mnemonic': 'ARSON1', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3'}, 'expected': ':SBF60NBD0001000203;'});
testCases.push({'test':{'mnemonic': 'ARSOF1', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3'}, 'expected': ':SBF60NBE0001000203;'});
testCases.push({'test':{'mnemonic': 'EXTC4', 'Ext_OPC': '1', 'byte1':'2', 'byte2':'3', 'byte3':'4', 'byte4':'5'}, 'expected': ':SBF60NBF0102030405;'});
testCases.push({'test':{'mnemonic': 'RDCC5', 'repetitions': '1', 'byte0':'2', 'byte1':'3', 'byte2':'4', 'byte3':'5', 'byte4':'6'}, 'expected': ':SAF60NC0010203040506;'});
testCases.push({'test':{'mnemonic': 'WCVOA', 'address': '1', 'CV':'2', 'mode':'3', 'value':'4'}, 'expected': ':SAF60NC1000100020304;'});
testCases.push({'test':{'mnemonic': 'CABDAT', 'address': '1', 'datcode':'2', 'aspect1':'3', 'aspect2':'4', 'speed':'5'}, 'expected': ':SAF60NC2000102030405;'});
testCases.push({'test':{'mnemonic': 'DGN', 'nodeNumber': '1', 'ServiceIndex':'2', 'DiagnosticCode':'3', 'DiagnosticValue':'4'}, 'expected': ':SBF60NC7000102030004;'});
testCases.push({'test':{'mnemonic': 'FCLK', 'minutes': '1', 'hours':'2', 'dayOfWeek':'3', 'dayOfMonth':'4', 'month':'5', 'div':'6', 'temperature':'7'}, 'expected': ':SBF60NCF010253060407;'});
testCases.push({'test':{'mnemonic': 'ACON2', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3', 'data2':'4'}, 'expected': ':SBF60ND0000100020304;'});
testCases.push({'test':{'mnemonic': 'ACOF2', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3', 'data2':'4'}, 'expected': ':SBF60ND1000100020304;'});
testCases.push({'test':{'mnemonic': 'EVLRN', 'nodeNumber': '1', 'eventNumber':'2', 'eventVariableIndex':'3', 'eventVariableValue':'4'}, 'expected': ':SBF60ND2000100020304;'});
testCases.push({'test':{'mnemonic': 'EVANS', 'nodeNumber': '1', 'eventNumber':'2', 'eventVariableIndex':'3', 'eventVariableValue':'4'}, 'expected': ':SBF60ND3000100020304;'});
testCases.push({'test':{'mnemonic': 'ARON2', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3', 'data2':'4'}, 'expected': ':SBF60ND4000100020304;'});
testCases.push({'test':{'mnemonic': 'AROF2', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3', 'data2':'4'}, 'expected': ':SBF60ND5000100020304;'});
testCases.push({'test':{'mnemonic': 'ASON2', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3', 'data2':'4'}, 'expected': ':SBF60ND8000100020304;'});
testCases.push({'test':{'mnemonic': 'ASOF2', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3', 'data2':'4'}, 'expected': ':SBF60ND9000100020304;'});
testCases.push({'test':{'mnemonic': 'ARSON2', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3', 'data2':'4'}, 'expected': ':SBF60NDD000100020304;'});
testCases.push({'test':{'mnemonic': 'ARSOF2', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3', 'data2':'4'}, 'expected': ':SBF60NDE000100020304;'});
testCases.push({'test':{'mnemonic': 'EXTC5', 'Ext_OPC': '1', 'byte1':'2', 'byte2':'3', 'byte3':'4', 'byte4':'5', 'byte5':'6'}, 'expected': ':SBF60NDF010203040506;'});
testCases.push({'test':{'mnemonic': 'RDCC6', 'repetitions': '1', 'byte0':'2', 'byte1':'3', 'byte2':'4', 'byte3':'5', 'byte4':'6', 'byte5':'7'}, 'expected': ':SAF60NE001020304050607;'});
testCases.push({'test':{'mnemonic': 'PLOC', 'session': '1', 'address':'2', 'speed':'3', 'direction':'Forward', 'Fn1':'5', 'Fn2':'6', 'Fn3':'7'}, 'expected': ':SAF60NE101000283050607;'});
testCases.push({'test':{'mnemonic': 'NAME', 'name': '1234567'}, 'expected': ':SBF60NE231323334353637;'});
testCases.push({'test':{'mnemonic': 'STAT', 'nodeNumber':'1', 'CS':'2', 'flags':'3', 'major':'4', 'minor':'5', 'build':'6'}, 'expected': ':SAF60NE300010203040506;'});
testCases.push({'test':{'mnemonic': 'ENACK', 'nodeNumber':'1', 'ackOpCode':'02', 'eventIdentifier':'00000003'}, 'expected': ':SAF60NE600010200000003;'});
testCases.push({'test':{'mnemonic': 'ESD', 'nodeNumber':'1', 'ServiceIndex':'2', 'ServiceType':'3', 'Data1':'4', 'Data2':'5', 'Data3':'6'}, 'expected': ':SAF60NE700010203040506;'});
testCases.push({'test':{'mnemonic': 'DTXC', 'streamIdentifier':'1', 'sequenceNumber':'0', 'messageLength':'3', 'CRC16':'4', 'flags':'5'}, 'expected': ':SBF60NE901000003000405;'});
testCases.push({'test':{'mnemonic': 'DTXC', 'streamIdentifier':'1', 'sequenceNumber':'255', 'Data1':'3', 'Data2':'4', 'Data3':'5', 'Data4':'6', 'Data5':'7'}, 'expected': ':SBF60NE901FF0304050607;'});
testCases.push({'test':{'mnemonic': 'PARAMS', 'param1': '1', 'param2':'2', 'param3':'3', 'param4':'4', 'param5':'5', 'param6':'6', 'param7':'7'}, 'expected': ':SBF60NEF01020304050607;'});
testCases.push({'test':{'mnemonic': 'ACON3', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3', 'data2':'4', 'data3':'5'}, 'expected': ':SBF60NF000010002030405;'});
testCases.push({'test':{'mnemonic': 'ACOF3', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3', 'data2':'4', 'data3':'5'}, 'expected': ':SBF60NF100010002030405;'});
testCases.push({'test':{'mnemonic': 'ENRSP', 'nodeNumber': '1', 'eventIdentifier':'00000002', 'eventIndex':'3'}, 'expected': ':SBF60NF200010000000203;'});
testCases.push({'test':{'mnemonic': 'ARON3', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3', 'data2':'4', 'data3':'5'}, 'expected': ':SBF60NF300010002030405;'});
testCases.push({'test':{'mnemonic': 'AROF3', 'nodeNumber': '1', 'eventNumber':'2', 'data1':'3', 'data2':'4', 'data3':'5'}, 'expected': ':SBF60NF400010002030405;'});
testCases.push({'test':{'mnemonic': 'EVLRNI', 'nodeNumber':'1', 'eventNumber':'2', 'eventNumberIndex':'3', 'eventVariableIndex':'4', 'eventVariableValue':'5'}, 'expected': ':SBF60NF500010002030405;'});
testCases.push({'test':{'mnemonic': 'ACDAT', 'nodeNumber': '1', 'data1':'2', 'data2':'3', 'data3':'4', 'data4':'5', 'data5':'6'}, 'expected': ':SBF60NF600010203040506;'});
testCases.push({'test':{'mnemonic': 'ARDAT', 'nodeNumber': '1', 'data1':'2', 'data2':'3', 'data3':'4', 'data4':'5', 'data5':'6'}, 'expected': ':SBF60NF700010203040506;'});
testCases.push({'test':{'mnemonic': 'ASON3', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3', 'data2':'4', 'data3':'5'}, 'expected': ':SBF60NF800010002030405;'});
testCases.push({'test':{'mnemonic': 'ASOF3', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3', 'data2':'4', 'data3':'5'}, 'expected': ':SBF60NF900010002030405;'});
testCases.push({'test':{'mnemonic': 'DDES', 'deviceNumber':'1', 'data1':'2', 'data2':'3', 'data3':'4', 'data4':'5', 'data5':'6'}, 'expected': ':SBF60NFA00010203040506;'});
testCases.push({'test':{'mnemonic': 'DDRS', 'deviceNumber':'1', 'data1':'2', 'data2':'3', 'data3':'4', 'data4':'5', 'data5':'6'}, 'expected': ':SBF60NFB00010203040506;'});
testCases.push({'test':{'mnemonic': 'DDWS', 'deviceNumber':'1', 'data1':'2', 'data2':'3', 'data3':'4', 'data4':'5', 'data5':'6'}, 'expected': ':SBF60NFC00010203040506;'});
testCases.push({'test':{'mnemonic': 'ARSON3', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3', 'data2':'4', 'data3':'5'}, 'expected': ':SBF60NFD00010002030405;'});
testCases.push({'test':{'mnemonic': 'ARSOF3', 'nodeNumber': '1', 'deviceNumber':'2', 'data1':'3', 'data2':'4', 'data3':'5'}, 'expected': ':SBF60NFE00010002030405;'});
testCases.push({'test':{'mnemonic': 'EXTC6', 'Ext_OPC': '1', 'byte1':'2', 'byte2':'3', 'byte3':'4', 'byte4':'5', 'byte5':'6', 'byte6':'7'}, 'expected': ':SBF60NFF01020304050607;'});
testCases.push({'test':{"ID_TYPE":"X","operation":"PUT","type":"CONTROL","address":"000001","CTLBT":"2","SPCMD":"3","CPDTL":"4","CPDTH":"5"}, 'expected': ':X00080004N0100000002030405;'});
testCases.push({'test':{"ID_TYPE":"X","operation":"PUT","type":"DATA","data":[1,2,3,4,5,6,7,8]}, 'expected': ':X00080005N0102030405060708;'});
testCases.push({'test':{"ID_TYPE":"X","operation":"RESPONSE","response":'1'}, 'expected': ':X80080004N01;'});
return testCases;
}
//
//
itParam("Generic encode test - ${JSON.stringify(value.test)}", GetTestCase_encode(), function (value) {
winston.info({message: 'cbusMessage test: BEGIN Generic encode test '});
var encode = cbusLib.encode(value.test);
winston.info({message: 'cbusMessage test: Generic encode ' + JSON.stringify(encode)});
expect(encode.mnemonic).to.equal(value.test.mnemonic, 'mnemonic');
expect(encode.encoded).to.equal(value.expected, 'encoded');
// now run encoded value into the decoder to see if encode/decode json matches
// checks that decode() will accept JSON
var decode = cbusLib.decode(encode);
winston.info({message: 'cbusMessage test: decode result ' + JSON.stringify(decode)});
// check all encode JSON properties exist in decode result (may be extra properties in decode we're not worried about)
winston.info({message: 'cbusMessage test: --------------------------'});
Object.entries(value.test).forEach(function([key, item]){
winston.info({message: 'cbusMessage test: ' + key + ' : ' + item});
// ensure we compare like with like, so convert both sides to strings
expect(decode[key].toString()).to.equal(value.test[key].toString());
});
winston.info({message: 'cbusMessage test: --------------------------'});
// now check that if we put the decode back into the encode, we stll get the same encoding
var encode2 = cbusLib.encode(decode);
expect(encode2.encoded).to.equal(value.expected, 'encoded#2');
winston.info({message: 'cbusMessage test: encode2 ' + JSON.stringify(encode2)});
})
// Generic encode fail test cases
//
function GetTestCase_encodeFail () {
var testCases = [];
testCases.push({'test':{'fail':1}, 'expected':'encode: unable to determine message type - no ID_TYPE present'});
testCases.push({'test':{'mnemonic': 'unknown'}, 'expected':'encode standard: \'unknown\' not supported'});
testCases.push({'test':{'mnemonic': 'KLOC'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'QLOC'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'DKEEP'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'DBG1'}, 'expected': 'encode: property \'status\' missing'});
testCases.push({'test':{'mnemonic': 'EXTC'}, 'expected': 'encode: property \'Ext_OPC\' missing'});
testCases.push({'test':{'mnemonic': 'RLOC'}, 'expected': 'encode: property \'address\' missing'});
testCases.push({'test':{'mnemonic': 'QCON', 'index': '2'}, 'expected': 'encode: property \'conID\' missing'});
testCases.push({'test':{'mnemonic': 'QCON', 'conID':'1'}, 'expected': 'encode: property \'index\' missing'});
testCases.push({'test':{'mnemonic': 'SNN'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ALOC', 'allocationCode': '2'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'ALOC', 'session':'1'}, 'expected': 'encode: property \'allocationCode\' missing'});
testCases.push({'test':{'mnemonic': 'STMOD', 'modeByte': '2'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'STMOD', 'session':'1'}, 'expected': 'encode: property \'modeByte\' missing'});
testCases.push({'test':{'mnemonic': 'PCON', 'consistAddress': '2'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'PCON', 'session':'1'}, 'expected': 'encode: property \'consistAddress\' missing'});
testCases.push({'test':{'mnemonic': 'KCON', 'consistAddress': '2'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'KCON', 'session':'1'}, 'expected': 'encode: property \'consistAddress\' missing'});
testCases.push({'test':{'mnemonic': 'DSPD', 'speed':'1','direction': 'Reverse'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'DSPD', 'session':'1','direction': 'Reverse'}, 'expected': 'encode: property \'speed\' missing'});
testCases.push({'test':{'mnemonic': 'DSPD', 'session':'1','speed': '2'}, 'expected': 'encode: property \'direction\' missing'});
testCases.push({'test':{'mnemonic': 'DFLG', 'flags': '2'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'DFLG', 'session':'1'}, 'expected': 'encode: property \'flags\' missing'});
testCases.push({'test':{'mnemonic': 'DFNON', 'functionNumber': '2'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'DFNON', 'session':'1'}, 'expected': 'encode: property \'functionNumber\' missing'});
testCases.push({'test':{'mnemonic': 'DFNOF', 'functionNumber': '2'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'DFNOF', 'session':'1'}, 'expected': 'encode: property \'functionNumber\' missing'});
testCases.push({'test':{'mnemonic': 'SSTAT', 'status': '2'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'SSTAT', 'session':'1'}, 'expected': 'encode: property \'status\' missing'});
testCases.push({'test':{'mnemonic': 'NNRSM'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'RQNN'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NNREL'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NNACK'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NNLRN'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NNULN'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NNCLR'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NNEVN'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NERD'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'RQEVN'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'WRACK'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'RQDAT'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'RQDDS'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'BOOTM'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ENUM'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NNRST'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'EXTC1', 'byte1':'2'}, 'expected': 'encode: property \'Ext_OPC\' missing'});
testCases.push({'test':{'mnemonic': 'EXTC1', 'Ext_OPC':'1'}, 'expected': 'encode: property \'byte1\' missing'});
testCases.push({'test':{'mnemonic': 'DFUN', 'Fn1':'2', 'Fn2': '3'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'DFUN', 'session':'1', 'Fn2': '3'}, 'expected': 'encode: property \'Fn1\' missing'});
testCases.push({'test':{'mnemonic': 'DFUN', 'session':'1', 'Fn1': '2'}, 'expected': 'encode: property \'Fn2\' missing'});
testCases.push({'test':{'mnemonic': 'GLOC', 'flags':'1'}, 'expected': 'encode: property \'address\' missing'});
testCases.push({'test':{'mnemonic': 'GLOC', 'address':'1'}, 'expected': 'encode: property \'flags\' missing'});
testCases.push({'test':{'mnemonic': 'ERR', 'data2':'2', 'errorNumber': '3'}, 'expected': 'encode: property \'data1\' missing'});
testCases.push({'test':{'mnemonic': 'ERR', 'data1':'2', 'errorNumber': '3'}, 'expected': 'encode: property \'data2\' missing'});
testCases.push({'test':{'mnemonic': 'ERR', 'data1':'2', 'data2': '3'}, 'expected': 'encode: property \'errorNumber\' missing'});
testCases.push({'test':{'mnemonic': 'SQU', 'capacityIndex': '2'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'SQU', 'nodeNumber':'1'}, 'expected': 'encode: property \'capacityIndex\' missing'});
testCases.push({'test':{'mnemonic': 'CMDERR', 'errorNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'CMDERR', 'nodeNumber':'2'}, 'expected': 'encode: property \'errorNumber\' missing'});
testCases.push({'test':{'mnemonic': 'EVNLF', 'EVSPC': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'EVNLF', 'nodeNumber':'2'}, 'expected': 'encode: property \'EVSPC\' missing'});
testCases.push({'test':{'mnemonic': 'NVRD', 'nodeVariableIndex': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NVRD', 'nodeNumber':'2'}, 'expected': 'encode: property \'nodeVariableIndex\' missing'});
testCases.push({'test':{'mnemonic': 'NENRD', 'eventIndex': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NENRD', 'nodeNumber':'2'}, 'expected': 'encode: property \'eventIndex\' missing'});
testCases.push({'test':{'mnemonic': 'RQNPN', 'parameterIndex': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'RQNPN', 'nodeNumber':'2'}, 'expected': 'encode: property \'parameterIndex\' missing'});
testCases.push({'test':{'mnemonic': 'NUMEV', 'eventCount': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NUMEV', 'nodeNumber':'2'}, 'expected': 'encode: property \'eventCount\' missing'});
testCases.push({'test':{'mnemonic': 'CANID', 'CAN_ID': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'CANID', 'nodeNumber':'2'}, 'expected': 'encode: property \'CAN_ID\' missing'});
testCases.push({'test':{'mnemonic': 'MODE', 'ModeNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'MODE', 'nodeNumber':'2'}, 'expected': 'encode: property \'ModeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'RQSD', 'ServiceIndex': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'RQSD', 'nodeNumber':'2'}, 'expected': 'encode: property \'ServiceIndex\' missing'});
testCases.push({'test':{'mnemonic': 'EXTC2', 'byte1':'2', 'byte2':'3'}, 'expected': 'encode: property \'Ext_OPC\' missing'});
testCases.push({'test':{'mnemonic': 'EXTC2', 'Ext_OPC':'1', 'byte2':'3'}, 'expected': 'encode: property \'byte1\' missing'});
testCases.push({'test':{'mnemonic': 'EXTC2', 'Ext_OPC':'1', 'byte1':'2'}, 'expected': 'encode: property \'byte2\' missing'});
testCases.push({'test':{'mnemonic': 'RDCC3', 'byte0':'2', 'byte1':'3', 'byte2':'4'}, 'expected': 'encode: property \'repetitions\' missing'});
testCases.push({'test':{'mnemonic': 'RDCC3', 'repetitions':'2', 'byte1':'3', 'byte2':'4'}, 'expected': 'encode: property \'byte0\' missing'});
testCases.push({'test':{'mnemonic': 'RDCC3', 'repetitions':'2', 'byte0':'3', 'byte2':'4'}, 'expected': 'encode: property \'byte1\' missing'});
testCases.push({'test':{'mnemonic': 'RDCC3', 'repetitions':'2', 'byte0':'3', 'byte1':'4'}, 'expected': 'encode: property \'byte2\' missing'});
testCases.push({'test':{'mnemonic': 'WCVO', 'CV':'1', 'value':'3'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'WCVO', 'session':'1', 'value':'3'}, 'expected': 'encode: property \'CV\' missing'});
testCases.push({'test':{'mnemonic': 'WCVO', 'session':'1', 'CV':'2'}, 'expected': 'encode: property \'value\' missing'});
testCases.push({'test':{'mnemonic': 'WCVB', 'CV':'1', 'value':'3'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'WCVB', 'session':'1', 'value':'3'}, 'expected': 'encode: property \'CV\' missing'});
testCases.push({'test':{'mnemonic': 'WCVB', 'session':'1', 'CV':'2'}, 'expected': 'encode: property \'value\' missing'});
testCases.push({'test':{'mnemonic': 'QCVS', 'CV':'1', 'mode':'3'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'QCVS', 'session':'1', 'mode':'3'}, 'expected': 'encode: property \'CV\' missing'});
testCases.push({'test':{'mnemonic': 'QCVS', 'session':'1', 'CV':'2'}, 'expected': 'encode: property \'mode\' missing'});
testCases.push({'test':{'mnemonic': 'PCVS', 'CV':'1', 'value':'3'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'PCVS', 'session':'1', 'value':'3'}, 'expected': 'encode: property \'CV\' missing'});
testCases.push({'test':{'mnemonic': 'PCVS', 'session':'1', 'CV':'2'}, 'expected': 'encode: property \'value\' missing'});
testCases.push({'test':{'mnemonic': 'RDGN', 'ServiceIndex':2, 'DiagnosticCode': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'RDGN', 'nodeNumber':'1', 'DiagnosticCode': '3'}, 'expected': 'encode: property \'ServiceIndex\' missing'});
testCases.push({'test':{'mnemonic': 'RDGN', 'nodeNumber':'1', 'ServiceIndex': '2'}, 'expected': 'encode: property \'DiagnosticCode\' missing'});
testCases.push({'test':{'mnemonic': 'NVSETRD', 'nodeVariableIndex':2, 'nodeVariableValue': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NVSETRD', 'nodeNumber':'1', 'nodeVariableValue': '3'}, 'expected': 'encode: property \'nodeVariableIndex\' missing'});
testCases.push({'test':{'mnemonic': 'NVSETRD', 'nodeNumber':'1', 'nodeVariableIndex': '2'}, 'expected': 'encode: property \'nodeVariableValue\' missing'});
testCases.push({'test':{'mnemonic': 'ACON', 'eventNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ACON', 'nodeNumber':'2'}, 'expected': 'encode: property \'eventNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ACOF', 'eventNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ACOF', 'nodeNumber':'2'}, 'expected': 'encode: property \'eventNumber\' missing'});
testCases.push({'test':{'mnemonic': 'AREQ', 'eventNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'AREQ', 'nodeNumber':'2'}, 'expected': 'encode: property \'eventNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ARON', 'eventNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ARON', 'nodeNumber':'2'}, 'expected': 'encode: property \'eventNumber\' missing'});
testCases.push({'test':{'mnemonic': 'AROF', 'eventNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'AROF', 'nodeNumber':'2'}, 'expected': 'encode: property \'eventNumber\' missing'});
testCases.push({'test':{'mnemonic': 'EVULN', 'eventNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'EVULN', 'nodeNumber':'2'}, 'expected': 'encode: property \'eventNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NVSET', 'nodeVariableIndex':'2', 'nodeVariableValue':'3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NVSET', 'nodeNumber':'2', 'nodeVariableValue':'3'}, 'expected': 'encode: property \'nodeVariableIndex\' missing'});
testCases.push({'test':{'mnemonic': 'NVSET', 'nodeNumber':'2', 'nodeVariableIndex':'3'}, 'expected': 'encode: property \'nodeVariableValue\' missing'});
testCases.push({'test':{'mnemonic': 'NVANS', 'nodeVariableIndex':'2', 'nodeVariableValue':'3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NVANS', 'nodeNumber':'2', 'nodeVariableValue':'3'}, 'expected': 'encode: property \'nodeVariableIndex\' missing'});
testCases.push({'test':{'mnemonic': 'NVANS', 'nodeNumber':'2', 'nodeVariableIndex':'3'}, 'expected': 'encode: property \'nodeVariableValue\' missing'});
testCases.push({'test':{'mnemonic': 'ASON', 'deviceNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ASON', 'nodeNumber':'2'}, 'expected': 'encode: property \'deviceNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ASOF', 'deviceNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ASOF', 'nodeNumber':'2'}, 'expected': 'encode: property \'deviceNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ASRQ', 'deviceNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ASRQ', 'nodeNumber':'2'}, 'expected': 'encode: property \'deviceNumber\' missing'});
testCases.push({'test':{'mnemonic': 'PARAN', 'parameterIndex':'2', 'parameterValue':'3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'PARAN', 'nodeNumber':'2', 'parameterValue':'3'}, 'expected': 'encode: property \'parameterIndex\' missing'});
testCases.push({'test':{'mnemonic': 'PARAN', 'nodeNumber':'2', 'parameterIndex':'3'}, 'expected': 'encode: property \'parameterValue\' missing'});
testCases.push({'test':{'mnemonic': 'REVAL', 'eventIndex':'2', 'eventVariableIndex':'3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'REVAL', 'nodeNumber':'2', 'eventVariableIndex':'3'}, 'expected': 'encode: property \'eventIndex\' missing'});
testCases.push({'test':{'mnemonic': 'REVAL', 'nodeNumber':'2', 'eventIndex':'3'}, 'expected': 'encode: property \'eventVariableIndex\' missing'});
testCases.push({'test':{'mnemonic': 'ARSON', 'deviceNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ARSON', 'nodeNumber':'2'}, 'expected': 'encode: property \'deviceNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ARSOF', 'deviceNumber': '3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ARSOF', 'nodeNumber':'2'}, 'expected': 'encode: property \'deviceNumber\' missing'});
testCases.push({'test':{'mnemonic': 'EXTC3', 'byte1':'2', 'byte2':'3', 'byte3':'4'}, 'expected': 'encode: property \'Ext_OPC\' missing'});
testCases.push({'test':{'mnemonic': 'EXTC3', 'Ext_OPC':'1', 'byte2':'3', 'byte3':'4'}, 'expected': 'encode: property \'byte1\' missing'});
testCases.push({'test':{'mnemonic': 'EXTC3', 'Ext_OPC':'1', 'byte1':'2', 'byte3':'4'}, 'expected': 'encode: property \'byte2\' missing'});
testCases.push({'test':{'mnemonic': 'EXTC3', 'Ext_OPC':'1', 'byte1':'2', 'byte2':'3'}, 'expected': 'encode: property \'byte3\' missing'});
testCases.push({'test':{'mnemonic': 'RDCC4', 'byte0':'2', 'byte1':'3', 'byte2':'4', 'byte3':'5'}, 'expected': 'encode: property \'repetitions\' missing'});
testCases.push({'test':{'mnemonic': 'RDCC4', 'repetitions':'2', 'byte1':'3', 'byte2':'4', 'byte3':'5'}, 'expected': 'encode: property \'byte0\' missing'});
testCases.push({'test':{'mnemonic': 'RDCC4', 'repetitions':'2', 'byte0':'3', 'byte2':'4', 'byte3':'5'}, 'expected': 'encode: property \'byte1\' missing'});
testCases.push({'test':{'mnemonic': 'RDCC4', 'repetitions':'2', 'byte0':'3', 'byte1':'4', 'byte3':'5'}, 'expected': 'encode: property \'byte2\' missing'});
testCases.push({'test':{'mnemonic': 'RDCC4', 'repetitions':'2', 'byte0':'3', 'byte1':'4', 'byte2':'5'}, 'expected': 'encode: property \'byte3\' missing'});
testCases.push({'test':{'mnemonic': 'WCVS', 'CV':'2', 'mode':'3', 'value':'4'}, 'expected': 'encode: property \'session\' missing'});
testCases.push({'test':{'mnemonic': 'WCVS', 'session':'1', 'mode':'3', 'value':'4'}, 'expected': 'encode: property \'CV\' missing'});
testCases.push({'test':{'mnemonic': 'WCVS', 'session':'1', 'CV':'2', 'value':'4'}, 'expected': 'encode: property \'mode\' missing'});
testCases.push({'test':{'mnemonic': 'WCVS', 'session':'1', 'CV':'2', 'mode':'3'}, 'expected': 'encode: property \'value\' missing'});
testCases.push({'test':{'mnemonic': 'HEARTB', 'SequenceCount':'2', 'StatusByte1':'3', 'StatusByte2':'4'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'HEARTB', 'nodeNumber':'1', 'StatusByte1':'3', 'StatusByte2':'4'}, 'expected': 'encode: property \'SequenceCount\' missing'});
testCases.push({'test':{'mnemonic': 'HEARTB', 'nodeNumber':'1', 'SequenceCount':'2', 'StatusByte2':'4'}, 'expected': 'encode: property \'StatusByte1\' missing'});
testCases.push({'test':{'mnemonic': 'HEARTB', 'nodeNumber':'1', 'SequenceCount':'2', 'StatusByte1':'3'}, 'expected': 'encode: property \'StatusByte2\' missing'});
testCases.push({'test':{'mnemonic': 'SD', 'ServiceIndex':2, 'ServiceType': '3', 'ServiceVersion': '4'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'SD', 'nodeNumber':'1', 'ServiceType': '3', 'ServiceVersion': '4'}, 'expected': 'encode: property \'ServiceIndex\' missing'});
testCases.push({'test':{'mnemonic': 'SD', 'nodeNumber':'1', 'ServiceIndex': '2', 'ServiceVersion': '4'}, 'expected': 'encode: property \'ServiceType\' missing'});
testCases.push({'test':{'mnemonic': 'SD', 'nodeNumber':'1', 'ServiceIndex': '2', 'ServiceType': '3',}, 'expected': 'encode: property \'ServiceVersion\' missing'});
testCases.push({'test':{'mnemonic': 'GRSP', 'requestOpCode':'2', 'serviceType':'3', 'result':'4'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'GRSP', 'nodeNumber':'1', 'serviceType':'3', 'result':'4'}, 'expected': 'encode: property \'requestOpCode\' missing'});
testCases.push({'test':{'mnemonic': 'GRSP', 'nodeNumber':'1', 'requestOpCode':'2', 'result':'4'}, 'expected': 'encode: property \'serviceType\' missing'});
testCases.push({'test':{'mnemonic': 'GRSP', 'nodeNumber':'1', 'requestOpCode':'2', 'serviceType':'3'}, 'expected': 'encode: property \'result\' missing'});
testCases.push({'test':{'mnemonic': 'ACON1', 'eventNumber': '2', 'data1':'3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ACON1', 'nodeNumber':'2', 'data1':'3'}, 'expected': 'encode: property \'eventNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ACON1', 'nodeNumber':'2', 'eventNumber':'2'}, 'expected': 'encode: property \'data1\' missing'});
testCases.push({'test':{'mnemonic': 'ACOF1', 'eventNumber': '2', 'data1':'3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ACOF1', 'nodeNumber':'2', 'data1':'3'}, 'expected': 'encode: property \'eventNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ACOF1', 'nodeNumber':'2', 'eventNumber':'2'}, 'expected': 'encode: property \'data1\' missing'});
testCases.push({'test':{'mnemonic': 'REQEV', 'eventNumber': '2', 'eventVariableIndex':'3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'REQEV', 'nodeNumber':'2', 'eventVariableIndex':'3'}, 'expected': 'encode: property \'eventNumber\' missing'});
testCases.push({'test':{'mnemonic': 'REQEV', 'nodeNumber':'2', 'eventNumber':'2'}, 'expected': 'encode: property \'eventVariableIndex\' missing'});
testCases.push({'test':{'mnemonic': 'ARON1', 'eventNumber': '2', 'data1':'3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ARON1', 'nodeNumber':'2', 'data1':'3'}, 'expected': 'encode: property \'eventNumber\' missing'});
testCases.push({'test':{'mnemonic': 'ARON1', 'nodeNumber':'2', 'eventNumber':'2'}, 'expected': 'encode: property \'data1\' missing'});
testCases.push({'test':{'mnemonic': 'AROF1', 'eventNumber': '2', 'data1':'3'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'AROF1', 'nodeNumber':'2', 'data1':'3'}, 'expected': 'encode: property \'eventNumber\' missing'});
testCases.push({'test':{'mnemonic': 'AROF1', 'nodeNumber':'2', 'eventNumber':'2'}, 'expected': 'encode: property \'data1\' missing'});
testCases.push({'test':{'mnemonic': 'NEVAL', 'eventIndex':'2', 'eventVariableIndex':'3', 'eventVariableValue':'4'}, 'expected': 'encode: property \'nodeNumber\' missing'});
testCases.push({'test':{'mnemonic': 'NEVAL', 'nodeNumber':'1', 'eventVariableIndex':'3', 'eventVariableValue':'4'}, 'expected': 'encode: property \'eventIndex\' missing'});
testCases.push({'test':{'mnemonic': 'NEVAL', 'nodeNumber':'1', 'eventIndex':'2', 'eventVariableValue':'4'}, 'expected': 'encode: property \'eventVariableIndex\' missing'});
testCases.push({'test':{'mnemonic': 'NEVAL', 'nodeNumber':'1', 'eventIndex':'2', 'eventVariableIndex':'3'}, 'expected': 'encode: prop