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.
https://github.com/oliveres/Loxone-ZivyObraz/tree/main
Stačilo použít blok Klouzavý průměr nebo jak se to teď jmenuje.