From b4ae20b1cf63116b89ddc4add7b538227423ca2f Mon Sep 17 00:00:00 2001 From: evekto <36211178+evekto@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:19:43 +0100 Subject: [PATCH 1/3] Use require only with static paths This allows the library to be used in bundlers without friction. --- index.js | 10 ---------- src/dptlib/index.js | 40 ++++++++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/index.js b/index.js index 7fcc8cc..1cf6e7d 100644 --- a/index.js +++ b/index.js @@ -3,16 +3,6 @@ * (C) 2016-2017 Elias Karakoulakis */ -const path = require('path'); -const util = require('util'); -const log = require('log-driver').logger; - -const knx_path = path.join(__dirname, 'package.json'); -const pkginfo = require(knx_path); - -log.info(util.format('Loading %s: %s, version: %s', - pkginfo.name, pkginfo.description, pkginfo.version)); - exports.Connection = require('./src/Connection.js'); exports.Datapoint = require('./src/Datapoint.js'); exports.Devices = require('./src/devices'); diff --git a/src/dptlib/index.js b/src/dptlib/index.js index 2181a5a..8bdba2d 100644 --- a/src/dptlib/index.js +++ b/src/dptlib/index.js @@ -33,26 +33,34 @@ Unlimited string 8859_1 . DPT 24 DPT 24 List 3-byte value 3 Byte DPT 232 DPT 232 RGB[0,0,0]...[255,255,255] */ -const fs = require('fs'); -const path = require('path'); const util = require('util'); const log = require('log-driver').logger; const dpts = {}; -for (const entry of fs.readdirSync(__dirname)) { - const matches = entry.match(/(dpt.*)\.js/); - if (!matches) continue; - const dptid = matches[1].toUpperCase(); // DPT1..DPTxxx - const mod = require(__dirname + path.sep + entry); - if ( - !mod.hasOwnProperty('basetype') || - !mod.basetype.hasOwnProperty('bitlength') - ) - throw 'incomplete ' + dptid + ', missing basetype and/or bitlength!'; - mod.id = dptid; - dpts[dptid] = mod; - //log.trace('DPT library: loaded %s (%s)', dptid, dpts[dptid].basetype.desc); -} +dpts.DP1 = require('./dpt1.js'); +dpts.DP2 = require('./dpt2.js'); +dpts.DP3 = require('./dpt3.js'); +dpts.DP4 = require('./dpt4.js'); +dpts.DP5 = require('./dpt5.js'); +dpts.DP6 = require('./dpt6.js'); +dpts.DP7 = require('./dpt7.js'); +dpts.DP8 = require('./dpt8.js'); +dpts.DP9 = require('./dpt9.js'); +dpts.DP10 = require('./dpt10.js'); +dpts.DP11 = require('./dpt11.js'); +dpts.DP12 = require('./dpt12.js'); +dpts.DP13 = require('./dpt13.js'); +dpts.DP14 = require('./dpt14.js'); +dpts.DP15 = require('./dpt15.js'); +dpts.DP16 = require('./dpt16.js'); +dpts.DP17 = require('./dpt17.js'); +dpts.DP18 = require('./dpt18.js'); +dpts.DP19 = require('./dpt19.js'); +dpts.DP20 = require('./dpt20.js'); +dpts.DP21 = require('./dpt21.js'); +dpts.DP232 = require('./dpt232.js'); +dpts.DP237 = require('./dpt237.js'); +dpts.DP238 = require('./dpt238.js'); // a generic DPT resolution function // DPTs might come in as 9/"9"/"9.001"/"DPT9.001" From 6975e0cb5c4198c0262e21260d1c894f4b77801b Mon Sep 17 00:00:00 2001 From: evekto <36211178+evekto@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:22:50 +0100 Subject: [PATCH 2/3] Export dptlib This allows to parsing byte-arrays according to DPTs --- index.d.ts | 53 +++++++++++++++++++++++++++++++++++++++++++ index.js | 1 + src/dptlib/index.js | 55 ++++++++++++++++++++++++--------------------- 3 files changed, 83 insertions(+), 26 deletions(-) diff --git a/index.d.ts b/index.d.ts index ebb2f91..4158842 100644 --- a/index.d.ts +++ b/index.d.ts @@ -116,4 +116,57 @@ declare module "knx" { write(value: KnxValue): void; read(callback?: (src: KnxDeviceAddress, value: KnxValue) => void): void; } + + export interface DatapointSubtype { + scalar_range?: [number, number] + name: string + use?: string + desc: string + force_encoding?: string + unit?: string + enc?: Record + range?: [number, number] | [undefined, undefined] + } + + export interface DatapointType { + basetype: { + bitlength: number + signedness?: string + range?: [number, number] + valuetype: string + desc?: string + } + subtypes: Record + formatAPDU?: (value: any) => Buffer | void + fromBuffer?: (buf: Buffer) => KnxValue + } + + export class dptlib { + static DPT1: DatapointType + static DPT2: DatapointType + static DPT3: DatapointType + static DPT4: DatapointType + static DPT5: DatapointType + static DPT6: DatapointType + static DPT7: DatapointType + static DPT8: DatapointType + static DPT9: DatapointType + static DPT10: DatapointType + static DPT11: DatapointType + static DPT12: DatapointType + static DPT13: DatapointType + static DPT14: DatapointType + static DPT15: DatapointType + static DPT16: DatapointType + static DPT17: DatapointType + static DPT18: DatapointType + static DPT19: DatapointType + static DPT20: DatapointType + static DPT21: DatapointType + static DPT232: DatapointType + static DPT237: DatapointType + static DPT238: DatapointType + + static fromBuffer: (buf: Buffer, dpt: DatapointType, subtype?: DatapointSubtype) => KnxValue + } } diff --git a/index.js b/index.js index 1cf6e7d..5862e9b 100644 --- a/index.js +++ b/index.js @@ -7,3 +7,4 @@ exports.Connection = require('./src/Connection.js'); exports.Datapoint = require('./src/Datapoint.js'); exports.Devices = require('./src/devices'); exports.Log = require('./src/KnxLog.js'); +exports.dptlib = require('./src/dptlib/index.js'); diff --git a/src/dptlib/index.js b/src/dptlib/index.js index 8bdba2d..552c06b 100644 --- a/src/dptlib/index.js +++ b/src/dptlib/index.js @@ -37,30 +37,30 @@ const util = require('util'); const log = require('log-driver').logger; const dpts = {}; -dpts.DP1 = require('./dpt1.js'); -dpts.DP2 = require('./dpt2.js'); -dpts.DP3 = require('./dpt3.js'); -dpts.DP4 = require('./dpt4.js'); -dpts.DP5 = require('./dpt5.js'); -dpts.DP6 = require('./dpt6.js'); -dpts.DP7 = require('./dpt7.js'); -dpts.DP8 = require('./dpt8.js'); -dpts.DP9 = require('./dpt9.js'); -dpts.DP10 = require('./dpt10.js'); -dpts.DP11 = require('./dpt11.js'); -dpts.DP12 = require('./dpt12.js'); -dpts.DP13 = require('./dpt13.js'); -dpts.DP14 = require('./dpt14.js'); -dpts.DP15 = require('./dpt15.js'); -dpts.DP16 = require('./dpt16.js'); -dpts.DP17 = require('./dpt17.js'); -dpts.DP18 = require('./dpt18.js'); -dpts.DP19 = require('./dpt19.js'); -dpts.DP20 = require('./dpt20.js'); -dpts.DP21 = require('./dpt21.js'); -dpts.DP232 = require('./dpt232.js'); -dpts.DP237 = require('./dpt237.js'); -dpts.DP238 = require('./dpt238.js'); +dpts.DPT1 = require('./dpt1.js'); +dpts.DPT2 = require('./dpt2.js'); +dpts.DPT3 = require('./dpt3.js'); +dpts.DPT4 = require('./dpt4.js'); +dpts.DPT5 = require('./dpt5.js'); +dpts.DPT6 = require('./dpt6.js'); +dpts.DPT7 = require('./dpt7.js'); +dpts.DPT8 = require('./dpt8.js'); +dpts.DPT9 = require('./dpt9.js'); +dpts.DPT10 = require('./dpt10.js'); +dpts.DPT11 = require('./dpt11.js'); +dpts.DPT12 = require('./dpt12.js'); +dpts.DPT13 = require('./dpt13.js'); +dpts.DPT14 = require('./dpt14.js'); +dpts.DPT15 = require('./dpt15.js'); +dpts.DPT16 = require('./dpt16.js'); +dpts.DPT17 = require('./dpt17.js'); +dpts.DPT18 = require('./dpt18.js'); +dpts.DPT19 = require('./dpt19.js'); +dpts.DPT20 = require('./dpt20.js'); +dpts.DPT21 = require('./dpt21.js'); +dpts.DPT232 = require('./dpt232.js'); +dpts.DPT237 = require('./dpt237.js'); +dpts.DPT238 = require('./dpt238.js'); // a generic DPT resolution function // DPTs might come in as 9/"9"/"9.001"/"DPT9.001" @@ -162,7 +162,7 @@ dpts.populateAPDU = (value, apdu, dptid) => { * - or by this generic version, which: * -- 1) checks if the value adheres to the range set from the DPT's bitlength */ -dpts.fromBuffer = (buf, dpt) => { +dpts.fromBuffer = (buf, dpt, subtype) => { // sanity check if (!dpt) throw util.format('DPT %s not found', dpt); // get the raw APDU data for the given JS value @@ -187,10 +187,13 @@ dpts.fromBuffer = (buf, dpt) => { dpt.hasOwnProperty('subtype') && dpt.subtype.hasOwnProperty('scalar_range') ) { + subtype = dpt.subtype; + } + if (subtype && subtype.hasOwnProperty('scalar_range')) { const [r_min, r_max] = dpt.basetype.hasOwnProperty('range') ? dpt.basetype.range : [0, Math.pow(2, dpt.basetype.bitlength) - 1]; - const [s_min, s_max] = dpt.subtype.scalar_range; + const [s_min, s_max] = subtype.scalar_range; // convert value from its scalar representation // e.g. in DPT5.001, 50(%) => 0x7F , 100(%) => 0xFF const a = (s_max - s_min) / (r_max - r_min); From a4b5ace00588c40a4a3494aa4a94b21e46e40b77 Mon Sep 17 00:00:00 2001 From: evekto <36211178+evekto@users.noreply.github.com> Date: Tue, 3 Feb 2026 14:19:16 +0100 Subject: [PATCH 3/3] types: Export populateAPDU --- index.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.d.ts b/index.d.ts index 4158842..b8bfe89 100644 --- a/index.d.ts +++ b/index.d.ts @@ -168,5 +168,7 @@ declare module "knx" { static DPT238: DatapointType static fromBuffer: (buf: Buffer, dpt: DatapointType, subtype?: DatapointSubtype) => KnxValue + + static populateAPDU: (value: KnxValue, apdu: Object, dptid: string) => void } }