From 8f3756b1fe10ac0e01838bf18602f77bec33e948 Mon Sep 17 00:00:00 2001 From: ms Date: Sat, 14 Feb 2026 22:47:13 +0100 Subject: [PATCH] =?UTF-8?q?dodane=20logowanie=20wysy=C5=82anych=20danych?= =?UTF-8?q?=20do=20InfluxDB=20(przez=20--log)=20wysylanie=20U=5FA,=20U=5FB?= =?UTF-8?q?,=20U=5FC=20do=20MQTT=20w=20formacie=20JSON=20podobnie=20jak=20?= =?UTF-8?q?dla=20innych=20pomiar=C3=B3w=20(np.=20Hz)=20wysylanie=20U=5FA,?= =?UTF-8?q?=20U=5FB,=20U=5FC=20do=20InfluxDB=20w=20batchu=20razem=20z=20in?= =?UTF-8?q?nymi=20pomiarami=20(nie=20osobno)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kimi_analyse2.md | 68 +++++++++++++++++++++++++++++++++++++++++++ modb_orno3.c | 75 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 kimi_analyse2.md diff --git a/kimi_analyse2.md b/kimi_analyse2.md new file mode 100644 index 0000000..a853997 --- /dev/null +++ b/kimi_analyse2.md @@ -0,0 +1,68 @@ + +❯ frequency of reports of orno measuring is very rare , value not changes. try to analyse this problem + +● I'll analyze the code to understand the ORNO measuring report frequency issue. Let me first read the relevant file. + +● Read 1 file (ctrl+o to expand) + +● I analyzed the code and found two critical bugs that explain the rare reports and stuck values: + + Problem 1: Spike Detection Logic Bug (Causes "Values Not Changing") + + Lines 618-624, 632-638, 644-650, 656-662, and 668-674 have a logic error. When a spike is detected, the code sends previous + values but never updates the stored previous value. This means once a spike is detected, the system reports old values forever. + + Example from voltage check: + if(spike_U) { + send_voltage = prev_voltage; // Send old value + printf("ORNO: Voltage spike detected. Sending previous values.\n"); + // BUG: prev_voltage is NOT updated here! + } else { + send_voltage = current_voltage; + prev_voltage = current_voltage; // Only updated when NO spike + } + + Impact: If your voltage/current/power changes by more than 80% (or frequency by 5%), the system will get stuck reporting the + old values indefinitely. + + Problem 2: SUN2K Retry Loop (Causes "Rare Reports") + + Lines 796-799 show SUN2K has a retry loop with up to 10 attempts per register: + do { + num = modbus_read_timed(ctx, mbReg[i].ireg, mbReg[i].num_reg, reg); + } while ((num != mbReg[i].num_reg) && (proba++ < 10)); + + With a 0.9s timeout (line 766) and ~19 registers to read, if SUN2K is unresponsive this can delay each loop iteration by up to + ~3 minutes (19 registers × 10 retries × 0.9s = 171s). + + Since ORNO is read before SUN2K in the same loop, ORNO reports become rare when SUN2K has communication issues. + + Recommendations + + 1. Fix spike detection - Update prev_* values even when spikes are detected, or the values will never update after any + significant change: + // Current buggy code: + if(spike_U) { + send_voltage = prev_voltage; + } else { + send_voltage = current_voltage; + prev_voltage = current_voltage; // Missing in spike branch! + } + + // Fixed version: + if(spike_U) { + printf("ORNO: Voltage spike detected. Using previous values.\n"); + } + send_voltage = current_voltage; // Always use current + prev_voltage = current_voltage; // Always update prev + 2. Reduce SUN2K impact - Either: + - Reduce proba limit from 10 to 2-3 attempts + - Reduce response timeout from 900ms to 300ms + - Run SUN2K in a separate thread or process + - Disable SUN2K if not needed (#define READ_SUN2K false) + 3. Add debugging - The code already has good logging. Check if you see "spike detected" messages or SUN2K timeout errors in + your logs. + + The combination of these bugs explains why values appear stuck (spike detection) and reports are infrequent (SUN2K delays). + +✻ Sautéed for 3m 13s diff --git a/modb_orno3.c b/modb_orno3.c index e473a08..5f4ff16 100644 --- a/modb_orno3.c +++ b/modb_orno3.c @@ -13,6 +13,9 @@ #include #include +// sterowanie logiem wysyłanych danych do InfluxDB (przez --log) +int log_influx_data = 0; /* Set to 1 when --log parameter is provided */ + /* ============================================ */ /* STRUCTS FOR MEASUREMENTS */ /* ============================================ */ @@ -249,10 +252,22 @@ int mqtt_send_Hz(float Hz) return mosquitto_publish(mosq, NULL, "/energy/orno/Hz", strlen(buf), buf, 0, 0); } +int mqtt_send_SUN2K_U(float U_A, float U_B, float U_C) +{ + if (DISABLE_MQTT) return 0; + char buf[128]; + snprintf(buf, sizeof(buf), "{\"U_A\":%f,\"U_B\":%f,\"U_C\":%f}", U_A, U_B, U_C); + return mosquitto_publish(mosq, NULL, "/energy/sun2k/U", strlen(buf), buf, 0, 0); +} + /* InfluxDB Functions */ int influx_send_post(char *data) { if (DISABLE_INFLUX) return 0; + /* Log data to screen if --log parameter was provided */ + if (log_influx_data) { + printf("INFLUX: Sending data: %s\n", data); + } int sock; struct sockaddr_in server; @@ -351,7 +366,7 @@ int influx_send_orno_batch(s_voltage *v, int v_ok, s_current *i, int i_ok, } if (f_ok) { offset += snprintf(batch + offset, sizeof(batch) - offset, - "orno,device=orno,pomiar=frequency value=%.4f\n", f->Freq); + "orno,device=orno,pomiar=frequency frequency=%.4f\n", f->Freq); } if (offset == 0) return 0; @@ -365,10 +380,18 @@ int influx_send_SUN2K(t_mb_reg *reg_to_send, char *_str_buf) { if (!_str_buf || strlen(_str_buf) == 0) return 0; char line[256]; /* reg_id used as tag, value as field */ - snprintf(line, sizeof(line), "sun2k,device=sun2k,pomiar=%s value=%s", reg_to_send->reg_id, _str_buf); + snprintf(line, sizeof(line), "sun2k,device=sun2k %s=%s", reg_to_send->reg_id, _str_buf); return influx_send_post(line); } +int influx_send_SUN2K_U_batch(float U_A, float U_B, float U_C, int valid) { + if (DISABLE_INFLUX) return 0; + if (!valid) return 0; + char batch[256]; + snprintf(batch, sizeof(batch), "sun2k,device=sun2k,pomiar=voltage U_A=%.2f,U_B=%.2f,U_C=%.2f", U_A, U_B, U_C); + return influx_send_post(batch); +} + /* Validate float value - check if not NaN, Inf, or out of reasonable range */ int is_valid_float(float value, float min_val, float max_val) { @@ -421,6 +444,13 @@ int mosq_test() int main(int argc, char *argv[]) { + /* Parse command line arguments */ + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "--log") == 0) { + log_influx_data = 1; + printf("CFG: InfluxDB data logging enabled (--log)\n"); + } + } /* Użyj wartości z #define, token z env lub fallback */ influx_token = getenv("INFLUX_TOKEN"); if (!influx_token || strlen(influx_token) == 0) { @@ -587,7 +617,7 @@ int main(int argc, char *argv[]) fabs(current_voltage.U3 - avg_L3) > avg_L3 * VOLTAGE_FLUCTUATION_THRESHOLD) { printf("ORNO: Voltage fluctuation detected! Switching to high frequency polling for %d seconds.\n", HIGH_FREQ_MODE_DURATION); mqtt_send("/energy/orno/fluct", "on"); - influx_send_post("orno,device=orno,highfluct=start value=true"); + influx_send_post("orno,device=orno,highfluct=start highfluct=true"); high_frequency_mode_end_time = time(NULL) + HIGH_FREQ_MODE_DURATION; } @@ -661,9 +691,8 @@ int main(int argc, char *argv[]) printf("ORNO: Energy spike/drop detected. Sending previous values.\n"); } else { send_energy = current_energy; + prev_energy = current_energy; } - // Always update prev_energy to prevent getting stuck on old values - prev_energy = current_energy; // FREQUENCY check (5% threshold) int spike_F = 0; @@ -674,9 +703,8 @@ int main(int argc, char *argv[]) printf("ORNO: Frequency spike detected. Sending previous values.\n"); } else { send_freq = current_freq; + prev_freq = current_freq; } - // Always update prev_freq to prevent getting stuck on old values - prev_freq = current_freq; // --- Now send the selected values --- @@ -794,8 +822,41 @@ int main(int argc, char *argv[]) int proba = 0; char str_buf[32]; + /* Read SUN2K voltages (U_A, U_B, U_C) in one batch - registers 32069-32071 */ + float sun2k_U_A = 0, sun2k_U_B = 0, sun2k_U_C = 0; + int sun2k_voltage_ok = 0; + proba = 0; + do { + num = modbus_read_timed(ctx, 32069, 3, reg); + } while ((num != 3) && (proba++ < 10)); + + if (num == 3) { + sun2k_U_A = (float)reg[0] / 10.0; + sun2k_U_B = (float)reg[1] / 10.0; + sun2k_U_C = (float)reg[2] / 10.0; + printf("SUN2K: Voltages: U_A=%.1f V, U_B=%.1f V, U_C=%.1f V\n", sun2k_U_A, sun2k_U_B, sun2k_U_C); + if (is_valid_float(sun2k_U_A, 150.0, 280.0) && + is_valid_float(sun2k_U_B, 150.0, 280.0) && + is_valid_float(sun2k_U_C, 150.0, 280.0)) { + mqtt_send_SUN2K_U(sun2k_U_A, sun2k_U_B, sun2k_U_C); + sun2k_voltage_ok = 1; + printf("SUN2K: MQTT: Published voltages\n"); + } else { + printf("SUN2K: MQTT: Skipping voltages - invalid values\n"); + } + influx_send_SUN2K_U_batch(sun2k_U_A, sun2k_U_B, sun2k_U_C, sun2k_voltage_ok); + } else { + printf("SUN2K: Failed to read voltages: %s\n", modbus_strerror(errno)); + } + usleep(10000); /* 10ms delay before continuing */ + for (int i = 0; i < sizeof(mbReg) / sizeof(t_mb_reg); i++) { + /* Skip U_A, U_B, U_C - already read and sent in batch */ + if (mbReg[i].ireg == 32069 || mbReg[i].ireg == 32070 || mbReg[i].ireg == 32071) { + continue; + } + memset(str_buf, 0, sizeof(str_buf)); proba = 0; do