node-red-contrib-knx-ultimate 4.3.2 → 4.3.5

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.
@@ -136,6 +136,7 @@ module.exports = function (RED) {
136
136
  }
137
137
  const mode = (req.body && req.body.mode ? String(req.body.mode) : 'read').toLowerCase()
138
138
  const grpaddr = targetNode.topic
139
+ const isRawMode = typeof targetNode.dpt === 'string' && targetNode.dpt.trim().toLowerCase() === 'raw'
139
140
  if (mode !== 'read') {
140
141
  if (!grpaddr || String(grpaddr).trim() === '') {
141
142
  res.status(400).json({ error: 'Group address not set' })
@@ -145,6 +146,10 @@ module.exports = function (RED) {
145
146
  res.status(400).json({ error: 'Datapoint not defined for this node' })
146
147
  return
147
148
  }
149
+ if (isRawMode) {
150
+ res.status(400).json({ error: 'Manual write is not available when the node datapoint is set to raw' })
151
+ return
152
+ }
148
153
  }
149
154
 
150
155
  if (mode === 'read') {
@@ -299,7 +304,7 @@ module.exports = function (RED) {
299
304
  const payloadRounder = require('./utils/payloadManipulation')
300
305
  const dptlib = require('knxultimate').dptlib
301
306
 
302
- function knxUltimate (config) {
307
+ function knxUltimate(config) {
303
308
  RED.nodes.createNode(this, config)
304
309
  const node = this
305
310
  node.serverKNX = RED.nodes.getNode(config.server) || undefined
@@ -365,7 +370,7 @@ module.exports = function (RED) {
365
370
  // Get the Group Address from various sources
366
371
  if (config.setTopicType === undefined || config.setTopicType === 'str') {
367
372
  node.topic = config.topic
368
- node.dpt = config.dpt || '1.001'
373
+ node.dpt = (config.dpt === undefined || config.dpt === '') ? '1.001' : config.dpt
369
374
  } else if (config.setTopicType === 'flow') {
370
375
  try {
371
376
  node.topic = node.context().flow.get(config.topic)
@@ -467,6 +472,7 @@ module.exports = function (RED) {
467
472
  if (node.listenallga === true) return
468
473
  if (typeof node.topic !== 'string' || node.topic === '') return
469
474
  if (typeof node.dpt !== 'string' || node.dpt === '' || node.dpt === 'auto') return
475
+ if (node.dpt.trim().toLowerCase() === 'raw') return
470
476
 
471
477
  node.serverKNX.sendKNXTelegramToKNXEngine({
472
478
  grpaddr: node.topic,
@@ -500,36 +506,61 @@ module.exports = function (RED) {
500
506
  }
501
507
 
502
508
  // Used in the KNX Function TAB
503
- const getGAValue = function getGAValue (_ga = undefined, _dpt = undefined) {
504
- try {
505
- if (_ga === undefined) return
506
- // The GA can have the devicename as well, separated by a blank space (1/1/0 light table ovest),
507
- // I must take the GA only
508
- const blankSpacePosition = _ga.indexOf(' ')
509
- if (blankSpacePosition > -1) _ga = _ga.substring(0, blankSpacePosition)
510
- // Is there a GA in the server's exposedGAs?
511
- const found = node.serverKNX.exposedGAs.find(a => a.ga === _ga)
509
+ const getGAValue = async function getGAValue(_ga = undefined, _dpt = undefined) {
510
+ if (_ga === undefined) return null
511
+ // Strip devicename if present (e.g. "1/1/1 Light name" → "1/1/1")
512
+ const blankSpacePosition = _ga.indexOf(' ')
513
+ if (blankSpacePosition > -1) _ga = _ga.substring(0, blankSpacePosition)
514
+
515
+ const tryDecode = (rawValue, dpt) => {
516
+ try {
517
+ if (rawValue === null || rawValue === undefined) return undefined
518
+ return dptlib.fromBuffer(rawValue, dptlib.resolve(dpt))
519
+ } catch (_e) { return undefined }
520
+ }
521
+
522
+ const sendRead = () => {
523
+ try {
524
+ node.serverKNX.sendKNXTelegramToKNXEngine({
525
+ grpaddr: _ga, payload: '', dpt: '', outputtype: 'read', nodecallerid: node.id
526
+ })
527
+ RED.log.warn('getGAValue: sent groupvalue_read for ' + _ga)
528
+ } catch (e) {
529
+ RED.log.error('getGAValue: failed to send read for ' + _ga + ': ' + e.message)
530
+ }
531
+ }
532
+
533
+ // Check cache first
534
+ let found = node.serverKNX.exposedGAs.find(a => a.ga === _ga)
535
+ if (found !== undefined) {
536
+ const dptFinal = _dpt || found.dpt
537
+ if (!dptFinal) {
538
+ RED.log.error('getGAValue: no DPT for ' + _ga + '. Provide it as second parameter.')
539
+ return null
540
+ }
541
+ const val = tryDecode(found.rawValue, dptFinal)
542
+ if (val !== undefined) return val
543
+ // rawValue present but decode failed (bad format) — fall through to read
544
+ RED.log.warn('getGAValue: cached rawValue for ' + _ga + ' could not be decoded, sending read request')
545
+ }
546
+
547
+ // Not cached or decode failed: send read and poll up to 3 seconds
548
+ sendRead()
549
+ for (let i = 0; i < 30; i++) {
550
+ await new Promise(resolve => setTimeout(resolve, 100))
551
+ found = node.serverKNX.exposedGAs.find(a => a.ga === _ga)
512
552
  if (found !== undefined) {
513
- if (_dpt === undefined && found.dpt === undefined) {
514
- const errM = 'getGaValue: node ID:' + node.id + ' ' + 'No CSV file imported. Please provide the dpt manually'
515
- RED.log.error(errM)
516
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(errM)
517
- return
518
- };
519
- return dptlib.fromBuffer(found.rawValue, dptlib.resolve(_dpt || found.dpt))
520
- } else {
521
- const errM = 'getGaValue: node ID:' + node.id + ' ' + 'Group Address not yet read, try later.'
522
- RED.log.error(errM)
523
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(errM)
553
+ const dptFinal = _dpt || found.dpt
554
+ if (!dptFinal) return null
555
+ const val = tryDecode(found.rawValue, dptFinal)
556
+ if (val !== undefined) return val
524
557
  }
525
- } catch (error) {
526
- const errM = 'getGaValue: node ID:' + node.id + ' ' + error.stack
527
- RED.log.error(errM)
528
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(errM)
529
558
  }
559
+ RED.log.warn('getGAValue: no response from KNX bus for ' + _ga + ' within 3 seconds')
560
+ return null
530
561
  }
531
562
  // Used in the KNX Function TAB
532
- const setGAValue = function setGAValue (_ga = undefined, _value = undefined, _dpt = undefined) {
563
+ const setGAValue = function setGAValue(_ga = undefined, _value = undefined, _dpt = undefined) {
533
564
  try {
534
565
  if (_ga === undefined) return
535
566
  // The GA can have the devicename as well, separated by a blank space (1/1/0 light table ovest),
@@ -556,7 +587,7 @@ module.exports = function (RED) {
556
587
  }
557
588
  }
558
589
  // Used in the KNX Function TAB
559
- const self = function self (_value) {
590
+ const self = function self(_value) {
560
591
  try {
561
592
  node.serverKNX.sendKNXTelegramToKNXEngine({
562
593
  grpaddr: node.topic, payload: _value, dpt: node.dpt, outputtype: 'write', nodecallerid: node.id
@@ -568,7 +599,7 @@ module.exports = function (RED) {
568
599
  }
569
600
  }
570
601
  // Used in the KNX Function TAB
571
- const toggle = function toggle () {
602
+ const toggle = function toggle() {
572
603
  if (node.currentPayload === true || node.currentPayload === false) {
573
604
  try {
574
605
  node.serverKNX.sendKNXTelegramToKNXEngine({
@@ -583,7 +614,7 @@ module.exports = function (RED) {
583
614
  }
584
615
 
585
616
  // This function is called by the knx-ultimate config node, to output a msg.payload.
586
- node.handleSend = (msg) => {
617
+ node.handleSend = async (msg) => {
587
618
  // 27/03/2020 can i merge the last input msg arrived, with the output?
588
619
  try {
589
620
  if (node.passthrough === 'yes') {
@@ -613,8 +644,8 @@ module.exports = function (RED) {
613
644
  // -+++++++++++++++++++++++++++++++++++++++++++
614
645
  if (node.receiveMsgFromKNXCode !== undefined) {
615
646
  try {
616
- const receiveMsgFromKNXCode = new Function('msg', 'getGAValue', 'node', 'RED', 'self', 'toggle', 'setGAValue', node.receiveMsgFromKNXCode)
617
- msg = receiveMsgFromKNXCode(msg, getGAValue, node, RED, self, toggle, setGAValue)
647
+ const receiveMsgFromKNXCode = (new (Object.getPrototypeOf(async function () { }).constructor)('msg', 'getGAValue', 'node', 'RED', 'self', 'toggle', 'setGAValue', node.receiveMsgFromKNXCode))
648
+ msg = await receiveMsgFromKNXCode(msg, getGAValue, node, RED, self, toggle, setGAValue)
618
649
  } catch (error) {
619
650
  RED.log.error('knxUltimate: receiveMsgFromKNXCode: node ID:' + node.id + ' ' + error.message)
620
651
  if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`receiveMsgFromKNXCode: node id ${node.id} ` || ' ' + error.stack)
@@ -631,7 +662,7 @@ module.exports = function (RED) {
631
662
  if (msg !== undefined) node.send(msg)
632
663
  }
633
664
 
634
- node.on('input', (msg) => {
665
+ node.on('input', async (msg) => {
635
666
  if (typeof msg === 'undefined') return
636
667
  if (!node.serverKNX) return // 29/08/2019 Server not instantiate
637
668
 
@@ -679,8 +710,8 @@ module.exports = function (RED) {
679
710
  // -+++++++++++++++++++++++++++++++++++++++++++
680
711
  if (node.sendMsgToKNXCode !== undefined) {
681
712
  try {
682
- const sendMsgToKNXCode = new Function('msg', 'getGAValue', 'node', 'RED', 'self', 'toggle', 'setGAValue', node.sendMsgToKNXCode)
683
- msg = sendMsgToKNXCode(msg, getGAValue, node, RED, self, toggle, setGAValue)
713
+ const sendMsgToKNXCode = (new (Object.getPrototypeOf(async function () { }).constructor)('msg', 'getGAValue', 'node', 'RED', 'self', 'toggle', 'setGAValue', node.sendMsgToKNXCode))
714
+ msg = await sendMsgToKNXCode(msg, getGAValue, node, RED, self, toggle, setGAValue)
684
715
  if (msg === undefined) return
685
716
  } catch (error) {
686
717
  RED.log.error('knxUltimate: sendMsgToKNXCode: node ID:' + node.id + ' ' + error.message)
@@ -886,8 +917,11 @@ module.exports = function (RED) {
886
917
  // connection.writeRaw('1/0/0', Buffer.from('0730', 'hex'))
887
918
  if (msg.hasOwnProperty('writeraw') && msg.hasOwnProperty('writeraw') !== null) {
888
919
  try {
889
- if (msg.hasOwnProperty('bitlenght') && msg.bitlenght !== null) {
890
- node.serverKNX.knxConnection.writeRaw(grpaddr, msg.writeraw, msg.bitlenght)
920
+ const rawBitlength = msg.hasOwnProperty('bitlength') && msg.bitlength !== null
921
+ ? msg.bitlength
922
+ : (msg.hasOwnProperty('bitlenght') && msg.bitlenght !== null ? msg.bitlenght : null)
923
+ if (rawBitlength !== null) {
924
+ node.serverKNX.knxConnection.writeRaw(grpaddr, msg.writeraw, rawBitlength)
891
925
  } else {
892
926
  node.serverKNX.knxConnection.writeRaw(grpaddr, msg.writeraw)
893
927
  }
@@ -902,6 +936,20 @@ module.exports = function (RED) {
902
936
  return
903
937
  }
904
938
 
939
+ if (typeof dpt === 'string' && dpt.trim().toLowerCase() === 'raw') {
940
+ node.setNodeStatus({
941
+ fill: 'red',
942
+ shape: 'dot',
943
+ text: 'RAW mode accepts only msg.writeraw for outgoing telegrams',
944
+ payload: '',
945
+ GA: grpaddr,
946
+ dpt: '',
947
+ devicename: ''
948
+ })
949
+ node.sysLogger?.error(`node id: ${node.id} RAW mode accepts only msg.writeraw for outgoing telegrams (${grpaddr})`)
950
+ return
951
+ }
952
+
905
953
  if (outputtype == 'response') {
906
954
  try {
907
955
  node.currentPayload = msg.payload// 31/12/2019 Set the current value (because, if the node is a virtual device, then it'll never fire "GroupValue_Write" in the server node, causing the currentPayload to never update)
@@ -960,9 +1008,9 @@ module.exports = function (RED) {
960
1008
  })
961
1009
 
962
1010
  // On each deploy, add the node to the server list
963
- if (node.serverKNX) {
964
- node.serverKNX.addClient(node)
965
- if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(`addClient: node id ${node.id}` || '' + ` with topic ${node.topic || ''} has been added to the server.`)
1011
+ if (node.serverKNX) {
1012
+ node.serverKNX.addClient(node)
1013
+ if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.info(`addClient: node id ${node.id}` || '' + ` with topic ${node.topic || ''} has been added to the server.`)
966
1014
  // 05/11/2021 if the node is set to read from bus, issue a read.
967
1015
  // "node-input-initialread0": "No",
968
1016
  // "node-input-initialread1": "Leggi dal BUS KNX",
@@ -975,11 +1023,11 @@ module.exports = function (RED) {
975
1023
  const t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
976
1024
  node.emit('input', { readstatus: true })
977
1025
  }, 3000)
978
- }
979
- }
1026
+ }
1027
+ }
980
1028
 
981
- // Start periodic send timer (optional)
982
- startPeriodicSendTimer()
983
- }
984
- RED.nodes.registerType('knxUltimate', knxUltimate)
1029
+ // Start periodic send timer (optional)
1030
+ startPeriodicSendTimer()
1031
+ }
1032
+ RED.nodes.registerType('knxUltimate', knxUltimate)
985
1033
  }
@@ -112,7 +112,7 @@ if (msg.payload === false && getGAValue('0/0/11','1.001') === false){ return; }
112
112
  - **event (string)**: `GroupValue_Write`, `GroupValue_Response`, `Update_NoWrite` (nur interner Wert, kein BUS-Senden)
113
113
  - **readstatus (boolean)**: Leseauftrag an den BUS
114
114
  - **dpt (string)**: z. B. `1.001`
115
- - **writeraw (buffer)** + **bitlenght (int)**: RAW-Senden; `bitlenght` in Bit
115
+ - **writeraw (buffer)** + **bitlength (int)**: RAW-Senden; `bitlength` in Bit (`bitlenght` wird aus Kompatibilitaetsgruenden weiterhin akzeptiert)
116
116
  - **resetRBE (boolean)**: RBE-Filter zurücksetzen
117
117
  - **setConfig (json)**: GA/DPT des Nodes per Nachricht ändern
118
118
 
@@ -181,7 +181,8 @@ Für Read statt `event` bitte `msg.readstatus = true` verwenden.
181
181
 
182
182
  - **msg.readstatus = true**: Read an den BUS
183
183
  - **msg.dpt**: z. B. `1.001` (auch `9`, `"9"`, `"DPT9.001"`)
184
- - **msg.writeraw** + **msg.bitlenght**: RAW-Senden; ignoriert den am Node gesetzten DPT
184
+ - **msg.dpt = raw**: eingehende Telegramme bleiben undekodiert; `msg.payload` ist `null` und die Bytes stehen in `msg.knx.rawValue`. Zum Senden von RAW-Telegrammen `msg.writeraw` verwenden
185
+ - **msg.writeraw** + **msg.bitlength**: RAW-Senden; ignoriert den am Node gesetzten DPT
185
186
  - **msg.resetRBE = true**: RBE-Filter zurücksetzen
186
187
 
187
188
  ## Konfiguration per Nachricht ändern
@@ -227,7 +228,7 @@ msg.readstatus = true; return msg;
227
228
  ```javascript
228
229
 
229
230
  msg.writeraw = Buffer.from('01','hex');
230
- msg.bitlenght = 1; return msg;
231
+ msg.bitlength = 1; return msg;
231
232
  // Temperatur (DPT9): 18.4 °C = <0730>
232
233
  // msg.writeraw = Buffer.from('0730','hex'); return msg;
233
234
  ```
@@ -159,8 +159,9 @@ if (msg.payload === false && getGAValue('0/0/11','1.001') === false){
159
159
  - **event (string)**: `_GroupValue_Write_` / `_GroupValue_Response_` / `_Update_NoWrite_` (`_Update_NoWrite_` updates the internal value only)
160
160
  - **readstatus (boolean)**: issue a read request to the KNX bus (pass `_true_` every time: `msg.readstatus = true`)
161
161
  - **dpt (string)**: for example `"1.001"` (sets the datapoint)
162
- - **writeraw (buffer)**: sends a raw buffer value to the bus (use with **bitlenght**)
163
- - **bitlenght (int)**: bit length of **writeraw**
162
+ - **dpt = raw**: keeps incoming telegrams undecoded; `msg.payload` will be `null` and the bytes will be available in `msg.knx.rawValue`. Use `msg.writeraw` to send raw telegrams
163
+ - **writeraw (buffer)**: sends a raw buffer value to the bus (use with **bitlength**)
164
+ - **bitlength (int)**: bit length of **writeraw** (`bitlenght` is still accepted for backward compatibility)
164
165
  - **resetRBE (boolean)**: resets the internal RBE filters (`msg.resetRBE = true`)
165
166
  - **setConfig (json)**: programmatically change the node Group Address and Datapoint (see details)
166
167
 
@@ -263,8 +264,9 @@ msg = {
263
264
  - **event (string)**: `_GroupValue_Write_` / `_GroupValue_Response_` / `_Update_NoWrite_` (`_Update_NoWrite_` updates the internal value only)
264
265
  - **readstatus (boolean)**: issue a read request to the KNX bus (pass `_true_` every time: `msg.readstatus = true`)
265
266
  - **dpt (string)**: for example `"1.001"` (sets the datapoint)
266
- - **writeraw (buffer)**: sends a raw buffer value to the bus (use with **bitlenght**)
267
- - **bitlenght (int)**: bit length of **writeraw**
267
+ - **dpt = raw**: keeps incoming telegrams undecoded; `msg.payload` will be `null` and the bytes will be available in `msg.knx.rawValue`. Use `msg.writeraw` to send raw telegrams
268
+ - **writeraw (buffer)**: sends a raw buffer value to the bus (use with **bitlength**)
269
+ - **bitlength (int)**: bit length of **writeraw** (`bitlenght` is still accepted for backward compatibility)
268
270
  - **resetRBE (boolean)**: resets the internal RBE filters (`msg.resetRBE = true`)
269
271
  - **setConfig (json)**: programmatically change the node Group Address and Datapoint (see details)
270
272
 
@@ -436,7 +438,7 @@ Issue a "Read" command to the BUS.
436
438
  **msg.dpt** <br/>
437
439
  For example "1.001". Sets the <b>Datapoint</b>. (You can write it in these formats: 9 , "9" , "9.001" or "DPT9.001")
438
440
 
439
- **msg.writeraw ** <br/>**msg.bitlenght** <br/>
441
+ **msg.writeraw ** <br/>**msg.bitlength** <br/>
440
442
  Writes RAW data to the KNX BUS. Please see below an example.<br/>
441
443
 
442
444
  **msg.resetRBE** <br/> pass msg.resetRBE = true to a device node, to reset both input and output RBE filter on that particular node.<br/>
@@ -500,23 +502,23 @@ return msg;
500
502
 
501
503
  **SEND RAW VALUE TO THE BUS** <br/>
502
504
 
503
- To send a RAW buffer value to the KNX bus, use the _ **writeraw ** _ and _**bitlenght** _ properties of the msg input.<br/>
505
+ To send a RAW buffer value to the KNX bus, use the _ **writeraw ** _ and _**bitlength** _ properties of the msg input.<br/>
504
506
  In this case, the _Datapoint_ you set in the property window will be ignored.<br/>
505
507
  Slap a function node in front of knx-ultimate and paste his code:
506
508
 
507
509
  ```javascript
508
510
 
509
511
  // If you encode the values by yourself, you can write raw buffers with writeraw.
510
- // The bitlenght is necessary for datapoint types where the bitlenght does not equal the buffers bytelenght * 8. This is the case for dpt 1 (bitlength 1), 2 (bitlenght 2) and 3 (bitlenght 4).
512
+ // The bitlength is necessary for datapoint types where the bitlength does not equal the buffer bytelength * 8. This is the case for dpt 1 (bitlength 1), 2 (bitlength 2) and 3 (bitlength 4).
511
513
  // Write raw buffer to a groupaddress with dpt 1 (e.g light on = value true = Buffer<01>) with a bitlength of 1
512
514
  msg.writeraw = Buffer.from('01', 'hex'); // Put '00' instead of '01' to switch off the light.
513
- msg.bitlenght = 1;
515
+ msg.bitlength = 1;
514
516
  return msg;
515
517
 
516
518
  // Temperature sample (uncomment below and comment above)
517
519
  // Write raw buffer to a groupaddress with dpt 9 (e.g temperature 18.4 °C = Buffer<0730>) without bitlength
518
520
  // msg.writeraw = Buffer.from('0730', 'hex');
519
- // msg.bitlenght = 1;
521
+ // msg.bitlength = 1;
520
522
  // return msg;
521
523
 
522
524
  ```
@@ -159,7 +159,8 @@ if (msg.payload === false && getGAValue('0/0/11','1.001') === false){
159
159
  - **event (string)**: `GroupValue_Write` / `GroupValue_Response` / `Update_NoWrite` (`Update_NoWrite` actualiza el valor interno y no envía al BUS)
160
160
  - **readstatus (boolean)**: emite una solicitud de lectura al bus (use siempre `true`: `msg.readstatus = true`)
161
161
  - **dpt (string)**: por ejemplo `1.001` (datapoint)
162
- - **writeraw (buffer)** + **bitlenght (int)**: envío RAW al BUS (ver ejemplo)
162
+ - **dpt = raw**: mantiene los telegramas entrantes sin decodificar; `msg.payload` sera `null` y los bytes estaran disponibles en `msg.knx.rawValue`. Para enviar RAW use `msg.writeraw`
163
+ - **writeraw (buffer)** + **bitlength (int)**: envio RAW al BUS (ver ejemplo); `bitlenght` sigue siendo aceptado por compatibilidad
163
164
  - **resetRBE (boolean)**: restablece filtros RBE internos (`msg.resetRBE = true`)
164
165
  - **setConfig (json)**: cambia programáticamente GA y DPT (ver detalles)
165
166
 
@@ -257,7 +258,8 @@ msg = {
257
258
  - **event (string)**: `GroupValue_Write` / `GroupValue_Response` / `Update_NoWrite`
258
259
  - **readstatus (boolean)**: solicitud de lectura al bus (`msg.readstatus = true`)
259
260
  - **dpt (string)**: por ejemplo `1.001`
260
- - **writeraw (buffer)** + **bitlenght (int)**: envío RAW (ver ejemplo)
261
+ - **dpt = raw**: mantiene los telegramas entrantes sin decodificar; `msg.payload` sera `null` y los bytes estaran disponibles en `msg.knx.rawValue`. Para enviar RAW use `msg.writeraw`
262
+ - **writeraw (buffer)** + **bitlength (int)**: envio RAW (ver ejemplo); `bitlenght` sigue siendo aceptado por compatibilidad
261
263
  - **resetRBE (boolean)**: restablece los filtros RBE (`msg.resetRBE = true`)
262
264
  - **setConfig (json)**: cambia GA y DPT (ver detalles)
263
265
 
@@ -418,7 +420,7 @@ PRECAUCIÓN: en el caso de _msg.event = "update \ _nowrite" _ Todos los nodos co
418
420
 
419
421
  Si desea emitir un comando "Leer", use "ReadStatus" en su lugar (ver más abajo). <BR/> ** msg.readstatus = true** <br/>
420
422
  Emita un comando de "leer" al bus. ** msg.dpt** <br/>
421
- Por ejemplo "1.001". Establece el punto de datos <b> </b>. (Puede escribirlo en estos formatos: 9, "9", "9.001" o "DPT9.001") ** msg.writeraw ** <br/>**msg.bitlenght** <br/>
423
+ Por ejemplo "1.001". Establece el punto de datos <b> </b>. (Puede escribirlo en estos formatos: 9, "9", "9.001" o "DPT9.001") ** msg.writeraw ** <br/>**msg.bitlength** <br/>
422
424
  Escribe datos sin procesar en el bus KNX. Consulte a continuación un ejemplo. <br/> ** msg.resetrbe** <br/> pase msg.resetrbe = true a un nodo de dispositivo, para restablecer tanto el filtro de entrada como de salida RBE en ese nodo particular. <br/>
423
425
 
424
426
  <br/>
@@ -478,23 +480,23 @@ return msg;
478
480
 
479
481
  ** Enviar valor bruto al bus** <br/>
480
482
 
481
- Para enviar un valor de búfer en bruto al bus KNX, use el _ ** escritorw ** _ y _**bitLenght** _ Propiedades de la entrada de MSG. <br/>
483
+ Para enviar un valor de buffer RAW al bus KNX, use las propiedades _ **writeraw** _ y _**bitlength** _ de la entrada MSG. <br/>
482
484
  En este caso, se ignorará el _datapoint_ que establece en la ventana de la propiedad. <br/>
483
485
  Softe un nodo de función frente a KNX-Ulimate y pegue su código:
484
486
 
485
487
  ```javascript
486
488
 
487
489
  // If you encode the values by yourself, you can write raw buffers with writeraw.
488
- // The bitlenght is necessary for datapoint types where the bitlenght does not equal the buffers bytelenght * 8. This is the case for dpt 1 (bitlength 1), 2 (bitlenght 2) and 3 (bitlenght 4).
490
+ // The bitlength is necessary for datapoint types where the bitlength does not equal the buffer bytelength * 8. This is the case for dpt 1 (bitlength 1), 2 (bitlength 2) and 3 (bitlength 4).
489
491
  // Write raw buffer to a groupaddress with dpt 1 (e.g light on = value true = Buffer<01>) with a bitlength of 1
490
492
  msg.writeraw = Buffer.from('01', 'hex'); // Put '00' instead of '01' to switch off the light.
491
- msg.bitlenght = 1;
493
+ msg.bitlength = 1;
492
494
  return msg;
493
495
 
494
496
  // Temperature sample (uncomment below and comment above)
495
497
  // Write raw buffer to a groupaddress with dpt 9 (e.g temperature 18.4 °C = Buffer<0730>) without bitlength
496
498
  // msg.writeraw = Buffer.from('0730', 'hex');
497
- // msg.bitlenght = 1;
499
+ // msg.bitlength = 1;
498
500
  // return msg;
499
501
 
500
502
  ```
@@ -159,7 +159,8 @@ if (msg.payload === false && getGAValue('0/0/11','1.001') === false){
159
159
  - **event (string)**: `GroupValue_Write` / `GroupValue_Response` / `Update_NoWrite` (`Update_NoWrite` met à jour la valeur interne et n'envoie rien au BUS)
160
160
  - **readstatus (boolean)**: demande de lecture au bus (utiliser toujours `true`: `msg.readstatus = true`)
161
161
  - **dpt (string)**: par exemple `1.001` (datapoint)
162
- - **writeraw (buffer)** + **bitlenght (int)**: envoi RAW au BUS (voir exemple)
162
+ - **dpt = raw**: conserve les telegrammes entrants sans decodage ; `msg.payload` sera `null` et les octets seront disponibles dans `msg.knx.rawValue`. Pour envoyer du RAW, utilisez `msg.writeraw`
163
+ - **writeraw (buffer)** + **bitlength (int)**: envoi RAW au BUS (voir exemple) ; `bitlenght` reste accepte pour compatibilite
163
164
  - **resetRBE (boolean)**: réinitialise les filtres RBE (`msg.resetRBE = true`)
164
165
  - **setConfig (json)**: modifier GA et DPT par message (voir détails)
165
166
 
@@ -257,7 +258,8 @@ msg = {
257
258
  - **event (string)**: `GroupValue_Write` / `GroupValue_Response` / `Update_NoWrite`
258
259
  - **readstatus (boolean)**: demande de lecture au bus (`msg.readstatus = true`)
259
260
  - **dpt (string)**: par exemple `1.001`
260
- - **writeraw (buffer)** + **bitlenght (int)**: envoi RAW au BUS (voir exemple)
261
+ - **dpt = raw**: conserve les telegrammes entrants sans decodage ; `msg.payload` sera `null` et les octets seront disponibles dans `msg.knx.rawValue`. Pour envoyer du RAW, utilisez `msg.writeraw`
262
+ - **writeraw (buffer)** + **bitlength (int)**: envoi RAW au BUS (voir exemple) ; `bitlenght` reste accepte pour compatibilite
261
263
  - **resetRBE (boolean)**: réinitialise les filtres RBE (`msg.resetRBE = true`)
262
264
  - **setConfig (json)**: modifier GA et DPT (voir détails)
263
265
 
@@ -418,7 +420,7 @@ ATTENTION: Dans le cas de _msg.event = "Update \ _Nowrite" _ Tous les nœuds ave
418
420
 
419
421
  Si vous souhaitez émettre une commande "lire", veuillez utiliser "ReadStatus" à la place (voir ci-dessous). <br/> ** msg.readstatus = true** <br/>
420
422
  Émettez une commande "lire" au bus. ** msg.dpt** <br/>
421
- Par exemple "1.001". Définit le <b> datapoint </b>. (Vous pouvez l'écrire dans ces formats: 9, "9", "9.001" ou "DPT9.001") ** msg.writeraw ** <br/>**msg.bitlenght** <br/>
423
+ Par exemple "1.001". Définit le <b> datapoint </b>. (Vous pouvez l'écrire dans ces formats: 9, "9", "9.001" ou "DPT9.001") ** msg.writeraw ** <br/>**msg.bitlength** <br/>
422
424
  Écrit des données brutes au bus KNX. Veuillez voir ci-dessous un exemple. <br/> ** MSG.RESETRBE** <BR/> PASS MSG.RESETRBE = VRAI À un nœud de périphérique, pour réinitialiser à la fois l'entrée et la sortie du filtre RBE sur ce nœud particulier. <br/>
423
425
 
424
426
  <br/>
@@ -478,23 +480,23 @@ return msg;
478
480
 
479
481
  **Envoyez la valeur brute au bus** <br/>
480
482
 
481
- Pour envoyer une valeur de tampon brute au bus KNX, utilisez les propriétés _ ** writerraw ** _ et _**bitlenght** _ de l'entrée msg. <br/>
483
+ Pour envoyer une valeur RAW au bus KNX, utilisez les proprietes _ **writeraw** _ et _**bitlength** _ de l'entree msg. <br/>
482
484
  Dans ce cas, le _datapoint_ que vous définissez dans la fenêtre de propriété sera ignoré. <br/>
483
485
  Grapez un nœud de fonction devant KNX-ultime et collez son code:
484
486
 
485
487
  ```javascript
486
488
 
487
489
  // If you encode the values by yourself, you can write raw buffers with writeraw.
488
- // The bitlenght is necessary for datapoint types where the bitlenght does not equal the buffers bytelenght * 8. This is the case for dpt 1 (bitlength 1), 2 (bitlenght 2) and 3 (bitlenght 4).
490
+ // The bitlength is necessary for datapoint types where the bitlength does not equal the buffer bytelength * 8. This is the case for dpt 1 (bitlength 1), 2 (bitlength 2) and 3 (bitlength 4).
489
491
  // Write raw buffer to a groupaddress with dpt 1 (e.g light on = value true = Buffer<01>) with a bitlength of 1
490
492
  msg.writeraw = Buffer.from('01', 'hex'); // Put '00' instead of '01' to switch off the light.
491
- msg.bitlenght = 1;
493
+ msg.bitlength = 1;
492
494
  return msg;
493
495
 
494
496
  // Temperature sample (uncomment below and comment above)
495
497
  // Write raw buffer to a groupaddress with dpt 9 (e.g temperature 18.4 °C = Buffer<0730>) without bitlength
496
498
  // msg.writeraw = Buffer.from('0730', 'hex');
497
- // msg.bitlenght = 1;
499
+ // msg.bitlength = 1;
498
500
  // return msg;
499
501
 
500
502
  ```
@@ -141,7 +141,7 @@ if (msg.payload === false && getGAValue('0/0/11','1.001') === false){
141
141
  - **event (string)**: `GroupValue_Write` (scrive sul BUS), `GroupValue_Response` (risponde sul BUS), `Update_NoWrite` (non invia al BUS, aggiorna solo il valore interno del nodo)
142
142
  - **readstatus (boolean)**: invia un "Read" al BUS (usa sempre `true`)
143
143
  - **dpt (string)**: per es. `1.001` (imposta il Datapoint)
144
- - **writeraw (buffer)** + **bitlenght (int)**: invio RAW verso il BUS (vedi esempio); `bitlenght` è la lunghezza in bit del dato RAW
144
+ - **writeraw (buffer)** + **bitlength (int)**: invio RAW verso il BUS (vedi esempio); `bitlength` è la lunghezza in bit del dato RAW (`bitlenght` resta accettato per retrocompatibilità)
145
145
  - **resetRBE (boolean)**: resetta i filtri RBE interni (`msg.resetRBE = true`)
146
146
  - **setConfig (json)**: cambia via msg il GA e il DPT del nodo (vedi sotto)
147
147
 
@@ -230,7 +230,8 @@ Se vuoi emettere un "read”, usa `msg.readstatus = true`.
230
230
 
231
231
  - **msg.readstatus = true**: emette un comando di lettura verso il BUS
232
232
  - **msg.dpt**: per es. `1.001` (accetta anche `9`, `"9"`, `"DPT9.001"`)
233
- - **msg.writeraw** + **msg.bitlenght**: invio RAW al BUS (vedi esempio sotto); se usi `writeraw`, il DPT impostato nel nodo viene ignorato
233
+ - **msg.dpt = raw**: lascia i telegrammi in ingresso non decodificati; `msg.payload` sara' `null` e i byte saranno disponibili in `msg.knx.rawValue`. Per inviare RAW usa `msg.writeraw`
234
+ - **msg.writeraw** + **msg.bitlength**: invio RAW al BUS (vedi esempio sotto); se usi `writeraw`, il DPT impostato nel nodo viene ignorato
234
235
  - **msg.resetRBE = true**: resetta i filtri RBE di input e output del nodo
235
236
 
236
237
  ## Cambiare la configurazione via msg
@@ -285,7 +286,7 @@ Inserisci un function node prima del nodo KNX-Ultimate e usa questo codice:
285
286
 
286
287
  // Esempio DPT 1: luce ON = Buffer<01> con bitlength = 1
287
288
  msg.writeraw = Buffer.from('01', 'hex');
288
- msg.bitlenght = 1;
289
+ msg.bitlength = 1;
289
290
  return msg;
290
291
 
291
292
  // Esempio temperatura (DPT 9): 18.4 °C = Buffer<0730>
@@ -112,7 +112,7 @@ if (msg.payload === false && getGAValue('0/0/11','1.001') === false){ return; }
112
112
  - **event (string)**:`GroupValue_Write` / `GroupValue_Response` / `Update_NoWrite`(`Update_NoWrite` 仅更新内部值,不发送)
113
113
  - **readstatus (boolean)**:向总线发起读取(使用 `msg.readstatus = true`)
114
114
  - **dpt (string)**:如 `1.001`
115
- - **writeraw (buffer)** + **bitlenght (int)**:发送 RAW,`bitlenght` 为比特长度
115
+ - **writeraw (buffer)** + **bitlength (int)**:发送 RAW,`bitlength` 为比特长度(为兼容旧流程,`bitlenght` 仍然可用)
116
116
  - **resetRBE (boolean)**:重置内部 RBE 过滤(`msg.resetRBE = true`)
117
117
  - **setConfig (json)**:通过消息修改节点的 GA 与 DPT
118
118
 
@@ -181,7 +181,8 @@ msg = {
181
181
 
182
182
  - **msg.readstatus = true**:向总线发起读取
183
183
  - **msg.dpt**:如 `1.001`(也接受 `9`、`"9"`、`"DPT9.001"`)
184
- - **msg.writeraw** + **msg.bitlenght**:发送 RAW;会忽略节点上设置的 DPT
184
+ - **msg.dpt = raw**:保持收到的报文不做解码;`msg.payload` 将为 `null`,原始字节可在 `msg.knx.rawValue` 中获取。发送 RAW 时请使用 `msg.writeraw`
185
+ - **msg.writeraw** + **msg.bitlength**:发送 RAW;会忽略节点上设置的 DPT
185
186
  - **msg.resetRBE = true**:重置 RBE 过滤
186
187
 
187
188
  ## 通过消息修改配置
@@ -229,7 +230,7 @@ msg.readstatus = true; return msg;
229
230
 
230
231
  // DPT1 示例:开灯 = Buffer<01>,bitlength = 1
231
232
  msg.writeraw = Buffer.from('01','hex');
232
- msg.bitlenght = 1; return msg;
233
+ msg.bitlength = 1; return msg;
233
234
  // 温度(DPT9)示例:18.4 °C = <0730>
234
235
  // msg.writeraw = Buffer.from('0730','hex'); return msg;
235
236
  ```