Forum
Ahoj, potřebuji posílat data ven z Miniserveru, ale ne každou změnu, ale průměrnou hodnotu za 5 minut (podmínka vizualizačního serveru). Takový funkční blok nebo možnost tuto funkci sestavit z více bloku jsem v Loxone Configu nenašel a tak jsem začal bádat jak napsat Pico C program, který tuto funkci udělá (v NodeRED je toto napříkad easy). Požádal jsem umělou inteligenci aby mi tento skript napsala a výsledek je, že mám jednu funkční verzi, která prochází if podmínkami 4 analogové vstupy a průměry za 5 minut posílá na výstupy. Problém je, když chci prográmek zjednodušit cyklem for, ten prostě nějak nechce za žádnou cenu fungovat. Řešil někdo něco podobného?
Zde je funkční kód
int nEvents; float sum[4] = {0, 0, 0, 0}; // Pole součtů pro každý vstup int count[4] = {0, 0, 0, 0}; // Pole počtů přijatých hodnot pro každý vstup unsigned int startTime = getcurrenttime(); // Počáteční čas pro měření 5 minutového intervalu while (TRUE) { nEvents = getinputevent(); if (nEvents & 0xf) { // Kontrola změny na prvních čtyřech analogových vstupech float input_value0 = getinput(0); // Získání hodnoty z vstupu č. 1 sum[0] += input_value0; // Přidání hodnoty do součtu pro první vstup count[0]++; // Inkrementace počtu přijatých hodnot pro první vstup float input_value1 = getinput(1); // Získání hodnoty z vstupu č. 2 sum[1] += input_value1; // Přidání hodnoty do součtu pro druhý vstup count[1]++; // Inkrementace počtu přijatých hodnot pro druhý vstup float input_value2 = getinput(2); // Získání hodnoty z vstupu č. 3 sum[2] += input_value2; // Přidání hodnoty do součtu pro třetí vstup count[2]++; // Inkrementace počtu přijatých hodnot pro třetí vstup float input_value3 = getinput(3); // Získání hodnoty z vstupu č. 4 sum[3] += input_value3; // Přidání hodnoty do součtu pro čtvrtý vstup count[3]++; // Inkrementace počtu přijatých hodnot pro čtvrtý vstup } if (getcurrenttime() - startTime >= 30) { // Každých 300 sekund (5 minut) int i = 0; do { if (count[i] > 0) { float average = sum[i] / count[i]; // Výpočet průměrné hodnoty pro i-tý vstup setoutput(i, average); // Odeslání průměrné hodnoty na i-tý výstup sum[i] = 0; // Reset součtu pro i-tý vstup count[i] = 0; // Reset počtu přijatých hodnot pro i-tý vstup } i++; } while (i < 4); startTime = getcurrenttime(); // Restart časovače pro další 5 minutový interval } sleep(100); // Krátké zpoždění pro zamezení zbytečného zatížení CPU }
A zde nefunkční
char szBuffer[128]; float sum[4] = {0, 0, 0, 0}; int count[4] = {0, 0, 0, 0}; unsigned int startTime = getcurrenttime(); while (TRUE) { int nEvents = getinputevent(); if (nEvents & 0x07f8) { // Check if any of the 8 analog inputs changed for (int i = 0; i < 4; i++) { int mask = 0x08 << i; // Bitmask for each analog input (AI1 to AI4) if (nEvents & mask) { float input_value = getinput(i); sum[i] += input_value; count[i]++; } } } if (getcurrenttime() - startTime >= 300) { // Every 300 seconds (5 minutes) for (int i = 0; i < 4; i++) { if (count[i] > 0) { float average = sum[i] / count[i]; setoutput(i, average); sum[i] = 0; count[i] = 0; } } startTime = getcurrenttime(); } sleep(100); }
Tak hotovo, podařilo se mi to vyřešit a zde je výsledný kód, jdu na to nakonec jinak, protože monitorování změn se nehodí do Loxone, pokud nedojde ke změně na vstupu, nic se nezmění ani na výstupu, což je chyba například při měření spotřeby a podobně. Zde je celý kód otestovaný a funkční, kdyby to někdo potřeboval.
Stačilo použít blok Klouzavý průměr nebo jak se to teď jmenuje.