src/datagram.js
/*! resol-vbus | Copyright (c) 2013-present, Daniel Wippermann | MIT license */
const { sprintf } = require('sprintf-js');
const Header = require('./header');
const { applyDefaultOptions } = require('./utils');
class Datagram extends Header {
/**
* Creates a new Datagram instance and optionally initializes its members with the given values.
*
* @constructs
* @augments Header
* @param {object} options Initialization values for this instance's members
* @param {number} options.command {@link Datagram#command}
* @param {number} options.valueId {@link Datagram#valueId}
* @param {Buffer} options.value {@link Datagram#value}
* @see Header#constructor
*
* @classdesc
* The Datagram sub-class provides access to all properties and methods applicable for VBus version 2 datagrams.
* In addition to the packet header it may contain a command, a value ID and a value.
* The value ID is a device-specific reference to one of the values presented in the device's menu interface.
*/
constructor(options) {
super(options);
applyDefaultOptions(this, options, /** @lends Datagram.prototype */ {
/**
* The command field of this VBus datagram. See the VBus Protocol Specification for details.
* @type {number}
*/
command: 0,
/**
* The value ID field of this VBus datagram.
* @type {number}
*/
valueId: 0,
/**
* The value field of this VBus datagram.
* @type {number}
*/
value: 0,
});
}
toLiveBuffer(origBuffer, start, end) {
const length = 16;
let buffer;
if (origBuffer === undefined) {
buffer = Buffer.alloc(length);
} else {
buffer = origBuffer.slice(start, end);
}
if (buffer.length < length) {
throw new Error('Buffer too small');
}
buffer [0] = 0xAA;
buffer.writeUInt16LE(this.destinationAddress & 0x7F7F, 1);
buffer.writeUInt16LE(this.sourceAddress & 0x7F7F, 3);
buffer [5] = this.getProtocolVersion();
buffer.writeUInt16LE(this.command & 0x7F7F, 6);
const frameData = Buffer.alloc(6);
frameData.writeUInt16LE(this.valueId, 0);
frameData.writeInt32LE(this.value, 2);
Datagram.extractSeptett(frameData, 0, 6, buffer, 8);
Datagram.calcAndSetChecksum(this.minorVersion, buffer, 1, 15);
return buffer;
}
getProtocolVersion() {
return 0x20 | this.minorVersion;
}
getInfo() {
let info;
if (this.command === 0x0900) {
info = this.valueId;
} else {
info = 0;
}
return info;
}
getId() {
const baseId = Header.prototype.getId.call(this);
const info = this.getInfo();
return sprintf('%s_%04X_%04X', baseId, this.command, info);
}
compareTo(that) {
let result = Header.prototype.compareTo.apply(this, arguments);
if (result === 0) {
result = this.command - that.command;
}
if (result === 0) {
result = this.getInfo() - that.getInfo();
}
return result;
}
static fromLiveBuffer(buffer, start, end) {
const frameData = Buffer.alloc(6);
Header.injectSeptett(buffer, start + 8, start + 14, frameData, 0);
return new Datagram({
destinationAddress: buffer.readUInt16LE(start + 1),
sourceAddress: buffer.readUInt16LE(start + 3),
command: buffer.readUInt16LE(start + 6),
valueId: frameData.readUInt16LE(0),
value: frameData.readInt32LE(2)
});
}
}
Object.assign(Datagram.prototype, /** @lends Datagram.prototype */ {
/**
* The command field of this VBus datagram. See the VBus Protocol Specification for details.
* @type {number}
*/
command: 0,
/**
* The value ID field of this VBus datagram.
* @type {number}
*/
valueId: 0,
/**
* The value field of this VBus datagram.
* @type {number}
*/
value: 0,
});
module.exports = Datagram;