Frames in Detail
The big picture¶
Please Zoom
To visualize the frame structure I used Gantt charts here. They are actually meant for something else, but they serve their purpose and can be easily generated with mermaid.js. Unfortunately the diagrams don't offer a zoom function, so use the browser zoom!
The following diagrams show the structure of a frame. And this byte by byte. Please note that the bytes are transmitted in little endian order.
Frame¶
gantt
title Structure of a frame
dateFormat YYYY-MM-DD
axisFormat %d
tickInterval 1day
section Frame
Whole frame : frame, 2014-01-01, 30d
section Header
Magic bytes : mb, 2014-01-01, 2d
CTRL : ctrl, after mb, 2d
Timestamp : ts, after ctrl, 12d
length : dlength, after ts, 2d
section Data
Data : crit, data, after dlength, 8d
section Checksum
CRC32 : active, crc, after data, 4d
In the diagram above the structure of a frame is shown. Please note that the length of the data block is variable and is only shown here as an example of 8 bytes. In reality a data block is significantly longer.
Magic Bytes¶
Each frame starts with a 2 byte MagicByte block. This always contains the values E3DC (Hexcode ...)
gantt
title Magic Bytes
dateFormat YYYY-MM-DD
axisFormat %d
tickInterval 1day
section Magic Bytes
0xE3 : e3, 2014-01-01, 1d
0xDC : dc, after e3, 1d
Control Bytes¶
The control bytes currently contain 2 pieces of information.
- Does the frame contain a checksum at the end (the checksum is optional)?
- Which protocol version is used? To my knowledge this is always 0x01 so far
Both information are placed in the first byte. The second byte is intended for future use is currently always 0.
gantt
title Control Bytes
dateFormat YYYY-MM-DD
axisFormat %d
tickInterval 1day
section CRC true
0x00 : b1, 2014-01-01, 1d
0x11 : b2, after b1, 1d
section CRC false
0x00 : b1, 2014-01-01, 1d
0x01 : b2, after b1, 1d
Timestamp¶
The timestamp area indicates the creation time of the frame. In seconds and nanoseconds since 01/01/1970 00:00. As I understand it in UTC.
The first 8 bytes indicate the seconds value and the next 4 bytes the nanoseconds.
The following timestamp block, represents the timestamp 2023-09-20T07:57:05.362489Z.
Since the 01.01.1970 00:00 o'clock up to this Timestamp 1,695,196,625 seconds and 362,489,000 nanoseconds have passed.
gantt
title Timestamp
dateFormat YYYY-MM-DD
axisFormat %d
tickInterval 1day
section Timestamp
0xd1a50a6500000000 : seconds, 2014-01-01, 8d
0xa8249b15 : nanos, after seconds, 4d
Length¶
In the length field the length of the following data block is indicated in bytes. Since a frame can consist of several data blocks, the sum of all data block lengths is specified here.
In the example 28bytes (0x1c00 in hexcode Little Endian)
gantt
title Length
dateFormat YYYY-MM-DD
axisFormat %d
tickInterval 1day
section Timestamp
0x1c00 : length, 2014-01-01, 2d
Data block¶
One or more data blocks follow. The length is determined by the previous length field. The structure is described in detail in the data block area.
Checksum¶
If the frame uses a checksum, it is specified here, with a length of 4 bytes. The standard algorithm CRC32 is used.
gantt
title CRC32
dateFormat YYYY-MM-DD
axisFormat %d
tickInterval 1day
section Timestamp
0xe2a60c5d : crc, 2014-01-01, 4d
Datenblock¶
A data block represents a concrete value in a frame. Exception: A data block is of the type 'container'. Then it contains further data blocks
gantt
title Structure of a Data Block
dateFormat YYYY-MM-DD
axisFormat %d
tickInterval 1day
section Data
Whole Block : block, 2014-01-01, 15d
section Header
Tag : tag, 2014-01-01, 4d
Type : type, after tag, 1d
Length : length, after type, 2d
section Value
Value : crit, value, after length, 8d
Tag¶
The tag gives a meaning to the content. It describes which area of the home power plant it is (namespace), whether it is a request or response block, and which field from the respective namespace is meant.
For example the tag MAC_ADDRESS
from the namespace INFO
. This has the value 0a80000a
.
gantt
title The Tag INFO.MAC_ADDRESS
dateFormat YYYY-MM-DD
axisFormat %d
tickInterval 1day
section Namespace
0x0a : ns, 2014-01-01, 1d
section Tag
0x00800a : tag, after ns, 3d
Info
Whether it is a request or response block can be seen by the first bit(!) of the tag area. 0=request, 1=response
Type¶
In the next byte the data type is specified. That is, how the value area in the block is to be interpreted (number, string, etc.).
gantt
title Datatype String
dateFormat YYYY-MM-DD
axisFormat %d
tickInterval 1day
section String
0x0d : type, 2014-01-01, 1d
Length¶
This area is 2 bytes long and specifies the length in bytes of the following value area.
gantt
title Lengthj
dateFormat YYYY-MM-DD
axisFormat %d
tickInterval 1day
section String
0x1100 : length, 2014-01-01, 2d
Value¶
Here hides the actual value, which can be interpreted depending on length and type. Here is an example for the software release number H20_2023_024
(tag INFO.SW_RELEASE
)
gantt
title Example String
dateFormat YYYY-MM-DD
axisFormat %d
tickInterval 1day
section String
0x4832305f323032335f303234 : value, 2014-01-01, 2d
Blocks as values
If the data type is container
, the value area contains a complete further data block(s)!
Example¶
To make things a little clearer, let's take a look at a request frame and its corresponding response frame.
We want to query the live data of the current PV production and the battery. For this purpose, we first assemble the query frame.
In human readable form:
Timestamp: 2023-09-20T08:42:32.818989Z
WithChecksum: true
Tag: EMS.REQ_POWER_PV - 01000001
Type: NONE - 00
Value: [NONE] -
Tag: EMS.REQ_POWER_BAT - 01000002
Type: NONE - 00
Value: [NONE] -
In home power plant readable form:
And once disassembled:
Bytes | Value | Description |
---|---|---|
1 - 2 | e3dc | Magic Bytes |
3 - 4 | 0011 | Controlbytes -> protocol version 1 and checksum is enabled |
5 - 12 | 78b00a6500000000 | Timestamp, seconds since 01.01.1970 00:00 UTC -> 1,695,199,352 |
13 - 16 | c8c7d030 | Timestamp, Nanoseconds -> 818,989,000 |
17 - 18 | 0e00 | Length of the data block area in bytes -> 14 bytes |
18 - 21 | 01000001 | Namespace + Tag -> EMS.REQ_POWER_PV |
22 | 00 | Data type -> None |
23 - 24 | 0000 | Length of the data block -> Data type is none , therefore 0 |
25 - 28 | 02000001 | Namespace + Tag -> EMS.REQ_POWER_BAT |
29 | 00 | Data type -> None |
31-32 | 0000 | Length of the data block -> data type is none , therefore 0 |
33-36 | 4c769f09 | CRC32 checksum |
As a response we get the following frame:
In human readable form:
Timestamp: 2023-09-20T08:42:35.019685Z
WithChecksum: true
Tag: EMS.POWER_PV - 01800001
Type: INT32 - 06
Value: 4687 - 4f120000
Tag: EMS.POWER_BAT - 01800002
Type: INT32 - 06
Value: 2139 - 5b080000
In home power plant readable form:
And once disassembled:
Bytes | Value | Description |
---|---|---|
1 - 2 | e3dc | Magic Bytes |
3 - 4 | 0011 | Kontrolbytes -> Protocol version 1 and checksum is activated |
5 - 12 | 7bb00a6500000000 | Timestamp, seconds since 01.01.1970 00:00 UTC -> 1,695,199,355 |
13 - 16 | 885e2c01 | Timestamp, Nanoseconds -> 19,685,000 |
17 - 18 | 1600 | Length of the data block area in bytes -> 22 bytes |
18 - 21 | 01008001 | Namespace + Tag -> EMS.POWER_PV |
22 | 06 | Data type -> INT32 |
23 - 24 | 0400 | Length of the data block -> data type is INT32 , therefore 4 bytes |
25 - 28 | 4f120000 | Actual value -> data type is INT32 , therefore 4,687 |
29 - 32 | 02008001 | Namespace + Tag -> EMS.POWER_BAT |
33 | 06 | Data type -> INT32 |
34 - 35 | 0400 | Length of the data block -> data type is INT32 , therefore 4 bytes |
36 - 39 | 5b080000 | Actual value -> data type is INT32 , therefore 2,139 |
40 - 43 | 58156e18 | CRC32 checksume |
Namespaces¶
E3DC has split all tags into different namespaces to create some overview. All namespaces known to me are documented in kdoc in the enum class de.jnkconsulting.e3dc.easyrscp.api.frame.Namespace
.
Tags¶
The multitude of tags is also documented in kdoc. Each namespace has its own enum class to ensure at least some overview.
If I know anything about the structure and meaning of the tag, it is stored in kdoc. Partly E3DC has documented a little bit. If available, I have included the original E3DC documentation in kdoc and marked it with Original E3DC Documentation:
. Once translated in English and once in German, as supplied by E3DC.
Here you can find the tags TAG API.
Data types¶
The protocol defines a set of data types. These are documented in the enum class de.jnkconsulting.e3dc.easyrscp.api.frame.DataType
.