How to get logs from Classic over Modbus?

Started by David, July 23, 2012, 09:57:13 AM

Previous topic - Next topic

rosebudd

Yann,

Your efforts are motivating me to have another go at Modbus....

It worked for me using a Modbus reader called Ananas with Wine/Linux, but massaging the data is another story. There is a lot to learn, but all fun.

Lurking in the shadows, but following your progress, keep it up.

thanks
steve
MS Classic 150, ~1.6kw pv, 500 ah , OB3524, ListerSL1/3kwgenAC .....so far
"retirement projects"

boB

#16
Quote from: Lya72 on August 16, 2012, 10:10:25 AM
Hi Bob,

Reference to your latest post, have you found the key of the desk where are stored the latest Classic ModBus specifications ???

My Classic is speaking to the Web but I need a dictionnary to understand him...

Also, always interested in how to read Classic logs via ModBus registers.

Thanks in advance.

Yann


Yann, I have been working on the writeup for this.  Here is what I have so far for retrieving single data points by way of simple modbus registers.
This is fine for single points but for say, graphing, you might want to use the modbus file transfer method to get 32 points at one time.
That is how the MNGP retrieves data for its graphing, but the single "textual" readout uses this retrieval method.  I will get to writing up the
file retrieval method later.  Hopefully this helps to get you started in understanding how this works.


This text tries to explain one of the two methods to retrieve internal Classic data logs.
This one retrieves one daily or recenty history (minutely) at a time.  The other method
retrieves 32 data points at a time using modbus file transfer.

To read a logged data value from the Classic's EEprom, first combine the dayly or minute log index,
(index means how many records ago), with the category of data you want to retrieve.
Category examples include, maximum power for a past day or what stage the charger was in
23 records ago.    "Minute Logs" is the same as "Recent History" and may be acquired as often
as 1 minute apart and up to 380 records total.  After 380 records are stored in the Classic,
the oldest data is overwritten with the penultimate (next to last) data point values.
In the future, there may be more categories, but at the moment, there are less than 8
for Daily and Recent History logs.  Daily logs are stored (usually) at midnight every day.
Actually, they are stored by the clock at 23:59 hours:minutes.  If the clock in the Classic has
not been set by the MNGP, this may happen 2 hours after the Classic last went to Resting.
At this time, the Classic's internal clock will be set to 23:59.  This might happen with a
Classic-Lite where no MNGP (graphics panel) is present. 

Summary of the 3 main data logging retrieval registers.      " | "  is   logical OR
Normal modbus convention will make it necessary to add 1 (one) to these register numbers.....

Modbus Address   ---   Register  ---    Index  OR'd  with Category to return in the LogValueRead Register

4253  DaylyLogCatIndex   =    [-DAY  &  0x03ff]  |  [ (DaylyLogCategory & 0x3ff) << 10 ]

4254   LogValueRead        =    Value returned after requested input changes

4255   MinLogCatIndex    =    [-MINUTERECORD  &  0x03ff]  |   [  (MinuteRecordCategory & 0x3ff) << 10 ]

4135   MinuteLogIntervalSec   =  How many seconds between data logging intervals.  (Minimum of 60 seconds)
       Logging Interval has a default of ten (10) minutes but will be changed eventually to every 5 minutes (300 seconds)
       MinuteLogIntervalSec    is remembered in the Classics EEProm

For example, request the charge stage category (5) from 2 minutely log records ago....

(2 records would be 2 X 10 minutes ago if interval is 10 minutes)....

    decimal                             binary                     binary                          hex

2  |  (5 << 10)  =  ( 0010  |   01010000000000)  =   01010000000010  =   0x1402



The value returned in LogValueRead, (register 4254), will not be filled with a
return category value until one of the combination index/category input registers,
(DaylyLogCategory or MinLogCatIndex), change request value.
This means that if you want to read a value twice, the request register must
change and then be changed back again to request the logged data point again.

The minus sign in front of MINUTERECORD  and DAY  index is to represent that these index
numbers are past histories.    All values  are unsigned and an index of zero is undefined.


Minute Logs Category   (MinuteRecordCategory)
0  Watts
1  PV input voltage (times 10 with tenth digit in LSDigit)
2  Battery Voltage  (times 10 with tenth digit in LSDigit)
3  Time Stamp Low
4 Time Stamp High
5  Charge Stage   ( in high byte of 16 bit result)
6  Battery Amps Out  (times 10 with tenth digit in LSDigit)
7  kW-Hours    (times 10 with tenth digit in LSDigit)

Daily Logs Category     (DaylyLogCategory )
0   kW-Hours     (times 10 with tenth digit in LSDigit)
1  Amp-Hours    (Not used yet)
2  Float Time in Minutes
3  Dailys Time Stamp Low
4  High Power watts
5  High FET Temperature  (Celcius)
6  Dailys Time Stamp High
7  High PV Input Voltage   (times 10 with tenth digit in LSDigit)
8  High Battery Voltage    (times 10 with tenth digit in LSDigit)

Time Stamp
TimeStampLow = (MONTH & 0x0f)  |   ((DOM & 0x1f) << 4)  |   ((((YEAR - 2000) & 0x7f) << 9))
TimeStampHigh =  (MINUTE & 0x3f)  |  ((HOUR & 0x1f) << 6)
DOM = Day Of Month, Year is encoded as years after 2000

Charge Stage  (High byte of 16 bit returned value)
Stage  =  value >> 8

Resting        0
Absorb        3
Bulk Mppt    4
Float           5
Float Mppt   6
Equalize      7
Eq Mppt      18   

[/font]


P.S.  Does anyone have an idea why I get the end font html tag printing at the end here ??  AFAIK, it should be "silent" and not actually displayed.
K7IQ 🌛  He/She/Me

Lya72

Hi Bob,

I was on my roof, increasing my panels power and you answered !!

Unattended  :P

On my first read, it seems complex to me.

First of all, i need to reorder your writes.

Secondly, the difficulty is with the Index and category combination.

Do I need to write a calculated value in a register to be able to read the requested result in another register ?,

The calculated value is obscur for me and the writable register is the same as the register giving the requested result ?

Thanks for the precisions.

Yann

1 Classic 200, 4 SILLIA panels 240W in 2 strings of 2, ie 960Watts and 60.8 Volts, 4 MIDAC Batteries 6V 240Ah, ie 24V bank (acid batteries)

boB

Quote from: Lya72 on August 22, 2012, 02:51:41 AM

First of all, i need to reorder your writes.

Secondly, the difficulty is with the Index and category combination.

Do I need to write a calculated value in a register to be able to read the requested result in another register ?,


Yann

Yann, I probably actually need to re-write some of my writing.  It is kind of complicated but as complicated
as some methods I have seen over the years.

The  LogValueRead  register returns any of the requested information... Either from a Day by day log (Dailys)
or a minute by minute (Minutely) log entry.

You do not have to calculate where in memory anything is...  You only need to give it an index which is how
many log entries ago you want to retrieve.   Index of 1 is 1 entry ago (Yesterday for Dailys), Index of 2
is 2 days ago, Index of 3 is 3 days ago, etc...

The log values are internally stored as a circular buffer and has an internal pointer to where "NOW" is
so it knows where the index will point to  in that buffer.

I will re-read and re-clarify as I can.  Thanks for the help !
boB

K7IQ 🌛  He/She/Me

rosebudd

Yann and all,

Had some success using Modpoll/Linux/RRDTool to graph data from the MS 150.

http://sunenr.homedns.org/cgi-bin/modclsc150.pl

Still have a bug in bash script....the "tail" command means the watt value below 100 is "nan"....need to find another way to parse the value. Just takes a little time.

satisfying to make pretty lines... :)

steve

ps willing to share my little bit if anyone is interested
MS Classic 150, ~1.6kw pv, 500 ah , OB3524, ListerSL1/3kwgenAC .....so far
"retirement projects"

boB

K7IQ 🌛  He/She/Me