knx.ts 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +51 -21
  2. package/README.md +274 -61
  3. package/dist/@types/interfaces/connection.d.ts +80 -13
  4. package/dist/@types/interfaces/servers.d.ts +18 -0
  5. package/dist/@types/interfaces/servers.js +2 -0
  6. package/dist/connection/KNXService.d.ts +13 -30
  7. package/dist/connection/KNXService.js +4 -164
  8. package/dist/connection/KNXTunneling.d.ts +4 -4
  9. package/dist/connection/KNXTunneling.js +35 -62
  10. package/dist/connection/KNXUSBConnection.d.ts +20 -0
  11. package/dist/connection/KNXUSBConnection.js +358 -0
  12. package/dist/connection/KNXnetIPServer.d.ts +29 -12
  13. package/dist/connection/KNXnetIPServer.js +261 -83
  14. package/dist/connection/Router.d.ts +52 -32
  15. package/dist/connection/Router.js +225 -153
  16. package/dist/connection/TPUART.d.ts +8 -3
  17. package/dist/connection/TPUART.js +41 -37
  18. package/dist/connection/TunnelConnection.d.ts +3 -1
  19. package/dist/connection/TunnelConnection.js +6 -4
  20. package/dist/core/CEMI.d.ts +7 -2
  21. package/dist/core/CEMI.js +5 -8
  22. package/dist/core/EMI.d.ts +312 -200
  23. package/dist/core/EMI.js +511 -1007
  24. package/dist/core/KNXnetIPStructures.d.ts +10 -1
  25. package/dist/core/KNXnetIPStructures.js +15 -10
  26. package/dist/core/MessageCodeField.d.ts +1 -1
  27. package/dist/core/cache/GroupAddressCache.d.ts +57 -0
  28. package/dist/core/cache/GroupAddressCache.js +227 -0
  29. package/dist/core/data/KNXDataDecode.d.ts +2 -2
  30. package/dist/core/data/KNXDataDecode.js +198 -183
  31. package/dist/core/enum/EnumControlField.d.ts +0 -5
  32. package/dist/core/enum/EnumControlField.js +1 -7
  33. package/dist/core/enum/EnumControlFieldExtended.d.ts +1 -1
  34. package/dist/core/enum/EnumShortACKFrame.d.ts +1 -1
  35. package/dist/core/enum/ErrorCodeSet.js +59 -0
  36. package/dist/core/enum/KNXnetIPEnum.d.ts +2 -2
  37. package/dist/core/enum/KNXnetIPEnum.js +19 -1
  38. package/dist/core/layers/data/NPDU.d.ts +2 -1
  39. package/dist/core/layers/data/NPDU.js +6 -3
  40. package/dist/index.d.ts +19 -2
  41. package/dist/index.js +36 -1
  42. package/dist/server/KNXMQTTGateway.d.ts +13 -0
  43. package/dist/server/KNXMQTTGateway.js +164 -0
  44. package/dist/server/KNXWebSocketServer.d.ts +12 -0
  45. package/dist/server/KNXWebSocketServer.js +118 -0
  46. package/dist/utils/CEMIAdapter.d.ts +4 -3
  47. package/dist/utils/CEMIAdapter.js +26 -30
  48. package/dist/utils/Logger.d.ts +4 -4
  49. package/dist/utils/Logger.js +3 -7
  50. package/package.json +27 -7
@@ -1,4 +1,4 @@
1
- import { LoggerOptions } from "pino";
1
+ import pino from "pino";
2
2
  import { ConnectionType } from "../../core/enum/KNXnetIPEnum";
3
3
  /**
4
4
  * Options for configuring a KNX Tunneling connection.
@@ -29,7 +29,9 @@ export interface KNXTunnelingOptions extends KNXnetIPOptions {
29
29
  */
30
30
  maxQueueSize?: number;
31
31
  }
32
- export interface KNXnetIPServerOptions extends KNXnetIPOptions {
32
+ export interface KNXnetIPServerOptions extends Omit<KNXnetIPOptions, "ip" | "port"> {
33
+ ip?: string;
34
+ port?: number;
33
35
  individualAddress?: string;
34
36
  serialNumber?: Buffer;
35
37
  friendlyName?: string;
@@ -46,10 +48,6 @@ export interface KNXnetIPServerOptions extends KNXnetIPOptions {
46
48
  * Setting this to a lower value can increase performance but may flood slow KNX segments.
47
49
  */
48
50
  routingDelay?: number;
49
- /**
50
- * Optional configuration for bridging to external connections (TPUART, Tunneling).
51
- */
52
- externals?: ExternalManagerOptions;
53
51
  /**
54
52
  * It abruptly stops a Tunneling client connection if it exceeds this limit of request messages per second; this is done to prevent performance degradation (the default is 100); to disable it, set it to less than 1
55
53
  */
@@ -62,6 +60,10 @@ export interface KNXnetIPServerOptions extends KNXnetIPOptions {
62
60
  useAllInterfaces?: boolean;
63
61
  }
64
62
  export interface ExternalManagerOptions {
63
+ /**
64
+ * Optional configuration for a KNXnetIPServer
65
+ */
66
+ knxNetIpServer?: KNXnetIPServerOptions;
65
67
  /**
66
68
  * Optional configuration for a physical TPUART connection.
67
69
  */
@@ -70,12 +72,16 @@ export interface ExternalManagerOptions {
70
72
  * Optional list of outbound KNX IP Tunneling client connections.
71
73
  */
72
74
  tunneling?: KNXTunnelingOptions[];
75
+ /**
76
+ * Optional configuration for a physical KNX USB connection.
77
+ */
78
+ usb?: KNXUSBOptions;
73
79
  /**
74
80
  * Pino logger configuration for the Router bridge.
75
81
  */
76
- logOptions?: LoggerOptions;
82
+ logOptions?: KNXLoggerOptions;
77
83
  }
78
- export interface KNXLoggerOptions extends LoggerOptions {
84
+ export interface KNXLoggerOptions extends pino.LoggerOptions {
79
85
  /**
80
86
  * Use pino-pretty but it's slow
81
87
  */
@@ -110,8 +116,8 @@ export interface KNXLoggerOptions extends LoggerOptions {
110
116
  logKeepCount?: number;
111
117
  }
112
118
  export interface KNXnetIPOptions {
113
- ip?: string;
114
- port?: number;
119
+ ip: string;
120
+ port: number;
115
121
  localIp?: string;
116
122
  localPort?: number;
117
123
  /**
@@ -119,15 +125,15 @@ export interface KNXnetIPOptions {
119
125
  */
120
126
  logOptions?: KNXLoggerOptions;
121
127
  }
122
- export interface TPUARTOptions extends KNXnetIPOptions {
128
+ export interface TPUARTOptions {
123
129
  /**
124
130
  * The serial port path (e.g., "/dev/ttyS0" or "COM3").
125
131
  */
126
132
  path: string;
127
133
  /**
128
- * Optional physical address to assign to the TPUART chip (e.g., "1.1.255").
134
+ * Physical address to assign to the TPUART chip (e.g., "1.1.255").
129
135
  */
130
- individualAddress?: string;
136
+ individualAddress: string;
131
137
  /**
132
138
  * If true, the TPUART will send an ACK for all group telegrams.
133
139
  */
@@ -136,4 +142,65 @@ export interface TPUARTOptions extends KNXnetIPOptions {
136
142
  * If true, the TPUART will send an ACK for all individual telegrams.
137
143
  */
138
144
  ackIndividual?: boolean;
145
+ /**
146
+ * Pino logger configuration.
147
+ */
148
+ logOptions?: KNXLoggerOptions;
149
+ }
150
+ export interface RouterConnOptions extends ExternalManagerOptions {
151
+ routerAddress: string;
152
+ /**
153
+ * Filtering IP addresses from KNXnetIP to other interfaces such as TPUART or USB
154
+ */
155
+ toLocalFilter?: {
156
+ individualAddress?: {
157
+ addresses: string[];
158
+ individualAddressToLocalFilterPolicie: "discard all" | "accept only";
159
+ };
160
+ groupAddress?: {
161
+ addresses: string[];
162
+ groupAddressToLocalFilterPolicie: "discard all" | "accept only";
163
+ };
164
+ };
165
+ /**
166
+ * Filtering addresses from interfaces such as TP UART or USB to KNXnet IP
167
+ */
168
+ toIpFilter?: {
169
+ individualAddress?: {
170
+ addresses: string[];
171
+ individualAddressToIpFilterPolicie: "discard all" | "accept only";
172
+ };
173
+ groupAddress?: {
174
+ addresses: string[];
175
+ groupAddressToIpFilterPolicie: "discard all" | "accept only";
176
+ };
177
+ };
178
+ }
179
+ export interface KNXUSBOptions {
180
+ path?: string;
181
+ vendorId?: number;
182
+ productId?: number;
183
+ individualAddress: string;
184
+ /**
185
+ * Pino logger configuration.
186
+ */
187
+ logOptions?: KNXLoggerOptions;
188
+ }
189
+ export type AllConnectionOptions = TPUARTOptions | KNXUSBOptions | KNXnetIPServerOptions | KNXTunnelingOptions;
190
+ /**
191
+ * Interface for a discovered KNXnet/IP device.
192
+ */
193
+ export interface KNXDiscoveredDevice {
194
+ ip: string;
195
+ port: number;
196
+ knxMediumRaw: number;
197
+ knxMedium: string;
198
+ deviceStatusRaw: number;
199
+ deviceStatus: string;
200
+ individualAddress: number;
201
+ projectInstallationId: number;
202
+ serialNumber: Buffer;
203
+ routingMulticastAddress: string;
204
+ macAddress: string;
205
+ friendlyName: string;
139
206
  }
@@ -0,0 +1,18 @@
1
+ import { KNXnetIPServer } from "../../connection/KNXnetIPServer";
2
+ import { KNXService } from "../../connection/KNXService";
3
+ import { Router } from "../../connection/Router";
4
+ export interface MQTTGatewayOptions {
5
+ knxContext: Router | KNXnetIPServer;
6
+ embeddedBroker?: {
7
+ port: number;
8
+ host?: string;
9
+ };
10
+ brokerUrl?: string;
11
+ mqttUsername?: string;
12
+ mqttPassword?: string;
13
+ topicPrefix?: string;
14
+ }
15
+ export interface WebSocketGatewayOptions {
16
+ port: number;
17
+ knxContext: KNXService;
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,35 +1,31 @@
1
1
  import { EventEmitter } from "events";
2
2
  import dgram from "dgram";
3
3
  import net from "net";
4
- import { SRP } from "../core/KNXnetIPStructures";
5
- import { ServiceMessage } from "../@types/interfaces/ServiceMessage";
6
4
  import { KnxDataEncoder } from "../core/data/KNXDataEncode";
5
+ import { CEMIInstance } from "../core/CEMI";
7
6
  import { AllDpts } from "../@types/types/AllDpts";
8
- import { KNXnetIPOptions, KNXnetIPServerOptions, KNXTunnelingOptions, TPUARTOptions } from "../@types/interfaces/connection";
7
+ import { AllConnectionOptions } from "../@types/interfaces/connection";
9
8
  import { Logger } from "pino";
10
- export declare abstract class KNXService extends EventEmitter {
9
+ export declare abstract class KNXService<TOptions extends AllConnectionOptions = AllConnectionOptions> extends EventEmitter {
11
10
  protected socket: dgram.Socket | net.Socket | null;
12
- readonly options: KNXnetIPOptions | KNXnetIPServerOptions | KNXTunnelingOptions | TPUARTOptions;
11
+ readonly options: TOptions;
13
12
  protected _transport: "UDP" | "TCP";
14
13
  protected logger: Logger;
15
- constructor(options?: KNXnetIPOptions | KNXnetIPServerOptions | KNXTunnelingOptions | TPUARTOptions);
16
- abstract connect(): Promise<void>;
17
- abstract disconnect(): void;
18
- abstract send(data: Buffer | ServiceMessage): Promise<void>;
14
+ individualAddress: string;
15
+ constructor(options?: TOptions);
19
16
  /**
20
- * Optional: Enable or disable busmonitor mode.
17
+ * Start the connection
21
18
  */
22
- setBusmonitor?(enabled: boolean): Promise<void>;
19
+ abstract connect(): Promise<void>;
23
20
  /**
24
- * Optional: Overriden by links that support selective routing (knxd pattern).
25
- * Return false to block a specific group address.
21
+ * Safe disconnection of the connection
26
22
  */
27
- shouldFilterGroup?(groupAddress: string): boolean;
23
+ abstract disconnect(): void;
28
24
  /**
29
- * Optional: Overriden by links that support selective routing (knxd pattern).
30
- * Return false to block a specific individual address.
25
+ * Send a telegram
26
+ * @param data A data buffer CEMI or EMI or an instance of a CEMI message
31
27
  */
32
- shouldFilterIA?(individualAddress: string): boolean;
28
+ abstract send(data: Buffer | CEMIInstance): Promise<void>;
33
29
  /**
34
30
  * Send a GroupValue_Write telegram to a group address.
35
31
  * @param destination The group address (e.g., "1/1/1")
@@ -42,17 +38,4 @@ export declare abstract class KNXService extends EventEmitter {
42
38
  * @param destination The group address (e.g., "1/1/1")
43
39
  */
44
40
  read(destination: string): Promise<void>;
45
- /**
46
- * Discovery Process (Search Request)
47
- */
48
- static discover(timeout?: number, localIp?: string): Promise<any[]>;
49
- /**
50
- * Extended Discovery Process (Search Request Extended)
51
- * Allows searching with filters (SRPs).
52
- */
53
- static discoverExtended(srps: SRP[], timeout?: number, localIp?: string): Promise<any[]>;
54
- /**
55
- * Description Request (Self Description) * Queries a specific device for its capabilities.
56
- */
57
- describe(): Promise<any>;
58
41
  }
@@ -1,14 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.KNXService = void 0;
7
4
  const events_1 = require("events");
8
- const dgram_1 = __importDefault(require("dgram"));
9
- const KNXnetIPHeader_1 = require("../core/KNXnetIPHeader");
10
- const KNXnetIPStructures_1 = require("../core/KNXnetIPStructures");
11
- const KNXnetIPEnum_1 = require("../core/enum/KNXnetIPEnum");
12
5
  const localIp_1 = require("../utils/localIp");
13
6
  const KNXDataEncode_1 = require("../core/data/KNXDataEncode");
14
7
  const CEMI_1 = require("../core/CEMI");
@@ -20,19 +13,15 @@ const APDU_1 = require("../core/layers/data/APDU");
20
13
  const APCI_1 = require("../core/layers/interfaces/APCI");
21
14
  const APCIEnum_1 = require("../core/enum/APCIEnum");
22
15
  const Logger_1 = require("../utils/Logger");
23
- const KNXnetIPServer_1 = require("./KNXnetIPServer");
24
- const KNXHelper_1 = require("../utils/KNXHelper");
25
- const InvalidKnxAddresExeption_1 = require("../errors/InvalidKnxAddresExeption");
26
16
  class KNXService extends events_1.EventEmitter {
27
17
  socket = null;
28
18
  options;
29
19
  _transport = "UDP";
30
20
  logger;
21
+ individualAddress = "1.0.1";
31
22
  constructor(options = {}) {
32
23
  super();
33
24
  this.options = {
34
- ip: "224.0.23.12",
35
- port: 3671,
36
25
  localIp: (0, localIp_1.getLocalIP)(),
37
26
  localPort: 0,
38
27
  ...options,
@@ -71,20 +60,10 @@ class KNXService extends events_1.EventEmitter {
71
60
  else {
72
61
  throw new Error("Cannot encode value without DPT or basic type (boolean/number/Buffer)");
73
62
  }
74
- let cf2Value = 0;
75
- if (KNXHelper_1.KNXHelper.isValidGroupAddress(destination)) {
76
- cf2Value = 0xe0;
77
- }
78
- else if (KNXHelper_1.KNXHelper.isValidIndividualAddress(destination)) {
79
- cf2Value = 0x60;
80
- }
81
- else {
82
- throw new InvalidKnxAddresExeption_1.InvalidKnxAddressException(`This address ${destination} is not valid`);
83
- }
84
63
  const cf1 = new ControlField_1.ControlField(0xbc);
85
- const cf2 = new ControlFieldExtended_1.ExtendedControlField(cf2Value);
64
+ const cf2 = new ControlFieldExtended_1.ExtendedControlField(0xe0);
86
65
  const tpdu = new TPDU_1.TPDU(new TPCI_1.TPCI(TPCI_1.TPCIType.T_DATA_GROUP_PDU), new APDU_1.APDU(new TPCI_1.TPCI(TPCI_1.TPCIType.T_DATA_GROUP_PDU), new APCI_1.APCI(APCIEnum_1.APCIEnum.A_GroupValue_Write_Protocol_Data_Unit), data, isShort), data);
87
- const cemi = new CEMI_1.CEMI.DataLinkLayerCEMI["L_Data.req"](null, cf1, cf2, this instanceof KNXnetIPServer_1.KNXnetIPServer ? this.individualAddress : "0.0.0", destination, tpdu);
66
+ const cemi = new CEMI_1.CEMI.DataLinkLayerCEMI["L_Data.req"](null, cf1, cf2, this.individualAddress, destination, tpdu);
88
67
  this.logger.debug({ service: cemi.constructor.name }, "Sending GroupValue_Write");
89
68
  return this.send(cemi);
90
69
  }
@@ -95,148 +74,9 @@ class KNXService extends events_1.EventEmitter {
95
74
  async read(destination) {
96
75
  const cf1 = new ControlField_1.ControlField(0xbc);
97
76
  const cf2 = new ControlFieldExtended_1.ExtendedControlField(0xe0);
98
- const tpdu = new TPDU_1.TPDU(new TPCI_1.TPCI(TPCI_1.TPCIType.T_DATA_GROUP_PDU), new APDU_1.APDU(new TPCI_1.TPCI(TPCI_1.TPCIType.T_DATA_GROUP_PDU), new APCI_1.APCI(APCIEnum_1.APCIEnum.A_GroupValue_Read_Protocol_Data_Unit), Buffer.alloc(0)), Buffer.alloc(0));
77
+ const tpdu = new TPDU_1.TPDU(new TPCI_1.TPCI(TPCI_1.TPCIType.T_DATA_GROUP_PDU), new APDU_1.APDU(new TPCI_1.TPCI(TPCI_1.TPCIType.T_DATA_GROUP_PDU), new APCI_1.APCI(APCIEnum_1.APCIEnum.A_GroupValue_Read_Protocol_Data_Unit), Buffer.alloc(1)), Buffer.alloc(1));
99
78
  const cemi = new CEMI_1.CEMI.DataLinkLayerCEMI["L_Data.req"](null, cf1, cf2, "0.0.0", destination, tpdu);
100
79
  return this.send(cemi);
101
80
  }
102
- /**
103
- * Discovery Process (Search Request)
104
- */
105
- static async discover(timeout = 3000, localIp) {
106
- return new Promise((resolve, reject) => {
107
- const socket = dgram_1.default.createSocket("udp4");
108
- const devices = [];
109
- const _localIp = localIp || (0, localIp_1.getLocalIP)();
110
- socket.on("message", (msg, rinfo) => {
111
- try {
112
- const header = KNXnetIPHeader_1.KNXnetIPHeader.fromBuffer(msg);
113
- if (header.serviceType === KNXnetIPEnum_1.KNXnetIPServiceType.SEARCH_RESPONSE) {
114
- const hpaiData = msg.subarray(6, 14);
115
- const hpai = KNXnetIPStructures_1.HPAI.fromBuffer(hpaiData);
116
- // Parse DIBs starting from byte 14
117
- const dibs = [];
118
- let offset = 14;
119
- while (offset < msg.length) {
120
- const dibLen = msg.readUInt8(offset);
121
- if (offset + dibLen > msg.length)
122
- break;
123
- const dibBuffer = msg.subarray(offset, offset + dibLen);
124
- dibs.push(KNXnetIPStructures_1.DIB.fromBuffer(dibBuffer));
125
- offset += dibLen;
126
- }
127
- devices.push({
128
- ip: hpai.ipAddress,
129
- port: hpai.port,
130
- dibs,
131
- });
132
- }
133
- }
134
- catch (e) {
135
- // Ignore malformed packets
136
- }
137
- });
138
- socket.bind(() => {
139
- const localHPAI = new KNXnetIPStructures_1.HPAI(KNXnetIPEnum_1.HostProtocolCode.IPV4_UDP, _localIp, socket.address().port);
140
- const header = new KNXnetIPHeader_1.KNXnetIPHeader(KNXnetIPEnum_1.KNXnetIPServiceType.SEARCH_REQUEST, 0);
141
- const hpaiBuffer = localHPAI.toBuffer();
142
- header.totalLength = header.toBuffer().length + hpaiBuffer.length;
143
- const packet = Buffer.concat([header.toBuffer(), hpaiBuffer]);
144
- // Send to Multicast Address
145
- socket.send(packet, 3671, "224.0.23.12");
146
- setTimeout(() => {
147
- socket.close();
148
- resolve(devices);
149
- }, timeout);
150
- });
151
- });
152
- }
153
- /**
154
- * Extended Discovery Process (Search Request Extended)
155
- * Allows searching with filters (SRPs).
156
- */
157
- static async discoverExtended(srps, timeout = 3000, localIp) {
158
- return new Promise((resolve, reject) => {
159
- const socket = dgram_1.default.createSocket("udp4");
160
- const devices = [];
161
- const _localIp = localIp || (0, localIp_1.getLocalIP)();
162
- socket.on("message", (msg, rinfo) => {
163
- try {
164
- const header = KNXnetIPHeader_1.KNXnetIPHeader.fromBuffer(msg);
165
- if (header.serviceType === KNXnetIPEnum_1.KNXnetIPServiceType.SEARCH_RESPONSE ||
166
- header.serviceType === KNXnetIPEnum_1.KNXnetIPServiceType.SEARCH_RESPONSE_EXTENDED) {
167
- // Extract IP/Port from HPAI
168
- const hpai = KNXnetIPStructures_1.HPAI.fromBuffer(msg.subarray(6, 14));
169
- const dibs = [];
170
- let offset = 14;
171
- while (offset < msg.length) {
172
- const dibLen = msg.readUInt8(offset);
173
- if (dibLen === 0)
174
- break;
175
- dibs.push(KNXnetIPStructures_1.DIB.fromBuffer(msg.subarray(offset, offset + dibLen)));
176
- offset += dibLen;
177
- }
178
- devices.push({ ip: hpai.ipAddress, port: hpai.port, dibs });
179
- }
180
- }
181
- catch (e) { }
182
- });
183
- socket.bind(() => {
184
- const localHPAI = new KNXnetIPStructures_1.HPAI(KNXnetIPEnum_1.HostProtocolCode.IPV4_UDP, _localIp, socket.address().port);
185
- const header = new KNXnetIPHeader_1.KNXnetIPHeader(KNXnetIPEnum_1.KNXnetIPServiceType.SEARCH_REQUEST_EXTENDED, 0);
186
- const hpaiBuf = localHPAI.toBuffer();
187
- const srpBufs = srps.map((s) => s.toBuffer());
188
- const body = Buffer.concat([hpaiBuf, ...srpBufs]);
189
- header.totalLength = 6 + body.length;
190
- socket.send(Buffer.concat([header.toBuffer(), body]), 3671, "224.0.23.12");
191
- setTimeout(() => {
192
- socket.close();
193
- resolve(devices);
194
- }, timeout);
195
- });
196
- });
197
- }
198
- /**
199
- * Description Request (Self Description) * Queries a specific device for its capabilities.
200
- */
201
- async describe() {
202
- return new Promise((resolve, reject) => {
203
- // Description is usually connectionless via UDP on the Control Endpoint
204
- const descSocket = dgram_1.default.createSocket("udp4");
205
- const targetIp = this.options.ip;
206
- const targetPort = this.options.port;
207
- const timeout = setTimeout(() => {
208
- descSocket.close();
209
- reject(new Error("Description request timed out"));
210
- }, 2000);
211
- descSocket.on("message", (msg) => {
212
- try {
213
- const header = KNXnetIPHeader_1.KNXnetIPHeader.fromBuffer(msg);
214
- if (header.serviceType === KNXnetIPEnum_1.KNXnetIPServiceType.DESCRIPTION_RESPONSE) {
215
- clearTimeout(timeout);
216
- // Similar parsing logic as Discovery
217
- const dibs = [];
218
- let offset = 6; // Header length
219
- while (offset < msg.length) {
220
- const dibLen = msg.readUInt8(offset);
221
- const dibBuffer = msg.subarray(offset, offset + dibLen);
222
- dibs.push(KNXnetIPStructures_1.DIB.fromBuffer(dibBuffer));
223
- offset += dibLen;
224
- }
225
- descSocket.close();
226
- resolve({ dibs });
227
- }
228
- }
229
- catch (e) { }
230
- });
231
- descSocket.bind(() => {
232
- const localHPAI = new KNXnetIPStructures_1.HPAI(KNXnetIPEnum_1.HostProtocolCode.IPV4_UDP, this.options.localIp, descSocket.address().port);
233
- const header = new KNXnetIPHeader_1.KNXnetIPHeader(KNXnetIPEnum_1.KNXnetIPServiceType.DESCRIPTION_REQUEST, 0);
234
- const hpaiBuffer = localHPAI.toBuffer();
235
- header.totalLength = 6 + hpaiBuffer.length;
236
- const packet = Buffer.concat([header.toBuffer(), hpaiBuffer]);
237
- descSocket.send(packet, targetPort, targetIp);
238
- });
239
- });
240
- }
241
81
  }
242
82
  exports.KNXService = KNXService;
@@ -1,18 +1,18 @@
1
1
  import { KNXService } from "./KNXService";
2
- import { ServiceMessage } from "../@types/interfaces/ServiceMessage";
2
+ import { CEMIInstance } from "../core/CEMI";
3
3
  import { KNXTunnelingOptions } from "../@types/interfaces/connection";
4
4
  /**
5
5
  * Handles KNXnet/IP Tunneling connections for point-to-point communication with a KNX gateway.
6
6
  * This class manages the connection state, sequence numbering for reliable delivery,
7
7
  * heartbeat monitoring (ConnectionState), and message queuing over both UDP and TCP transports.
8
8
  */
9
- export declare class KNXTunneling extends KNXService {
9
+ export declare class KNXTunneling extends KNXService<KNXTunnelingOptions> {
10
10
  private channelId;
11
11
  private sequenceNumber;
12
12
  private rxSequenceNumber;
13
13
  private isConnected;
14
14
  private tcpBuffer;
15
- assignedAddress: number;
15
+ individualAddress: string;
16
16
  private heartbeatTimer;
17
17
  private heartbeatFailures;
18
18
  private heartbeatRetryTimer;
@@ -29,7 +29,7 @@ export declare class KNXTunneling extends KNXService {
29
29
  private sendConnectRequest;
30
30
  disconnect(): void;
31
31
  private closeSocket;
32
- send(cemi: ServiceMessage | Buffer): Promise<void>;
32
+ send(cemi: CEMIInstance | Buffer): Promise<void>;
33
33
  private processQueue;
34
34
  private handleAckTimeout;
35
35
  getFeature(featureId: number): Promise<Buffer>;