Automate downloading of historical data from Sunny Explorer

If you have SMA solar power inverters and would be interested in automating download of historical data, read on. I have written a PowerShell script that downloads data as CSV format and places them into folders by year and month.

Motivation

If there is something that I need to do repeatedly, I like to invest my time automating them. Hereby sharing the solution in the hope that others may benefit from this and maybe hear of better options if you know any.

Setup

Pre-requisites

This tutorial is for users with SMA solar power inverters and Sunny Explorer software installed. I am assuming you have Sunny Explorer with a working plant configuration. Plant configurations have sx2 file extension. You should save this into a directory where you have write access to without needing to elevate to admin privileges. My automation script was written in PowerShell so you will need that installed too.

Automation script for downloading data from inverter

The script downloads last month’s data. It can be tweaked to download different ranges but I am sharing just the basics to keep this as simple as possible.

The script downloads and stores the following as CSV files:

  • Daily data in 5-minute intervals stored into <year>\<month>\<plant name>-<year><month><day>.csv
  • Monthly data in daily intervals stored into <year>\<plant name>-<year><month>.csv
  • Events (issues detected) stored into <year>\<plant name>-User-Events-<year><month>01-<year><month><last day of month>.csv

You will need to set:

  • Path to Sunny Explorer EXE
  • Path to plant configuration file
  • Password to access inverter

Save this script into the same directory where your plant configuration file sits. You can name it anything but I put DownloadLastMonth.ps1:

# Path to Sunny Explorer EXE
$sunnyExplorerExe = "C:\Program Files (x86)\SMA\Sunny Explorer\sunnyexplorer.exe"

# Path to plant configuration
$plantFile = "plant.sx2"

# Password to access inverter
$userPassword = "[password]"

$exportDirectory5MinuteInterval = "{0}\{1}"
$exportDirectoryDaily = "{0}"

$now = Get-Date
$lastMonth = $now.AddMonths(-1)

$exportDirectory5MinuteInterval = [string]::Format($exportDirectory5MinuteInterval, $lastMonth.Year, $lastMonth.Month)
if (![System.IO.Directory]::Exists($exportDirectory5MinuteInterval))
{
    [System.IO.Directory]::CreateDirectory($exportDirectory5MinuteInterval)
}

$exportDirectoryDaily = [string]::Format($exportDirectoryDaily, $lastMonth.Year)
if (![System.IO.Directory]::Exists($exportDirectoryDaily))
{
    [System.IO.Directory]::CreateDirectory($exportDirectoryDaily)
}

$beginningOfLastMonth = $lastMonth.ToString("yyyyMM") + "01"
$daysInLastMonth = [DateTime]::DaysInMonth($lastMonth.Year, $lastMonth.Month)
$endOfLastMonth = $lastMonth.ToString("yyyyMM") + $daysInLastMonth.ToString()

# 5-minute interval data
$process = New-Object System.Diagnostics.Process
try
{
    $process.StartInfo.Filename = $sunnyExplorerExe
    $process.StartInfo.Arguments = [string]::Format("`"{0}`" -userlevel user -password {1} -exportdir `"{2}`" -exportrange {3}-{4} -export energy5min", $plantFile, $userPassword, $exportDirectory5MinuteInterval, $beginningOfLastMonth, $endOfLastMonth)
    $process.StartInfo.UseShellExecute = $false
    $canBeStarted = $process.Start()
    $process.WaitForExit()
}
finally
{
    $process.Dispose()
}

# Daily data
$process = New-Object System.Diagnostics.Process
try
{
    $process.StartInfo.Filename = $sunnyExplorerExe
    $process.StartInfo.Arguments = [string]::Format("`"{0}`" -userlevel user -password {1} -exportdir `"{2}`" -exportrange {3}-{4} -export energydaily", $plantFile, $userPassword, $exportDirectoryDaily, $beginningOfLastMonth, $endOfLastMonth)
    $process.StartInfo.UseShellExecute = $false
    $canBeStarted = $process.Start()
    $process.WaitForExit()
}
finally
{
    $process.Dispose()
}

# Events
$process = New-Object System.Diagnostics.Process
try
{
    $process.StartInfo.Filename = $sunnyExplorerExe
    $process.StartInfo.Arguments = [string]::Format("`"{0}`" -userlevel user -password {1} -exportdir `"{2}`" -exportrange {3}-{4} -export events", $plantFile, $userPassword, $exportDirectoryDaily, $beginningOfLastMonth, $endOfLastMonth)
    $process.StartInfo.UseShellExecute = $false
    $canBeStarted = $process.Start()
    $process.WaitForExit()
}
finally
{
    $process.Dispose()
}

Running the PowerShell script

powershell.exe -f DownloadLastMonth.ps1

Test and make sure that works then create a batch file with the line above for your convenience. I named the file as DownloadLastMonth.cmd.

It takes about 3 to 4 minutes to complete downloading.

Optional: Scheduling the download

Schedule a task in Windows Task Scheduler to execute DownloadLastMonth.cmd to run on 1st of every month a little after midnight say 01:00. Do not forget to set the task to “Run task as soon as possible after a scheduled start is missed”.

Quirk

The CSV files generated are delimited by semicolon instead of comma so the file may not show up in proper columns on older Excel on regions that use comma delimiters.