#pragma once #include enum class FaultType : uint8_t { None = 0, MeterRead = 1, Decode = 2, LoraTx = 3 }; enum class RxRejectReason : uint8_t { None = 0, CrcFail = 1, InvalidMsgKind = 2, LengthMismatch = 3, DeviceIdMismatch = 4, BatchIdMismatch = 5 }; struct FaultCounters { uint32_t meter_read_fail; uint32_t decode_fail; uint32_t lora_tx_fail; }; struct MeterData { uint32_t ts_utc; uint16_t short_id; char device_id[16]; bool energy_multi; uint8_t energy_meter_count; uint32_t energy_kwh_int[3]; float energy_total_kwh; float phase_power_w[3]; float total_power_w; float battery_voltage_v; uint8_t battery_percent; bool valid; int16_t link_rssi_dbm; float link_snr_db; bool link_valid; uint32_t err_meter_read; uint32_t err_decode; uint32_t err_lora_tx; FaultType last_error; uint8_t rx_reject_reason; }; struct SenderStatus { MeterData last_data; uint32_t last_update_ts_utc; uint16_t last_acked_batch_id; bool has_data; }; void init_device_ids(uint16_t &short_id, char *device_id, size_t device_id_len); const char *rx_reject_reason_text(RxRejectReason reason);