@@ -111,7 +111,7 @@ boolean Plugin_052_init = false;
111
111
String detected_device_description;
112
112
113
113
unsigned int _plugin_052_last_measurement = 0 ;
114
- uint32_t _plugin_052_reads_processed = 0 ;
114
+ uint32_t _plugin_052_reads_pass = 0 ;
115
115
uint32_t _plugin_052_reads_crc_failed = 0 ;
116
116
117
117
ESPeasySerial *P052_easySerial;
@@ -213,7 +213,7 @@ boolean Plugin_052(byte function, struct EventStruct *event, String &string) {
213
213
}
214
214
addRowLabel (F (" Checksum (pass/fail)" ));
215
215
String chksumStats;
216
- chksumStats = _plugin_052_reads_processed ;
216
+ chksumStats = _plugin_052_reads_pass ;
217
217
chksumStats += ' /' ;
218
218
chksumStats += _plugin_052_reads_crc_failed;
219
219
addHtml (chksumStats);
@@ -329,6 +329,7 @@ boolean Plugin_052(byte function, struct EventStruct *event, String &string) {
329
329
String Plugin_052_getDevice_description (byte slaveAddress) {
330
330
bool more_follows = true ;
331
331
byte next_object_id = 0 ;
332
+ byte conformity_level = 0 ;
332
333
unsigned int object_value_int;
333
334
String description;
334
335
String obj_text;
@@ -338,33 +339,51 @@ String Plugin_052_getDevice_description(byte slaveAddress) {
338
339
if (object_id == 6 ) {
339
340
object_id = 0x82 ; // Skip to the serialnr/sensor type
340
341
}
341
- if ( 0 = = Plugin_052_modbus_get_MEI (slaveAddress, object_id, obj_text,
342
+ int result = Plugin_052_modbus_get_MEI (slaveAddress, object_id, obj_text,
342
343
object_value_int, next_object_id,
343
- more_follows)) {
344
- String label;
345
- switch (object_id) {
346
- case 0x01 :
347
- label = F (" Pcode" );
348
- break ;
349
- case 0x02 :
350
- label = F (" Rev" );
351
- break ;
352
- case 0x82 :
353
- label = F (" S/N" );
354
- break ;
355
- case 0x83 :
356
- label = F (" Type" );
357
- break ;
358
- default :
359
- break ;
344
+ more_follows, conformity_level);
345
+ String label;
346
+ switch (object_id) {
347
+ case 0x01 :
348
+ if (result == 0 ) label = F (" Pcode" );
349
+ break ;
350
+ case 0x02 :
351
+ if (result == 0 ) label = F (" Rev" );
352
+ break ;
353
+ case 0x82 :
354
+ {
355
+ if (result != 0 ) {
356
+ uint32_t sensorId = Plugin_052_readSensorId ();
357
+ obj_text = String (sensorId, HEX);
358
+ result = 0 ;
359
+
360
360
}
361
+ if (result == 0 ) label = F (" S/N" );
362
+ break ;
363
+ }
364
+ case 0x83 :
365
+ {
366
+ if (result != 0 ) {
367
+ uint32_t sensorId = Plugin_052_readTypeId ();
368
+ obj_text = String (sensorId, HEX);
369
+ result = 0 ;
370
+ }
371
+ if (result == 0 ) label = F (" Type" );
372
+ break ;
373
+ }
374
+ default :
375
+ break ;
376
+ }
377
+ if (result == 0 ) {
361
378
if (label.length () > 0 ) {
362
379
// description += Plugin_052_MEI_objectid_to_name(object_id);
363
380
description += label;
364
381
description += F (" : " );
365
382
}
366
- description += obj_text;
367
- description += F (" - " );
383
+ if (obj_text.length () > 0 ) {
384
+ description += obj_text;
385
+ description += F (" - " );
386
+ }
368
387
}
369
388
}
370
389
return description;
@@ -408,6 +427,12 @@ void Plugin_052_build_modbus_MEI_frame(byte slaveAddress, byte device_id,
408
427
_plugin_052_sendframe[0 ] = slaveAddress;
409
428
_plugin_052_sendframe[1 ] = 0x2B ;
410
429
_plugin_052_sendframe[2 ] = 0x0E ;
430
+
431
+ // The parameter "Read Device ID code" allows to define four access types :
432
+ // 01: request to get the basic device identification (stream access)
433
+ // 02: request to get the regular device identification (stream access)
434
+ // 03: request to get the extended device identification (stream access)
435
+ // 04: request to get one specific identification object (individual access)
411
436
_plugin_052_sendframe[3 ] = device_id;
412
437
_plugin_052_sendframe[4 ] = object_id;
413
438
_plugin_052_sendframe_used = 5 ;
@@ -444,7 +469,8 @@ String Plugin_052_MEI_objectid_to_name(byte object_id) {
444
469
445
470
String Plugin_052_parse_modbus_MEI_response (unsigned int &object_value_int,
446
471
byte &next_object_id,
447
- bool &more_follows) {
472
+ bool &more_follows,
473
+ byte &conformity_level) {
448
474
String result;
449
475
if (_plugin_052_recv_buf_used < 8 ) {
450
476
// Too small.
@@ -454,9 +480,10 @@ String Plugin_052_parse_modbus_MEI_response(unsigned int &object_value_int,
454
480
more_follows = false ;
455
481
return result;
456
482
}
457
- int pos = 3 ; // Data skipped: slave_address, FunctionCode, MEI type
458
- const byte device_id = _plugin_052_recv_buf[pos++];
459
- const byte conformity_level = _plugin_052_recv_buf[pos++];
483
+ int pos = 4 ; // Data skipped: slave_address, FunctionCode, MEI type, ReadDevId
484
+ // See http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf
485
+ // Page 45
486
+ conformity_level = _plugin_052_recv_buf[pos++];
460
487
more_follows = _plugin_052_recv_buf[pos++] != 0 ;
461
488
next_object_id = _plugin_052_recv_buf[pos++];
462
489
const byte number_objects = _plugin_052_recv_buf[pos++];
@@ -656,6 +683,7 @@ byte Plugin_052_processCommand() {
656
683
int nrRetriesLeft = 2 ;
657
684
byte return_value = 0 ;
658
685
while (nrRetriesLeft > 0 ) {
686
+ return_value = 0 ;
659
687
// Send the byte array
660
688
P052_easySerial->write (_plugin_052_sendframe, _plugin_052_sendframe_used);
661
689
delay (50 );
@@ -675,10 +703,11 @@ byte Plugin_052_processCommand() {
675
703
}
676
704
// Check checksum
677
705
crc = Plugin_052_ModRTU_CRC (_plugin_052_recv_buf, _plugin_052_recv_buf_used);
678
- ++_plugin_052_reads_processed;
679
706
if (crc != 0u ) {
680
707
++_plugin_052_reads_crc_failed;
681
708
return_value = Plugin_052_MODBUS_BADCRC;
709
+ } else {
710
+ ++_plugin_052_reads_pass;
682
711
}
683
712
switch (return_value) {
684
713
case MODBUS_EXCEPTION_ACKNOWLEDGE:
@@ -695,6 +724,18 @@ byte Plugin_052_processCommand() {
695
724
return return_value;
696
725
}
697
726
727
+ uint32_t Plugin_052_read_32b_InputRegister (short address) {
728
+ uint32_t result = 0 ;
729
+ int idHigh = Plugin_052_readInputRegister (address);
730
+ int idLow = Plugin_052_readInputRegister (address + 1 );
731
+ if (idHigh >= 0 && idLow >= 0 ) {
732
+ result = idHigh;
733
+ result = result << 16 ;
734
+ result += idLow;
735
+ }
736
+ return result;
737
+ }
738
+
698
739
int Plugin_052_readInputRegister (short address) {
699
740
// Only read 1 register
700
741
return Plugin_052_process_16b_register (P052_MODBUS_SLAVE_ADDRESS,
@@ -716,12 +757,15 @@ int Plugin_052_writeSingleRegister(short address, short value) {
716
757
717
758
byte Plugin_052_modbus_get_MEI (byte slaveAddress, byte object_id,
718
759
String &result, unsigned int &object_value_int,
719
- byte &next_object_id, bool &more_follows) {
760
+ byte &next_object_id, bool &more_follows,
761
+ byte &conformity_level) {
762
+ // Force device_id to 4 = individual access (reading one ID object per call)
720
763
Plugin_052_build_modbus_MEI_frame (slaveAddress, 4 , object_id);
721
764
const byte process_result = Plugin_052_processCommand ();
722
765
if (process_result == 0 ) {
723
766
result = Plugin_052_parse_modbus_MEI_response (object_value_int,
724
- next_object_id, more_follows);
767
+ next_object_id, more_follows,
768
+ conformity_level);
725
769
} else {
726
770
more_follows = false ;
727
771
}
@@ -733,14 +777,15 @@ void Plugin_052_modbus_log_MEI(byte slaveAddress) {
733
777
// Modbus command (0x2B / 0x0E) Read Device Identification
734
778
// And add to log.
735
779
bool more_follows = true ;
780
+ byte conformity_level = 0 ;
736
781
byte object_id = 0 ;
737
782
byte next_object_id = 0 ;
738
783
while (more_follows) {
739
784
String result;
740
785
unsigned int object_value_int;
741
786
const byte process_result = Plugin_052_modbus_get_MEI (
742
787
slaveAddress, object_id, result, object_value_int, next_object_id,
743
- more_follows);
788
+ more_follows, conformity_level );
744
789
if (process_result == 0 ) {
745
790
if (result.length () > 0 ) {
746
791
String log = Plugin_052_MEI_objectid_to_name (object_id);
@@ -758,6 +803,8 @@ void Plugin_052_modbus_log_MEI(byte slaveAddress) {
758
803
break ;
759
804
}
760
805
}
806
+ // If more parts are needed, collect them or iterate over the known list.
807
+ // For example with "individual access" a new request has to be sent for each single item
761
808
if (more_follows) {
762
809
object_id = next_object_id;
763
810
} else if (object_id < 0x84 ) {
@@ -814,6 +861,14 @@ int Plugin_052_readErrorStatus(void) {
814
861
return Plugin_052_readInputRegister (0x00 );
815
862
}
816
863
864
+ uint32_t Plugin_052_readTypeId () {
865
+ return Plugin_052_read_32b_InputRegister (25 );
866
+ }
867
+
868
+ uint32_t Plugin_052_readSensorId () {
869
+ return Plugin_052_read_32b_InputRegister (29 );
870
+ }
871
+
817
872
int Plugin_052_readCo2 (void ) { return Plugin_052_readInputRegister (0x03 ); }
818
873
819
874
int Plugin_052_readCo2_from_RAM (void ) {
@@ -888,7 +943,7 @@ bool Plugin_052_prepare_single_measurement_from_RAM() {
888
943
889
944
float Plugin_052_readTemperature (void ) {
890
945
int temperatureX100 = Plugin_052_readInputRegister (0x04 );
891
- float temperature = (float )temperatureX100 / 100 ;
946
+ float temperature = (float )temperatureX100 / 100.0 ;
892
947
return temperature;
893
948
}
894
949
0 commit comments