From MartinH

Inspired by Monitor your traffic with fritz box and pimatic I modified the script to read the current performance of my photovoltaics system and write it into a pimatic variable.
I used a php script I wrote for this before, but then I saw how to use curl within a shell script, which makes it easier to use without having to have php installed.
My photovoltaics system comes with an inverter from manufacturer SMA. Normally the data of these inverters can be fetched from the Sunny Portal if the inverter is connected to the internet.

Here’s the script:

#!/bin/bash

#########################################################
#
# modified script for reading data from a Fritzbox to get data from Sunny Portal
# for current performance of a photovoltaics system from SMA
# April 2015 - voltaikprojekt at thomashof-durlach dot de
#
# original from
# June 2013 - framp at linux-tips-and-tricks dot de
#
#########################################################

## Edit this ##
SUNNYPORTAL="https://www.sunnyportal.com"
USER="SUNNY PORTAL USER"
PASSWORD="SUNNY PORTAL PASSWORD"
PIMATIC_USER="PIMATIC-USER"
PIMATIC_PASS="PIMATIC-PASSWORD"
PIMATIC="PIMATIC IP:PIMATIC PORT"
PIMATIC_VAR="PIMATIC-VARIABLE NAME"
COOKIE_PATH="PATH TO COOKIE AND COOKIE NAME" # e.g. /tmp/pvcookie.txt

## script ##

url="$SUNNYPORTAL/Templates/Autologin.aspx"

authRsp=$(curl --header "Accept: text/html,application/xhtml+xml,application/xml" \
    --header "Content-Type: application/x-www-form-urlencoded"      \
    --cookie-jar $COOKIE_PATH    \
    --user-agent "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7"    \
    --referer ";auto"    \
    --insecure   \
    --location   \
    -d "user=$USER" -d "pass=$PASSWORD" \
    $url 2>/dev/null)

## debug ##
#echo $authRsp > /tmp/curlres.html
#exit 0

url="$SUNNYPORTAL/homemanager"

json=$(curl --header "Accept: application/json" \
    --cookie $COOKIE_PATH    \
    --user-agent "Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7"    \
    --referer ";auto"    \
    --insecure   \
    --location   \
    $url 2>/dev/null)

## debug ##
#echo $json > /tmp/curljson.txt
#exit 0

pvcurrent=$(echo $json | sed -r 's/^.*"PV":([0-9]*).*$/\1/' | sed -r 's/^.*("PV":[0-9]*,).*$/\1/')

## debug ##
#echo $pvcurrent #> /tmp/curlpvcurr.txt
#exit 0

regex="^[0-9]+$"
if ! [[ $pvcurrent =~ $regex ]]; then
    echo "No current PV value found"
    exit 0
fi

echo $pvcurrent

# send result to pimatic
curl --insecure -X PATCH --header "Content-Type:application/json" --data '{"type": "value", "valueOrExpression": '"${pvcurrent}"'}' --user "${PIMATIC_USER}:${PIMATIC_PASS}" http://$PIMATIC/api/variables/$PIMATIC_VAR >/dev/null 2>&1

I read the data every minute via cron and display it in a variable device in the pimatic frontend.

Maybe someone can use this for a similar pv system as mine.

Update 2015-04-30

I made some rules to calculate the total performance off a day and tested that for 13 days now, the result looks good in a comparison to the values that the solar system itself delivers:

| Date | ____ | Reported by solar system | ____ | Calculated by pimatic rules | ____ | Diff absolute | ____ | Diff % |
|----------------- |------ |-------------------------: |------ |----------------------------: |------ |--------------: |------ |-------: |
| 17.04.2015 | | 16,12 | | 16,00 | | -0,12 | | -0,77% |
| 18.04.2015 | | 37,44 | | 37,86 | | 0,42 | | 1,12% |
| 19.04.2015 | | 45,81 | | 45,83 | | 0,02 | | 0,05% |
| 20.04.2015 | | 44,01 | | 44,00 | | -0,01 | | -0,02% |
| 21.04.2015 | | 43,74 | | 43,71 | | -0,03 | | -0,08% |
| 22.04.2015 | | 42,39 | | 42,35 | | -0,04 | | -0,09% |
| 23.04.2015 | | 44,78 | | 44,80 | | 0,02 | | 0,06% |
| 24.04.2015 | | 44,72 | | 44,72 | | 0,00 | | 0,01% |
| 25.04.2015 | | 14,40 | | 14,43 | | 0,03 | | 0,21% |
| 26.04.2015 | | 40,62 | | 40,66 | | 0,04 | | 0,10% |
| 27.04.2015 | | 19,12 | | 19,30 | | 0,18 | | 0,92% |
| 28.04.2015 | | 18,69 | | 18,69 | | 0,00 | | -0,02% |
| 29.04.2015 | | 39,62 | | 39,90 | | 0,28 | | 0,71% |
| Total | | 451,46 | | 452,25 | | 0,788 | | 0,17% |

|

So I have just little differences and that’s ok for me, I can live with a tolerance of 0.17%

Here are the rules and variables I use:

    {
      "name": "pvperformance",
      "value": 0
    },
    {
      "name": "pv_daily_performance",
      "value": 0
    },
    {
      "name": "pv_total_performance",
      "value": 0
    },
    {
      "name": "last_pv_update",
      "value": 0
    }


    {
      "id": "calculate-kwh-per-minute",
      "name": "Calculate KWh per minute",
      "rule": "if $pvperformance gets updated and $last_pv_update = 0 then $pv_daily_performance = round( $pv_daily_performance + ( $pvleistung.pvperformance / 60000 ),3) and $last_pv_update = date(\"hh\") * 3600 + date(\"mm\") * 60 + date(\"ss\")",
      "active": true,
      "logging": false
    },
    {
      "id": "calculate-kwh-per-minute-2",
      "name": "Calculate KWh per minute 2",
      "rule": "if $pvperformance gets updated and $last_pv_update > 0 then $pv_daily_performance = round( $pv_daily_performance + ( $pvleistung.pvperformance / ((60 / (date(\"hh\") * 3600 + date(\"mm\") * 60 + date(\"ss\") - $last_pv_update) )*60000 )),3) and after 5 seconds $last_pv_update = date(\"hh\") * 3600 + date(\"mm\") * 60 + date(\"ss\") - 5",
      "active": true,
      "logging": false
    },
    {
      "id": "calculate-total-pv-performance",
      "name": "Calculate total PV performance",
      "rule": "if it is 23:59 then $pv_total_performance = $pv_total_performance + $pv_daily_performance",
      "active": true,
      "logging": true
    },
    {
      "id": "reset-daily-pv-performance",
      "name": "Reset Daily PV Performance",
      "rule": "if it is 00:01 then $pv_daily_performance = 0",
      "active": true,
      "logging": true
    },
    {
      "id": "reset-last-pv-update-var",
      "name": "Reset last pv update var",
      "rule": "if it is 00:01 then $last_pv_update = 0",
      "active": true,
      "logging": true
    }

These rules work with a cron job that get the values every minute. If the cronjob is set to another time one of the rules has to be changed.
E.g. for 2 minutes the rule with the id “” this has to be changed: $pvleistung.pvperformance / 120000
The value is: minutes * 60 * 1000

Have fun…
Martin