Wątek przeniesiony 2020-02-25 12:12 z C/C++ przez Shalom.

Poprawienie programu do monitorowania fotowoltaiki

0

Witam
próbowałem poprawić program do monitorowania fotowoltaiki aby działało na trzy falowniki aktualnie program pobierany z strony działa na dwa falowniki oto link do programu https://sourceforge.net/projects/auroramonitor/files/auroramon-1.07/
niestety mój efekt nie jest taki jak oczekiwalem grafika mi się rozjechała lub po nakładała, nie mogę wczytać w codeblock plików zródłowych brak pliku wx lub za mała wiedza , program napisany w c++ z dodatkiem wx 2.8
czy jest ktoś na tyle dobry w c++ aby to poprawił na trzy falowniki ?

Dodam wersje co ja próbowałem poprawiać ale nie działa jak powinno , zrobiłem zmiany wielkości okien bo się nie mieściły dane lub zlewały , spolszczyłem program w dużym stopniu , poprawiłem plik make

1

Obawiam się, że do takiego problemu nikt za darmo nie usiądzie. Możesz jedynie liczyć na łut szczęścia, że któryś z forumowiczów przerabiał kiedyś taki problem sam, ale to dość niszowa sprawa także nie łudziłbym się.

Więcej szczęścia miałbyś postując w Ogłoszenia drobne.

0

program nie przynosi żadnych dochodów to dla wiedzy jak działa fotowoltaika i ile generuje prądu , może kasa to nie wszystko i ktoś z większą wiedzą niż moja poprawi to na trzy falowniki

0

Gdyby ten kod miał przyzwoitą jakość, to by się znalazł ktoś, kto to zrobi (np ja).
Niestety najpierw trzeba przebić się przez krzaczory.
Mi wystarczy trafiać w pracy na takie krzaczory.

5

Strasznie ciężko czyta się ten kod.
Ale może to ci pomoże:
Szybka analiza wskazała mi że istnieje define N_INV, prawdopodobnie wystarczy zmienić w nim wartość, oraz przekompilować kod.

auroramon.h:#define N_INV     2      // max. of 2 inverters
0

niestety sama zmiana jednej linijki nic nie daje , ja zmieniłem sporo linijek kodu ale poruszanie się w zmiennej Y X trochę ciężko jest poustawiać grafikę , niestety grafika mi się rozjechała :(
ok może się spróbuje w ten sposób na forum to co nie wiem jak zrobić
kod

    for(ix=0; ix<N_PANEL_GROUPS; ix++)
    {
            pConfig->SetPath(wxString::Format(_T("/panelgroup%d"), ix));
            pConfig->Read(_T("tilt"), &panel_groups[ix].tilt, 0);
            pConfig->Read(_T("facing"), &panel_groups[ix].facing, 0);
    }

jak dopisac aby robilo w pliku conf
[panelgroup2]
tilt=0
facing=0

0

IMHO przerobienie tego kodu aby obsługiwał **trzy **falowniki nie jest sprawą trywialną w stylu zmienimy wartość w #define z **dwóch **na **trzy **i wszystko będzie dobrze.
Niestety nie obejdzie się bez gruntownego "przegryzienia" przez ten kod. W najlepszym razie będzie trzeba zmienić tylko kod bezpośrednio powiązany z tablicami.

INVERTER inverters[N_INV];
int inverter_address[N_INV] = {2, 0};

Patrząc na ten kod, ma ochotę napisać go jeszcze raz w jakimś innym IDE (np. Qt), i kto wie czy nie okazało by się to najszybszym rozwiązaniem.

0

TomaszLiMoon jeśli potrafisz to napisać w inny sposób aby działało to na trzy falowniki jestem bardzo ciekawy jak to będzie działać i efekt końcowy , na razie mam dwa falowniki ale nie długo będę miał trzeci , chwilowo pogoda nie pozwala na prace na zewnątrz wiec czekam na pogodę bardziej przyjazna , chciał bym zwrócić uwagę że program działa na raspberry pi wiec styl pisania tylko na windowsa odpada

1

Jeśli niekoniecznie chcesz mieć ten programik to zrobiłem mały rekonesans i znalazłem kilka innych alternatywnych rozwiązań:
http://www.curtronics.com/Solar/AuroraData.html
https://openenergymonitor.org/forum-archive/node/10536.html
Może akurat po małych zmianach Ci podpasuje. Patrzyłem też po tym "twoim" programiku i niestety ale to się nadaje tylko do napisania od nowa ;)

0

tomasz3dk miło że podsyłasz mi te linki ale już testowałem wszystko co tylko możliwe ten program aurora też , jak nadal najlepszy jest auroramon tylko brakuje opcji więcej niż dwa falowniki to jak na razie to największy błąd programu , gdyby był napisany na 64 falowniki to by był najlepszy z wszystkich co znam i testowałem

0

BTW można gdzieś znaleźć opis tego protokołu? Bo jak na razie to widzę to na necie można tylko znaleźć konwertery protokołu od ABB na modbus.

0

Tu powinno być https://new.abb.com/pl , jeśli nie ma to trzeba pisać do suport , po zarejestrowaniu jest panel z plikami update i fimware plus opisy w doc

2

Tutaj dostępny jest protokół/interfejs komunikacji z inwerterem. Mam nadzieję że jest to właściwy model.

0

TomaszLiMoon na to wygląda że to ten model PowerOne Aurora Inverters
teraz czy może się ktoś pochwalić wiedza i coś extra napisać na więcej niż 2 falowniki , najlepiej na 64 ( ale to marzenie !) , aby to współpracowało z https://pvoutput.org

chyba protokoły abb to są takie same na aurora bo firma abb przejęła firme aurora , firma auorora prawdopodobnie wymyśliła najlepszy protokół do falowników na fotowoltaike ale Chińczycy to skopiowali i aurora padła , aurora zrobiła falowniki wyprzedzające czasy obecne , chniny to uprościły i zrobili podobne w niskiej cenie tak mi powiedział kolega elektronik co to naprawia

0

Moze ktos mi z tym pomoże dodalem style 4 ale mi sie rozjechały okienka

void Mainframe::SetupStatusPanel(int control)
{//=========================================
// control bit 0: inverter addresses may have changed

// style 0:  show all
//         1:  show some
//         2:  show all inverter 0
//         3:  show all inverter 1

    int ix;
    int style;

    if(control & 1)
    {
        for(ix=0; ix<N_INV; ix++)
        {
            if(inverter_address[ix] == 0)
            {
                power_total[ix] = 0;
                inverters[ix].alive = 0;
            }
            else
            {
                txt_static[ix][0]->SetLabel(wxString::Format(_T("Falownik #%d"), inverter_address[ix]));
            }
        }
    }

    if(control & 2)
    {
        for(ix=0; ix < N_EXTRA_READINGS; ix++)
        {
            txt_dsp_param[0][ix]->Clear();
            txt_dsp_param[1][ix]->Clear();
            txt_dsp_param[2][ix]->Clear();
        }
    }

    style = chart_pages[graph_panel->page].status_type;

    if(inverter_address[1] == 0)
    {
        // only one inverter;
        PlaceReadings(1, 0,   0, false);
        PlaceReadings(1, 1,   0, false);
        PlaceReadings(2, 0, 149, true);
        PlaceReadings(2, 1,   0, false);
        PlaceReadings(3, 0, 423, true);
        PlaceReadings(3, 1,   0, false);
        PlaceReadings(4, 0, 749, true);
        PlaceReadings(4, 1,   0, false);
    }
    else
    {
        PlaceReadings(1, 0, 149, true);
        if(style == 0)
        {
            // all
            PlaceReadings(2, 0, 239, true);
            PlaceReadings(1, 1, 518, true);
            PlaceReadings(2, 1, 608, true);
            PlaceReadings(3, 0, 887, true);
            PlaceReadings(3, 1, 1207, true);
            PlaceReadings(4, 0, 1527, true);
            PlaceReadings(4, 1,   0, false);
        }
        if(style == 1)
        {
            // some
            PlaceReadings(2, 0, 239, true);
            PlaceReadings(1, 1, 509, true);
            PlaceReadings(2, 1, 599, true);
            PlaceReadings(3, 0,   0, false);
            PlaceReadings(3, 1,   0, false);
            PlaceReadings(4, 0, 931, true);
            PlaceReadings(4, 1,   0, false);
            PlaceReadings(5, 0, 861, true);
        }
        if(style == 2)
        {
            // inverter A
            PlaceReadings(2, 0, 239, true);
            PlaceReadings(1, 1, 831, true);
            PlaceReadings(2, 1,   0, false);
            PlaceReadings(3, 0, 511, true);
            PlaceReadings(3, 1,   0, false);
            PlaceReadings(4, 0, 931, true);
            PlaceReadings(4, 1,   0, false);
        }
        if(style == 3)
        {
            // inverter B
            PlaceReadings(2, 0,   0, false);
            PlaceReadings(1, 1, 259, true);
            PlaceReadings(2, 1, 349, true);
            PlaceReadings(3, 0,   0, false);
            PlaceReadings(3, 1, 611, true);
            PlaceReadings(4, 0,   0, false);
            PlaceReadings(4, 1, 931, true);
        }
        if(style == 4)
        {
            // inverter C
            PlaceReadings(2, 0,   0, false);
            PlaceReadings(1, 1, 259, true);
            PlaceReadings(2, 1, 349, true);
            PlaceReadings(3, 0,   0, false);
            PlaceReadings(3, 1, 611, true);
            PlaceReadings(4, 0,   0, false);
            PlaceReadings(4, 1, 931, true);
        }

    }

    for(ix=0; ix<N_INV; ix++)
    {
        ShowEnergy(ix);
        txt_energy[ix][1]->ChangeValue(wxString::Format(_T("%d"), inverters[ix].peak));
    }
}
0

Zmiany są niewystarczające. Zobacz niżej funkcję PlaceReadings, co przyjmuje za parametry. Teraz tylko powieliłeś drugi inwerter. Tu są potrzebne o wiele większe modyfikacje - drugi parametr to z tego co widzę numer inwertera, więc nie możesz się poruszać tylko w zakresie 0-1, trzeci to pozycja, czwarty to wyświetlanie/ukrywanie. Niżej (już za tym, co wkleiłeś, dalej w kodzie) pętle for też są niewystarczające przy < 2, bo będziesz iterować tylko dwa inwertery - 0 i 1. Jeśli dobrze się w to wgryzłem na szybko.

Niestety jak pisano wyżej - kod jest w kiepskim stanie, dość chaotyczny i często z wpisanymi na sztywno różnymi wartościami. Nawet w tym kawałku wstawionym przez Ciebie nie wiem po co autor wywołuje PlaceReadings, których wynik później ukrywa, nie wiem też czemu w style 2 w drugiej linii nagle ma pokazywać jeden odczyt dla inwertera B. Tak wiele pytań, tak mało odpowiedzi :D

Zgadzam się z opiniami, że sytuacja jest zasadniczo beznadziejna, przerobienie tego to jest wiele dni ciężkiego klepania. Bez sprzętu ciężkie do testowania. Może raczej powinieneś zaatakować temat gdzieś wśród posiadaczy i pasjonatów takiego sprzętu? Jeśli wpadniesz na programistę, który z tego jednocześnie korzysta, to prędzej do tego siądzie niż my tutaj. Ja mam zerowe pojęcie o fotowoltaice i w wielu przypadkach nawet bym nie rozumiał ocb.

0

BDA DVB napisałeś mi wyjaśniając że ten program nie jest łatwy do przerobienia , mecze go dość długo i nie udało mi się zrobić , probowałem aurora-1.9.3 ale niestety napisany na jeden falownik , nie można zsumować wyników , mój test zapytania

pi@raspberrypi:~$ aurora -a 2 /dev/ttyUSB0 -Y15 -e -c
      0.127        0.127        0.000       84.688      147.558    23162.340      172.785    OK
pi@raspberrypi:~$ aurora -a 2 -a 3 /dev/ttyUSB0 -Y15 -e -c
      0.105        0.105        0.000      144.137      185.298     8390.067     8390.035    OK
pi@raspberrypi:~$ aurora -a 3 /dev/ttyUSB0 -Y15 -e -c
      0.106        0.106        0.000      144.138      185.299     8390.068     8390.035    OK
pi@raspberrypi:~$ aurora -a 2 -a 3 /dev/ttyUSB0 -Y15 -e -c
      0.106        0.106        0.000      144.138      185.299     8390.068     8390.036    OK
pi@raspberrypi:~$ aurora -a 2 -a 3 /dev/ttyUSB0 -Y15 -e -c
      0.106        0.106        0.000      144.138      185.299     8390.068     8390.036    OK
pi@raspberrypi:~$ aurora -a 2,3 /dev/ttyUSB0 -Y15 -e -c
      0.129        0.129        0.000       84.690      147.560    23162.342      172.787    OK
pi@raspberrypi:~$ aurora -a 2-3 /dev/ttyUSB0 -Y15 -e -c
      0.130        0.130        0.000       84.691      147.561    23162.343      172.788    OK
pi@raspberrypi:~$ aurora -a 3 /dev/ttyUSB0 -Y15 -e -c
      0.107        0.107        0.000      144.139      185.300     8390.069     8390.037    OK
pi@raspberrypi:~$ aurora -a 2 /dev/ttyUSB0 -Y15 -e -c
      0.131        0.131        0.000       84.692      147.562    23162.344      172.789    OK
pi@raspberrypi:~$ aurora -a 2 -a 3 /dev/ttyUSB0 -Y15 -e -c
      0.108        0.108        0.000      144.140      185.301     8390.070     8390.038    OK
pi@raspberrypi:~$

chyba że coś żle robię z zapytaniem , chciałem przerobić ten script na dwa lub 3 falowniki

#!/bin/bash

# configuration
apikey="your api key here"
system="your system Id here"

rd=$(date +%Y%m%d)
rt1=$(date +%H)
rt2=$(date +%M)
rt="${rt1}%3A${rt2}"
solarout=`/usr/local/bin/aurora -a 2 /dev/ttyUSB0 -Y15 -e -c | awk '{printf $1}'`
solarwatts=`echo ${solarout} | sed -e "s/\.//"`
url="https://pvoutput.org/service/r2/addstatus.jsp?d=${rd}&t=${rt}&v1=${solarwatts}"

# only make the request if we have a value from the inverter
if [[ ! -z $solarwatts  ]]; then
    result=`curl -H "X-Rate-Limit: 1" -H "X-Pvoutput-Apikey: ${apikey}" -H "X-Pvoutput-SystemId: ${system}" ${url}`
    if [[ $result == *"OK"* ]]; then
        echo "${rd} $(date +%H:%M) : API call successful, power output: ${solarout}"
    else
        echo "${rd} $(date +%H:%M) : API call failed, ${result}"
    fi
else
    echo "${rd} $(date +%H:%M) : Inverter communication failure"
fi

może w aurora-1.9.3 wystarczy dodać możliwość zdawania zapytania do dwóch lub więcej falowników coś w tym stylu aurora -a 2,3,4

0

Wywołuj sobie aurorę w skrypcie w pętli gdzie podajesz adres pojedynczego urządzenia.
np w bash:

for addr in 2 3; do
    aurora -a $addr /dev/ttyUSB0 -Y15 -e -c
done

Wtedy dostaniesz dane ze wszystkich urządzeń, a później sobie to w zależności od potrzeb obrób/wyślij etc.

0

problem jest tego typu ze dane na statystyki są przyjmowane od jednego urządzenia więc trzeba by to sumować i wysyłać tylko wyniki , nap falownik1 ma 107 falownika2 ma 131 więc suma do wysłania 238

pi@raspberrypi:$ aurora -a 3 /dev/ttyUSB0 -Y15 -e -c
0.107 0.107 0.000 144.139 185.300 8390.069 8390.037 OK
pi@raspberrypi:
$ aurora -a 2 /dev/ttyUSB0 -Y15 -e -c
0.131 0.131 0.000 84.692 147.562 23162.344 172.789 OK
czyli wysłanie powinno być 0.238
nie wiem czy wszystkie dane trzeba sumować czy tylko wybrane , napisałem do twórcy aurora i odpisał że zmodyfikuje kod na więcej adresów i mi to prześle żebym sprawdził czy działa bo on nie ma na czym po testować , może coś z tego będzie :) jeśli podeśle mi poprawkę

0
tomasz3dk napisał(a):

Wywołuj sobie aurorę w skrypcie w pętli gdzie podajesz adres pojedynczego urządzenia.
np w bash:

for addr in 2 3; do
    aurora -a $addr /dev/ttyUSB0 -Y15 -e -c
done

Wtedy dostaniesz dane ze wszystkich urządzeń, a później sobie to w zależności od potrzeb obrób/wyślij etc.

załóżmy ze te zapytanie daje taki wyniki 7 pozycji z liczbami 0.108 0.108 0.000 144.140 185.301 8390.070 8390.038 i trzeba to zsumować obojętnie ile damy liczb w addr w jaki sposób byś to zsumował ??

0

Prosty skrypt bash do sumowania wartości:

#!/bin/bash

INVERTERS="" # put iverters addresses here
# Example
#INVERTERS="1 2 15 39 40 55"
SOLARSUM="0.0"
for INVERTER in $INVERTERS; do
    SOLAROUT=$( /usr/local/bin/aurora -a $INVERTER /dev/ttyUSB0 -Y15 -e -c | awk '{printf $1}' )
    # Enample data for testing
    #SOLAROUT=$( echo "0.105        0.105        0.000      144.137      185.298     8390.067     8390.035    OK"  | awk '{printf $1}')
    if [[ ! -z $SOLAROUT ]]; then
        echo "Value from inverter $INVERTER: $SOLAROUT"
        SOLARSUM=$( echo "$SOLARSUM + $SOLAROUT" | bc -l )
    else
        echo "Error while reading from inverter on address: $INVERTER"
    fi
done
echo "Total value $SOLARSUM"

Jedynie będziesz sobie musiał dopisać wysyłanie danych.

0

przetestuje to ale dopiero jutro jak nie ma dnia inventery nie działają więc nie da się testować dam znać jaki efekt
na szybko to chyba tak będzie cały skrypt

#!/bin/bash
apikey="api_key"
system="id_system"
INVERTERS="2 3 4" #addres inventers
SOLARSUM="0.0"
for INVERTER in $INVERTERS; do
    SOLAROUT=$( /usr/local/bin/aurora -a $INVERTER /dev/ttyUSB0 -Y15 -e -c | awk '{printf $1}' )
    if [[ ! -z $SOLAROUT ]]; then
        echo "Value from inverter $INVERTER: $SOLAROUT"
        SOLARSUM=$( echo "$SOLARSUM + $SOLAROUT" | bc -l )
    else
        echo "Error while reading from inverter on address: $INVERTER"
    fi
done
echo "Total value $SOLARSUM"

solarwatts=`echo ${SOLARSUM} | sed -e "s/\.//"`
url="https://pvoutput.org/service/r2/addstatus.jsp?d=${rd}&t=${rt}&v1=${solarwatts}"

if [[ ! -z $solarwatts  ]]; then
    result=`curl -H "X-Rate-Limit: 1" -H "X-Pvoutput-Apikey: ${apikey}" -H "X-Pvoutput-SystemId: ${system}" ${url}`
    if [[ $result == *"OK"* ]]; then
        echo "${rd} $(date +%H:%M) : API call successful, power output: ${solarout}"
    else
        echo "${rd} $(date +%H:%M) : API call failed, ${result}"
    fi
else
    echo "${rd} $(date +%H:%M) : Inverter communication failure"
fi


api parametry podają takie

Position	Field	Required	Format	Unit	Example
1	Output Date	Yes	yyyymmdd	date	20100830
2	Generated	Yes	number	watt hours	15000
3	Exported	No	number	watt hours	10000
4	Peak Power	No	number	watts	3000
5	Peak Time	No	hh:mm	time	13:15
6	Condition	No	text	-	Fine
Partly Cloudy
Mostly Cloudy
Cloudy
Showers
Snow
Not Sure
7	Min Temp	No	decimal	celsius	-8.2
8	Max Temp	No	decimal	celsius	20
9	Comments	No	text	-	Free text
10	Import Peak	No	number	watt hours	5000
11	Import Off-Peak	No	number	watt hours	4000
12	Import Shoulder	No	number	watt hours	2000
13	Import High Shoulder	No	number	watt hours	1000
14	Consumption	No	number	watt hours	2000
0

Zapomniałeś o:

rd=$(date +%Y%m%d)
rt1=$(date +%H)
rt2=$(date +%M)
rt="${rt1}%3A${rt2}"
0

no tak faktycznie , skrypt wygląda tak

#!/bin/bash
apikey="api_key"
system="id_system"
rd=$(date +%Y%m%d)
rt1=$(date +%H)
rt2=$(date +%M)
rt="${rt1}%3A${rt2}"
INVERTERS="2 3 4" #addres inventers
SOLARSUM="0.0"
for INVERTER in $INVERTERS; do
    SOLAROUT=$( /usr/local/bin/aurora -a $INVERTER /dev/ttyUSB0 -Y15 -e -c | awk '{printf $1}' )
    if [[ ! -z $SOLAROUT ]]; then
        echo "Value from inverter $INVERTER: $SOLAROUT"
        SOLARSUM=$( echo "$SOLARSUM + $SOLAROUT" | bc -l )
    else
        echo "Error while reading from inverter on address: $INVERTER"
    fi
done
echo "Total value $SOLARSUM"
solarwatts=`echo ${SOLARSUM} | sed -e "s/\.//"`
echo "api date ${solarwatts}"
url="https://pvoutput.org/service/r2/addstatus.jsp?d=${rd}&t=${rt}&v1=${solarwatts}"
if [[ ! -z $solarwatts  ]]; then
    result=`curl -H "X-Rate-Limit: 1" -H "X-Pvoutput-Apikey: ${apikey}" -H "X-Pvoutput-SystemId: ${system}" ${url}`
    if [[ $result == *"OK"* ]]; then
        echo "${rd} $(date +%H:%M) : API call successful, power output: ${SOLARSUM}"
    else
        echo "${rd} $(date +%H:%M) : API call failed, ${result}"
    fi
else
    echo "${rd} $(date +%H:%M) : Inverter communication failure"
fi

na nie działających inventerach wygląda dobrze

pi@raspberrypi:~$ ./inventer.sh
20200224-22:20:18: aurora: No response after 15 attempts
20200224-22:20:18: aurora: ERROR: Received bad return code (-1 0)
Error while reading from inverter on address: 2
20200224-22:20:25: aurora: No response after 15 attempts
20200224-22:20:25: aurora: ERROR: Received bad return code (-1 0)
Error while reading from inverter on address: 3
Total value 0.0
api date 00
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    35    0    35    0     0     40      0 --:--:-- --:--:-- --:--:--    40
20200224 22:20 : API call failed, Unauthorized 401: Invalid System ID
pi@raspberrypi:~$

0

przetestowałem ten skrypt i działa ok , lecz wysyła z byt mało danych , po przeszukaniu internetu trafiłem na 123solar w którym można dodać więcej niż dwa inventery i wysyła więcej danych oto log

#invt1 2002 Wh 729 W 242.3 V
#invt2 1889 Wh 702 W 243.7 V

Send for SYSID 71753 : 20200225 12:20 - 3891 Wh 1431 W 243.7 V 37.326847 C
Consumption : daily energy  Wh Avg. power  W
Extended data : v7 0 v8 0 v9  v10 124 v11  v12 365

PVoutput returned: OK 200: Added Status

na chwile obecną chyba musi wystarczyć , gdy dodam trzeci inventer sprawdzę działanie

1 użytkowników online, w tym zalogowanych: 0, gości: 1