Skip to content

Latest commit

 

History

History
451 lines (331 loc) · 20.6 KB

SMA Protocol.md

File metadata and controls

451 lines (331 loc) · 20.6 KB

SMA Protocol analysis

I did not find any thorough documentation on the SMA UDP Protocol, so I started analysing the packets. I sent packets to my inverters and looked at the responses. I might have things gotten wrong. If you know the protocol better let me know and I'll add the missing pieces here.

References:

SMA Protocol Packet

Sma Protocol starts with 'SMA\0' and then tag packets follow until a tag end packet

addr | type   | explanation
-----------------------------------
0x00 | U8     | 0x53    S
0x01 | U8     | 0x4D    M
0x02 | U8     | 0x41    A
0x03 | U8     | 0x0     \0

one or more Tag Packets follow
until End Tag Packet

SMA Tag Packet

Tag packet start with a , then a tag in big-endian order follow until the end tag packet (8 bytes of zeros)

0x00 | U16    | length of packet
0x02 | U16    | Tag
0x03 |        | Data
...           | ...
0x03 + length | Data

A SMA Tag seems to have a internal structure of 0xABBC A = 0 , B = Tag ID, C = 0

0x0000 | end marker usually 2 bytes content | content | U16 | 0x0000 - END of SMA Packets | | 0x0001 - More Tag Packets follow
|
0x0010 | SMA Net Version Version 1 Packet 0x0020 | Unkown, value: 0x0000 0001 0x0030 | IP Address of source ( 4 bytes ) 0x0040 | Unkown, value : 0x0000 0002 0x0070 | Unkown, value : 0xef0c = 239 12 -MCast ? 0x0080 | Unkown, value : 0x00 0x0200 | Discovery Request 0x02A0 | Group Packet 0x02C0 | Group Number

SMA Tag 0x200: Discovery Request

Discovery request has 4 bytes of data containing 0xff.

addr | type   | explanation
-----------------------------------
0x00 | U32    | 0xFFFF FFFF requesting discovery reply
     |        | 0x0000 0001 normal request

A full discovery request looks like this:

addr | type   | value       | explanation
------------------------------------
0x00 | U32    | 0x534D4100  | 'SMA\0'  Magic Number
-----|--------|-------------|-------
0x04 | U16    | 0x0004      | length of packet
0x06 | U16    | 0x02a0      | tag Group
0x08 | U32    | 0xFFFF FFFF | to all groups ? 
-----|--------|-------------|-------
0x0C | U16    | 0x0000      | length of packet
0x0E | U16    | 0x0200      | tag: discovery request )
-----|--------|-------------|-------
0x10 | U16    | 0x0000      | length of packet
0x12 | U16    | 0x0000      | tag ( End of packets )

Group Content 0x02C0

addr | type   | explanation
-----------------------------------
0x00 | U32    |   Group number ( usually 0x0000 0001 )
     |        |                  0xFF03 bluethooth ?

SMA Tag 0x0010 : SMA Net Version 1

addr | type   | explanation
-----|--------|--------------------
0x00 | U16    | Protocol ID:
     |        |    0x6069 Sunny Home Manger
     |        |    0x6065 Inverter Communication
     |        |    0x0001 ? Version ? followed by a 0x0003 as data          
0x02 | length | Data

SMA Tag 0x0010 SubTag 0x6069: Sunny Home Manger Protocol

The information on the Sunny Home Manger protocol 0x6069 EMETER-Protokoll-T1-de-10.pdf is enough to figure it out. Exact values I figured out can be found in Obis.swift

addr | type   | explanation
-----|--------|--------------------
0x00 |   U16  |   Source SysID
0x02 |   U32  |   Source Serial number
0x06 |   U32  |   Source Time in ms
0x0A |        |   0x6069 data packets follow:

Data Packets (Big Endian)

addr | type    | explanation
-----|---------|--------------------
0x00 |   U32   |   0xAABBCCDD
     |         |   0xAA = Channel id ( default 1)
     |         |   0xBB = 0x01 :
     |         |   0xCC = Kind   0x04 = Current Value    4 Byte length
     |         |               0x0x08 = Counter          8 Byte length
     |         |   0xDD = Tarif: 0x00 = Sum tarif
0x04 | U32|U64 |           BE: value byte length

SMA Tag 0x0010 SubTag 0x6065: Inverter Communication (Little Endian)

Beware, this protocol uses little endian format. Requests and responses share the same header format. Requests to the inverter send the header followed by a command (e.g. logon, logoff, data request ). Responses from the inverter have the same header with data then attached (e.g. ac-power values ).

0x6065 Protocol Header

addr |addr | type| explanation
----- -----------------------------------
0x00 | 00 | U8  | Length in 32bit words, to get length in bytes * 4
0x01 | 01 | U8  | Type only   0xYZ
                                Y: A = Request, E = Response
                                Z: 0 = network, 1 = group address

0x02 | 02 | U16 | Destination SysID
0x04 | 04 | U32 | Destination Serial number     or group 
0x08 | 08 | U8  | 0x00 always zero (padding)

0x09 | 09 | U8  | 0x00 sending does not seem to matter except for login
     |    |     |  receiving same value sent except bit 6
     |    |     |  0xA1 1010 0000b
     |    |     |  0xE0 1110 0000b          e0 means failed
     |    |     |       -X-- ----           0 ok, 1, failed
                |  From SB sessionprotocol bit7 addressing ( 0 = adr / 1 = group)
                |                          bit6 acknoledge ( 0 = request / 1 = answer )
                |                          bit 0-5 reserved
      
      'p9:0x00' => 504196,
      'p9:0x01' => 1887147,
      'p9:0x02' => 34,
      'p9:0x03' => 6,
      'p9:0xa0' => 399585,
      'p9:0xa1' => 160432,
      'p9:0xc0' => 14109,
      'p9:0xc1' => 2,
      'p9:0xc5' => 16871,   
      'p9:0xe0' => 127697
      'p9:0xe1' => 966354,

                
                
                
                
                

0x0A | 10 | U16 |  Source SysID           Any: 0xFFFF
0x0C | 12 | U32 |  Source Serial number   Any: 0xFFFF FFFF
0x10 | 16 | U8  |  0x00 always zero (padding)

0x11 | 17 | U8  |  job number usually 1 or 0 but can be chose freely it seems


0x12 | 18 | U16 |  Result:  0x0000 ok

      'reslt:0000' => 2981993,  ok 
      'reslt:0002' => 38,
      'reslt:0014' => 662745    
      'reslt:0015' => 415136,
      'reslt:0017' => 15705,    
      'reslt:0018' => 6,
      'reslt:0102' => 383,  invalid password
      'reslt:ffff' => 427,

     |    |     |           0x0002    0000 0010b  incorrect command ?
     |    |     |           0x0014    0000 1110b
     |    |     |           0x0015    0000 1111b  no values 
     |    |     |           0x0017    0001 0001b  not logged in
     |    |     |           0x0018    0001 0010b
                            0x0100  1 0000 0000b    inv. password?
     |    |     |           0x0102  1 0000 0010b   login not possible (busy)?
     |    |     |           0xffff

0x14 | 20 | U16 | remaining packets to come count

0x16 | 22 | U16 | packet id     Bit 0-14 packet id
     |    |     |               bit 15 
                                    request: 1
                                    response: 0 - fail
                                              1 - ok



0x18 | 24 | U8  |  commannd ??ctrl 

      'p24:0x00' => 501268
      'p24:0x01' => 1668148,
      'p24:0x0a' => 2987,
      'p24:0x0c' => 16882,      
      'p24:0x0d' => 525358,
      'p24:0x0e' => 1361790,
                            

            
0x19 | 25 | U8  | parametercount ?  data type? 
      'p25:0x00' => 572223,
      'p25:0x01' => 806438,
      'p25:0x02' => 2172375,
      'p25:0x03' => 28,
      'p25:0x04' => 525369
            
                            0x80

                    0x00 keep alive packet ? 
                    0x00
                    0x01 16 bit values
                    0x02 32 bit values
                    0x04 value length next packet ? 
                    0x02 && command == 0x000 - 
                                  
0x1A | 26 | U16 | command    

values follow

Requests to Inverter

login request

addr | type | explanation
-----------------------------------
0x16 | U8   | 0x0C          0000 1100b
0x17 | U8   | 0x04          0000 0100b
0x18 | U16  | 0xFFFD        Login
0x2A | U32  | 0x07 | 0x0A   Usergroup 0x07 = user / 0xA installer
0x2E | U32  | 0x384         ?? Timeout
0x32 | U32  | unixtime
0x36 | U32  | 0x00          ??
0x3A | U8*12| password characters + 0x88 User / 0xBB Installer

logout request

addr | type | explanation
-----------------------------------
0x16 | U8   | 0x0C ?0e
0x17 | U8   | 0x04 ?01
0x18 | U16  | 0xFFFD      Logout Command
0x2A | U32  | 0xFFFF FFFF

command request

Normal commands seem have same size ( position 0x16 - 0x24 )

addr | type| explanation
-----------------------------------
0x16 | U8  | ?? flags maybe usually 0x01 or 0x00
     |     |    flags   0000 0000b
     |     |            ---- ---Xb  0 = request
     |     |                        1 = answer
     |     |            ---- X--0b  8 -> response 9 as if adding one to the request
0x17 | U8  | ??  send:       seems not to matter except for login
     |     |     response:   usually 02
0x18 | U16 | Comand Request
0x1A | U32 | Range Start
0x20 | U32 | Range End

Responses from inverter

I've not seen any response from a logout.

addr | type| explanation
-----------------------------------
0x16 | U8  | ?? flags maybe usually 0x01, 0x0C , 0x0D,
     |     |    flags   0000 0000b
     |     |            ---- ---Xb  0 = request
     |     |                        1 = answer
     |     |            ---- X--0b  8 -> response 9 as if adding one to the request
0x17 | U8  | values seen: 00 , 01 , 02, 04
     |     | 00 packet data directly following address 0x1A
     |     | 01 address 0x1A contains packet count
     |     | 02 address 0x1A contains start , 0x20 contains end
     |     | 04 ?
0x18 | U16 | Command used in request 
     |     |    0x0000 keep alive ? contains no data option 1 & 2 : 0x0000 0000 & 0x0000 00ff
     |     |                        can contain 56 static bytes as well 
     |     |    0x5180 keep alive ? contains no data option 1 & 2 : 0x0021 4800 and 0x0041 4aff
     |     |    0x2800 special multicast answer ?
     |     |    
     |     |
     |     |
0x1A | U32 | option 1  (sometimes Range Start)  does 0x4 mean only short numbers are coming ? 
0x20 | U32 | option 2  (sometimes Range End)
     |     |
0x24 - End of packet | Array of values 

0x2800, 0x6a02,0x71e0 command answer

With these commands the answer seem to differ completly and the packets are very short.

If command is 0x2800 the answers option1 is then 0x500300 and option2 contains some timer counting up - it's not milliseconds. Maybe it's an answer to a discovery request ? it seems to contain static data but some of the data do change over time but not coherently. There seems to be more noise at the beginning of the packet when the sun is up - so maybe there is sunpower encoded in there.

Array of values format when not 0x2800

The response data is an array of values of different length just concatinated, starting at offset zero here for easier translation to code.

Value headers:

addr | type| explanation
-----------------------------------
0x00 | U8   |   number (like a string number) 
     |      |   0x00 not seen
     |      |   0x01-0x06 string
     |      |   0x07  number 0x07 no string 
     |      |
0x01 | U16  |   kind (a number in the range specified by the request)
     |      |
0x03 | U8   |   data format     0x00 usigned number(s)
     |      |                   0x40 signed number(s)
     |      |                   0x10 zero terminated string
     |      |                   0x08 version number
     |      |                   one caveat it seems that 0x8234 kind contains version numbers
     |      |
0x04 | U32  |   unix timestamp  usually the timestamp of the request (when the value was calculated)
     |      |                   for aggregated values it's the time of aggregation
     |      |                   aggregation happens usually every 5 minutes
     |      |                   if the timestamp is not 0 or at the current time,
     |      |                   it's the running time in seconds

Value format 0x00 unsigned number / serial number

Normal number value format

 addr | type| explanation
-----------------------------------
0x08 | U32  |   value1, UInt32Max == NaN
0x0C | U32  |   value2, UInt32Max == NaN, shortmarker
0x10 | U32  |   value3, UInt32Max == NaN
0x14 | U32  |   value4, UInt32Max == NaN
0x18 | U32  |   value5, long marker  0x0000 0001 for 1 value only. 

packet is long if longmarker == 1 or all content is zero
packet is short if its not long and shortmarker = 0

Serial Number

addr | type| explanation
-----------------------------------
0x08 | U32  |   0
0x0C | U32  |   0
0x10 | U32  |   0xFFFF FFFE  | 0xFFFF FED8
0x14 | U32  |   0xFFFF FFFE  | 0xFFFF FED8
0x10 | U8   |   Serial Number Type ( 4 = release ) ( none/experimental/alpha/beta/release/special)
0x11 | U8   |   Serial Number Build Number
0x12 | U8   |   Serial Number Minor Version
0x13 | U8   |   Serial Number Major Version
0x14 | U8*4 |   Serialnumber again 
0x18 | U32  |   0
0x1C | U32  |   0

Value format 0x40 signed number

Same format as for unsigned except that values are S32 and test for NaN is Int32Min.

Value format 0x10 string

Length 0x24 (40d) bytes.

addr         | type| explanation
-----------------------------------
0x08....0x1C | U8  | String zero terminated

Value format 0x08 tuple

Length 0x24 (40d) bytes. Contains tuples for requested kind. Contains tuples (key,value) value pairs of version data appended by 0xffff fffe.

addr         | type| explanation
-----------------------------------
0x08....0x1C | U16 | A: value  
             | U16 | B: valididation bit5
             |     |    ---0 ---- invalid
             |     |    ---1 ---- valid
             |     | A is valid if bit5 is set in B
             |     | End of values if A == 00FF && B == FFFE
             |     |  
            
            A    B    
Example: 0x1234 0x0100    1234 set as 0x1000
         0x5678 0x0000    5678 not set
         0x8001 0x0100    8001 set
         0x00FF 0xFFFE    end of values
    
Result: value is: 1234.8001 

Real world example: (Type 0x08 like system.mainmodel.1, system.type.1,... )

 SMApacket: length:458 raw:534d 4100 0004 02a0 0000 0001 01b6 0010 6065 6da0 1234 0000 4321 00a1 0011 2233 4455 0001 0000 0000 d489 0102 0058 0100 0000 0a00 0000 011e 8210 4032 1961 7375 6e6e 7962 6f79 3400 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 011f 8208 4032 1961 411f 0001 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0120 8208 4032 1961 b924 0000 ba24 0000 bb24 0001 bc24 0000 bd24 0000 feff ff00 0000 0000 0000 0000 0121 8208 9a39 1661 5902 0001 5b02 0001 5d02 0001 5e02 0001 5f02 0000 6202 0001 6302 0001 6a02 0001 0121 8208 9a39 1661 6f02 0001 7802 0001 7902 0001 7a02 0001 7b02 0001 7c02 0001 7d02 0001 8002 0001 0121 8208 9a39 1661 8102 0001 8702 0001 8802 0001 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 0125 8200 4032 1961 0000 0000 0000 0000 d8fe ffff d8fe ffff 1847 0000 1847 0000 0000 0000 0000 0000 0128 8208 8939 1661 2e01 0001 6904 0000 6a04 0000 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 012b 8208 8939 1661 cd01 0001 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0134 8200 a339 1661 0000 0000 0000 0000 feff ffff feff ffff 0424 1003 0424 1003 0000 0000 0000 0000 0000 0000 
SMApacket: Tag:0x02a0 length:4
SMApacket: discovery type:0x00000001 NORMAL
SMApacket: Tag:0x0010 length:438
SMAPacket: SMAnet tag.
SMAPacket: SMAnet packet protocol 0x6065 length:438
SMANet Packet:command:5800 response:0000: source:001122334455 destination:123400004321 pktflg:1 pktid:0x09d4 opt1:0x00000001 opt2:0x0000000a raw:0100 0000 0a00 0000 011e 8210 4032 1961 7375 6e6e 7962 6f79 3400 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 011f 8208 4032 1961 411f 0001 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0120 8208 4032 1961 b924 0000 ba24 0000 bb24 0001 bc24 0000 bd24 0000 feff ff00 0000 0000 0000 0000 0121 8208 9a39 1661 5902 0001 5b02 0001 5d02 0001 5e02 0001 5f02 0000 6202 0001 6302 0001 6a02 0001 0121 8208 9a39 1661 6f02 0001 7802 0001 7902 0001 7a02 0001 7b02 0001 7c02 0001 7d02 0001 8002 0001 0121 8208 9a39 1661 8102 0001 8702 0001 8802 0001 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 0125 8200 4032 1961 0000 0000 0000 0000 d8fe ffff d8fe ffff 1847 0000 1847 0000 0000 0000 0000 0000 0128 8208 8939 1661 2e01 0001 6904 0000 6a04 0000 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 012b 8208 8939 1661 cd01 0001 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0134 8200 a339 1661 0000 0000 0000 0000 feff ffff feff ffff 0424 1003 0424 1003 0000 0000 0000 0000 
001122334455 Code:0x5800-0x821e No:0x01 Type:0x10 2021-08-15T17:26:56               system.name.1                      sunnyboy4 realtype:0x10 len:40 raw: 011e 8210 4032 1961 7375 6e6e 7962 6f79 3400 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
001122334455 Code:0x5800-0x821f No:0x01 Type:0x08 2021-08-15T17:26:56          system.mainmodel.1                         v:8001 realtype:0x08 len:40 raw: 011f 8208 4032 1961 411f 0001 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
001122334455 Code:0x5800-0x8220 No:0x01 Type:0x08 2021-08-15T17:26:56               system.type.1                         v:9403 realtype:0x08 len:40 raw: 0120 8208 4032 1961 b924 0000 ba24 0000 bb24 0001 bc24 0000 bd24 0000 feff ff00 0000 0000 0000 0000 
001122334455 Code:0x5800-0x8221 No:0x01 Type:0x08 2021-08-13T11:21:30        type.unkown.0x8221.1 v:0601.0603.0605.0606.0610.0611 realtype:0x08 len:40 raw: 0121 8208 9a39 1661 5902 0001 5b02 0001 5d02 0001 5e02 0001 5f02 0000 6202 0001 6302 0001 6a02 0001 
001122334455 Code:0x5800-0x8221 No:0x01 Type:0x08 2021-08-13T11:21:30        type.unkown.0x8221.1 v:0623.0632.0633.0634.0635.0636.0637 realtype:0x08 len:40 raw: 0121 8208 9a39 1661 6f02 0001 7802 0001 7902 0001 7a02 0001 7b02 0001 7c02 0001 7d02 0001 8002 0001 
001122334455 Code:0x5800-0x8221 No:0x01 Type:0x08 2021-08-13T11:21:30        type.unkown.0x8221.1               v:0641.0647.0648 realtype:0x08 len:40 raw: 0121 8208 9a39 1661 8102 0001 8702 0001 8802 0001 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 
001122334455 Code:0x5800-0x8225 No:0x01 Type:0x00 2021-08-15T17:26:56        type.unkown.0x8225.1                      0:0:71:24 realtype:0x00 len:40 raw: 0125 8200 4032 1961 0000 0000 0000 0000 d8fe ffff d8fe ffff 1847 0000 1847 0000 0000 0000 0000 0000 
001122334455 Code:0x5800-0x8228 No:0x01 Type:0x08 2021-08-13T11:21:13        type.unkown.0x8228.1                         v:0302 realtype:0x08 len:40 raw: 0128 8208 8939 1661 2e01 0001 6904 0000 6a04 0000 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 
001122334455 Code:0x5800-0x822b No:0x01 Type:0x08 2021-08-13T11:21:13        type.unkown.0x822b.1                         v:0461 realtype:0x08 len:40 raw: 012b 8208 8939 1661 cd01 0001 feff ff00 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 
001122334455 Code:0x5800-0x8234 No:0x01 Type:0x00 2021-08-13T11:21:39    system.softwareversion.1                      3:16:36:4 realtype:0x00 len:40 raw: 0134 8200 a339 1661 0000 0000 0000 0000 feff ffff feff ffff 0424 1003 0424 1003 0000 0000 0000 0000