diff --git a/messages.js b/messages.js index 2e6f891..54240eb 100644 --- a/messages.js +++ b/messages.js @@ -11,6 +11,62 @@ function encodeZonesTamperCommand() { return message_impl.encodeNoDataCommand(message_impl.Commands.ZonesTamper); } +function encodeZonesAlarmCommand() { + return message_impl.encodeNoDataCommand(message_impl.Commands.ZonesAlarm); +} + +function encodeZonesTamperAlarmCommand() { + return message_impl.encodeNoDataCommand( + message_impl.Commands.ZonesTamperAlarm + ); +} + +function encodeZonesAlarmMemoryCommand() { + return message_impl.encodeNoDataCommand( + message_impl.Commands.ZonesAlarmMemory + ); +} + +function encodeZonesTamperAlarmMemoryCommand() { + return message_impl.encodeNoDataCommand( + message_impl.Commands.ZonesTamperAlarmMemory + ); +} + +function encodeZonesBypassStatusCommand() { + return message_impl.encodeNoDataCommand( + message_impl.Commands.ZonesBypassStatus + ); +} + +function encodeZonesNoViolationTroubleCommand() { + return message_impl.encodeNoDataCommand( + message_impl.Commands.ZonesNoViolationTrouble + ); +} + +function encodeZonesLongViolationTroubleCommand() { + return message_impl.encodeNoDataCommand( + message_impl.Commands.ZonesLongViolationTrouble + ); +} + +function encodeZonesIsolateStateCommand() { + return message_impl.encodeNoDataCommand( + message_impl.Commands.ZonesIsolateState + ); +} + +function encodeZonesMaskedCommand() { + return message_impl.encodeNoDataCommand(message_impl.Commands.ZonesMasked); +} + +function encodeZonesMaskedMemoryCommand() { + return message_impl.encodeNoDataCommand( + message_impl.Commands.ZonesMaskedMemory + ); +} + function encodeOutputsStateCommand() { return message_impl.encodeNoDataCommand(message_impl.Commands.OutputsState); } @@ -68,17 +124,16 @@ function encodeZonesIsolateCommand(prefixAndUserCode, zones) { } class FlagArrayAnswer { - constructor(length, longLength = undefined) { - this._length = length; - this._longLength = longLength; + constructor(allowedLengths) { + this._allowedLengths = allowedLengths; this._flags = []; } decode(frame) { if ( - frame.length != this._length && - typeof this._longLength != undefined && - frame.length != this._longLength + this._allowedLengths.every(function (allowedLength) { + return allowedLength != frame.length; + }) ) { return false; } @@ -100,25 +155,85 @@ class FlagArrayAnswer { class ZonesViolationAnswer extends FlagArrayAnswer { constructor() { - super(16, 32); + super([16, 32]); } } class ZonesTamperAnswer extends FlagArrayAnswer { constructor() { - super(16, 32); + super([16, 32]); } } class OutputsStateAnswer extends FlagArrayAnswer { constructor() { - super(16, 32); + super([16, 32]); + } +} + +class ZonesAlarmAnswer extends FlagArrayAnswer { + constructor() { + super([16, 32]); + } +} + +class ZonesTamperAlarmAnswer extends FlagArrayAnswer { + constructor() { + super([16, 32]); + } +} + +class ZonesAlarmMemoryAnswer extends FlagArrayAnswer { + constructor() { + super([16, 32]); + } +} + +class ZonesTamperAlarmMemoryAnswer extends FlagArrayAnswer { + constructor() { + super([16, 32]); + } +} + +class ZonesBypassStatusAnswer extends FlagArrayAnswer { + constructor() { + super([16, 32]); + } +} + +class ZonesNoViolationTroubleAnswer extends FlagArrayAnswer { + constructor() { + super([16, 32]); + } +} + +class ZonesLongViolationTroubleAnswer extends FlagArrayAnswer { + constructor() { + super([16, 32]); + } +} + +class ZonesIsolateStateAnswer extends FlagArrayAnswer { + constructor() { + super([16, 32]); + } +} + +class ZonesMaskedAnswer extends FlagArrayAnswer { + constructor() { + super([16, 32]); + } +} + +class ZonesMaskedMemoryAnswer extends FlagArrayAnswer { + constructor() { + super([16, 32]); } } class NewDataAnswer extends FlagArrayAnswer { constructor() { - super(5); + super([5, 6, 7]); } zonesViolationChanged() { @@ -132,6 +247,46 @@ class NewDataAnswer extends FlagArrayAnswer { outputsStateChanged() { return this._flags[message_impl.Commands.OutputsState]; } + + zonesAlarmChanged() { + return this._flags[message_impl.Commands.ZonesAlarm]; + } + + zonesTamperAlarmChanged() { + return this._flags[message_impl.Commands.ZonesTamperAlarm]; + } + + zonesAlarmMemoryChanged() { + return this._flags[message_impl.Commands.ZonesAlarmMemory]; + } + + zonesTamperAlarmMemoryChanged() { + return this._flags[message_impl.Commands.ZonesTamperAlarmMemory]; + } + + zonesBypassStatusChanged() { + return this._flags[message_impl.Commands.ZonesBypassStatus]; + } + + zonesNoViolationTroubleChanged() { + return this._flags[message_impl.Commands.ZonesNoViolationTrouble]; + } + + zonesLongViolationTroubleChanged() { + return this._flags[message_impl.Commands.ZonesLongViolationTrouble]; + } + + zonesIsolateStateChanged() { + return this._flags[message_impl.Commands.ZonesIsolateState]; + } + + zonesMaskedChanged() { + return this._flags[message_impl.Commands.ZonesMasked]; + } + + zonesMaskedMemoryChanged() { + return this._flags[message_impl.Commands.ZonesMaskedMemory]; + } } class CommandResultAnswer { @@ -256,6 +411,36 @@ function decodeMessage(frame) { case message_impl.Commands.CommandResult: message = new CommandResultAnswer(); break; + case message_impl.Commands.ZonesAlarm: + message = new ZonesAlarmAnswer(); + break; + case message_impl.Commands.ZonesTamperAlarm: + message = new ZonesTamperAlarmAnswer(); + break; + case message_impl.Commands.ZonesAlarmMemory: + message = new ZonesAlarmMemoryAnswer(); + break; + case message_impl.Commands.ZonesTamperAlarmMemory: + message = new ZonesTamperAlarmMemoryAnswer(); + break; + case message_impl.Commands.ZonesBypassStatus: + message = new ZonesBypassStatusAnswer(); + break; + case message_impl.Commands.ZonesNoViolationTrouble: + message = new ZonesNoViolationTroubleAnswer(); + break; + case message_impl.Commands.ZonesLongViolationTrouble: + message = new ZonesLongViolationTroubleAnswer(); + break; + case message_impl.Commands.ZonesIsolateState: + message = new ZonesIsolateStateAnswer(); + break; + case message_impl.Commands.ZonesMasked: + message = new ZonesMaskedAnswer(); + break; + case message_impl.Commands.ZonesMaskedMemory: + message = new ZonesMaskedMemoryAnswer(); + break; default: return null; } @@ -274,14 +459,34 @@ module.exports = { encodeOutputsOnCommand, encodeOutputsStateCommand, encodeOutputsSwitchCommand, + encodeZonesAlarmCommand, + encodeZonesAlarmMemoryCommand, encodeZonesBypassCommand, + encodeZonesBypassStatusCommand, encodeZonesIsolateCommand, + encodeZonesIsolateStateCommand, + encodeZonesLongViolationTroubleCommand, + encodeZonesMaskedCommand, + encodeZonesMaskedMemoryCommand, + encodeZonesNoViolationTroubleCommand, + encodeZonesTamperAlarmCommand, + encodeZonesTamperAlarmMemoryCommand, encodeZonesTamperCommand, encodeZonesUnbypassCommand, encodeZonesViolationCommand, CommandResultAnswer, NewDataAnswer, OutputsStateAnswer, + ZonesAlarmAnswer, + ZonesAlarmMemoryAnswer, + ZonesBypassStatusAnswer, + ZonesIsolateStateAnswer, + ZonesLongViolationTroubleAnswer, + ZonesMaskedAnswer, + ZonesMaskedMemoryAnswer, + ZonesNoViolationTroubleAnswer, + ZonesTamperAlarmAnswer, + ZonesTamperAlarmMemoryAnswer, ZonesTamperAnswer, ZonesViolationAnswer, }; diff --git a/messages.test.js b/messages.test.js index 120be0f..0aaa44f 100644 --- a/messages.test.js +++ b/messages.test.js @@ -6,29 +6,65 @@ const messages_impl = require("./messages_impl"); describe("Message encoding unit tests", function () { let noDataCommandTests = [ { - name: "zones violation", func: messages.encodeZonesViolationCommand, command: messages_impl.Commands.ZonesViolation, }, { - name: "zones tamper", func: messages.encodeZonesTamperCommand, command: messages_impl.Commands.ZonesTamper, }, { - name: "outputs state", func: messages.encodeOutputsStateCommand, command: messages_impl.Commands.OutputsState, }, { - name: "new data", func: messages.encodeNewDataCommand, command: messages_impl.Commands.NewData, }, + { + func: messages.encodeZonesAlarmCommand, + command: messages_impl.Commands.ZonesAlarm, + }, + { + func: messages.encodeZonesTamperAlarmCommand, + command: messages_impl.Commands.ZonesTamperAlarm, + }, + { + func: messages.encodeZonesAlarmMemoryCommand, + command: messages_impl.Commands.ZonesAlarmMemory, + }, + { + func: messages.encodeZonesTamperAlarmMemoryCommand, + command: messages_impl.Commands.ZonesTamperAlarmMemory, + }, + { + func: messages.encodeZonesBypassStatusCommand, + command: messages_impl.Commands.ZonesBypassStatus, + }, + { + func: messages.encodeZonesNoViolationTroubleCommand, + command: messages_impl.Commands.ZonesNoViolationTrouble, + }, + { + func: messages.encodeZonesLongViolationTroubleCommand, + command: messages_impl.Commands.ZonesLongViolationTrouble, + }, + { + func: messages.encodeZonesIsolateStateCommand, + command: messages_impl.Commands.ZonesIsolateState, + }, + { + func: messages.encodeZonesMaskedCommand, + command: messages_impl.Commands.ZonesMasked, + }, + { + func: messages.encodeZonesMaskedMemoryCommand, + command: messages_impl.Commands.ZonesMaskedMemory, + }, ]; noDataCommandTests.forEach(function (test) { - it("encode " + test.name + " command", function () { + it(test.func.name + "()", function () { const frame = test.func(); assert.equal(frame.length, 7); assert.equal(frame[2], test.command); @@ -37,39 +73,33 @@ describe("Message encoding unit tests", function () { let outputsAndZonesChangeTests = [ { - name: "outputs on", func: messages.encodeOutputsOnCommand, command: messages_impl.Commands.OutputsOn, }, { - name: "outputs off", func: messages.encodeOutputsOffCommand, command: messages_impl.Commands.OutputsOff, }, { - name: "outputs switch", func: messages.encodeOutputsSwitchCommand, command: messages_impl.Commands.OutputsSwitch, }, { - name: "zones bypass", func: messages.encodeZonesBypassCommand, command: messages_impl.Commands.ZonesBypass, }, { - name: "zones unbypass", func: messages.encodeZonesUnbypassCommand, command: messages_impl.Commands.ZonesUnbypass, }, { - name: "zones isolate", func: messages.encodeZonesIsolateCommand, command: messages_impl.Commands.ZonesIsolate, }, ]; outputsAndZonesChangeTests.forEach(function (test) { - it("encode short " + test.name + " command", function () { + it(test.func.name + "(), short", function () { const outputs = new Array(128).fill(false, 0, 128); outputs[0] = true; outputs[2] = true; @@ -105,7 +135,7 @@ describe("Message encoding unit tests", function () { ); }); - it("encode long " + test.name + " command", function () { + it(test.func.name + "(), long", function () { const outputs = new Array(256).fill(false, 0, 128); outputs[0] = true; outputs[2] = true; @@ -183,24 +213,61 @@ describe("Message decoding unit tests", () => { let flagArrayAnswerTests = [ { - name: "zones violation", message: messages.ZonesViolationAnswer, command: messages_impl.Commands.ZonesViolation, }, { - name: "zones tamper", message: messages.ZonesTamperAnswer, command: messages_impl.Commands.ZonesTamper, }, { - name: "outputs state", message: messages.OutputsStateAnswer, command: messages_impl.Commands.OutputsState, }, + { + message: messages.ZonesAlarmAnswer, + command: messages_impl.Commands.ZonesAlarm, + }, + { + message: messages.ZonesTamperAlarmAnswer, + command: messages_impl.Commands.ZonesTamperAlarm, + }, + { + message: messages.ZonesAlarmMemoryAnswer, + command: messages_impl.Commands.ZonesAlarmMemory, + }, + { + message: messages.ZonesTamperAlarmMemoryAnswer, + command: messages_impl.Commands.ZonesTamperAlarmMemory, + }, + { + message: messages.ZonesBypassStatusAnswer, + command: messages_impl.Commands.ZonesBypassStatus, + }, + { + message: messages.ZonesNoViolationTroubleAnswer, + command: messages_impl.Commands.ZonesNoViolationTrouble, + }, + { + message: messages.ZonesLongViolationTroubleAnswer, + command: messages_impl.Commands.ZonesLongViolationTrouble, + }, + { + message: messages.ZonesIsolateStateAnswer, + command: messages_impl.Commands.ZonesIsolateState, + }, + { + message: messages.ZonesMaskedAnswer, + command: messages_impl.Commands.ZonesMasked, + }, + { + message: messages.ZonesMaskedMemoryAnswer, + command: messages_impl.Commands.ZonesMaskedMemory, + }, ]; flagArrayAnswerTests.forEach(function (test) { - it("decode short " + test.name + " answer", function () { + it("decode " + test.message.name + ", short", function () { const encoder = new Encoder(); encoder.addBytes( Buffer.from([test.command].concat(Array(16).fill(0xaa))) @@ -216,7 +283,7 @@ describe("Message decoding unit tests", () => { } }); - it("decode long " + test.name + " answer", function () { + it("decode " + test.message.name + ", long", function () { const encoder = new Encoder(); encoder.addBytes( Buffer.from([test.command].concat(Array(32).fill(0xaa))) @@ -234,9 +301,43 @@ describe("Message decoding unit tests", () => { }); let newDataAnswerTests = [ - { name: "zones violation", command: messages_impl.Commands.ZonesViolation }, - { name: "zones tamper", command: messages_impl.Commands.ZonesTamper }, - { name: "outputs state", command: messages_impl.Commands.OutputsState }, + { name: "ZonesViolation", command: messages_impl.Commands.ZonesViolation }, + { name: "ZonesTamper", command: messages_impl.Commands.ZonesTamper }, + { name: "OutputsState", command: messages_impl.Commands.OutputsState }, + { name: "ZonesAlarm", command: messages_impl.Commands.ZonesAlarm }, + { + name: "ZonesTamperAlarm", + command: messages_impl.Commands.ZonesTamperAlarm, + }, + { + name: "ZonesAlarmMemory", + command: messages_impl.Commands.ZonesAlarmMemory, + }, + { + name: "ZonesTamperAlarmMemory", + command: messages_impl.Commands.ZonesTamperAlarmMemory, + }, + { + name: "ZonesBypassStatus", + command: messages_impl.Commands.ZonesBypassStatus, + }, + { + name: "ZonesNoViolationTrouble", + command: messages_impl.Commands.ZonesNoViolationTrouble, + }, + { + name: "ZonesLongViolationTrouble", + command: messages_impl.Commands.ZonesLongViolationTrouble, + }, + { + name: "ZonesIsolateState", + command: messages_impl.Commands.ZonesIsolateState, + }, + { name: "ZonesMasked", command: messages_impl.Commands.ZonesMasked }, + { + name: "ZonesMaskedMemory", + command: messages_impl.Commands.ZonesMaskedMemory, + }, ]; newDataAnswerTests.forEach(function (test) { @@ -249,6 +350,8 @@ describe("Message decoding unit tests", () => { 0x00, 0x00, 0x00, + 0x00, + 0x00, ]); const index = Math.floor(test.command / 8) + 1; frame[index] = frame[index] | (1 << test.command % 8); @@ -267,6 +370,46 @@ describe("Message decoding unit tests", () => { message.outputsStateChanged(), test.command == messages_impl.Commands.OutputsState ); + assert.strictEqual( + message.zonesAlarmChanged(), + test.command == messages_impl.Commands.ZonesAlarm + ); + assert.strictEqual( + message.zonesTamperAlarmChanged(), + test.command == messages_impl.Commands.ZonesTamperAlarm + ); + assert.strictEqual( + message.zonesAlarmMemoryChanged(), + test.command == messages_impl.Commands.ZonesAlarmMemory + ); + assert.strictEqual( + message.zonesTamperAlarmMemoryChanged(), + test.command == messages_impl.Commands.ZonesTamperAlarmMemory + ); + assert.strictEqual( + message.zonesBypassStatusChanged(), + test.command == messages_impl.Commands.ZonesBypassStatus + ); + assert.strictEqual( + message.zonesNoViolationTroubleChanged(), + test.command == messages_impl.Commands.ZonesNoViolationTrouble + ); + assert.strictEqual( + message.zonesLongViolationTroubleChanged(), + test.command == messages_impl.Commands.ZonesLongViolationTrouble + ); + assert.strictEqual( + message.zonesIsolateStateChanged(), + test.command == messages_impl.Commands.ZonesIsolateState + ); + assert.strictEqual( + message.zonesMaskedChanged(), + test.command == messages_impl.Commands.ZonesMasked + ); + assert.strictEqual( + message.zonesMaskedMemoryChanged(), + test.command == messages_impl.Commands.ZonesMaskedMemory + ); }); }); diff --git a/messages_impl.js b/messages_impl.js index 5ea7ee4..c0ef262 100644 --- a/messages_impl.js +++ b/messages_impl.js @@ -5,7 +5,17 @@ const Encoder = require("./encoder"); const Commands = Object.freeze({ ZonesViolation: 0x00, ZonesTamper: 0x01, + ZonesAlarm: 0x02, + ZonesTamperAlarm: 0x03, + ZonesAlarmMemory: 0x04, + ZonesTamperAlarmMemory: 0x05, + ZonesBypassStatus: 0x06, + ZonesNoViolationTrouble: 0x07, + ZonesLongViolationTrouble: 0x08, OutputsState: 0x17, + ZonesIsolateState: 0x26, + ZonesMasked: 0x28, + ZonesMaskedMemory: 0x29, NewData: 0x7f, ZonesBypass: 0x86, ZonesUnbypass: 0x87, diff --git a/package-lock.json b/package-lock.json index fc77d6a..e806407 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "satel-integra-integration-protocol", - "version": "0.5.1", + "version": "0.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 640151b..25a73dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "satel-integra-integration-protocol", - "version": "0.5.1", + "version": "0.6.0", "description": "Satel Integra integration protocol", "main": "messages.js", "scripts": {