diff --git a/software/src/modules/meters_modbus_tcp/generic_modbus_tcp_client.cpp b/software/src/modules/meters_modbus_tcp/generic_modbus_tcp_client.cpp index 13ac4e111..737d39d02 100644 --- a/software/src/modules/meters_modbus_tcp/generic_modbus_tcp_client.cpp +++ b/software/src/modules/meters_modbus_tcp/generic_modbus_tcp_client.cpp @@ -80,15 +80,17 @@ void GenericModbusTCPClient::read_next() static_cast(connected_client)->read(data_type, device_address, read_start_address, read_count, target_buffer, 2000000, [this](TFModbusTCPClientTransactionResult result) { if (result != TFModbusTCPClientTransactionResult::Success) { - logger.printfln("Modbus read failed: %s (%d) client=%p host_name='%s' port=%u device_address=%u start_address=%u register_count=%u", - get_tf_modbus_tcp_client_transaction_result_name(result), - static_cast(result), - static_cast(connected_client), - host_name.c_str(), - port, - device_address, - generic_read_request.start_address, - generic_read_request.register_count); + if (result != TFModbusTCPClientTransactionResult::Timeout) { + logger.printfln("Modbus read failed: %s (%d) client=%p host_name='%s' port=%u device_address=%u start_address=%u register_count=%u", + get_tf_modbus_tcp_client_transaction_result_name(result), + static_cast(result), + static_cast(connected_client), + host_name.c_str(), + port, + device_address, + generic_read_request.start_address, + generic_read_request.register_count); + } generic_read_request.result = result; generic_read_request.done_callback(); diff --git a/software/src/modules/meters_modbus_tcp/meter_modbus_tcp.cpp b/software/src/modules/meters_modbus_tcp/meter_modbus_tcp.cpp index eeb0952d7..0f1b4cd7e 100644 --- a/software/src/modules/meters_modbus_tcp/meter_modbus_tcp.cpp +++ b/software/src/modules/meters_modbus_tcp/meter_modbus_tcp.cpp @@ -1074,17 +1074,22 @@ bool MeterModbusTCP::is_carlo_gavazzi_em510() const void MeterModbusTCP::read_done_callback() { if (generic_read_request.result != TFModbusTCPClientTransactionResult::Success) { - logger.printfln("Modbus error reading %s / %s (address: %zu, number: %zu): %s [%d]", - get_meter_modbus_tcp_table_id_name(table_id), - table->specs[read_index].name, - table->specs[read_index].start_address, - table->specs[read_index].start_address + 1, - get_tf_modbus_tcp_client_transaction_result_name(generic_read_request.result), - static_cast(generic_read_request.result)); + if (generic_read_request.result == TFModbusTCPClientTransactionResult::Timeout) { + auto modbus_timeout = errors->get("modbus_timeout"); + modbus_timeout->updateUint(modbus_timeout->asUint() + 1); + } + else { + logger.printfln("Modbus error reading %s / %s (address: %zu, number: %zu): %s [%d]", + get_meter_modbus_tcp_table_id_name(table_id), + table->specs[read_index].name, + table->specs[read_index].start_address, + table->specs[read_index].start_address + 1, + get_tf_modbus_tcp_client_transaction_result_name(generic_read_request.result), + static_cast(generic_read_request.result)); + } read_allowed = true; register_buffer_index = METER_MODBUS_TCP_REGISTER_BUFFER_SIZE; - return; } diff --git a/software/src/modules/meters_modbus_tcp/meters_modbus_tcp.cpp b/software/src/modules/meters_modbus_tcp/meters_modbus_tcp.cpp index 6b77e740e..9a8f7d733 100644 --- a/software/src/modules/meters_modbus_tcp/meters_modbus_tcp.cpp +++ b/software/src/modules/meters_modbus_tcp/meters_modbus_tcp.cpp @@ -174,6 +174,10 @@ void MetersModbusTCP::pre_setup() )}, }); + errors_prototype = Config::Object({ + {"modbus_timeout", Config::Uint32(0)}, + }); + meters.register_meter_generator(get_class(), this); } @@ -200,5 +204,5 @@ const Config *MetersModbusTCP::get_state_prototype() const Config *MetersModbusTCP::get_errors_prototype() { - return Config::Null(); + return &errors_prototype; } diff --git a/software/src/modules/meters_modbus_tcp/meters_modbus_tcp.h b/software/src/modules/meters_modbus_tcp/meters_modbus_tcp.h index dec1a5d52..1770b98a6 100644 --- a/software/src/modules/meters_modbus_tcp/meters_modbus_tcp.h +++ b/software/src/modules/meters_modbus_tcp/meters_modbus_tcp.h @@ -51,6 +51,7 @@ class MetersModbusTCP final : public IModule, public MeterGenerator Config config_prototype; Config table_custom_registers_prototype; std::vector> table_prototypes; + Config errors_prototype; }; #if defined(__GNUC__) diff --git a/software/src/modules/meters_sun_spec/meter_sun_spec.cpp b/software/src/modules/meters_sun_spec/meter_sun_spec.cpp index 9b0168500..4a46456e5 100644 --- a/software/src/modules/meters_sun_spec/meter_sun_spec.cpp +++ b/software/src/modules/meters_sun_spec/meter_sun_spec.cpp @@ -131,7 +131,16 @@ void MeterSunSpec::read_done_callback() read_allowed = true; if (generic_read_request.result != TFModbusTCPClientTransactionResult::Success) { - logger.printfln("Modbus read error: %s (%d)", get_tf_modbus_tcp_client_transaction_result_name(generic_read_request.result), static_cast(generic_read_request.result)); + if (generic_read_request.result == TFModbusTCPClientTransactionResult::Timeout) { + auto modbus_timeout = errors->get("modbus_timeout"); + modbus_timeout->updateUint(modbus_timeout->asUint() + 1); + } + else { + logger.printfln("Modbus read error: %s (%d)", + get_tf_modbus_tcp_client_transaction_result_name(generic_read_request.result), + static_cast(generic_read_request.result)); + } + return; } diff --git a/software/src/modules/meters_sun_spec/meters_sun_spec.cpp b/software/src/modules/meters_sun_spec/meters_sun_spec.cpp index 2d6017c52..8cf57cc1a 100644 --- a/software/src/modules/meters_sun_spec/meters_sun_spec.cpp +++ b/software/src/modules/meters_sun_spec/meters_sun_spec.cpp @@ -61,6 +61,10 @@ void MetersSunSpec::pre_setup() {"model_instance", Config::Uint16(0)}, }); + errors_prototype = Config::Object({ + {"modbus_timeout", Config::Uint32(0)}, + }); + meters.register_meter_generator(get_class(), this); scan_config = ConfigRoot{Config::Object({ @@ -652,7 +656,7 @@ const Config *MetersSunSpec::get_state_prototype() [[gnu::const]] const Config *MetersSunSpec::get_errors_prototype() { - return Config::Null(); + return &errors_prototype; } MetersSunSpec::ScanState MetersSunSpec::scan_get_next_state_after_read_error() diff --git a/software/src/modules/meters_sun_spec/meters_sun_spec.h b/software/src/modules/meters_sun_spec/meters_sun_spec.h index 8b4a829e9..42e103102 100644 --- a/software/src/modules/meters_sun_spec/meters_sun_spec.h +++ b/software/src/modules/meters_sun_spec/meters_sun_spec.h @@ -77,6 +77,7 @@ class MetersSunSpec final : public IModule, public MeterGenerator [[gnu::format(__printf__, 2, 3)]] void scan_printfln(const char *fmt, ...); Config config_prototype; + Config errors_prototype; TFModbusTCPClient client; ConfigRoot scan_config;