Benutzer-Werkzeuge

Webseiten-Werkzeuge


howto:wechselrichter_sma

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
Nächste ÜberarbeitungBeide Seiten der Revision
howto:wechselrichter_sma [2014/05/29 11:18] wf_bitplan.comhowto:wechselrichter_sma [2018/01/25 16:04] – code jau
Zeile 48: Zeile 48:
 </code> </code>
  
-=== Beispiele === +==== Beispiel STP 9000 TL-20 mit SMASpot per Ethernet / Perl->Middleware ====
-== Beispiel STP 9000 TL-20 mit SMASpot per Ethernet / Perl->Middleware ==+
  
  
Zeile 63: Zeile 62:
 Anbei das Script: Anbei das Script:
  
-<code>+<code perl sma.pl>
 #!/usr/bin/perl #!/usr/bin/perl
 use LWP::UserAgent; use LWP::UserAgent;
Zeile 126: Zeile 125:
 </code> </code>
  
-Um den Eigenverbrauch zu bestimmen bilde ich die Differenz zwischen der Einspeisung, gemessen am Stromzähler. ( mit vzlogger) und der erzeugten Strommenge des SMA. Da der SMA immer etwas verzögert die Werte anzeigt, lege ich nur einen Messpunkt alle 15 Minuten ab: Die Kanäle sind zuvor in der Weboberfläche anzulegen, und mit mysql die channel_id zu selektieren.+Um den Eigenverbrauch zu bestimmen bilde ich die Differenz zwischen der Einspeisung, gemessen am Stromzähler. ( mit vzlogger) und der erzeugten Strommenge des SMA. Da der SMA immer etwas verzögert die Werte anzeigt, lege ich nur einen Messpunkt alle 15 Minuten ab: Die Kanäle sind zuvor in der Weboberfläche anzulegen, und mit mysql die channel_id zu selektieren.  
 +Änderung 04.06.2014: Die Berechnung des Gesamtverbrauchs ist aktualisiert
  
-<code bash|Berechnung Eigenverbrauch mit mysql>+== Originalscript von Markus == 
 +<code bash eigenverbrauch.sh>
 #!/bin/bash #!/bin/bash
 echo ' echo '
Zeile 150: Zeile 151:
  
 echo ' echo '
-INSERT INTO `data`( `channel_id`, `timestamp`, `value`) select 8,  timestamp_7,   data_7.value + data_1.value/1000     from (+INSERT INTO `data`( `channel_id`, `timestamp`, `value`) select 8,  timestamp_1,   (select data.value from data where channel_id = 7 and  data.timestamp <= data_1.timestamp order by timestamp desc limit 1) + data_1.value/1000     from  
 +(
 SELECT  SELECT 
 max(case when `channel_id`  = 1 then timestamp else 0 end) timestamp_1, max(case when `channel_id`  = 1 then timestamp else 0 end) timestamp_1,
 max(case when `channel_id`  = 7 then timestamp else 0 end) timestamp_7 max(case when `channel_id`  = 7 then timestamp else 0 end) timestamp_7
   FROM `data` where channel_id in (1,7)    FROM `data` where channel_id in (1,7) 
-group by floor(`timestamp`/60/1000/15) ) a inner join data data_7 on  timestamp_7  = data_7.timestamp and data_7.channel_id = 7 +group by floor(`timestamp`/60/1000/15)  
-inner join data data_1 on  timestamp_1  = data_1.timestamp and data_1.channel_id = 1 +) a inner join data data_1 on  timestamp_1  = data_1.timestamp and data_1.channel_id = 1 
-' | mysql --user=vz --password=fdfdfdfdf volkszaehler+' | mysql --user=vz --password=dsdsdsdsds volkszaehler
  
 </code> </code>
 auch diese Script wird mit cron gestartet, aber nur ein mal die Stunde. auch diese Script wird mit cron gestartet, aber nur ein mal die Stunde.
 <code> <code>
-1  * * * *    bash /home/markus/hack/Volksz/eigenverbrauch.bash+1  * * * *    bash /home/markus/hack/Volksz/eigenverbrauch.sh
 </code> </code>
  
 +== Modifiziertes Script (Versuch von Wolfgang) ==
 +<code bash eigenverbrauch.sh>
 +#!/bin/bash
 +# calculate own PV usage 
 +# Author: Markus 2014-05-20
 +# latest version:
 +# $Header: /home/wf/smaspot/RCS/eigenverbrauch.bash,v 1.5 2014/05/29 10:17:11 wf Exp wf $
 +
 +#
 +# get the delete query for the given channel
 +#
 +deletequery() {
 +  local l_channel=$1
 +cat << EOF
 +  DELETE 
 +   FROM `data` 
 +   WHERE `timestamp` = 
 +     (SELECT MAX(timestamp) FROM data WHERE channel_id = $l_channel)  
 +   AND channel_id = $l_channel;
 +EOF
 +}
 +
 +#
 +# get the insert query for the given channels
 +#  l_chanel the channel to insert into
 +#    l_c2 - the channel to substract 
 +#    l_c3 - the channel to substract the value from
 +#
 +insertquery() {
 +  local l_channel=$1
 +  local l_c2=$2
 +  local l_c3=$3
 +cat << EOF
 +  INSERT INTO `data`( `channel_id`, `timestamp`, `value`) 
 +    SELECT $l_chanel,  timestamp_2,   data_3.value - data_2.value /1000    
 +    FROM (
 +      SELECT 
 +        MAX(CASE WHEN `channel_id` = $l_c2 then timestamp else 0 end) timestamp_2,
 +        MAX(CASE WHEN `channel_id` = $l_c3 then timestamp else 0 end) timestamp_3
 +        FROM `data` 
 +        WHERE channel_id in ($l_c2,$l_c3) 
 +          AND timestamp > (
 +            SELECT MAX(timestamp) FROM data WHERE `channel_id` = $l_channel 
 +          )
 +        GROUP by floor(`timestamp`/60/1000/15) ) a 
 +        INNER JOIN data data_2 
 +          ON  timestamp_2  = data_2.timestamp 
 +          AND data_2.channel_id = $l_c2 
 +        INNER JOIN data data_3 
 +          ON  timestamp_3  = data_3.timestamp 
 +          AND data_3.channel_id = $l_c3 
 +EOF
 +}
 +
 +# modify according to your volkszaehler mysql database settings
 +user=vz
 +password=fdfdfdfdf 
 +db=volkszaehler 
 +
 +# debug setting
 +debug=
 +# uncomment to debug sql
 +#debug=-T
 +
 +# modify to suite your channel settings
 +
 +# channel 7 is calculated from as channel 4 - channel 2 / 1000 
 +deletequery 7     | egrep -v "^#" | mysql --user=$user --password=$password $db $debug
 +insertquery 7 2 4 | egrep -v "^#" | mysql --user=$user --password=$password $db $debug
 +
 +# channel 8 is calculated from as channel 7 - channel 1 / 1000 
 +echo "DELETE FROM `data` WHERE channel_id = 8" |  mysql --user=$user --password=$password $db $debug
 +insertquery 8 1 7 | egrep -v "^#" | mysql --user=$user --password=$password $db $debug
 +
 +</code>
 Und so sieht es aus: Und so sieht es aus:
  
 {{:howto:screenshotsma.jpg?800|}} {{:howto:screenshotsma.jpg?800|}}
  
-== Beispiel SB 4000 TL-21 + SB 1300TL-10 mit SMASpot und PHP ==+==== Beispiel SB 4000 TL-21 + SB 1300TL-10 mit SMASpot und PHP ==== 
 +The solution consists of three parts: 
 +  - the bash script sma2vz 
 +  - the php script sma2vz.php 
 +  - the php helper script vzapihelper.php (same as in the youless page)
  
 +the bash script sma2vz has a function configure - this needs to run once you might want
 +to configure the here-document part in the function inverters of this script
  
 +there is a help screen available:
 +<code bash sma2vz>
 +./sma2vz --help
 +   usage: ./sma2vz --vzurl=vzurl --cuuid_pwr=x --cuuid_kwh=y 
 +     [ --daytimeonly --lat=lattitude --lon=longitude]
 +     [--loop --delay=delay] 
 +    | [--help] 
 +    | [--configure] 
 +    
 +     --vzurl=<url> 
 +        volkszaehler middleware url  
 +    
 +     --cuuid_pwr=<uuid> 
 +        channel uuid for power (watt) PV output 
 +    
 +     --cuuid_kwh=<uuid>  
 +       channel uuid for energy (kwH) PV total 
 + 
 +     --daytimeonly
 +       do not post data at night (e.g. if your device does not supply data)
 +
 +     --lon=<longitude>
 +       plant longitude geo coordinate
 +
 +     --lat=<lattitude>
 +       plant lattitude geo coordinate
 +    
 +     --loop  
 +       poll SMA inverters in a loop  
 +    
 +     --delay=<secs>  
 +       how many secs to wait between each reading (default: 15 secs)
 +    
 +     --configure 
 +       create SMAsport configuration file(s) 
 +         modify ./sma2vz inverters shell function 
 +         here document to fit your plant's data
 +</code>
 +
 +<code bash configure example>
 +./sma2vz --lat 51.244 --lon 6.52 --configure
 +</code>        
 +
 +<code bash loop example>
 +./sma2vz \
 +  --vzurl "http://capri/vz/middleware.php/data" \
 +  --cuuid_pwr "7744bbf0-e74d-11e3-9ec7-xxxx" \
 +  --cuuid_kwh "460feba0-e74f-11e3-8a0d-xxxx" \
 +  --daytimeonly --lat 51.244 --lon 6.52 \
 +  --loop --delay 15
 +</code>
 +
 +<code bash cron example>
 +cd /home/wf/smaspot
 +/home/wf/smaspot/sma2vz \
 +  --vzurl "http://capri/vz/middleware.php/data" \
 +  --cuuid_pwr "7744bbf0-e74d-11e3-9ec7-xxxx" \
 +  --cuuid_kwh "460feba0-e74f-11e3-8a0d-xxxx" \
 +  --daytimeonly --lat 51.244 --lon 6.52 >> /var/log/energymeter.log
 +</code>
 +
 +<code | logoutput example>
 +2014-06-01 12:52:08 PV:  1409 Watt   6699.801 kwH sun rise:05:21 set:21:42
 +2014-06-01 12:53:07 PV:  2176 Watt   6699.826 kwH sun rise:05:21 set:21:42
 +2014-06-01 12:54:07 PV:  1699 Watt   6699.855 kwH sun rise:05:21 set:21:42
 +2014-06-01 12:55:07 PV:  3375 Watt   6699.898 kwH sun rise:05:21 set:21:42
 +2014-06-01 12:56:07 PV:  3578 Watt   6699.957 kwH sun rise:05:21 set:21:42
 +</code>
 +
 +Any feedback please to wf (at) bitplan.com - enjoy!
 +
 +
 +<code bash sma2vz>
 +#/bin/bash
 +# SMAspot with Volkszaehler
 +# WF 2014-05-29
 +# $Header: /home/wf/smaspot/RCS/sma2vz,v 1.8 2014/06/01 10:49:38 wf Exp wf $
 +
 +#
 +# get a configuration
 +#  param 1: bluetooth address
 +#  param 2: name of configuration/plant
 +#  param 3: "USER" password for SMA device
 +#  param 4: latitude of plant
 +#  param 5: longitude of plant
 +#  param 6: path to output files of SMAspot
 +#
 +smaspot_config() {
 + local l_btaddr=$1
 + local l_name=$2
 + local l_password=$3
 + local l_lon=$4
 + local l_lat=$5
 + local l_path=$6
 +cat << EOF
 +################################################################################
 +#                ____  __  __    _                    _   
 +#               / ___||  \/  |  / \   ___ _ __   ___ | |_ 
 +#               \___ \| |\/| | / _ \ / __| '_ \ / _ \| __|
 +#                ___) | |  | |/ ___ \\__ \ |_) | (_) | |_ 
 +#               |____/|_|  |_/_/   \_\___/ .__/ \___/ \__|
 +#                                        |_|              
 +#
 +#  SMAspot.cfg - Configuration file for SMAspot.exe
 +#  SMAspot - Yet another tool to read power production of SMA solar inverters
 +#  (c)2012-2014, SBF
 +#
 +#  DISCLAIMER:
 +#  A user of SMAspot software acknowledges that he or she is receiving this
 +#  software on an "as is" basis and the user is not relying on the accuracy 
 +#  or functionality of the software for any purpose. The user further
 +#  acknowledges that any use of this software will be at his own risk 
 +#  and the copyright owner accepts no responsibility whatsoever arising from
 +#  the use or application of the software. 
 +#
 +################################################################################
 +
 +# SMA Inverter's Bluetooth address
 +# Windows: smaspot -scan
 +# Linux  : hcitool scan
 +# IMPORTANT FOR SPEEDWIRE USERS: COMMENT OUT BTADDRESS (PUT # IN FRONT)
 +BTAddress=$l_btaddr
 +
 +# SMA Inverter's Speedwire IP address
 +# If IP_Address is not set or is 0.0.0.0 SMAspot will try to detect the speedwire inverter by broadcast
 +# If IP_Address is set to a valid IP, SMAspot will try to connect directly to that IP without broadcast detection
 +#IP_Address=0.0.0.0
 +
 +# User password (default 0000)
 +Password=$l_password
 +
 +# MIS_Enabled (Multi Inverter Support: Default=0 Disabled)
 +# +------------+-------+-------------+
 +# | #Inverters | NetID | MIS_Enabled |
 +# +------------+-------+-------------+
 +# |      1         | Don't Care  |
 +# +------------+-------+-------------+
 +# |      1       > |      0      |
 +# +------------+-------+-------------+
 +# |      >1    |   > |      1      |
 +# +------------+-------+-------------+
 +MIS_Enabled=0
 +
 +# Plantname
 +Plantname=$l_name
 +
 +# OutputPath (Place to store CSV files)
 +
 +# Windows: C:\TEMP\SMA\%Y
 +# Linux  : /home/sbf/Documents/sma/%Y
 +# %Y %m and %d will be expanded to Year Month and Day
 +OutputPath=$l_path/%Y
 +
 +# OutputPathEvents (Place to store CSV files for events)
 +# If omitted, OutputPath is used
 +OutputPathEvents=$l_path/Events
 +
 +# Position of pv-plant http://itouchmap.com/latlong.html
 +# Example for Ukkel, Belgium
 +Latitude=$l_lat
 +Longitude=$l_lon
 +
 +# Calculate Missing SpotValues
 +# If set to 1, values not provided by inverter will be calculated
 +# eg: Pdc1 = Idc1 * Udc1
 +CalculateMissingSpotValues=1
 +
 +# DateTimeFormat (default %d/%m/%Y %H:%M:%S)
 +# For details see strftime() function
 +# http://www.cplusplus.com/reference/clibrary/ctime/strftime/
 +DateTimeFormat=%Y-%m-%d %H:%M:%S
 +
 +# DateFormat (default %d/%m/%Y)
 +DateFormat=%-%m-%d
 +
 +# DecimalPoint (comma/point default comma)
 +DecimalPoint=point
 +
 +# TimeFormat (default %H:%M:%S)
 +TimeFormat=%H:%M:%S
 +
 +# SynchTime (default 1 = On)
 +# If set to 1 the Inverter time is synchronised with pc time
 +# Some inverters don't have a real-time clock
 +SynchTime=1
 +
 +# SunRSOffset
 +# Offset to start before sunrise and end after sunset (0-3600 - default 900 seconds)
 +SunRSOffset=900
 +
 +# Locale
 +# Translate Entries in CSV files
 +# Surpported locales: de-DE;en-US;fr-FR;nl-NL;es-ES;it-IT
 +# Default en-US
 +Locale=de-DE
 +
 +# Timezone
 +# Select the right timezone in date_time_zonespec.csv
 +# e.g. Timezone=Europe/Brussels
 +Timezone=Europe/Berlin
 +
 +###########################
 +### CSV Export Settings ###
 +###########################
 +# With CSV_* settings you can define the CSV file format
 +
 +# CSV_Export (default 1 = Enabled)
 +# Enables or disables the CSV Export functionality
 +CSV_Export=1
 +
 +# CSV_ExtendedHeader (default 1 = On)
 +# Enables or disables the SMA extended header info (8 lines)
 +# isep=;
 +# Version CSV1|Tool SMAspot|Linebreaks CR/LF|Delimiter semicolon|Decimalpoint comma|Precision 3
 +# etc...
 +# This is usefull for manual data upload to pvoutput.org
 +CSV_ExtendedHeader=1
 +
 +# CSV_Header (default 1 = On)
 +# Enables or disables the CSV data header info (1 line)
 +# dd/MM/yyyy HH:mm:ss;kWh;kW
 +# This is usefull for manual data upload to pvoutput.org
 +# If CSV_ExtendedHeader is enabled, CSV_Header is also enabled
 +CSV_Header=1
 +
 +# CSV_SaveZeroPower (default 1 = On)
 +# When enabled, daily csv files contain all data from 00:00 to 23:55
 +# This is usefull for manual data upload to pvoutput.org
 +CSV_SaveZeroPower=1
 +
 +# CSV_Delimiter (comma/semicolon default semicolon)
 +CSV_Delimiter=semicolon
 +
 +# CSV_Spot_TimeSource (Inverter|Computer default Inverter)
 +CSV_Spot_TimeSource=Inverter
 +
 +# CSV_Spot_WebboxHeader (Default 0 = Off)
 +# When enabled, use Webbox style header (DcMs.Watt[A];DcMs.Watt[B]...)
 +CSV_Spot_WebboxHeader=0
 +
 +#################################
 +### Online Monitoring Systems ###
 +#################################
 +#
 +# In the future, multiple online monitoring systems can be defined
 +# Here we can activate the ones we like
 +#
 +################################
 +### PVoutput Upload Settings ###
 +################################
 +# PVoutput (default 0 = Disabled)
 +# Enables or disables the upload functionality to pvoutput.org
 +# When enabled, be sure to use -u switch on the command line
 +PVoutput=0
 +
 +#PVoutput_SID
 +#Sets PVoutput System ID
 +PVoutput_SID=
 +
 +#PVoutput_Key
 +#Sets PVoutput API Key
 +PVoutput_Key=
 +
 +# VoltageLogging sets AC or DC logging.
 +# Possible values are:
 +# NONE (disabled)
 +# MAX(AC) (default)
 +# AC(PH1) or AC(PH2) or AC(PH3)
 +# MAX(DC) or DC(ST1) or DC(ST2)
 +VoltLogging=MAX(AC)
 +
 +# InverterTemp (default 0 = disabled)
 +# Enables or disables the upload of the inverter's temperature
 +InverterTemp=0
 +
 +# InverterTempMapTo (default v5 = Use standard PVoutput Temperature Graph)
 +# In Donation Mode only, map inverter's temperature to extended data field (v7..v12)
 +# For more info, see http://pvoutput.org/help.html#donations 
 +InverterTempMapTo=v5
 +
 +# CumulativeEnergy (default 0 = Today's Energy)
 +# Set the cumulative flag = 1 when you wish to pass lifetime energy or 0 for today's energy
 +# WARNING!!! DO NOT CHANGE THIS FLAG DURING DAYLIGHT AS THIS WILL MESS UP YOUR PVOUTPUT GRAPHS
 +CumulativeEnergy=0
 +EOF
 +}
 +
 +#
 +#inverters
 +#
 +inverters() {
 +# insert your data from 
 +#   hcitool scan | grep SMA
 +
 +# first  column is bluetooth address
 +# second column is the name of the device (here just the wattage is used)
 +# third  column is the password for "USER" that the SMA Device expects
 +# fourth column is the latitude
 +# fifth  column is the longitude
 +cat << EOF
 +00:80:25:24:xx:xy 1300Watt password /home/wf/smaspot
 +00:80:25:29:xx:xy 4000Watt password /home/wf/smaspot
 +EOF
 +}
 +
 +#
 +# create configuration files
 +#
 +configure() {
 +  checklonlat "configure"
 +inverters | while read btaddr name password path; do
 +  echo "creating ${name}.cfg for bluetooth addr $btaddr" 1>&2
 +  smaspot_config $btaddr $name $password $lon $lat $path > ${name}.cfg
 +done
 +}
 +
 +#
 +# get the sma meter reading
 +#
 +getsmameter() {
 +  # temp filename base for SMAspor result
 +  tmp=/tmp/smaspot$$
 +  # read data from all inverters
 +  inverters | while read btaddr name password path; do
 +    # single shot run of SMAspot with no CVS export
 +    # uncomment to debug
 +    #echo "running smaspot with ${name}.cfg for bluetooth addr $btaddr"
 +    ./SMAspot -v -nocsv -cfg${name}.cfg > ${tmp}_${name}
 +    # the lines we need look like:
 +    #  EToday: 3.358kWh
 +   #  ETotal: 5151.294kWh
 +    #  Total Pac   :   0.442kW
 +
 +    # let's filter the result with awk
 +    cat ${tmp}_${name} | awk '
 +# set the field separator fitting the x: y format
 +BEGIN        { FS=":";doublequote="\x22" }
 +# check the input lines for the three patterns and remove
 +# the unit at the end - assign to the three variables
 +# etoday, etotal and totalpac
 +/EToday:/    { etoday  =$2;gsub("kWh","",etoday)   }
 +/ETotal:/    { etotal  =$2;gsub("kWh","",etotal)   }
 +/Total Pac/  { totalpac=$2;gsub("kW" ,"",totalpac) }
 +# at the end of all lines print out a single json formatted result line
 +END          { 
 +                printf("{%s,%s,%s}\n", 
 +                  json("etoday",etoday),
 +                  json("etotal",etotal),
 +                  json("totalpac",totalpac)) 
 +             }
 +# helper function to create json name values
 +function json(name,value,result) {
 +  # trim value
 +  gsub(" ","",value);
 +  result=quote(name)":"quote(value);
 +  return result 
 +}
 +
 +# helper function to quote a string
 +function quote(s,result) {
 +  result=doublequote s doublequote;
 +  return result 
 +}' 
 +  rm ${tmp}_${name}
 +done
 +}
 +
 +#
 +# show usage
 +#
 +usage() { 
 +cat << EOF
 +   usage: $0 --vzurl=vzurl --cuuid_pwr=x --cuuid_kwh=y 
 +     [ --daytimeonly --lat=lattitude --lon=longitude]
 +     [--loop --delay=delay] 
 +    | [--help] 
 +    | [--configure] 
 +    
 +     --vzurl=<url> 
 +        volkszaehler middleware url  
 +    
 +     --cuuid_pwr=<uuid> 
 +        channel uuid for power (watt) PV output 
 +    
 +     --cuuid_kwh=<uuid>  
 +       channel uuid for energy (kwH) PV total 
 + 
 +     --daytimeonly
 +       do not post data at night (e.g. if your device does not supply data)
 +
 +     --lon=<longitude>
 +       plant longitude geo coordinate
 +
 +     --lat=<lattitude>
 +       plant lattitude geo coordinate
 +    
 +     --loop  
 +       poll SMA inverters in a loop  
 +    
 +     --delay=<secs>  
 +       how many secs to wait between each reading (default: 15 secs)
 +    
 +     --configure 
 +       create SMAsport configuration file(s) 
 +         modify $0 inverters shell function 
 +         here document to fit your plant's data
 +EOF
 +  exit 1
 +}
 +
 +
 +# show error and exit
 +#
 +error() {
 +  local l_msg=$1
 +  local l_hint=$2
 +  echo "error $0: $l_msg" 1>&2
 +  echo "  you might want to $l_hint !" 1>&2
 +  exit 1
 +}
 +
 +#
 +# check that longitude and lattitude are supplied
 +#
 +checklonlat() {
 +  local l_title="$1"
 +  if [ "$lon" == "" ]
 +  then
 +    error "option --lon" "supply lon longitude setting for $l_title to work"
 +  fi
 +  if [ "$lat" == "" ]
 +  then
 +    error "option --lat" "supply lat lattitude setting for $l_title to work"
 +  fi
 +}
 +
 +# defaults
 +delay=15
 +maxloops=1
 +daytimeonly=0
 +
 +# check command line arguments
 +while [ $# -gt 0 ]
 +do
 +  arg="$1"
 +  #echo "$arg"
 +  case "$arg" in 
 +     --help)
 +       usage
 +       ;;
 +
 +     --vzurl) 
 +       vzurl="$2"
 +       shift
 +       ;;
 +
 +     --cuuid_pwr) 
 +       cuuid_pwr="$2"
 +       shift
 +       ;;
 +
 +     --cuuid_kwh) 
 +       cuuid_kwh="$2"
 +       #echo $cuuid_kwh
 +       shift
 +       ;;
 +
 +     --daytimeonly)
 +       daytimeonly=1;
 +       ;;
 +
 +     --lat) 
 +       lat="$2"
 +       shift
 +       ;;
 +
 +     --lon) 
 +       lon="$2"
 +       shift
 +       ;;
 +
 +     --delay) 
 +       delay=$2     
 +       shift
 +       ;;
 +
 +     --loop)
 +       maxloops=10000000;
 +       ;;
 +
 +     --configure)
 +
 +       echo "creating configuration files"
 +       configure
 +       exit
 +       ;;
 +     *)
 +       echo >&2 "Invalid argument: $1"
 +       exit 1
 +     ;;
 +   esac
 +   shift
 +done
 +
 +# check that options are set
 +if [ "$vzurl" == "" ]
 +then
 +  error "option --vzurl is missing" "check and use volkszaehler middleware url"
 +fi
 +if [ "${cuuid_pwr}" == "" ]
 +then
 +  error "option --cuuid_pwr is missing" "check the uuid for the PV power (Watt) channel"
 +fi
 +if [ "$cuuid_kwh" == "" ]
 +then
 +  error "option --cuuid_kwh" "check the uuid for the PV energy (kwH) channel"
 +fi
 +if [ "$daytimeonly" -eq 1 ]
 +then
 +  checklonlat "daytimeonly"
 +fi
 +
 +loop=0
 +while [ $loop -lt $maxloops ]
 +do
 +  # get the SMA meter readings
 +  getsmameter | php sma2vz.php --vzurl=$vzurl --cuuid_pwr=$cuuid_pwr --cuuid_kwh=$cuuid_kwh --daytimeonly=$daytimeonly --lat=$lat --lon=$lon
 +  # sleep a while
 +  if [ $maxloops -gt 1 ]
 +  then
 +    sleep $delay
 +  fi
 +  loop=`expr $loop + 1 `
 +done
 +
 +</code>
 +<code php sma2vz.php>
 +<?php
 +  /**
 +   * read meter data from SMA device
 +   * and post it to volkszaehler
 +   * $Header: /home/wf/smaspot/RCS/sma2vz.php,v 1.6 2014/06/01 10:40:27 wf Exp wf $
 +   */
 +
 +// common code for reading and posting
 +require __DIR__.'/vzapihelper.php';
 +
 +  /**
 +   * check the daytime values
 +   */
 +  function daytime($latitude,$longitude) {
 +    $result=array();
 +    // 08:53 CEST
 +    // $time_format = 'H:i T';
 +    // 08:53
 +    $time_format = 'H:i';
 +
 +    // find time offset in hours
 +    $tzoffset = date("Z")/60 / 60;
 +
 +    $zenith = 90+(50/60); // True sunrise/sunset
 +
 +    // determine sunrise time
 +    $sunrise = date_sunrise(time(), SUNFUNCS_RET_STRING, $latitude, $longitude, $zenith, $tzoffset);
 +    $sunrise_time = date($time_format, strtotime(date("Y-m-d") . ' '. $sunrise));
 +    // determine sunset time
 +    $sunset = date_sunset(time(), SUNFUNCS_RET_STRING, $latitude, $longitude, $zenith, $tzoffset);
 +    $sunset_time = date($time_format, strtotime(date("Y-m-d") . ' '. $sunset));
 +
 +    // check whether it's daytime
 +    $sunrise_epoch = date_sunrise(time(), SUNFUNCS_RET_TIMESTAMP, $latitude, $longitude, $zenith, $tzoffset);
 +    $sunset_epoch  = date_sunset(time(), SUNFUNCS_RET_TIMESTAMP, $latitude, $longitude, $zenith, $tzoffset);
 +    $time_epoch = time(); // time now
 +
 +    $result["daytime"]=($time_epoch < $sunset_epoch and $time_epoch > $sunrise_epoch);
 +
 +    $result["rise"] = $sunrise_time;
 +    $result["set"] = $sunset_time;
 +    $result["time"] = date("Y-m-d H:i:s",time());
 +    return $result;
 +  } 
 +
 +  $loop=0;
 +  // possible command line options
 +  // --vzurl= --cuuid_pwr= --cuuid_kwh= --daytimeonly
 +  $longopts=array("vzurl:","cuuid_pwr:","cuuid_kwh:","lat:","lon:","daytimeonly:");
 +  $shortopts="";
 +  $options=getopt($shortopts,$longopts);
 +  // the volkszaehler middleware url
 +  $vzurl=checkoption("vzurl",$options);
 +  // channel uuids
 +  // power (watts)
 +  $cuuid_pwr=checkoption("cuuid_pwr",$options);
 +  // energy (kWh)
 +  $cuuid_kwh=checkoption("cuuid_kwh",$options);
 +  // daytimeonly? 
 +  $daytimeonly=checkoption("daytimeonly",$options);
 +  if ($daytimeonly) {
 +    $latitude=checkoption("lat",$options);
 +    $longitude=checkoption("lon",$options);
 +  }
 +  
 +  $jsonlines=file("php://stdin");
 +  $tmeter=array();
 +  foreach ($jsonlines as $line_nume => $json) {
 +    // get the meter reading
 +    $meter=json_decode($json, true);
 +    #var_dump($meter);
 +    foreach ($meter as $name => $value) {
 +      if (!array_key_exists($name,$tmeter)) 
 +        $tmeter[$name]=0;
 +      $tmeter[$name]+=$value;
 +    }
 +  }
 +  #var_dump($tmeter);
 +  //array(3) { ["etoday"]=> float(2.52)
 +  // ["etotal"]=> float(6632.462)
 +  //["totalpac"]=> float(2.478) }
 +  $etotal=$tmeter["etotal"];
 +  $totalpac=$tmeter["totalpac"]*1000;
 +  if ($daytimeonly) {
 +    $daytime=daytime($latitude,$longitude);
 +    if (!$daytime["daytime"]) {
 +      printf("%s after sunset: %s wait for sunrise: %s\n",$daytime["time"],$daytime["set"],$daytime["rise"]);
 +      exit(2); 
 +    }
 +  }
 +  # total wattage of all inverters
 +  post2vz($vzurl,$cuuid_pwr,$totalpac);
 +  # total kwh of all inverters 
 +  post2vz($vzurl,$cuuid_kwh,$etotal);
 +  if ($daytimeonly) {
 +    printf("%s PV: % 5d Watt % 10.3f kwH sun rise:%s set:%s\n",$daytime["time"],$totalpac,$etotal,$daytime["rise"],$daytime["set"]); 
 +  } else {
 +    printf("PV Current/Total: %4.0f Watt %.3f kwH\n",$totalpac,$etotal); 
 +  }
 +  exit(0);
 +?>
 +
 +</code>
 +
 +<code php vzapihelper.php>
 +<?php
 +  /**
 +   * vzapi helper functions
 +   * $Header: /home/wf/youless/RCS/vzapihelper.php,v 1.3 2014/05/30 06:57:23 wf Exp $
 +   */
 +
 +  /**
 +   * get a curl channel
 +   */
 +  function curl($url) {
 +    //  Initiate curl
 +    $ch = curl_init();
 +    // Disable SSL verification
 +    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 +    // Will return the response, if false it print the response
 +    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 +    // Set the url
 +    curl_setopt($ch, CURLOPT_URL,$url);
 +
 +    return $ch;
 +  }
 +  
 +  /**
 +   * read the given url
 +   * @param $url:the url to read from
 +   */
 +  function readUrl($url)  {
 +    $ch=curl($url);
 +    
 +    // Execute
 +    $result=curl_exec($ch);
 +    return $result;
 +  }
 +  
 +  /**
 +   * post to the given url
 +   */
 +  function postUrl($url,$fields) {
 +     $ch=curl($url);
 +     $fields_string="";
 +     //url-ify the data for the POST
 +    foreach($fields as $key=>$value) { 
 +      $fields_string .= $key.'='.$value.'&'; 
 +    }
 +    rtrim($fields_string, '&');
 +    curl_setopt($ch,CURLOPT_POST, count($fields));
 +    curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);  
 +    $result=curl_exec($ch);
 +    return $result;
 +   }
 +
 +   /**
 +    * post data to vz middleware
 +    *   param 1: vzurl - middleware url of volkszaehler
 +    *   param 2: channel uuid 
 +    *   param 3: value to post
 +    */
 +   function post2vz($vzurl,$cuuid,$value,$debug=false) {
 +     // post data to middleware according to: 
 +     // http://wiki.volkszaehler.org/development/api/reference
 +
 +     // adapt timestamp to volkszaehler conventions
 + $timestamp=time()*1000;
 +
 +     # first 
 +     $posturl=$vzurl."/".$cuuid.".json";
 +     $fields=array("ts"=>$timestamp,"value" => $value );
 +     $presult=postUrl($posturl,$fields);
 +     if ($debug) {
 +       echo $presult;
 +     }
 +   }
 +
 +  /**
 +   * check that option $opt is available in $options
 +   * return the value if available
 +   */
 +  function checkoption($opt,$options) {
 +    if (array_key_exists($opt,$options))
 +      return $options[$opt];
 +    else
 +      die("option $opt missing!\n");
 +  }
 +
 +?>
 +
 +</code>
howto/wechselrichter_sma.txt · Zuletzt geändert: 2018/04/01 15:56 von jau