jdblair / sunspec

Sunspec Reference Implementation and Test Tool
Other
20 stars 5 forks source link

SunSpec Test Tool README

Updates

2011-Oct-05: Added improvements and fixes based on testing during the Sunspec Plugfest.

2011-Oct-21: Added the ezxml library. Added xml model format.

2012-Jan-24: Changes to support libmodbus version 3.0.1, the current stable release rather than version 2.9.3.

2012-Jan-25: Makefile changes to fix build issues on Ubuntu 11.10. Correct some unit labels that were incorrect in the AC meter map.

2012-Feb-04: Added support for 64 bit data types. Added custom decimal floating point text output routines to eliminate approximation errors caused by computing sunspec scale factors using IEEE 754 floating point numbers.

2012-Apr-15: Summarizing a large number of changes that have been made since February

          Fix a bug with the -l option, which allows reading sets
          of registers

          Add some verbose detail when performing multiple reads
          to retrieve all the data in a model (accessed with
          verbose level 2, -vv)

          Fix mistakes in the 404 string model (discovered when
          trying to verify the Ecogard string combiner)

          Generate appropriate warnings when expected model
          lengths do not match the provided model length

          Generate warnings when an implemented data point
          references an unimplemented scale factor (also
          substitutes zero for the scale factor to try and do the
          right thing).

          Remove an un-intended build dependency on sqlite.h

          Assorted other corrections of errors and omissions in
          models having to do with labels, short names and units.

          There is also a lot of new work to implement a SunSpec
          host (available with the -H flag), a sqlite data store, and
          a simple tool for accessing the data store.  This work is
          not yet stable.

2012-Apr-27: Incorporating bugs discovered and some features requested during the April Plugfest:

          Clean up improper use of malloc() in suns_lang.y
          Fix the -M option so the tool does not search for model files
            installed on the system if one uses the -M flag.
          Add the proposed "ipaddr" type.
          Add vendor blocks contributed by Outback Power, Veris Industries
            and Eltek.

          Calling this release 1.0.1 - the first numbered release.

          There was a short lived 1.0.0 release, but I've cleaned up
          the source code tree of some extraneous files and bumped the
          version number to avoid confusion.

2012-Jul-14: Retire custom sunslang model format used as the primary model representation up until now. The xml format, now called SMDX, is the primary form of all the model files.

          The test tool has been adjusted to read the latest version
          of SMDX and functions the same as it did reading the old
          model files.

          The old model format is still used to represent static
          test data.  A library of test data can be found in
          models/test.

2013-Aug-13: Implement error checking for the presence and correct location of the common model and the end marker.

          Include the complete end marker in the test server (0xFFFF 0x0000,
          not just 0xFFFF).

          Fix warnings output when built using the 64 bit version of
          gcc 4.6.3 on Ubuntu 12.04.

Dependencies

The test tool uses libmodbus to implement the modbus communication layer. The tool works with libmodbus 3.0.1, the current stable release.

The libmodbus project is available here: http://libmodbus.org

Download version 3.0.1 (the stable release at the time this was written) from: http://github.com/downloads/stephane/libmodbus/libmodbus-3.0.1.tar.gz

Build and install libmodbus on your system. libmodbus installs in /usr/local/lib, so make sure /usr/local/lib is in your LD search path.

pkg-config is used to link properly against libmodbus. You will need to install pkg-config if its not already present on your system.

GNU flex (lex) and bison (yacc) is used to write the configuration language parser.

Building

In the src/ subdirectory, type "make."

The build has currently only been tested on Ubuntu 10.4. It should work on other systems but YMMV.

Build Issues FAQ

/usr/bin/ld: cannot find -lmodbus collect2: ld returned 1 exit status make: *** [suns] Error 1

You probably have not installed libmodbus in /usr/local/lib. Type "sudo make install" in the libmodbus-3.0.1 directory.

./suns: error while loading shared libraries: libmodbus.so.4: cannot open shared object file: No such file or directory

You most likeley don't have libmodbus.so in your LD search path. To fix this on my Ubuntu build system, and most other distros (as root):

echo /usr/local/lib >> /etc/ld.so.conf ldconfig

Running

You must always specify a model definition file to be able to decode any discovered SunSpec data models. The model definition file contains both a description of the SunSpec data model as well as canned test data for running a "test slave" used to test the tool itself.

These examples assume you have installed the suns tool on your system by running "make install." These means the model files do not need to be specified, as they will be read from /usr/local/lib/suns/models.

Quickstart:

To learn more about what is going on, specify additional verbosity by adding up to for "-v" flags.

The model file is not strictly required, but the tool is not very useful without it. Without a model file the tool will search for sunspec blocks and then report the DID of every block it finds until it hits the end marker. Without the model definition file the tool can't interpret the values in any of these blocks.

Sunspec Background

The following is a summary of information in the Common Model specification.

SunSpec is currently defined to use modbus, as this is the most common non-proprietary interface method currently used in the solar world.

SunSpec is designed to allow an unknown device to be discovered by defining a flexible data model marked using a "magic value" stored in either modbus register 40001 or 50001.

Immediately following the SunSpec magic value should be the Common Model data block. This describes information common to all devices, like manufacturer name and serial number.

Following the common model should appear at least one data model, describing the information specific to this device. Additional data models can follow.

+-------------------+
| sunspec magic:    |
| 0x5375 0x6e53     |
+-------------------+
|                   |
| common model      |
| block             |
|                   |
+-------------------+
|                   |
| one required      |
| model block       |
|                   |
+-------------------+
|                   |
| optional          |
| additional        |
| model blocks      |
/                   /
/                   /
|                   |
+-------------------+
| end marker        |
| 0xFFFF 0x0000     |
+-------------------+

Every SunSpec data model starts with a Device ID (DID) value, followed by the length of the block. The presence of the length register allows a reading application to skip over data models which it does not a priori know about.

The internal structure of SunSpec data models allows for fixed length and variable length data models.

1) Fixed length data blocks:

+-----------------+
| device id       |
+-----------------+
| model length    |
+-----------------+
| fixed length    |
| data block      |
|                 |
|                 |
|                 |
+-----------------+

Examples: common, ac_meter, inverter

In these cases the length register provided by the device must be
the fixed size defined in the SunSpec model.

2) Variable length data blocks:

Variable length data models are always a multiple of a fixed size
data block which is repeated in the modbus register address space.
The reading device must read the model length register value to
determine how many individual records exist on the given device.

Variable length records come in two forms:

a) A fixed "header" block which is not repeated, followed by a variable length section.

+-----------------+
| device id       |
+-----------------+
| model length    |
+-----------------+
| fixed length    |
| data block      |
|                 |
|                 |
|                 |
+-----------------+
| variable length |
| data block      |
|                 |
|                 |
|                 |
+-----------------+

To determine the number of records in the variable length section, the
reading application needs to know the length of the fixed length section,
the length of each record in the variable length section, and the length
of a specific data model on a device.

number of records = (length - fixed length) / variable section length

An example of a data model like this is the String Combiner model (401).

The string combiner has a fixed section of length 14 registers, followed
by a variable length section with a record length of 8 registers.  Thus
if a device reports a String combiner model of length 118, the reading
application can determine there will be data from 12 strings.

12 = (118 - 22) / 8

b) A variable length section with no initial fixed length block. This case devolves into the previous case by thinking of the fixed length block size as zero.

+-----------------+
| DID             |
+-----------------+
| Model Length    |
+-----------------+
| variable length |
| data block      |
|                 |
|                 |
|                 |
+-----------------+

Examples: Irradiance Model (302), Back of Module Temperature (303),
          Inclinometer Model (304)

If the reading application discovers DID 304 with a length of 18 it
knows there are 3 individual records, since it knows the record length
is 6 registers.

3 = (18 - 0) / 6