node-red-zelecproto 0.0.9 → 0.1.1
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.
- package/645.js +7 -80
- package/698.js +45 -46
- package/package.json +1 -1
package/645.js
CHANGED
|
@@ -534,52 +534,17 @@ function decode645(_msg) {
|
|
|
534
534
|
}
|
|
535
535
|
};
|
|
536
536
|
|
|
537
|
-
//
|
|
537
|
+
// 状态字2/3只保留原始数值和binary,具体位义由上层业务或文档表解释。
|
|
538
538
|
const w2 = readU16LE();
|
|
539
|
-
const dir = (b) => (b ? '反向' : '正向');
|
|
540
539
|
const word2 = (w2 === null) ? null : {
|
|
541
540
|
rawValue: w2,
|
|
542
|
-
binary: bin16(w2)
|
|
543
|
-
fields: {
|
|
544
|
-
'A相有功功率方向': dir(bit(w2, 0)),
|
|
545
|
-
'B相有功功率方向': dir(bit(w2, 1)),
|
|
546
|
-
'C相有功功率方向': dir(bit(w2, 2)),
|
|
547
|
-
'A相无功功率方向': dir(bit(w2, 4)),
|
|
548
|
-
'B相无功功率方向': dir(bit(w2, 5)),
|
|
549
|
-
'C相无功功率方向': dir(bit(w2, 6))
|
|
550
|
-
}
|
|
541
|
+
binary: bin16(w2)
|
|
551
542
|
};
|
|
552
543
|
|
|
553
|
-
// —— 状态字3(与你现有的 04000503 保持一致)——
|
|
554
544
|
const w3 = readU16LE();
|
|
555
|
-
const supplyBits = (w3 === null) ? 0 : ((w3 >> 1) & 0b11);
|
|
556
|
-
const supplyMode = (
|
|
557
|
-
supplyBits === 0 ? '主电源' :
|
|
558
|
-
supplyBits === 1 ? '辅助电源' :
|
|
559
|
-
supplyBits === 2 ? '电池供电' : '保留'
|
|
560
|
-
);
|
|
561
|
-
const meterTypeBits = (w3 === null) ? 0 : ((w3 >> 8) & 0b11);
|
|
562
|
-
const meterType = (
|
|
563
|
-
meterTypeBits === 0 ? '非预付费表' :
|
|
564
|
-
meterTypeBits === 1 ? '电量型预付费表' :
|
|
565
|
-
meterTypeBits === 2 ? '电费型预付费表' : '保留'
|
|
566
|
-
);
|
|
567
545
|
const word3 = (w3 === null) ? null : {
|
|
568
546
|
rawValue: w3,
|
|
569
|
-
binary: bin16(w3)
|
|
570
|
-
fields: {
|
|
571
|
-
当前运行时段套数: (bit(w3, 0) ? '第二套' : '第一套'),
|
|
572
|
-
供电方式: supplyMode,
|
|
573
|
-
编程允许状态: (bit(w3, 3) ? '有效' : '失效'),
|
|
574
|
-
继电器状态: (bit(w3, 4) ? '断' : '通'),
|
|
575
|
-
当前运行时区套数: (bit(w3, 5) ? '第二套' : '第一套'),
|
|
576
|
-
继电器命令状态: (bit(w3, 6) ? '断' : '通'),
|
|
577
|
-
预跳闸报警状态: (bit(w3, 7) ? '有' : '无'),
|
|
578
|
-
电能表类型: meterType,
|
|
579
|
-
当前运行分时费率套数: (bit(w3, 10) ? '第二套' : '第一套'),
|
|
580
|
-
当前阶梯套数: (bit(w3, 11) ? '第二套' : '第一套'),
|
|
581
|
-
保电状态: (bit(w3, 12) ? '保电' : '非保电')
|
|
582
|
-
}
|
|
547
|
+
binary: bin16(w3)
|
|
583
548
|
};
|
|
584
549
|
|
|
585
550
|
// —— 密钥状态字(与你现有的 04000508 保持一致,32位)——
|
|
@@ -630,64 +595,26 @@ function decode645(_msg) {
|
|
|
630
595
|
}
|
|
631
596
|
};
|
|
632
597
|
} else if (di === '04000502' && arrPush.length >= 6) {
|
|
633
|
-
//
|
|
598
|
+
// 状态字2只返回原始数值,binary为bit15..bit0。
|
|
634
599
|
const lo = arrPush[4] & 0xFF;
|
|
635
600
|
const hi = arrPush[5] & 0xFF;
|
|
636
601
|
const v = (hi << 8) | lo;
|
|
637
602
|
const bin = v.toString(2).padStart(16, '0');
|
|
638
603
|
|
|
639
|
-
const bit = (n) => ((v >> n) & 0x1);
|
|
640
|
-
const dir = (b) => (b ? '反向' : '正向');
|
|
641
|
-
|
|
642
604
|
value = {
|
|
643
605
|
rawValue: v,
|
|
644
|
-
binary: bin
|
|
645
|
-
fields: {
|
|
646
|
-
'A相有功功率方向': dir(bit(0)),
|
|
647
|
-
'B相有功功率方向': dir(bit(1)),
|
|
648
|
-
'C相有功功率方向': dir(bit(2)),
|
|
649
|
-
'A相无功功率方向': dir(bit(4)),
|
|
650
|
-
'B相无功功率方向': dir(bit(5)),
|
|
651
|
-
'C相无功功率方向': dir(bit(6))
|
|
652
|
-
}
|
|
606
|
+
binary: bin
|
|
653
607
|
};
|
|
654
608
|
} else if (di === '04000503' && arrPush.length >= 6) {
|
|
655
|
-
//
|
|
609
|
+
// 状态字3只返回原始数值,binary为bit15..bit0。
|
|
656
610
|
const lo = arrPush[4] & 0xFF;
|
|
657
611
|
const hi = arrPush[5] & 0xFF;
|
|
658
612
|
const v = (hi << 8) | lo;
|
|
659
613
|
const bin = v.toString(2).padStart(16, '0');
|
|
660
614
|
|
|
661
|
-
const supplyBits = (v >> 1) & 0b11; // bit2-bit1
|
|
662
|
-
const supplyMode = (
|
|
663
|
-
supplyBits === 0 ? '主电源' :
|
|
664
|
-
supplyBits === 1 ? '辅助电源' :
|
|
665
|
-
supplyBits === 2 ? '电池供电' : '保留'
|
|
666
|
-
);
|
|
667
|
-
|
|
668
|
-
const meterTypeBits = (v >> 8) & 0b11; // bit9-bit8
|
|
669
|
-
const meterType = (
|
|
670
|
-
meterTypeBits === 0 ? '非预付费表' :
|
|
671
|
-
meterTypeBits === 1 ? '电量型预付费表' :
|
|
672
|
-
meterTypeBits === 2 ? '电费型预付费表' : '保留'
|
|
673
|
-
);
|
|
674
|
-
|
|
675
615
|
value = {
|
|
676
616
|
rawValue: v,
|
|
677
|
-
binary: bin
|
|
678
|
-
fields: {
|
|
679
|
-
当前运行时段套数: (v & 0x1) ? '第二套' : '第一套', // bit0
|
|
680
|
-
供电方式: supplyMode, // bit2-bit1
|
|
681
|
-
编程允许状态: (v & (1 << 3)) ? '有效' : '失效', // bit3
|
|
682
|
-
继电器状态: (v & (1 << 4)) ? '断' : '通', // bit4(线路实际工作状态)
|
|
683
|
-
当前运行时区套数: (v & (1 << 5)) ? '第二套' : '第一套', // bit5
|
|
684
|
-
继电器命令状态: (v & (1 << 6)) ? '断' : '通', // bit6(远程拉闸命令)
|
|
685
|
-
预跳闸报警状态: (v & (1 << 7)) ? '有' : '无', // bit7
|
|
686
|
-
电能表类型: meterType, // bit9-bit8
|
|
687
|
-
当前运行分时费率套数: (v & (1 << 10)) ? '第二套' : '第一套', // bit10
|
|
688
|
-
当前阶梯套数: (v & (1 << 11)) ? '第二套' : '第一套', // bit11
|
|
689
|
-
保电状态: (v & (1 << 12)) ? '保电' : '非保电' // bit12
|
|
690
|
-
}
|
|
617
|
+
binary: bin
|
|
691
618
|
};
|
|
692
619
|
}
|
|
693
620
|
// else if (['0000FF00', '0001FF00', '0002FF00'].includes(di) && arrPush.length > 4) {
|
package/698.js
CHANGED
|
@@ -859,6 +859,39 @@ function toBigEndian16(value) {
|
|
|
859
859
|
// 将小端(低字节在前)转换为大端(高字节在前)
|
|
860
860
|
return (lower << 8) | upper;
|
|
861
861
|
}
|
|
862
|
+
|
|
863
|
+
function parseStatusWordFromAxdrBitString(buffer) {
|
|
864
|
+
if (!Buffer.isBuffer(buffer) || buffer.length < 3 || buffer[0] !== 0x04) return null;
|
|
865
|
+
const L = readAxdrLength(buffer, 1);
|
|
866
|
+
const byteLen = Math.ceil(L.len / 8);
|
|
867
|
+
const start = 1 + L.size;
|
|
868
|
+
const end = start + byteLen;
|
|
869
|
+
if (end > buffer.length) return null;
|
|
870
|
+
const bytes = buffer.slice(start, end);
|
|
871
|
+
if (bytes.length < 2) return null;
|
|
872
|
+
const bits = [];
|
|
873
|
+
const lowToHighBits = [];
|
|
874
|
+
// A-XDR bit-string按每字节高位到低位展开;另保留低位到高位展示用于和现场口径对照。
|
|
875
|
+
for (const byte of bytes.slice(0, 2)) {
|
|
876
|
+
for (let bit = 7; bit >= 0; bit--) {
|
|
877
|
+
bits.push((byte >> bit) & 0x01);
|
|
878
|
+
}
|
|
879
|
+
for (let bit = 0; bit <= 7; bit++) {
|
|
880
|
+
lowToHighBits.push((byte >> bit) & 0x01);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
let statusWord = 0;
|
|
884
|
+
// 文档表F.x中的bit编号按展开后的bit-string下标映射,后续binary再按645一致的数值形式输出。
|
|
885
|
+
for (let i = 0; i < 16; i++) {
|
|
886
|
+
statusWord |= bits[i] << i;
|
|
887
|
+
}
|
|
888
|
+
return {
|
|
889
|
+
statusWord,
|
|
890
|
+
binaryLowToHigh: lowToHighBits.slice(0, 16).join(''),
|
|
891
|
+
binaryHighToLow: bits.slice(0, 16).join('')
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
|
|
862
895
|
/**
|
|
863
896
|
* 解析电表运行状态字2 - 与645协议格式保持一致
|
|
864
897
|
* @param {Buffer} dataBuffer - 数据缓冲区
|
|
@@ -928,42 +961,19 @@ function parseMeterStatusWord3(dataBuffer) {
|
|
|
928
961
|
const oad = '20140203';
|
|
929
962
|
const result = createStandardResult("电表运行状态字3", oad, dataBuffer);
|
|
930
963
|
try {
|
|
931
|
-
const
|
|
964
|
+
const bitStringStatus = parseStatusWordFromAxdrBitString(dataBuffer);
|
|
965
|
+
const statusWord = bitStringStatus?.statusWord ?? parseMeterStatusOptimized(dataBuffer);
|
|
932
966
|
if (statusWord === null) throw new Error('无法解析状态字');
|
|
933
967
|
|
|
934
968
|
const val16 = statusWord & 0xFFFF; // 低16位
|
|
969
|
+
// binary按最终状态字数值输出(bit15..bit0),与645状态字binary保持一致。
|
|
935
970
|
const bin = val16.toString(2).padStart(16, '0');
|
|
936
971
|
|
|
937
|
-
const supplyBits = (val16 >> 1) & 0b11; // bit2-bit1
|
|
938
|
-
const supplyMode = (
|
|
939
|
-
supplyBits === 0 ? '主电源' :
|
|
940
|
-
supplyBits === 1 ? '辅助电源' :
|
|
941
|
-
supplyBits === 2 ? '电池供电' : '保留'
|
|
942
|
-
);
|
|
943
|
-
|
|
944
|
-
const meterTypeBits = (val16 >> 8) & 0b11; // bit9-bit8
|
|
945
|
-
const meterType = (
|
|
946
|
-
meterTypeBits === 0 ? '非预付费表' :
|
|
947
|
-
meterTypeBits === 1 ? '电量型预付费表' :
|
|
948
|
-
meterTypeBits === 2 ? '电费型预付费表' : '保留'
|
|
949
|
-
);
|
|
950
|
-
|
|
951
972
|
result.value = {
|
|
952
973
|
rawValue: val16,
|
|
953
974
|
binary: bin,
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
供电方式: supplyMode, // bit2-bit1
|
|
957
|
-
编程允许状态: (val16 & (1 << 3)) ? '有效' : '失效', // bit3
|
|
958
|
-
继电器状态: (val16 & (1 << 4)) ? '断' : '通', // bit4(线路实际工作状态)
|
|
959
|
-
当前运行时区套数: (val16 & (1 << 5)) ? '第二套' : '第一套',
|
|
960
|
-
继电器命令状态: (val16 & (1 << 6)) ? '断' : '通', // bit6(远程拉闸命令)
|
|
961
|
-
预跳闸报警状态: (val16 & (1 << 7)) ? '有' : '无', // bit7
|
|
962
|
-
电能表类型: meterType, // bit9-bit8
|
|
963
|
-
当前运行分时费率套数: (val16 & (1 << 10)) ? '第二套' : '第一套',
|
|
964
|
-
当前阶梯套数: (val16 & (1 << 11)) ? '第二套' : '第一套',
|
|
965
|
-
保电状态: (val16 & (1 << 12)) ? '保电' : '非保电'
|
|
966
|
-
}
|
|
975
|
+
...(bitStringStatus?.binaryLowToHigh ? { binaryLowToHigh: bitStringStatus.binaryLowToHigh } : {}),
|
|
976
|
+
...(bitStringStatus?.binaryHighToLow ? { binaryHighToLow: bitStringStatus.binaryHighToLow } : {})
|
|
967
977
|
};
|
|
968
978
|
|
|
969
979
|
setSuccessResult(result, {
|
|
@@ -984,31 +994,20 @@ function parseMeterStatusWord2(dataBuffer) {
|
|
|
984
994
|
const oad = '20140202';
|
|
985
995
|
const result = createStandardResult("电表运行状态字2", oad, dataBuffer);
|
|
986
996
|
try {
|
|
987
|
-
const
|
|
997
|
+
const bitStringStatus = parseStatusWordFromAxdrBitString(dataBuffer);
|
|
998
|
+
const statusWord = bitStringStatus?.statusWord ?? parseMeterStatusOptimized(dataBuffer);
|
|
988
999
|
if (statusWord === null) throw new Error('无法解析状态字');
|
|
989
1000
|
|
|
990
1001
|
const val16 = statusWord & 0xFFFF;
|
|
1002
|
+
// binary按最终状态字数值输出(bit15..bit0),与645状态字binary保持一致。
|
|
991
1003
|
const bin = val16.toString(2).padStart(16, '0');
|
|
992
1004
|
|
|
993
|
-
const bit = (n) => ((val16 >> n) & 0x1);
|
|
994
|
-
const dir = (b) => (b ? '反向' : '正向'); // 0=正向, 1=反向
|
|
995
|
-
|
|
996
|
-
// 按表F.2位义生成具名字段
|
|
997
|
-
const fields = {
|
|
998
|
-
'A相有功功率方向': dir(bit(0)), // bit0
|
|
999
|
-
'B相有功功率方向': dir(bit(1)), // bit1
|
|
1000
|
-
'C相有功功率方向': dir(bit(2)), // bit2
|
|
1001
|
-
'A相无功功率方向': dir(bit(4)), // bit4
|
|
1002
|
-
'B相无功功率方向': dir(bit(5)), // bit5
|
|
1003
|
-
'C相无功功率方向': dir(bit(6)) // bit6
|
|
1004
|
-
// 其余bit3、bit7、bit8~bit15为保留
|
|
1005
|
-
};
|
|
1006
|
-
|
|
1007
1005
|
result.value = {
|
|
1008
1006
|
rawValue: val16,
|
|
1009
1007
|
binary: bin,
|
|
1010
|
-
|
|
1011
|
-
|
|
1008
|
+
...(bitStringStatus?.binaryLowToHigh ? { binaryLowToHigh: bitStringStatus.binaryLowToHigh } : {}),
|
|
1009
|
+
...(bitStringStatus?.binaryHighToLow ? { binaryHighToLow: bitStringStatus.binaryHighToLow } : {}),
|
|
1010
|
+
bits: decodeMeterStatusBits(val16)
|
|
1012
1011
|
};
|
|
1013
1012
|
|
|
1014
1013
|
setSuccessResult(result, { statusWord: val16, statusWordHex: val16.toString(16).padStart(4, '0').toUpperCase(), statusBits: decodeMeterStatusBits(val16) }, { generic: { dataType: 'bit-string' } });
|
|
@@ -3005,4 +3004,4 @@ function batchMsg698(msg) {
|
|
|
3005
3004
|
}
|
|
3006
3005
|
|
|
3007
3006
|
module.exports = batchMsg698;
|
|
3008
|
-
module.exports.batchMsg698 = batchMsg698;
|
|
3007
|
+
module.exports.batchMsg698 = batchMsg698;
|