# SolarMax (S6000) - Getting data

**URL:** <https://community.openhab.org/t/solarmax-s6000-getting-data/135341>\
**Category:** Solutions\
**Tags:** rules, scripts, openhab3\
**Created:** [April 21, 2022, 4:03pm UTC](https://community.openhab.org/t/solarmax-s6000-getting-data/135341 "2022-04-21T16:03:09Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sofa1780](https://community.openhab.org/user_avatar/community.openhab.org/sofa1780/32/76053_2.png) [@Sofa1780](https://community.openhab.org/u/Sofa1780)\
**Post date:** [April 21, 2022, 4:03pm UTC](https://community.openhab.org/t/solarmax-s6000-getting-data/135341/1 "2022-04-21T16:03:09Z")

</div>

Hi there,

since the SolarMax Binding for OpenHab is not released, yet - more information about that project can be found [here](https://community.openhab.org/t/solarmax-initial-contribution-binding-for-solarmax-power-inverters/119879) - I’ve made a simple script for reading out the data provided by the inverters.  
Usually, this solution should also work with other SolarMax Inverters than the S6000, which I am working with.

After capturing a Wireshark capture of the communication with the provided software MaxTalk and the inverter I recognized that the parameters are transferred via a TCP connection with plain ASCII data.  
A quick research led me to the following page, which confirmed my assumption.  
[SolarMax MaxTalk protocol reverse engineered](https://2007.blog.dest-unreach.be/2009/04/15/solarmax-maxtalk-protocol-reverse-engineered/comment-page-1/)

So I decided to script the usage of [netcat](https://wiki.ubuntuusers.de/netcat/) on my Linux machine for polling the inverter data and calculating the checksum for the communication automatically.  
For this approach, netcat has to be installed on your machine as well.

Bash-Script:

```auto
#!/bin/bash

# Solar Max Request script

# Script parameters
# $Source: Linux server
# $Destination: Inverter module
# $Cmd: Semicolan seperated command(s) (PAC, PDC)
# $IpAddress: Ip address of your inverter
# $PortNumber: Portnumber assigned to your inverter

Source=$1 # e.g "FF"
Destination=$2 # e.g. "01" depending on your inverter address
Cmd=$3 # e.g. "PAC;KDY" for the total Power (AC) and the total energy this year
IpAddress=$4
PortNumber=$5

# Calculate lenght of the command; Lenght of Source, Destination, Lenght and CheckSum is fixed
printf -v Length "%02X" "$((${#Cmd} + 19))"

# Calculate TCP command without checksum
TcpCmd="$Source;$Destination;$Length|64:$Cmd|"

# Calculate checksum - Sum up all the bytes of string "$Source;$Destination;$Length|64:$Cmd|" and keep the lowest 16 bits of the sum.

for i in $(seq 1 ${#TcpCmd})
do
    # Get charackter bytes
    printf -v AsciiByte "%02X" "'${TcpCmd:i-1:1}"

    # Calclulate checksum
    CheckSum=$(( $CheckSum + 16#$AsciiByte ))
done

# Get lower bytes of checksum
printf -v CheckSum "%04X" "${CheckSum}"

# Append checksum to command
TcpCmd="{${TcpCmd}$CheckSum}"

# Get solar max properties according to TCP command using netcat; The first response is taken; Timeout is set to 5 seconds
echo -n $TcpCmd | netcat -W1 -w5 $IpAddress $PortNumber
echo ""

```

This script can be easily used with the parameters:  
SolarMax\_GetData.sh “SourceAddress” “DestinationAddress” “SemicolonSeperatedParameters” “InverterIpAddress” “InverterPortNumber”

For using the script automatically within OpenHab, I am using the [Exec Binding](https://www.openhab.org/addons/bindings/exec/) and saved the script into the script’s directory.  
Make sure for adding the command using the script to the whitelist, as described within the Exec Binding configuration more thoroughly.

Now a simple rule can be used to cyclically call the script and pull the inverter data. I also used the rule to convert the returning hexadecimal value into decimal values for a better interpretation.

Things-File:

```auto
//Using exec binding to execute script
//Keep aware of listing the executed conmmand line at $OpenHAB_config/misc/exec.whitelist
//Keep aware of setting propper folder/file permissions

// Solar Max Thing
Thing exec:command:SolarMaxUpdate "SolarMax" [command="/openhab/conf/scripts/SolarMax_GetData.sh %2$s", interval=60, timeout=5, autorun=false]

```

Items-File:

```auto
// Solar Max Script items
Switch SolarMaxUpdate_update "SolarMax update" {channel="exec:command:SolarMaxUpdate:run"}
String SolarMaxUpdate_output "SolarMax output string" {channel="exec:command:SolarMaxUpdate:output"}
String SolarMaxUpdate_input "SolarMax input string" {channel="exec:command:SolarMaxUpdate:input"}
Number SolarMaxUpdate_return "SolarMax return value" {channel="exec:command:SolarMaxUpdate:exit"}
DateTime SolarMaxUpdate_executed "SolarMax executed" {channel="exec:command:SolarMaxUpdate:lastexecution"}

// Solar Max items
Switch SolarMaxUpdate_manualUpdate "SolarMax update"

Number SolarMax_PAC "SolarMax AC power [%.0f W]"
Number SolarMax_PDC "SolarMax DC power [%.0f W]"
Number SolarMax_KHR "SolarMax operating hours [%d h]"
Number SolarMax_KDY "SolarMax energy today [%d Wh]"
Number SolarMax_KYR "SolarMax energy this year [%d kWh]"

Number SolarMax_UDC "SolarMax DC voltage [%.2f V]"
Number SolarMax_UL1 "SolarMax AC voltage L1 [%.2f V]"
Number SolarMax_IDC "SolarMax DC current [%.2f A]"
Number SolarMax_IL1 "SolarMax AC current L1 [%.2f A]"
Number SolarMax_PIN "SolarMax installed power [%.0f W]"
Number SolarMax_PRL "SolarMax used power [%d %%]"

```

Rules-File:

```auto
val String Source = "FF"
val String Destination = "01"
val String Prperties = "PAC;PDC;KHR;KDY;KYR;UDC;UL1;IDC;IL1;PIN;PRL"
val String IpAddresse = "xxx.xxx.xxx.xxx"
val String PortNumber = "12345"

rule "SolarMax update parameters"
when
    Time cron "0 0/5 * * * ?" or// every 5 Minute
    Item SolarMaxUpdate_manualUpdate changed to ON
then
    logInfo("SolarMax", "Request Solar Max stats")

    // Set input string for command
    var String Command = String.format("'%s' '%s' '%s' '%s' '%s'", Source, Destination, Prperties, IpAddresse, PortNumber);
    SolarMaxUpdate_input.sendCommand(Command)

    //Executing Solar Max updates script
    logInfo("SolarMax", "Requestion command: {}", Command)
    SolarMaxUpdate_update.sendCommand(ON)

    var String Output = SolarMaxUpdate_output.state.toString()
    logInfo("SolarMax", "Returning command: {}", Output)

    var int StartIndex = Output.indexOf(':') + 1
    var int EndIndex = Output.length() - 6

    var String Result = Output.substring(StartIndex, EndIndex);

    var String[] SplittedProperties = Result.split(";")

    // Loop through respond properties
    SplittedProperties.forEach [Prop |
        // Split values
        // logDebug("SolarMax", "Returning property: {}", Prop)
        var String[] temp = Prop.split("=")
        var String PropName = temp.get(0)
        var String PropValue_hex = temp.get(1) // Hexadecimal

        // Convert hex to dec
        var int PropValue_dec = Integer.parseInt(PropValue_hex, 16)
        //logDebug("SolarMax", "Returning property: {}, {}", PropName, PropValue_dec)

        // Assign items
        switch (PropName) {
            case "PAC": SolarMax_PAC.sendCommand(PropValue_dec)
            case "PDC": SolarMax_PDC.sendCommand(PropValue_dec)
            case "KHR": SolarMax_KHR.sendCommand(PropValue_dec)
            case "KDY": SolarMax_KDY.sendCommand(PropValue_dec)
            case "KYR": SolarMax_KYR.sendCommand(PropValue_dec)
            case "UDC": SolarMax_UDC.sendCommand(PropValue_dec.doubleValue()/10)
            case "UL1": SolarMax_UL1.sendCommand(PropValue_dec.doubleValue()/10)
            case "IDC": SolarMax_IDC.sendCommand(PropValue_dec.doubleValue()/100)
            case "IL1": SolarMax_IL1.sendCommand(PropValue_dec.doubleValue()/100)
            case "PIN": SolarMax_PIN.sendCommand(PropValue_dec)
            case "PRL": SolarMax_PRL.sendCommand(PropValue_dec)
        }
    ]

    //Set items to initial state
    createTimer(now.plusSeconds(1))[|SolarMaxUpdate_update.postUpdate(OFF)]
    createTimer(now.plusSeconds(1))[|SolarMaxUpdate_manualUpdate.postUpdate(OFF)]
end

```

I hope, this slight workaround will fit your needs until the SolarMax Binding is finished.

Best regards

---

<div class="post-metadata">

**Author:** ![Sofa1780](https://community.openhab.org/user_avatar/community.openhab.org/sofa1780/32/76053_2.png) [@Sofa1780](https://community.openhab.org/u/Sofa1780)\
**Post date:** [April 21, 2022, 4:04pm UTC](https://community.openhab.org/t/solarmax-s6000-getting-data/135341/2 "2022-04-21T16:04:56Z")

</div>

The parameters I found during the communication between MaxTalk and the inverters are as follows.  
Unfortunately, I only recognized the few I am using in the rule above.

COS  
CPA  
CYC  
DD00  
DD01  
DD02  
DD03  
DD04  
DD05  
DD06  
DD07  
DD08  
DD09  
DD10  
DD11  
DD12  
DD13  
DD14  
DD15  
DD16  
DD17  
DD18  
DD19  
DD20  
DD21  
DD22  
DD23  
DD24  
DD25  
DD26  
DD27  
DD28  
DD29  
DD30  
DIN  
DM00  
DM01  
DM02  
DM03  
DM04  
DM05  
DM06  
DM07  
DM08  
DM09  
DM10  
DM11  
DY00  
DY01  
DY02  
DY03  
DY04  
DY05  
DY06  
DY07  
DY08  
DY09  
IAA  
IAM  
IDC  
IEA  
IED  
IEE  
IEM  
IL1  
ILM  
ISL  
KDY  
KHR  
KLD  
KLM  
KLY  
KMT  
KT0  
KYR  
PAC  
PAM  
PDC  
PLF  
PRL  
RSD  
SAL  
SYS  
TKK  
TND  
TNF  
TNH  
TNL  
TYP  
UDC  
UGD  
UL1  
ULH  
ULL  
UM1  
UMX

Best regards
