Modbus basics

Modbus basics

Postby intellact on Sun Nov 08, 2015 9:40 pm

So if you are vaguely familiar with the Modbus protocol, you will know that when trying to read the holding registers of an AXS Port, you really only have one starting address: 40069 (for the OutBack Block).

Every other address will depend on the length of every block which comes before it, and the length of blocks will change, based on the devices you have and even the firmware releases (so please don't bother posting any of your own addresses in this forum as a help to other users - it will only confuse them :wink:).

That being said, I thought I would share the Block IDs that I have detected in my single inverter and FnDC system:

64110 - OutBack block - expected
64120 - OutBack System Control block - expected
101 - SunSpec Single-Phase Inverter block - not expected, but OK, I can see why it might be there
64255 - What is this? Even Google cannot identify blocks with this ID :???: (it has a length of 55)
64113 - FX Real-time block - expected
64114 - FX Config block - expected
64118 - FnDC Real-time block - expected
64119 - FnDC Config block - expected
65535 (i.e. -1) - unexpected

The last block is a little unexpected because the OutBack documentation (don't get me started) says: "The final End Block formally marks the end of the block structure", but nowhere is "End Block" identified or described.

If any AXS users out there can comment on either Block ID 64255 or End Blocks, I'd love to hear from you. :smile:

In return, I will try to post discoveries and help out new AXS port programmers as much as I can. :smile:
Andrew Welch, creator of WattPlot
User avatar
intellact
OutBack Czar
 
Posts: 652
Joined: Mon Nov 28, 2005 4:20 am
Location: Ontario, Canada

Re: Modbus basics

Postby tallgirl on Wed Dec 02, 2015 9:44 pm

The data format is SunSpec. There's a SunSpec "end block" which terminates the variable length data structure which started at address 40001.

(Edited to elaborate -- I've spent years looking at SunSpec and that wasn't the best of information for the uninitiated!)

The Single Phase Inverter block is exactly what you'd get for a system with a single phase inverter -- OutBack only sells single phase inverters, tho you can put 3 of them together and make 3-phase. I suspect the Radians are "Split Phase" inverters since that's what they are -- there's no such thing as "2-phase" anymore.

Each of the blocks starts with an identifier ("DID") which says what kind of block you've got -- 101 is a single phase inverter "Device ID". Because the model is variable length, you need something to tell you when you're done. That's what the "End Block" is all about -- where's the end.

Here's the constants from my SunSpec code --

Code: Select all
public class Values {
        public static final int SUNSPEC_COMMON_BLOCK_1 = 0x5375;
        public static final int SUNSPEC_COMMON_BLOCK_2 = 0x6E53;
        public static final int SUNSPEC_COMMON_BLOCK =
                        ((SUNSPEC_COMMON_BLOCK_1 << 16) | SUNSPEC_COMMON_BLOCK_2);

        public static final int SUNSPEC_AGGREGATION_BLOCK = 2;

        public static final int SUNSPEC_INVERTER_1PH = 101;
        public static final int SUNSPEC_INVERTER_1PH_SPLIT = 102;
        public static final int SUNSPEC_INVERTER_3PH = 103;

        public static final int SUNSPEC_MODULE_FLOAT = 501;
        public static final int SUNSPEC_MODULE_INT = 502;

        public static final int SUNSPEC_END_BLOCK = 65535;
}


OutBack has "reserved" DIDs that they use, but they are also going to use the standard DIDs where they are appropriate. The usual approach is to look at the DID, and if you know what to do with it, fantastic! If not skip it. So, the main loop starts with something like this --

Code: Select all
                while (true) {
                        ModbusTransaction trans = transport.createTransaction();
                        trans.setCheckingValidity(true);
                        trans.setRetries(3);

                        readRequest = new ReadInputRegistersRequest();
                        readRequest.setUnitID(0);
                        readRequest.setReference(lastBlockStart);
                        readRequest.setWordCount(2);


That sets up a 2 register read request, recalling that the starting block has a 2 register long DID. When you've gotten that, and used a switch statement to select your block type (heh), you can extract the device type and block length, like this --

Code: Select all
                                case Values.SUNSPEC_INVERTER_1PH:
                                case Values.SUNSPEC_INVERTER_3PH:
                                case Values.SUNSPEC_INVERTER_1PH_SPLIT:
                                        blockType = header[0].toUnsignedShort();
                                        blockLength = header[1].toUnsignedShort() + 2;


Remember that infinite loop at the top? Well, when you get a DID of SUNSPEC_END_BLOCK you need to terminate it.

There you have it. All the SunSpec fun you could ever want.
Julie in Texas

greenMonitor(tm) for OutBack Power Technologies systems from greenHouse Gas and Electric. Learn more now!
User avatar
tallgirl
OutBack Emperor
 
Posts: 4329
Joined: Wed Sep 26, 2007 9:59 am
Location: Austin, TX
My RE system: 16 Kyocera KC175GT (2,800 watts DC), MX-60, 2 OutBack GVFX3648, 24 GC2 batteries (6v @ 215AH), 14 Pantheon-based ACPV modules (3,200 watts DC), La Crosse Technologies WS2310 Weather Station, greenLogger Sensors environmental monitor, WattNode watt-hour meter, greenLogger Lite data logger.

Re: Modbus basics

Postby intellact on Thu Dec 03, 2015 8:38 am

Thanks so much for your reply, Julie.

tallgirl wrote:The data format is SunSpec. There's a SunSpec "end block" which terminates the variable length data structure which started at address 40001.

Interesting. You start at 40001, I start at 40069. I wonder if you have used your code on an actual AXS Port. Here's what my AXS kicks out:

Address 40069: Block ID = 64110, block length = 420 (as expected, and all documented blocks follow nicely)
Address 40001: Block ID = 28243, block length = 1 :???: Huh? This doesn't look like any Modbus block that I would recognize... help, anyone?

tallgirl wrote:Each of the blocks starts with an identifier ("DID") which says what kind of block you've got -- 101 is a single phase inverter "Device ID". Because the model is variable length, you need something to tell you when you're done. That's what the "End Block" is all about -- where's the end.

Actually, I don't think that's quite what you meant to say. Yes, each model block is variable length, but you use the block length to determine where the end of each block is. An "End Block" should tell you when you are out of blocks (i.e. out of devices - the AXS typically has 2 blocks per device), but as I pointed out in my original post, the documentation doesn't define what the block ID of an "End Block" is.

From your code and my results, I presume that the DID of an End Block is indeed 65535. Thanks for confirming that.

tallgirl wrote:OutBack has "reserved" DIDs that they use, but they are also going to use the standard DIDs where they are appropriate. The usual approach is to look at the DID, and if you know what to do with it, fantastic! If not skip it.

OutBack may use standard DIDs where appropriate, but the vast majority of the data is in "reserved" DIDs, as noted in the list in my original post. I'm quite happy to skip blocks that I don't recognize, but my original question was "What is block 64255" (presumaby an OutBack-specific block) and why is it not documented?

Here's my guess... the AXS has generic SunSpec blocks for whatever system devices are a match to generic devices. (See the 101 in my original list.) It then closes that set of generic blocks with a 64255 and starts its own list of reserved blocks. That would be my guess, but that is not documented anywhere, nor are the values of a 64255 block defined anywhere. ](*,)

tallgirl wrote:<snip code> There you have it. All the SunSpec fun you could ever want.

Since my system is already running Modbus monitoring, your code is appreciated but I'm sort of past that now.

A more pressing problem (as raised in another post) is why the AXS Port will not allow me to write any of my so-called "programmable" values back to the device. ](*,)
Andrew Welch, creator of WattPlot
User avatar
intellact
OutBack Czar
 
Posts: 652
Joined: Mon Nov 28, 2005 4:20 am
Location: Ontario, Canada

Re: Modbus basics

Postby tallgirl on Thu Dec 03, 2015 3:32 pm

Well ... I was paid a very large pile of money to work on SunSpec-compliant monitoring stuff and on megawatt-scale systems, so I'm fairly sure I know what I'm talking about ;)

Depending on how you number your Modbus addresses, SunSpec starts at address 40000 ... or 40001. That's one of the joys of Modbus. The first DID (it's not a DID - it's a 32-bit magic number) is a double-register value having two parts. They are --

Code: Select all
        public static final int SUNSPEC_COMMON_BLOCK_1 = 0x5375;
        public static final int SUNSPEC_COMMON_BLOCK_2 = 0x6E53;


If you read from "real address" 40001 and got 28243, you found SUNSPEC_COMMON_BLOCK_2, which is the second register of that value. At "real address" 40000 you'll find 0x5375 or decimal 21365.

The reason you see data on 40069 is because the common model is 67 registers long, and you've got 2 registers to start with -- there's your 69 registers. So, you're skipping over the common model, which you really shouldn't do -- you should always scan the address space linearly since each block may have a length you aren't quite expecting.

As for running on an actual AXS port, I don't have to -- the AXS port is a SunSpec compliant device. It's going to work the way SunSpec says it must \:D/

That said, I'm surprised you're seeing an ID of 64255, though that may be a vendor ending block as it's 0xFAFF -- OutBack has the range 64110 to 64119 assigned to it and no one has 64255, or anything including 64255, assigned to them. I'd be interested in knowing how long that block is and what it contains.
Julie in Texas

greenMonitor(tm) for OutBack Power Technologies systems from greenHouse Gas and Electric. Learn more now!
User avatar
tallgirl
OutBack Emperor
 
Posts: 4329
Joined: Wed Sep 26, 2007 9:59 am
Location: Austin, TX
My RE system: 16 Kyocera KC175GT (2,800 watts DC), MX-60, 2 OutBack GVFX3648, 24 GC2 batteries (6v @ 215AH), 14 Pantheon-based ACPV modules (3,200 watts DC), La Crosse Technologies WS2310 Weather Station, greenLogger Sensors environmental monitor, WattNode watt-hour meter, greenLogger Lite data logger.

Re: Modbus basics

Postby intellact on Thu Dec 03, 2015 10:52 pm

tallgirl wrote:Depending on how you number your Modbus addresses, SunSpec starts at address 40000 ... or 40001. That's one of the joys of Modbus.

Actually, having a choice between using 0-based and 1-based addressing is only the beginning. OutBack uses both in their documentation, so that addresses within blocks are differently numbered from one manual revision to the next. Now that's a joy.

Not. ](*,)

tallgirl wrote:If you read from "real address" 40001 and got 28243, you found SUNSPEC_COMMON_BLOCK_2, which is the second register of that value. At "real address" 40000 you'll find 0x5375 or decimal 21365.

You are correct that I should have started at 40000, not 40001 for the software I'm using. Of course, if there had been any mention of either address in the OutBack documentation, I wouldn't be here on the forum. :roll: Perhaps I should have started with the full SunSpec Technical Specifications, but posting here was way easier. :wink: Thank you for your assistance. Now that my code is straightened out, the SunSpec specifications are a bit more helpful.

I should clarify for other readers that 40000 and 40001 are not part of the SunSpec Common Model Block at all - that starts at 40002. Instead, they are used to identify what follows as being a SunSpec Modbus map. (To anyone who might be interested, the 21635 and 28243 translate to "SunS"! \:D/)

So here's what we have:

Code: Select all
 Modbus Map ID   40000  =  21635  ("Su")
 (2 registers)   40001  =  28243  ("nS")
SunSpec Common   40002  =  1      (Block ID of SunSpec Common Model Block)
   Model Block   40003  =  65     (Block Length)
          >      40004  =  20341  ("Ou")
          >      40005  =  29762  ("tB")
          >      40006  =  24931  ("ac")
          >      40007  =  27487  ("k_")
          >      40008  =  20591  ("Po")
          >      40009  =  30565  ("we")
          >      40010  =  29184  ("r")
          >      ...
          >      40069  =  64110  (Block ID of OutBack Block)


So, AXS programmers should start their code with a check of 40000 and 40001 to confirm what Modbus standard they are talking to. If they are the values given above, then they can read 40002, confirm it's a SunSpec Common Block ("1"), then get the block length from 40003, confirm the "OutBack_Power" (etc.) if they want, and finally do the following calculation in order to proceed walking the map:

Take the base address (40002), account for the first two registers (Block ID and Length), then add the block length (65?).

e.g. 40002 + 2 + 65 = 40069

tallgirl wrote:So, you're skipping over the common model, which you really shouldn't do -- you should always scan the address space linearly since each block may have a length you aren't quite expecting.

Yep, it's a lot easier to play by the rules when you finally find the rule book, and easy to get lost when there's misleading information floating around. My software has always done a linear scan - it just started one block in.

tallgirl wrote:As for running on an actual AXS port, I don't have to -- the AXS port is a SunSpec compliant device.

Yeah, I didn't think you had.

tallgirl wrote:That said, I'm surprised you're seeing an ID of 64255, though that may be a vendor ending block as it's 0xFAFF -- OutBack has the range 64110 to 64119 assigned to it and no one has 64255, or anything including 64255, assigned to them. I'd be interested in knowing how long that block is and what it contains.

I'd be interested to know too. #-o That's why I posed that question in my original post.
Andrew Welch, creator of WattPlot
User avatar
intellact
OutBack Czar
 
Posts: 652
Joined: Mon Nov 28, 2005 4:20 am
Location: Ontario, Canada

Re: Modbus basics

Postby fatheadl on Fri Dec 04, 2015 8:24 am

Hi. 64255 is OPTICS packet statistics.
8 KC130TM, FM60, RTS, Samlex S1500-124, Mate3, FN-DC, 8 NSB170FT Blue AGM
User avatar
fatheadl
OutBack Whiz
 
Posts: 39
Joined: Wed Dec 13, 2006 8:16 am
Location: Knigston, Jamaica

Re: Modbus basics

Postby intellact on Fri Dec 04, 2015 9:52 am

fatheadl wrote:Hi. 64255 is OPTICS packet statistics.

Thanks! Mystery solved. =D>
Andrew Welch, creator of WattPlot
User avatar
intellact
OutBack Czar
 
Posts: 652
Joined: Mon Nov 28, 2005 4:20 am
Location: Ontario, Canada

Re: Modbus basics

Postby tallgirl on Fri Dec 04, 2015 3:29 pm

Andrew -

The mixing of 0-based and 1-based numbering has been the one constant in Modbus communications since the '70s. It drives everyone who touches Modbus completely to distraction.

For generic SunSpec, there are multiple possible base registers -- 40001, 50001 or just plain ... 1. And of course, those are really "physical addresses" 40000, 50000 and 0. The canonically correct way of dealing with SunSpec compliant devices is to read address 40000, 50000 and then 0 searching for the first register value ("Su"), and if found check the next register for the second value ("nS") -- and I figured you'd get a kick out of that. If you ever get around to chatting up other SunSpec devices (Veris and Continent Controls both have SunSpec capable meters, though Veris has the more complete of the two as much as I hate to say that) that would be handy to know.
Julie in Texas

greenMonitor(tm) for OutBack Power Technologies systems from greenHouse Gas and Electric. Learn more now!
User avatar
tallgirl
OutBack Emperor
 
Posts: 4329
Joined: Wed Sep 26, 2007 9:59 am
Location: Austin, TX
My RE system: 16 Kyocera KC175GT (2,800 watts DC), MX-60, 2 OutBack GVFX3648, 24 GC2 batteries (6v @ 215AH), 14 Pantheon-based ACPV modules (3,200 watts DC), La Crosse Technologies WS2310 Weather Station, greenLogger Sensors environmental monitor, WattNode watt-hour meter, greenLogger Lite data logger.

Re: Modbus basics

Postby tallgirl on Fri Dec 04, 2015 3:31 pm

fatheadl wrote:Hi. 64255 is OPTICS packet statistics.


Y'all need to stop doing that. It's completely non-compliant and goes against everything that SunSpec is all about. If you want to leave room for other power equipment, you should change that value to 60119.
Julie in Texas

greenMonitor(tm) for OutBack Power Technologies systems from greenHouse Gas and Electric. Learn more now!
User avatar
tallgirl
OutBack Emperor
 
Posts: 4329
Joined: Wed Sep 26, 2007 9:59 am
Location: Austin, TX
My RE system: 16 Kyocera KC175GT (2,800 watts DC), MX-60, 2 OutBack GVFX3648, 24 GC2 batteries (6v @ 215AH), 14 Pantheon-based ACPV modules (3,200 watts DC), La Crosse Technologies WS2310 Weather Station, greenLogger Sensors environmental monitor, WattNode watt-hour meter, greenLogger Lite data logger.

Re: Modbus basics

Postby mgoldbach on Tue Oct 17, 2017 9:15 pm

Thanks all for a great thread.
My only question is where have you seen documentation for model 64113? I've downloaded what I believe is the latest from Outback and don't see it in the excel spreadsheet.

Nevermind, I figured it out. The additional information is available here: http://www.outbackpower.com/downloads/d ... P_NOTE.pdf
mgoldbach
Member
 
Posts: 7
Joined: Mon Oct 16, 2017 9:37 pm
My RE system: AXS Port
2 x MX60
2 x GVFX3648


Return to AXS Port

Who is online

Users browsing this forum: No registered users and 1 guest