RalfJL / S10history

Read historical data from a S10/E3DC solar power station
6 stars 2 forks source link

Compiling Issues #2

Open Digioso opened 4 years ago

Digioso commented 4 years ago

Heya,

thanks for this tool! I'm trying to compile this on Windows 10 PC within a Cygwin installation. I downloaded the rlog 1.4 source code from here and copied it to /usr/include Looks fine as far as I can see. However your code seems to be having lots of issues unfortunately and cannot be compiled. Could you perhaps have a look at this?

I don't think that it has to do with my, let's say unusual setup. I'm using E3DC-Control for example, which I can compile without any issues.

Digioso@DigiSlave ~ $ git clone https://github.com/RalfJL/S10history.git Cloning into 'S10history'... cd Sremote: Enumerating objects: 49, done. remote: Total 49 (delta 0), reused 0 (delta 0), pack-reused 49 Unpacking objects: 100% (49/49), done.

Digioso@DigiSlave ~ $ cd S10history/

Digioso@DigiSlave ~/S10history $ make rm S10history /usr/bin/g++ -lrlog -Irlog -O2 -Wall S10history.cpp RscpReader.cpp RscpProtocol.cpp AES.cpp SocketConnection.cpp -o S10history S10history.cpp: In function ‘int main(int, char)’: S10history.cpp:83:20: error: ‘STDERR_FILENO’ was not declared in this scope 83 | StdioNode stdLog( STDERR_FILENO, StdioNode::OutputChannel); | ^~~~~ S10history.cpp:126:11: warning: ISO C++ forbids converting a string constant to ‘char’ [-Wwrite-strings] 126 | putenv("TZ=UTC"); | ^~~~ RscpReader.cpp: In function ‘int handleResponseValue(RscpProtocol, SRscpValue)’: RscpReader.cpp:379:11: warning: variable ‘ucBatteryIndex’ set but not used [-Wunused-but-set-variable] 379 | uint8_t ucBatteryIndex = 0; | ^~~~~~ RscpReader.cpp: In function ‘int db_value_container(RscpProtocol, std::vector)’: RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol, std::vector)::val_t::consumption’ may be used uninitialized in this function [-Wmaybe-uninitialized] 176 | printf("[%d]-%s-CSV: %d;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n", graph_index, value_prefix, (int) d, val.bat_in, val.bat_out, val.bat_charge_level, val.production, val.grid_in, | ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 177 | val.grid_out, val.consumption); | ~~~~~~ RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol, std::vector)::val_t::bat_in’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol, std::vector)::val_t::grid_out’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol, std::vector)::val_t::bat_charge_level’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol, std::vector)::val_t::bat_out’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol, std::vector)::val_t::grid_in’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol, std::vector)::val_t::production’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpReader.cpp: In function ‘int db_sum_container(RscpProtocol, std::vector)’: RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol, std::vector)::sum_t::grid_out’ may be used uninitialized in this function [-Wmaybe-uninitialized] 291 | printf("%s-CSV: %d;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n", sum_prefix, (int) start.seconds, sum.bat_in, sum.bat_out, sum.bat_charge_level, sum.production, sum.grid_in, sum.grid_out, | ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 292 | sum.consumption); | ~~~~ RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol, std::vector)::sum_t::bat_charge_level’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol, std::vector)::sum_t::bat_in’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol, std::vector)::sum_t::grid_in’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol, std::vector)::sum_t::consumption’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol, std::vector)::sum_t::bat_out’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol, std::vector)::sum_t::production’ may be used uninitialized in this function [-Wmaybe-uninitialized] RscpProtocol.cpp:46:2: warning: #warning No time source is available. [-Wcpp] 46 | #warning No time source is available. | ^~~ RscpProtocol.cpp: In member function ‘bool RscpProtocol::setHeaderTimestamp(SRscpFrame)’: RscpProtocol.cpp:48:16: error: ‘struct SRscpFrameHeader’ has no member named ‘timeSec’ 48 | frame->header.timeSec = 0; | ^~~ RscpProtocol.cpp:49:16: error: ‘struct SRscpFrameHeader’ has no member named ‘timeNanosec’ 49 | frame->header.timeNanosec = 0; | ^~~ SocketConnection.cpp: In function ‘int SocketConnect(const char, int)’: SocketConnection.cpp:55:9: warning: unused variable ‘iRetries’ [-Wunused-variable] 55 | int iRetries = 3; | ^~~~ make: [Makefile:9: S10history] Error 1

Digioso@DigiSlave ~/S10history $ echo $? 2

Digioso@DigiSlave ~/S10history $

RalfJL commented 4 years ago

Hi, sorry for that. Most of the code is coming from E3DC's demo. I modified it only to generate some output and I ignored all warnings that were coming from it. Actually I am very unsure if I really should dig more into that "Demo" code and fix all warnings it contains.

There are plenty of issues compiling Linux code on a cygwin environment on Windows. Mainly because of issues with file, event and timing.

Fortunately the Demo Code contains hooks for Windows. Did you try to define "WINNT"? can you please run g++ with -DWINNT and report again?

Thanks

Ralf

Digioso commented 4 years ago

Heya,

thanks for the quick answer. :) With -DWINNT I'm down to only one error as it seems.

S10history.cpp:83:20: error: ‘STDERR_FILENO’ was not declared in this scope

Digioso@DigiSlave ~/S10history
$ cat Makefile
CXX=/usr/bin/g++
ROOT_VALUE=S10history
LDFLAGS=-lrlog
CCFLAGS=-Irlog  -O2 -DWINNT

all: $(ROOT_VALUE)

$(ROOT_VALUE): clean
        $(CXX) $(LDFLAGS) $(CCFLAGS)  -Wall   S10history.cpp RscpReader.cpp RscpProtocol.cpp AES.cpp SocketConnection.cpp -o $@

clean:
        -rm $(ROOT_VALUE) $(VECTOR)

Digioso@DigiSlave ~/S10history
$
Digioso@DigiSlave ~/S10history
$ make
rm S10history
/usr/bin/g++ -lrlog -Irlog  -O2 -DWINNT  -Wall   S10history.cpp RscpReader.cpp RscpProtocol.cpp AES.cpp SocketConnection.cpp -o S10history
S10history.cpp: In function ‘int main(int, char**)’:
S10history.cpp:83:20: error: ‘STDERR_FILENO’ was not declared in this scope
   83 |  StdioNode stdLog( STDERR_FILENO, StdioNode::OutputChannel);
      |                    ^~~~~~~~~~~~~
S10history.cpp:126:11: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
  126 |    putenv("TZ=UTC");
      |           ^~~~~~~~
RscpReader.cpp: In function ‘int handleResponseValue(RscpProtocol*, SRscpValue*)’:
RscpReader.cpp:379:11: warning: variable ‘ucBatteryIndex’ set but not used [-Wunused-but-set-variable]
  379 |   uint8_t ucBatteryIndex = 0;
      |           ^~~~~~~~~~~~~~
RscpReader.cpp: In function ‘int db_value_container(RscpProtocol*, std::vector<SRscpValue>*)’:
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::consumption’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  176 |  printf("[%d]-%s-CSV: %d;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n", graph_index, value_prefix, (int) d, val.bat_in, val.bat_out, val.bat_charge_level, val.production, val.grid_in,
      |  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  177 |    val.grid_out, val.consumption);
      |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::grid_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_charge_level’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::grid_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::production’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp: In function ‘int db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)’:
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::grid_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  291 |  printf("%s-CSV: %d;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n", sum_prefix, (int) start.seconds, sum.bat_in, sum.bat_out, sum.bat_charge_level, sum.production, sum.grid_in, sum.grid_out,
      |  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  292 |    sum.consumption);
      |    ~~~~~~~~~~~~~~~~
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_charge_level’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::grid_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::consumption’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::production’ may be used uninitialized in this function [-Wmaybe-uninitialized]
SocketConnection.cpp: In function ‘int SocketConnect(const char*, int)’:
SocketConnection.cpp:55:9: warning: unused variable ‘iRetries’ [-Wunused-variable]
   55 |     int iRetries = 3;
      |         ^~~~~~~~
make: *** [Makefile:9: S10history] Error 1

Digioso@DigiSlave ~/S10history
RalfJL commented 4 years ago

Hi,

actually there should be an include file that defines them like this:

ifndef STDIN_FILENO

define STDIN_FILENO 0

endif

ifndef STDOUT_FILENO

define STDOUT_FILENO 1

endif

ifndef STDERR_FILENO

define STDERR_FILENO 2

endif

Don`t know in cygwin were this is handled. So you can either search in all include files from cygwin for those defines and add the according include to the source code, surrounded with the WINNT IF's, or you simply define it on the command line like: -DSTDERR_FILENO=2 This is not a great solution, but it should do the trick.

Please try Ralf

Digioso commented 4 years ago

Thanks a lot. :) One step further at least. :)

/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lrlog collect2: error: ld returned 1 exit status

If I see it correctly it now has trouble with rlog. Do you need a compiled version or the source code? Maybe I have the wrong rlog version? As I said, I used the 1.4 version from here.

But basically g++ seems to be finding rlog. Before I copied it to /usr/include g++ was complaing about not finding the rlog source code for compilation.

I also added /usr/include (or rather /cygdrive/c/cygwin/usr/include) to $PATH and $LD_LIBRARY_PATH and exprorted both variables prior to compilation.

Digioso@DigiSlave ~/S10history
$ make
rm S10history
rm: cannot remove 'S10history': No such file or directory
make: [Makefile:13: clean] Error 1 (ignored)
/usr/bin/g++ -lrlog -Irlog  -O2   -DWINNT -DSTDERR_FILENO=2 -Wall   S10history.cpp RscpReader.cpp RscpProtocol.cpp AES.cpp SocketConnection.cpp -o S10history
S10history.cpp: In function ‘int main(int, char**)’:
S10history.cpp:126:11: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
  126 |    putenv("TZ=UTC");
      |           ^~~~~~~~
RscpReader.cpp: In function ‘int handleResponseValue(RscpProtocol*, SRscpValue*)’:
RscpReader.cpp:379:11: warning: variable ‘ucBatteryIndex’ set but not used [-Wunused-but-set-variable]
  379 |   uint8_t ucBatteryIndex = 0;
      |           ^~~~~~~~~~~~~~
RscpReader.cpp: In function ‘int db_value_container(RscpProtocol*, std::vector<SRscpValue>*)’:
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::consumption’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  176 |  printf("[%d]-%s-CSV: %d;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n", graph_index, value_prefix, (int) d, val.bat_in, val.bat_out, val.bat_charge_level, val.production, val.grid_in,
      |  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  177 |    val.grid_out, val.consumption);
      |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::grid_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_charge_level’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::grid_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::production’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp: In function ‘int db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)’:
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::grid_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  291 |  printf("%s-CSV: %d;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n", sum_prefix, (int) start.seconds, sum.bat_in, sum.bat_out, sum.bat_charge_level, sum.production, sum.grid_in, sum.grid_out,
      |  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  292 |    sum.consumption);
      |    ~~~~~~~~~~~~~~~~
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_charge_level’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::grid_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::consumption’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::production’ may be used uninitialized in this function [-Wmaybe-uninitialized]
SocketConnection.cpp: In function ‘int SocketConnect(const char*, int)’:
SocketConnection.cpp:55:9: warning: unused variable ‘iRetries’ [-Wunused-variable]
   55 |     int iRetries = 3;
      |         ^~~~~~~~
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lrlog
collect2: error: ld returned 1 exit status
make: *** [Makefile:9: S10history] Error 1

Digioso@DigiSlave ~/S10history
$
RalfJL commented 4 years ago

Hi, it says it can't find the library rlog. LD_LIBRARY_PATH is a runtime environment variable and not for compiling please add -L to your compile command. But than you would need LD_LIBRARY_PATH being set for executing the command It is much better to "compile" the library path into the executable itself. Like described here: https://stackoverflow.com/questions/2726993/how-to-specify-preference-of-library-path

so please add to you compile line: -Wl,-rpath, you can add several paths with that. Please try. Ralf

Digioso commented 4 years ago

Thanks for your time. :)

And sorry for all the questions.

I also have a Mini-PC running Linux Mint. Unfortunately rlog doesn't seem to be available in the Linux Mint repository. :(

And it also is not simply possible to replace all rError and rWarning by printf. The syntax of identical but you are using rlog on A LOT more (EG: rDebug, rInfo). So simply removing it doesn't work without mostly rewriting everything. :(

No change with the added parameters. I hope I understodd how they work correctly.

I don't understand what exactly it is looking for, though. From my understanding it is looking for a file or directly named "-lrlog" which obviously doesn't exist. /usr/include is a default path used by gcc. It is not complaining about not finding rlog.h

Digioso@DigiSlave ~/S10history
$ make
rm S10history
rm: cannot remove 'S10history': No such file or directory
make: [Makefile:13: clean] Error 1 (ignored)
/usr/bin/g++ -lrlog -Irlog  -O2   -DWINNT -DSTDERR_FILENO=2 -Wl,-rpath,/usr/include -Wall   S10history.cpp RscpReader.cpp RscpProtocol.cpp AES.cpp SocketConnection.cpp -o S10history
S10history.cpp: In function ‘int main(int, char**)’:
S10history.cpp:126:11: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
  126 |    putenv("TZ=UTC");
      |           ^~~~~~~~
RscpReader.cpp: In function ‘int handleResponseValue(RscpProtocol*, SRscpValue*)’:
RscpReader.cpp:379:11: warning: variable ‘ucBatteryIndex’ set but not used [-Wunused-but-set-variable]
  379 |   uint8_t ucBatteryIndex = 0;
      |           ^~~~~~~~~~~~~~
RscpReader.cpp: In function ‘int db_value_container(RscpProtocol*, std::vector<SRscpValue>*)’:
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::consumption’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  176 |  printf("[%d]-%s-CSV: %d;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n", graph_index, value_prefix, (int) d, val.bat_in, val.bat_out, val.bat_charge_level, val.production, val.grid_in,
      |  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  177 |    val.grid_out, val.consumption);
      |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::grid_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_charge_level’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::grid_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::production’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp: In function ‘int db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)’:
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::grid_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  291 |  printf("%s-CSV: %d;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n", sum_prefix, (int) start.seconds, sum.bat_in, sum.bat_out, sum.bat_charge_level, sum.production, sum.grid_in, sum.grid_out,
      |  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  292 |    sum.consumption);
      |    ~~~~~~~~~~~~~~~~
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_charge_level’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::grid_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::consumption’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::production’ may be used uninitialized in this function [-Wmaybe-uninitialized]
SocketConnection.cpp: In function ‘int SocketConnect(const char*, int)’:
SocketConnection.cpp:55:9: warning: unused variable ‘iRetries’ [-Wunused-variable]
   55 |     int iRetries = 3;
      |         ^~~~~~~~
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lrlog
collect2: error: ld returned 1 exit status
make: *** [Makefile:9: S10history] Error 1

Digioso@DigiSlave ~/S10history
RalfJL commented 4 years ago

Hi, sorry, but your path is not correct. You added the path to the "include" files as library path. Include files are header files for compiling. They are not good for linking. The error message is not coming from the compiler but from the linker - bin/ld. The linker is the program that assembles all libraries and compiled files to an executable program. What you need to add is the path to the library file of rlog. The library file of rlog should look something like "rlog.so" or "rlog.a". Please change the "-Wl,-rpath,/usr/include" to something like "-Wl,-rpath,/usr/local/lib" and make sure that rlog.so or rlog.a is located in that directory. Ralf

Digioso commented 4 years ago

OK, now you lost me. :)

Why do you need a compiled rlog? In your tool you're using the rlog header files.

include <rlog/rlog.h>

include <rlog/StdioNode.h>

include <rlog/RLogChannel.h>

What are those needed for when you need a pre-compiled rlog anyway? oO It's been quite a while that I've programmed in C, but from my past knowledge the header files you include will be used for compiling the binary file. Usually they include additional functions that can be used. Like printf from stdio.h So all those functions provided by rlog should be taken rlog.h and compiled into the binary file.

Anyway I compiled rlog now and copied the bunch of files from the .libs directory it created to /usr/local/lib Unfortunately the error message stays the same. :(

Digioso@DigiSlave ~/S10history
$ find /usr/local/lib
/usr/local/lib
/usr/local/lib/Error.o
/usr/local/lib/librlog.a
/usr/local/lib/librlog.la
/usr/local/lib/librlog.lai
/usr/local/lib/rlog
/usr/local/lib/rlog/Error.o
/usr/local/lib/rlog/librlog.a
/usr/local/lib/rlog/librlog.la
/usr/local/lib/rlog/librlog.lai
/usr/local/lib/rlog/rlog.o
/usr/local/lib/rlog/RLogChannel.o
/usr/local/lib/rlog/rloginit.o
/usr/local/lib/rlog/rloglocation.o
/usr/local/lib/rlog/RLogNode.o
/usr/local/lib/rlog/RLogPublisher.o
/usr/local/lib/rlog/RLogTime.o
/usr/local/lib/rlog/StdioNode.o
/usr/local/lib/rlog/SyslogNode.o
/usr/local/lib/rlog.o
/usr/local/lib/RLogChannel.o
/usr/local/lib/rloginit.o
/usr/local/lib/rloglocation.o
/usr/local/lib/RLogNode.o
/usr/local/lib/RLogPublisher.o
/usr/local/lib/RLogTime.o
/usr/local/lib/StdioNode.o
/usr/local/lib/SyslogNode.o

Digioso@DigiSlave ~/S10history
$

Digioso@DigiSlave ~/S10history
$ make
rm S10history
rm: cannot remove 'S10history': No such file or directory
make: [Makefile:13: clean] Error 1 (ignored)
/usr/bin/g++ -lrlog -Irlog  -O2 -Wl,-rpath,/usr/local/lib -DWINNT -DSTDERR_FILENO=2 -Wall   S10history.cpp RscpReader.cpp RscpProtocol.cpp AES.cpp SocketConnection.cpp -o S10history
S10history.cpp: In function ‘int main(int, char**)’:
S10history.cpp:126:11: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
  126 |    putenv("TZ=UTC");
      |           ^~~~~~~~
RscpReader.cpp: In function ‘int handleResponseValue(RscpProtocol*, SRscpValue*)’:
RscpReader.cpp:379:11: warning: variable ‘ucBatteryIndex’ set but not used [-Wunused-but-set-variable]
  379 |   uint8_t ucBatteryIndex = 0;
      |           ^~~~~~~~~~~~~~
RscpReader.cpp: In function ‘int db_value_container(RscpProtocol*, std::vector<SRscpValue>*)’:
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::consumption’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  176 |  printf("[%d]-%s-CSV: %d;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n", graph_index, value_prefix, (int) d, val.bat_in, val.bat_out, val.bat_charge_level, val.production, val.grid_in,
      |  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  177 |    val.grid_out, val.consumption);
      |    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::grid_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_charge_level’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::bat_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::grid_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:176:8: warning: ‘val.db_value_container(RscpProtocol*, std::vector<SRscpValue>*)::val_t::production’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp: In function ‘int db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)’:
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::grid_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  291 |  printf("%s-CSV: %d;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f;%.2f\n", sum_prefix, (int) start.seconds, sum.bat_in, sum.bat_out, sum.bat_charge_level, sum.production, sum.grid_in, sum.grid_out,
      |  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  292 |    sum.consumption);
      |    ~~~~~~~~~~~~~~~~
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_charge_level’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::grid_in’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::consumption’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::bat_out’ may be used uninitialized in this function [-Wmaybe-uninitialized]
RscpReader.cpp:291:8: warning: ‘sum.db_sum_container(RscpProtocol*, std::vector<SRscpValue>*)::sum_t::production’ may be used uninitialized in this function [-Wmaybe-uninitialized]
SocketConnection.cpp: In function ‘int SocketConnect(const char*, int)’:
SocketConnection.cpp:55:9: warning: unused variable ‘iRetries’ [-Wunused-variable]
   55 |     int iRetries = 3;
      |         ^~~~~~~~
/usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lrlog
collect2: error: ld returned 1 exit status
make: *** [Makefile:9: S10history] Error 1

Digioso@DigiSlave ~/S10history
$
RalfJL commented 4 years ago

OK, back to the basics of compiling. Source code -extension .c or .c++ or .cc- is human readable. Your program may use functions from other programs called libraries. E.g. sprintf is a function from stdio that prints something on the terminal. For the compiler to know how sprintf looks like you include the definition file stdio.h in your program or the compiler complains that it does not know sprintf. This only means you are including the definition, not the function itself!! If the compiler is happy with your source code it will generate an object file ".o" that contains only your code and pointers to other needed functions, like sprintf. Object code is not executable!!

Next step is to invoke the linker to collect all needed object files and create an executable file from it. And now we have to distinguish between static libraries ".a" and dynamic libraries ".so". If you hand over a static library ".a" to the linker together with your object code it will embed that static library in the executable. So that executable will contain your code and the library as one program. If you allow dynamic binding with ".so" libraries- which is the default, the linker will create an executable that does NOT contain the library but only your code and hints to the dynamic libraries. When you start the executable the so called loader will look around for the needed dynamic libraries and will construct a runnable process from it. (Only the loader works with LD_LIBRARY_PATH) The advantages of dynamic libraries are they consume less memory, because they can be shared between programs and that you can update those libraries without recompiling your own program. Simply stop and restart your program and it will automatically use the fixed library.

So your problem is that you will have to generate a dynamic library of rlog. This normally is done when you compile the sources of rlog and do a "make install". That will compile several .o files and combine them in a rlog.so file or/and a rlog.a file and install that file in the location that was given to autoconf. You have to locate the rlog.so file and set the -Wl.rpath, or the linker will not find it and cannot assemble your object code to an executable. DO NOT use the files in .libs, they are only there to assemble the so file and will be deleted when you do a "make clean". The rpath directive is a linker directive and says that the location of rlog.so is compiled in the executable program. But only the location, not the code. If you remove rlog.so your program will not be able to start.

Ralf

Digioso commented 4 years ago

Thanks for the explanation. :)

I indeed did forget the "make install" for rlog. :(

Make install created a librlog.a file in /usr/local/lib . Unfortunately the compilation still fails with the exact same error message.

/usr/bin/g++ -lrlog -Irlog -O2 -Wl,-rpath,/usr/local/lib -DWINNT -DSTDERR_FILENO=2 -Wall S10history.cpp RscpReader.cpp RscpProtocol.cpp AES.cpp SocketConnection.cpp -o S10history ... ... ... /usr/lib/gcc/x86_64-pc-cygwin/9.3.0/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lrlog collect2: error: ld returned 1 exit status

Rlog installation:

Digioso@DigiSlave ~/rlog-1.4
$ ./configure
checking build system type... x86_64-unknown-cygwin
checking host system type... x86_64-unknown-cygwin
checking target system type... x86_64-unknown-cygwin
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for g++... g++
checking for C++ compiler default output file name... a.exe
checking whether the C++ compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... .exe
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking for style of include used by make... GNU
checking dependency style of g++... gcc3
checking for gcc... gcc
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking for a sed that does not truncate output... /usr/bin/sed
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ld used by gcc... /usr/x86_64-pc-cygwin/bin/ld.exe
checking if the linker (/usr/x86_64-pc-cygwin/bin/ld.exe) is GNU ld... yes
checking for /usr/x86_64-pc-cygwin/bin/ld.exe option to reload object files... -r
checking for BSD-compatible nm... /usr/bin/nm -B
checking whether ln -s works... yes
checking how to recognize dependent libraries... file_magic ^x86 archive import|^x86 DLL
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking dlfcn.h usability... yes
checking dlfcn.h presence... yes
checking for dlfcn.h... yes
checking how to run the C++ preprocessor... g++ -E
checking for g77... no
checking for xlf... no
checking for f77... no
checking for frt... no
checking for pgf77... no
checking for cf77... no
checking for fort77... no
checking for fl32... no
checking for af77... no
checking for xlf90... no
checking for f90... no
checking for pgf90... no
checking for pghpf... no
checking for epcf90... no
checking for gfortran... gfortran
checking whether we are using the GNU Fortran 77 compiler... yes
checking whether gfortran accepts -g... yes
checking the maximum length of command line arguments... 8192
checking command to parse /usr/bin/nm -B output from gcc object... ok
checking for objdir... .libs
checking for ar... ar
checking for ranlib... ranlib
checking for strip... strip
checking if gcc supports -fno-rtti -fno-exceptions... no
checking for gcc option to produce PIC... -DDLL_EXPORT
checking if gcc PIC flag -DDLL_EXPORT works... yes
checking if gcc static flag -static works... yes
checking if gcc supports -c -o file.o... yes
checking whether the gcc linker (/usr/x86_64-pc-cygwin/bin/ld.exe) supports shared libraries... yes
checking whether -lc should be explicitly linked in... yes
checking dynamic linker characteristics... Win32 ld.exe
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no
configure: creating libtool
appending configuration tag "CXX" to libtool
checking for ld used by g++... /usr/x86_64-pc-cygwin/bin/ld.exe
checking if the linker (/usr/x86_64-pc-cygwin/bin/ld.exe) is GNU ld... yes
checking whether the g++ linker (/usr/x86_64-pc-cygwin/bin/ld.exe) supports shared libraries... yes
checking for g++ option to produce PIC... -DDLL_EXPORT
checking if g++ PIC flag -DDLL_EXPORT works... yes
checking if g++ static flag -static works... yes
checking if g++ supports -c -o file.o... yes
checking whether the g++ linker (/usr/x86_64-pc-cygwin/bin/ld.exe) supports shared libraries... yes
checking dynamic linker characteristics... Win32 ld.exe
(cached) (cached) checking how to hardcode library paths into programs... immediate
appending configuration tag "F77" to libtool
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no
checking for gfortran option to produce PIC... -DDLL_EXPORT
checking if gfortran PIC flag -DDLL_EXPORT works... yes
checking if gfortran static flag -static works... yes
checking if gfortran supports -c -o file.o... yes
checking whether the gfortran linker (/usr/x86_64-pc-cygwin/bin/ld.exe) supports shared libraries... yes
checking dynamic linker characteristics... Win32 ld.exe
(cached) (cached) checking how to hardcode library paths into programs... immediate
checking for the pthreads library -lpthreads... no
checking whether pthreads work without any flags... yes
checking for joinable pthread attribute... PTHREAD_CREATE_JOINABLE
checking if more special flags are required for pthreads... no
checking for cc_r... gcc
checking if __printf__ attribute can apply to function pointers... yes
checking if compiler has C99 variadac macro... yes
checking if compiler has pre-C99 variadac macro... yes
checking valgrind/valgrind.h usability... no
checking valgrind/valgrind.h presence... no
checking for valgrind/valgrind.h... no
checking for doxygen... no
checking for latex... no
checking for pdflatex... no
checking for localtime_r... yes
checking sstream usability... yes
checking sstream presence... yes
checking for sstream... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating rlog/Makefile
config.status: creating docs/Makefile
config.status: creating config/Makefile
config.status: creating rlog/common.h
config.status: creating librlog.pc
config.status: creating rlog.spec
config.status: creating makedist2.sh
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing depfiles commands

Digioso@DigiSlave ~/rlog-1.4
$ make
make  all-recursive
make[1]: Entering directory '/home/Digioso/rlog-1.4'
Making all in rlog
make[2]: Entering directory '/home/Digioso/rlog-1.4/rlog'
/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT rlog.lo -MD -MP -MF .deps/rlog.Tpo -c -o rlog.lo rlog.cpp
mkdir .libs
 g++ -DHAVE_CONFIG_H -I. -I.. -I.. -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -MT rlog.lo -MD -MP -MF .deps/rlog.Tpo -c rlog.cpp  -DDLL_EXPORT -DPIC -o .libs/rlog.o
mv -f .deps/rlog.Tpo .deps/rlog.Plo
/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT rloginit.lo -MD -MP -MF .deps/rloginit.Tpo -c -o rloginit.lo rloginit.cpp
 g++ -DHAVE_CONFIG_H -I. -I.. -I.. -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -MT rloginit.lo -MD -MP -MF .deps/rloginit.Tpo -c rloginit.cpp  -DDLL_EXPORT -DPIC -o .libs/rloginit.o
mv -f .deps/rloginit.Tpo .deps/rloginit.Plo
/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT rloglocation.lo -MD -MP -MF .deps/rloglocation.Tpo -c -o rloglocation.lo rloglocation.cpp
 g++ -DHAVE_CONFIG_H -I. -I.. -I.. -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -MT rloglocation.lo -MD -MP -MF .deps/rloglocation.Tpo -c rloglocation.cpp  -DDLL_EXPORT -DPIC -o .libs/rloglocation.o
mv -f .deps/rloglocation.Tpo .deps/rloglocation.Plo
/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT Error.lo -MD -MP -MF .deps/Error.Tpo -c -o Error.lo Error.cpp
 g++ -DHAVE_CONFIG_H -I. -I.. -I.. -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -MT Error.lo -MD -MP -MF .deps/Error.Tpo -c Error.cpp  -DDLL_EXPORT -DPIC -o .libs/Error.o
mv -f .deps/Error.Tpo .deps/Error.Plo
/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT RLogChannel.lo -MD -MP -MF .deps/RLogChannel.Tpo -c -o RLogChannel.lo RLogChannel.cpp
 g++ -DHAVE_CONFIG_H -I. -I.. -I.. -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -MT RLogChannel.lo -MD -MP -MF .deps/RLogChannel.Tpo -c RLogChannel.cpp  -DDLL_EXPORT -DPIC -o .libs/RLogChannel.o
mv -f .deps/RLogChannel.Tpo .deps/RLogChannel.Plo
/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT RLogNode.lo -MD -MP -MF .deps/RLogNode.Tpo -c -o RLogNode.lo RLogNode.cpp
 g++ -DHAVE_CONFIG_H -I. -I.. -I.. -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -MT RLogNode.lo -MD -MP -MF .deps/RLogNode.Tpo -c RLogNode.cpp  -DDLL_EXPORT -DPIC -o .libs/RLogNode.o
mv -f .deps/RLogNode.Tpo .deps/RLogNode.Plo
/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT RLogPublisher.lo -MD -MP -MF .deps/RLogPublisher.Tpo -c -o RLogPublisher.lo RLogPublisher.cpp
 g++ -DHAVE_CONFIG_H -I. -I.. -I.. -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -MT RLogPublisher.lo -MD -MP -MF .deps/RLogPublisher.Tpo -c RLogPublisher.cpp  -DDLL_EXPORT -DPIC -o .libs/RLogPublisher.o
mv -f .deps/RLogPublisher.Tpo .deps/RLogPublisher.Plo
/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT RLogTime.lo -MD -MP -MF .deps/RLogTime.Tpo -c -o RLogTime.lo RLogTime.cpp
 g++ -DHAVE_CONFIG_H -I. -I.. -I.. -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -MT RLogTime.lo -MD -MP -MF .deps/RLogTime.Tpo -c RLogTime.cpp  -DDLL_EXPORT -DPIC -o .libs/RLogTime.o
mv -f .deps/RLogTime.Tpo .deps/RLogTime.Plo
/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT StdioNode.lo -MD -MP -MF .deps/StdioNode.Tpo -c -o StdioNode.lo StdioNode.cpp
 g++ -DHAVE_CONFIG_H -I. -I.. -I.. -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -MT StdioNode.lo -MD -MP -MF .deps/StdioNode.Tpo -c StdioNode.cpp  -DDLL_EXPORT -DPIC -o .libs/StdioNode.o
mv -f .deps/StdioNode.Tpo .deps/StdioNode.Plo
/bin/sh ../libtool --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT SyslogNode.lo -MD -MP -MF .deps/SyslogNode.Tpo -c -o SyslogNode.lo SyslogNode.cpp
 g++ -DHAVE_CONFIG_H -I. -I.. -I.. -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -MT SyslogNode.lo -MD -MP -MF .deps/SyslogNode.Tpo -c SyslogNode.cpp  -DDLL_EXPORT -DPIC -o .libs/SyslogNode.o
mv -f .deps/SyslogNode.Tpo .deps/SyslogNode.Plo
/bin/sh ../libtool --tag=CXX   --mode=link g++ -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -version-info 5:0:0   -o librlog.la -rpath /usr/local/lib rlog.lo rloginit.lo rloglocation.lo Error.lo RLogChannel.lo RLogNode.lo RLogPublisher.lo RLogTime.lo StdioNode.lo SyslogNode.lo
libtool: link: warning: undefined symbols not allowed in x86_64-unknown-cygwin shared libraries
ar cru .libs/librlog.a  .libs/rlog.o .libs/rloginit.o .libs/rloglocation.o .libs/Error.o .libs/RLogChannel.o .libs/RLogNode.o .libs/RLogPublisher.o .libs/RLogTime.o .libs/StdioNode.o .libs/SyslogNode.o
ranlib .libs/librlog.a
creating librlog.la
(cd .libs && rm -f librlog.la && ln -s ../librlog.la librlog.la)
g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT test.o -MD -MP -MF .deps/test.Tpo -c -o test.o test.cpp
mv -f .deps/test.Tpo .deps/test.Po
/bin/sh ../libtool --tag=CXX   --mode=link g++ -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2     -o test.exe test.o librlog.la
g++ -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -o test.exe test.o  ./.libs/librlog.a
g++ -DHAVE_CONFIG_H -I. -I..   -I..   -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2   -MT testlog-testlog.o -MD -MP -MF .deps/testlog-testlog.Tpo -c -o testlog-testlog.o `test -f 'testlog.cpp' || echo './'`testlog.cpp
mv -f .deps/testlog-testlog.Tpo .deps/testlog-testlog.Po
/bin/sh ../libtool --tag=CXX   --mode=link g++ -DRLOG_COMPONENT="rlog" -DUSE_VALGRIND=0 -g -O2     -o testlog.exe testlog-testlog.o librlog.la
g++ -DRLOG_COMPONENT=rlog -DUSE_VALGRIND=0 -g -O2 -o testlog.exe testlog-testlog.o  ./.libs/librlog.a
make[2]: Leaving directory '/home/Digioso/rlog-1.4/rlog'
Making all in docs
make[2]: Entering directory '/home/Digioso/rlog-1.4/docs'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/home/Digioso/rlog-1.4/docs'
Making all in config
make[2]: Entering directory '/home/Digioso/rlog-1.4/config'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/home/Digioso/rlog-1.4/config'
make[2]: Entering directory '/home/Digioso/rlog-1.4'
make[2]: Leaving directory '/home/Digioso/rlog-1.4'
make[1]: Leaving directory '/home/Digioso/rlog-1.4'

Digioso@DigiSlave ~/rlog-1.4
$ echo $?
0
Digioso@DigiSlave ~/rlog-1.4
$ make install
Making install in rlog
make[1]: Entering directory '/home/Digioso/rlog-1.4/rlog'
make[2]: Entering directory '/home/Digioso/rlog-1.4/rlog'
test -z "/usr/local/lib" || /usr/bin/mkdir -p "/usr/local/lib"
 /bin/sh ../libtool   --mode=install /usr/bin/install -c  'librlog.la' '/usr/local/lib/librlog.la'
/usr/bin/install -c .libs/librlog.lai /usr/local/lib/librlog.la
/usr/bin/install -c .libs/librlog.a /usr/local/lib/librlog.a
chmod 644 /usr/local/lib/librlog.a
ranlib /usr/local/lib/librlog.a
----------------------------------------------------------------------
Libraries have been installed in:
   /usr/local/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-LLIBDIR' linker flag

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
test -z "/usr/local/include/rlog" || /usr/bin/mkdir -p "/usr/local/include/rlog"
 /usr/bin/install -c -m 644 'common.h' '/usr/local/include/rlog/common.h'
 /usr/bin/install -c -m 644 'Error.h' '/usr/local/include/rlog/Error.h'
 /usr/bin/install -c -m 644 'Lock.h' '/usr/local/include/rlog/Lock.h'
 /usr/bin/install -c -m 644 'Mutex.h' '/usr/local/include/rlog/Mutex.h'
 /usr/bin/install -c -m 644 'rlog-c99.h' '/usr/local/include/rlog/rlog-c99.h'
 /usr/bin/install -c -m 644 'RLogChannel.h' '/usr/local/include/rlog/RLogChannel.h'
 /usr/bin/install -c -m 644 'rlog.h' '/usr/local/include/rlog/rlog.h'
 /usr/bin/install -c -m 644 'rloginit.h' '/usr/local/include/rlog/rloginit.h'
 /usr/bin/install -c -m 644 'rloglocation.h' '/usr/local/include/rlog/rloglocation.h'
 /usr/bin/install -c -m 644 'RLogNode.h' '/usr/local/include/rlog/RLogNode.h'
 /usr/bin/install -c -m 644 'rlog-novariadic.h' '/usr/local/include/rlog/rlog-novariadic.h'
 /usr/bin/install -c -m 644 'rlog-prec99.h' '/usr/local/include/rlog/rlog-prec99.h'
 /usr/bin/install -c -m 644 'RLogPublisher.h' '/usr/local/include/rlog/RLogPublisher.h'
 /usr/bin/install -c -m 644 'RLogTime.h' '/usr/local/include/rlog/RLogTime.h'
 /usr/bin/install -c -m 644 'StdioNode.h' '/usr/local/include/rlog/StdioNode.h'
 /usr/bin/install -c -m 644 'SyslogNode.h' '/usr/local/include/rlog/SyslogNode.h'
make[2]: Leaving directory '/home/Digioso/rlog-1.4/rlog'
make[1]: Leaving directory '/home/Digioso/rlog-1.4/rlog'
Making install in docs
make[1]: Entering directory '/home/Digioso/rlog-1.4/docs'
make[2]: Entering directory '/home/Digioso/rlog-1.4/docs'
make[2]: Nothing to be done for 'install-exec-am'.
echo installing to /usr/local/share/doc/rlog/html
installing to /usr/local/share/doc/rlog/html
/bin/sh ../mkinstalldirs /usr/local/share/doc/rlog/html
mkdir -p -- /usr/local/share/doc/rlog/html
install html/* /usr/local/share/doc/rlog/html
test -z "/usr/local/share/doc/rlog" || /usr/bin/mkdir -p "/usr/local/share/doc/rlog"
 /usr/bin/install -c -m 644 'latex/refman.pdf' '/usr/local/share/doc/rlog/refman.pdf'
make[2]: Leaving directory '/home/Digioso/rlog-1.4/docs'
make[1]: Leaving directory '/home/Digioso/rlog-1.4/docs'
Making install in config
make[1]: Entering directory '/home/Digioso/rlog-1.4/config'
make[2]: Entering directory '/home/Digioso/rlog-1.4/config'
make[2]: Nothing to be done for 'install-exec-am'.
make[2]: Nothing to be done for 'install-data-am'.
make[2]: Leaving directory '/home/Digioso/rlog-1.4/config'
make[1]: Leaving directory '/home/Digioso/rlog-1.4/config'
make[1]: Entering directory '/home/Digioso/rlog-1.4'
make[2]: Entering directory '/home/Digioso/rlog-1.4'
make[2]: Nothing to be done for 'install-exec-am'.
test -z "/usr/local/lib/pkgconfig" || /usr/bin/mkdir -p "/usr/local/lib/pkgconfig"
 /usr/bin/install -c -m 644 'librlog.pc' '/usr/local/lib/pkgconfig/librlog.pc'
make[2]: Leaving directory '/home/Digioso/rlog-1.4'
make[1]: Leaving directory '/home/Digioso/rlog-1.4'

Digioso@DigiSlave ~/rlog-1.4
$ echo $?
0

Digioso@DigiSlave ~/rlog-1.4
$ ls -lart /usr/local/lib/
total 1672
-rwxr-xr-x  1 Digioso Digioso     763 May 25 14:25 librlog.la
-rw-r--r--  1 Digioso Digioso 1703010 May 25 14:25 librlog.a
drwxr-xr-x+ 1 Digioso Digioso       0 May 25 14:26 ..
drwxr-xr-x+ 1 Digioso Digioso       0 May 25 14:26 .
drwxr-xr-x+ 1 Digioso Digioso       0 May 25 14:26 pkgconfig

Digioso@DigiSlave ~/rlog-1.4
$ 
RalfJL commented 4 years ago

Is the librlog.a a dynamic or static library? please try file /usr/local/lib/librlog.a to me that looks like a static library and that is not good for your gcc options. If it is a static library it might be the best to use it, though the binary will get bigger but you can skip all that rpath or LD_LIBRARY_PATH thing. please try: /usr/bin/g++ -lrlog -O2 -DWINNT -DSTDERR_FILENO=2 -Wall S10history.cpp RscpReader.cpp RscpProtocol.cpp AES.cpp SocketConnection.cpp /usr/local/lib/librlog.a -o S10history

If this does not work try it without -lrlog switch

Digioso commented 4 years ago

Digioso@DigiSlave ~ $ file /usr/local/lib/librlog.a /usr/local/lib/librlog.a: current ar archive

Digioso@DigiSlave ~ $

Aaaand this worked :) Connection to E3DC works and it delivers data as well. Thanks a lot. ^^

/usr/bin/g++ -O2 -DWINNT -DSTDERR_FILENO=2 -Wall S10history.cpp RscpReader.cpp RscpProtocol.cpp AES.cpp SocketConnection.cpp /usr/local/lib/librlog.a -o S10history

Digioso@DigiSlave ~/S10history $ ls -lart total 1641 -rw-r--r-- 1 Digioso Digioso 21994 May 23 22:47 AES.cpp -rw-r--r-- 1 Digioso Digioso 6653 May 23 22:47 AES.h -rw-r--r-- 1 Digioso Digioso 3097 May 23 22:47 README.md -rw-r--r-- 1 Digioso Digioso 28374 May 23 22:47 RscpProtocol.h -rw-r--r-- 1 Digioso Digioso 20340 May 23 22:47 RscpProtocol.cpp -rw-r--r-- 1 Digioso Digioso 48954 May 23 22:47 RscpTags.h -rw-r--r-- 1 Digioso Digioso 29037 May 23 22:47 RscpReader.cpp -rw-r--r-- 1 Digioso Digioso 2221 May 23 22:47 RscpTypes.h -rw-r--r-- 1 Digioso Digioso 5323 May 23 22:47 S10toMysql.pl -rw-r--r-- 1 Digioso Digioso 8279 May 23 22:47 S10history.cpp -rw-r--r-- 1 Digioso Digioso 686 May 23 22:47 SocketConnection.h -rw-r--r-- 1 Digioso Digioso 2750 May 23 22:47 SocketConnection.cpp drwxr-xr-x+ 1 Digioso Digioso 0 May 23 22:47 examples drwxr-xr-x+ 1 Digioso Digioso 0 May 23 22:47 .git -rw-r--r-- 1 Digioso Digioso 311 May 25 16:32 Makefile drwxr-xr-x+ 1 Digioso Digioso 0 May 25 16:32 .. drwxr-xr-x+ 1 Digioso Digioso 0 May 25 16:34 . -rwxr-xr-x 1 Digioso Digioso 1463959 May 25 16:34 S10history.exe

Digioso@DigiSlave ~/S10history $

RalfJL commented 4 years ago

Perfect.

I just compiled it under the Linux App on Windows 10. I installed the Linux app from Microsoft store, and installed Ubuntu 18 in it. After opening the Ubuntu app I did: sudo apt-get update sudo apt install gcc sudo apt install g++ sudo apt install librlog5v5 sudo apt install librlog-dev

Makefile has to be changed to: CXX=/usr/bin/g++ ROOT_VALUE=S10history LDFLAGS=-Wl,-rpath,/usr/lib/x86_64-linux-gnu -lrlog -L/usr/lib/x86_64-linux-gnu CCFLAGS=-Irlog -O2 -DSTDERR_FILENO=2

all: $(ROOT_VALUE)

$(ROOT_VALUE): clean $(CXX) $(CCFLAGS) S10history.cpp RscpReader.cpp RscpProtocol.cpp AES.cpp SocketConnection.cpp $(LDFLAGS) -o $@

clean: -rm $(ROOT_VALUE) $(VECTOR)

Sorry for cheating, I removed the -Wall to concentrate on errors

Ralf

Digioso commented 4 years ago

OK, the Linux APP would've been indeed an alternative to Cygwin. :) It's just that I've been using Cygwin for more than 10 years now, so when I want to have Linux stuff on Windows Cygwin is the first thing that comes to my mind.

Digioso commented 4 years ago

I rewrote your getYearperDay.sh example into a Perl program and added installation date as a required parameter (so that you cannot request dates prior to installation of the E3DC system). If you request data from the installation year the script also sets the starting day to the installation date (in my case 31.10.2019). Required paramaters for your tool (user, pw, ...) are now read from a config file. And I reduced the output to the three values that I am interested in the most (kWh production, kWh into the grid and kWh used by the house). Maybe this is useful to someone else as well. :) I'm going to write another script to run daily, save the values and create a monthly report.

Sample output:

Digioso@DigiSlave ~/S10history $ ./daily.pl 2018 The given year is lower than the installation year. That doesn't work. Usage of this program:

./daily.pl YYYY Example: ./daily.pl 2020

Year cannot be lower than the installation year. Digioso@DigiSlave ~/S10history $ Digioso@DigiSlave ~/S10history $ ./daily.pl 2019 Setting startdate to installation date 20191031. 31.10.2019 Production: 4.13 kWh Into Grid: 1.37 kWh Usage: 2.76 kWh 01.11.2019 Production: 1.68 kWh Into Grid: 0.00 kWh Usage: 1.68 kWh 02.11.2019 Production: 4.19 kWh Into Grid: 6.67 kWh Usage: -2.49 kWh 03.11.2019 Production: 7.71 kWh Into Grid: 0.26 kWh Usage: 7.46 kWh 04.11.2019 Production: 5.31 kWh Into Grid: 0.07 kWh Usage: 5.24 kWh 05.11.2019 Production: 3.34 kWh Into Grid: 0.06 kWh Usage: 3.27 kWh Digioso@DigiSlave ~/S10history $ ./daily.pl 2020 01.01.2020 Production: 15.73 kWh Into Grid: 8.11 kWh Usage: 7.62 kWh 02.01.2020 Production: 3.14 kWh Into Grid: 0.07 kWh Usage: 3.07 kWh 03.01.2020 Production: 0.42 kWh Into Grid: 0.00 kWh Usage: 0.42 kWh 04.01.2020 Production: 0.59 kWh Into Grid: 0.00 kWh Usage: 0.58 kWh 05.01.2020 Production: 0.61 kWh Into Grid: 0.00 kWh Usage: 0.61 kWh 06.01.2020 Production: 11.40 kWh Into Grid: 0.32 kWh Usage: 11.08 kWh 07.01.2020 Production: 1.16 kWh Into Grid: 0.06 kWh Usage: 1.10 kWh Digioso@DigiSlave ~/S10history $

The script has to be put into the same directoy as S10history binary. config-file named config.ini also needs to be placed there.

Example config.ini file: USER = your_e3dc@mail.address PW = e3dc_website_password AES = aes_password IP = 1.1.1.1 INSTALLDATE = 20191031

And the script:

#!/usr/bin/perl -w
#
# S10 Daily Status
#
# Function  : Prints information about solar production, how much went into the grid and consumption
#
# Parameters: 1
#           1: year in format YYYY (required)
# Author    : Digioso - https://www.digioso.org
# Released under the terms and conditions of the GNU General Public License (http://gnu.org).
# Version history:
# 26.05.2020 - 1.0 - Digioso - initial version
use strict;
use warnings;
use File::Basename;
use Time::Local;
use Time::Local 'timelocal_nocheck';

sub error_codes($$);
sub exit_script($$);
sub ctime_calc($);
sub date_to_ctime($);
sub day_of_year($$$);

my $exit_success     = 0;
my $exit_failure     = 1;
my $exit_usermistake = 2;
my $exit_openfile    = 3;
my $exit_config      = 4;
my $exit_installdate = 5;

exit_script($exit_usermistake, "") if(scalar @ARGV != 1 || $ARGV[0] !~ /^\d{4}$/);

my %config  = ();
my $confdir = (fileparse($0))[1];
my $conff   = "$confdir/config.ini";

if(open CFG, "< $conff")
{
    while(my $row = <CFG>)
    {
        chomp $row;
        $config{uc($1)} = $2 if($row =~ /^(\w+)\s*=\s*(.*?)$/);
    }
    close CFG;
}
else
{
    exit_script($exit_openfile, $conff);
}

exit_script($exit_config, "") unless(defined $config{USER} && $config{USER} ne "" && $config{PW} && $config{PW} ne "" && $config{AES} && $config{AES} ne "" && $config{IP} && $config{IP} ne "" && defined $config{INSTALLDATE});

my $installyear;
my $installmonth;
my $installday;
if($config{INSTALLDATE} =~ /^(\d{4})(\d\d)(\d\d)$/)
{
    $installyear  = $1;
    $installmonth = $2;
    $installday   = $3;
    $config{INSTALLDATE} = date_to_ctime("$installday.$installmonth.$installyear 00:00:00");
}
else
{
    exit_script($exit_installdate, "");
}

$config{YEAR} = $ARGV[0];
chomp $config{YEAR};

my $numdays = 365;
$numdays    = 366 if($config{YEAR} % 4 == 0 && $config{YEAR} % 100 != 0 || $config{YEAR} % 400 == 0);

# Startdate of year for calculation
my $startday = 1;

if($installyear > $config{YEAR})
{
    print "The given year is lower than the installation year. That doesn't work.\n";
    exit_script($exit_usermistake, "");
}
elsif($installyear == $config{YEAR})
{
    # Set startdate for calculation to installation date in case installation year is the same as the requested year. You'll get an error if you request a date prior to the installation date.
    $startday = day_of_year($installday, $installmonth, $installyear);
    print "Setting startdate to installation date $installyear$installmonth$installday.\n";
}

my %months = ("Jan" => "01", "Feb" => "02", "Mar" => "03", "Apr" => "04", "May" => "05", "Jun" => "06", "Jul" => "07", "Aug" => "08", "Sep" => "09", "Oct" => 10, "Nov" => 11, "Dec" => 12);

for(my $day = $startday; $day <= $numdays; ++$day)
{
    my $cmd = "$confdir/S10history -u $config{USER} -p $config{PW} -a $config{AES} -i $config{IP} -y $config{YEAR} -m 1 -b -d $day 2>&1";
    #print "$cmd\n";
    if(open IN, "$cmd |")
    {
        my $yearday;
        while(my $row = <IN>)
        {
            chomp $row;
            if($row =~ /ERROR/)
            {
                print "$row\n";
                close IN;
                exit 1;
            }
            if($row =~ /^Day start: \d+ - ... (\w{3})\s+(\d+) ..:..:.. (\d+)$/)
            {
                $yearday = $2;
                $yearday = "0$yearday" if($yearday < 10);
                $yearday .= ".$months{$1}.$3";
            }
            elsif($row =~ /^Day-CSV:/)
            {
                my @csv = split(";", $row);
                printf("%s Production: %.2f kWh Into Grid: %.2f kWh Usage: %.2f kWh\n", $yearday, $csv[4]/1000, $csv[5]/1000, ($csv[4] - $csv[5]) / 1000);
            }
        }
        close IN;
    }
    else
    {
        print "Cannot execute $cmd !\n";
    }
}
exit_script($exit_success, "");

#
#error_codes
#
# Function  : reads error codes and prints their specific messages
#
# Parameters: 2
#           1: errorcode    (required)
#           2: errormessage (required)
# Author    : Digioso - https://www.digioso.org
# Date      : 26.05.2020
#
sub error_codes($$)
{
    my $errorcode        = $_[0];
    my $message          = $_[1];
    my $exit_success     = 0;
    my $exit_failure     = 1;
    my $exit_usermistake = 2;
    my $exit_openfile    = 3;
    my $exit_config      = 4;
    my $exit_installdate = 5;

    if($errorcode == $exit_success)
    {
        print "\nSuccess !\n";
    }
    elsif($errorcode == $exit_failure)
    {
        print "\nAn error occured !\n";
    }
    elsif($errorcode == $exit_usermistake)
    {
        print "Usage of this program:\n\n$0 YYYY\n";
        print "Example: $0 2020\n\nYear cannot be lower than the installation year.";
    }
    elsif($errorcode == $exit_openfile)
    {
        print "\nCan't open file $message !\n";
    }
    elsif($errorcode == $exit_config)
    {
        print "\nPlease check your config-file! INSTALLDATE, USER, PW, AES & IP must be set !\n";
    }
    elsif($errorcode == $exit_installdate)
    {
        print "\nPlease check your config-file! INSTALLDATE seems to be invalid !\n";
    }
    return 0;
}

#
#exit_script
#
# Function  : quits the program with an errorcode
#
# Parameters: 2
#           1: error code    (required)
#           2: error message (required)
# Author    : Digioso - https://www.digioso.org
# Date      : 26.05.2020
#
sub exit_script($$)
{
    my $exitcode = $_[0];
    my $message  = $_[1];
    error_codes($exitcode, $message);
    exit $exitcode;
}

#
# ctime_calc
#
# Function  : calculate CTime into DD.MM.YYYY HH:MM:SS format
#
# Parameters: 1
#           1: CTime
#
# 19.12.2012    Digioso         initial version
sub ctime_calc($)
{
    my $time = shift;
    my ($sec, $min, $hrs, $day, $mth, $year ) = (localtime($time))[0,1,2,3,4,5];
    $mth++;
    $year += 1900;
    ($sec < 10) && ($sec = "0$sec");
    ($min < 10) && ($min = "0$min");
    ($hrs < 10) && ($hrs = "0$hrs");
    ($mth < 10) && ($mth = "0$mth");
    ($day < 10) && ($day = "0$day");
    return "$day.$mth.$year $hrs:$min:$sec";
}

#
# date_to_ctime
#
# Function  : calculate DD.MM.YYYY HH:MM:SS time into CTime
#
# Parameters: 1
#           1: Time in format DD.MM.YYYY HH:MM:SS
#
# 31.07.2013    Digioso         initial version
sub date_to_ctime($)
{
    return timelocal_nocheck($6, $5, $4, $1, $2 - 1, $3) if($_[0] =~ /^(..).(..).(....) (..):(..):(..)$/);
}

#
# day_of_year
#
# Function  : returns the day of the year
#
# Parameters: 3
#           1: day in format DD
#           2: month in fromat MM
#           3: year in format YYYY
#
# 26.05.2020    Digioso         initial version
sub day_of_year($$$)
{
    my ($d,$m,$y) = @_;
    return (localtime(timelocal(0,0,0,$d,$m - 1,$y)))[7];
};