knxnetjs
Version:
A TypeScript library for KNXnet/IP communication
272 lines • 10.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CEMIPropertyReadCon = exports.CEMIPropertyReadReq = exports.CEMIPropertyWrite = exports.DPT_CommMode = exports.Properties = void 0;
const cemi_1 = require("./cemi");
var Properties;
(function (Properties) {
Properties[Properties["PID_COMM_MODE"] = 52] = "PID_COMM_MODE";
})(Properties || (exports.Properties = Properties = {}));
var DPT_CommMode;
(function (DPT_CommMode) {
DPT_CommMode[DPT_CommMode["DataLinkLayer"] = 0] = "DataLinkLayer";
DPT_CommMode[DPT_CommMode["DataLinkLayerBusmonitor"] = 1] = "DataLinkLayerBusmonitor";
DPT_CommMode[DPT_CommMode["DataLinkLayerRawFrames"] = 2] = "DataLinkLayerRawFrames";
DPT_CommMode[DPT_CommMode["CEMITranpsortLayer"] = 6] = "CEMITranpsortLayer";
DPT_CommMode[DPT_CommMode["NoLayer"] = 255] = "NoLayer";
})(DPT_CommMode || (exports.DPT_CommMode = DPT_CommMode = {}));
/*
* Basic message structure for Data Properties
*
* Message code, 1 byte
* Interface object, 2 byte
* Object Instance, 1 byte
* Property Id, 1 byte
* Number of elements, 4 bits
* start index, 12 bits
* data
*/
class CEMIPropertyWrite {
constructor(interfaceObject, objectInstance, propertyId, numberOfElements, startIndex, data) {
if (numberOfElements > 15) {
throw new Error("Number of elements cannot exceed 15 (4 bits)");
}
if (startIndex > 4095) {
throw new Error("Start index cannot exceed 4095 (12 bits)");
}
// Calculate buffer size: 1 (msg code) + 2 (interface obj) + 1 (obj instance) + 1 (prop id) + 2 (elements+index) + data
const bufferSize = 7 + data.length;
this.buffer = Buffer.allocUnsafe(bufferSize);
let offset = 0;
// Message code - M_PROP_WRITE_REQ
this.buffer.writeUInt8(cemi_1.CEMIMessageCode.M_PROP_WRITE_REQ, offset++);
// Interface object (2 bytes, big endian)
this.buffer.writeUInt16BE(interfaceObject, offset);
offset += 2;
// Object Instance (1 byte)
this.buffer.writeUInt8(objectInstance, offset++);
// Property Id (1 byte)
this.buffer.writeUInt8(propertyId, offset++);
// Number of elements (4 bits) + start index (12 bits)
// Pack into 2 bytes: NNNN IIII IIII IIII
const packed = (numberOfElements << 12) | (startIndex & 0x0fff);
this.buffer.writeUInt16BE(packed, offset);
offset += 2;
// Data
data.copy(this.buffer, offset);
}
static fromBuffer(buffer) {
if (buffer.length < 7) {
throw new Error("Invalid CEMIPropertyWrite frame: too short");
}
const messageCode = buffer.readUInt8(0);
if (messageCode !== 0xf6) {
throw new Error("Invalid message code for CEMIPropertyWrite");
}
const interfaceObject = buffer.readUInt16BE(1);
const objectInstance = buffer.readUInt8(3);
const propertyId = buffer.readUInt8(4);
// Unpack number of elements and start index from 2 bytes
const packed = buffer.readUInt16BE(5);
const numberOfElements = (packed >> 12) & 0x0f;
const startIndex = packed & 0x0fff;
const data = buffer.subarray(7);
return new CEMIPropertyWrite(interfaceObject, objectInstance, propertyId, numberOfElements, startIndex, data);
}
get messageCode() {
return this.buffer.readUInt8(0);
}
get interfaceObject() {
return this.buffer.readUInt16BE(1);
}
get objectInstance() {
return this.buffer.readUInt8(3);
}
get propertyId() {
return this.buffer.readUInt8(4);
}
get numberOfElements() {
const packed = this.buffer.readUInt16BE(5);
return (packed >> 12) & 0x0f;
}
get startIndex() {
const packed = this.buffer.readUInt16BE(5);
return packed & 0x0fff;
}
get data() {
return this.buffer.subarray(7);
}
toBuffer() {
return Buffer.from(this.buffer);
}
isValid() {
return (this.buffer.length >= 7 &&
this.messageCode === cemi_1.CEMIMessageCode.M_PROP_WRITE_REQ &&
this.numberOfElements <= 15 &&
this.startIndex <= 4095);
}
}
exports.CEMIPropertyWrite = CEMIPropertyWrite;
/*
* Property Read Request message structure
* Same as write but without payload data
*/
class CEMIPropertyReadReq {
constructor(interfaceObject, objectInstance, propertyId, numberOfElements, startIndex) {
if (numberOfElements > 15) {
throw new Error("Number of elements cannot exceed 15 (4 bits)");
}
if (startIndex > 4095) {
throw new Error("Start index cannot exceed 4095 (12 bits)");
}
// Calculate buffer size: 1 (msg code) + 2 (interface obj) + 1 (obj instance) + 1 (prop id) + 2 (elements+index)
const bufferSize = 7;
this.buffer = Buffer.allocUnsafe(bufferSize);
let offset = 0;
// Message code - M_PROP_READ_REQ
this.buffer.writeUInt8(cemi_1.CEMIMessageCode.M_PROP_READ_REQ, offset++);
// Interface object (2 bytes, big endian)
this.buffer.writeUInt16BE(interfaceObject, offset);
offset += 2;
// Object Instance (1 byte)
this.buffer.writeUInt8(objectInstance, offset++);
// Property Id (1 byte)
this.buffer.writeUInt8(propertyId, offset++);
// Number of elements (4 bits) + start index (12 bits)
// Pack into 2 bytes: NNNN IIII IIII IIII
const packed = (numberOfElements << 12) | (startIndex & 0x0fff);
this.buffer.writeUInt16BE(packed, offset);
}
static fromBuffer(buffer) {
if (buffer.length < 7) {
throw new Error("Invalid CEMIPropertyReadReq frame: too short");
}
const messageCode = buffer.readUInt8(0);
if (messageCode !== cemi_1.CEMIMessageCode.M_PROP_READ_REQ) {
throw new Error("Invalid message code for CEMIPropertyReadReq");
}
const interfaceObject = buffer.readUInt16BE(1);
const objectInstance = buffer.readUInt8(3);
const propertyId = buffer.readUInt8(4);
// Unpack number of elements and start index from 2 bytes
const packed = buffer.readUInt16BE(5);
const numberOfElements = (packed >> 12) & 0x0f;
const startIndex = packed & 0x0fff;
return new CEMIPropertyReadReq(interfaceObject, objectInstance, propertyId, numberOfElements, startIndex);
}
get messageCode() {
return this.buffer.readUInt8(0);
}
get interfaceObject() {
return this.buffer.readUInt16BE(1);
}
get objectInstance() {
return this.buffer.readUInt8(3);
}
get propertyId() {
return this.buffer.readUInt8(4);
}
get numberOfElements() {
const packed = this.buffer.readUInt16BE(5);
return (packed >> 12) & 0x0f;
}
get startIndex() {
const packed = this.buffer.readUInt16BE(5);
return packed & 0x0fff;
}
toBuffer() {
return Buffer.from(this.buffer);
}
isValid() {
return (this.buffer.length >= 7 &&
this.messageCode === cemi_1.CEMIMessageCode.M_PROP_READ_REQ &&
this.numberOfElements <= 15 &&
this.startIndex <= 4095);
}
}
exports.CEMIPropertyReadReq = CEMIPropertyReadReq;
/*
* Property Read Confirmation message structure
* Same as read request but with M_PROP_READ_CON message code and includes data payload
*/
class CEMIPropertyReadCon {
constructor(interfaceObject, objectInstance, propertyId, numberOfElements, startIndex, data) {
if (numberOfElements > 15) {
throw new Error("Number of elements cannot exceed 15 (4 bits)");
}
if (startIndex > 4095) {
throw new Error("Start index cannot exceed 4095 (12 bits)");
}
// Calculate buffer size: 1 (msg code) + 2 (interface obj) + 1 (obj instance) + 1 (prop id) + 2 (elements+index) + data
const bufferSize = 7 + data.length;
this.buffer = Buffer.allocUnsafe(bufferSize);
let offset = 0;
// Message code - M_PROP_READ_CON
this.buffer.writeUInt8(cemi_1.CEMIMessageCode.M_PROP_READ_CON, offset++);
// Interface object (2 bytes, big endian)
this.buffer.writeUInt16BE(interfaceObject, offset);
offset += 2;
// Object Instance (1 byte)
this.buffer.writeUInt8(objectInstance, offset++);
// Property Id (1 byte)
this.buffer.writeUInt8(propertyId, offset++);
// Number of elements (4 bits) + start index (12 bits)
// Pack into 2 bytes: NNNN IIII IIII IIII
const packed = (numberOfElements << 12) | (startIndex & 0x0fff);
this.buffer.writeUInt16BE(packed, offset);
offset += 2;
// Data
data.copy(this.buffer, offset);
}
static fromBuffer(buffer) {
if (buffer.length < 7) {
throw new Error("Invalid CEMIPropertyReadCon frame: too short");
}
const messageCode = buffer.readUInt8(0);
if (messageCode !== cemi_1.CEMIMessageCode.M_PROP_READ_CON) {
throw new Error("Invalid message code for CEMIPropertyReadCon");
}
const interfaceObject = buffer.readUInt16BE(1);
const objectInstance = buffer.readUInt8(3);
const propertyId = buffer.readUInt8(4);
// Unpack number of elements and start index from 2 bytes
const packed = buffer.readUInt16BE(5);
const numberOfElements = (packed >> 12) & 0x0f;
const startIndex = packed & 0x0fff;
const data = buffer.subarray(7);
return new CEMIPropertyReadCon(interfaceObject, objectInstance, propertyId, numberOfElements, startIndex, data);
}
get messageCode() {
return this.buffer.readUInt8(0);
}
get interfaceObject() {
return this.buffer.readUInt16BE(1);
}
get objectInstance() {
return this.buffer.readUInt8(3);
}
get propertyId() {
return this.buffer.readUInt8(4);
}
get numberOfElements() {
const packed = this.buffer.readUInt16BE(5);
return (packed >> 12) & 0x0f;
}
get startIndex() {
const packed = this.buffer.readUInt16BE(5);
return packed & 0x0fff;
}
get data() {
return this.buffer.subarray(7);
}
toBuffer() {
return Buffer.from(this.buffer);
}
isValid() {
return (this.buffer.length >= 7 &&
this.messageCode === cemi_1.CEMIMessageCode.M_PROP_READ_CON &&
this.numberOfElements <= 15 &&
this.startIndex <= 4095);
}
}
exports.CEMIPropertyReadCon = CEMIPropertyReadCon;
//# sourceMappingURL=cemi-properties.js.map