diff --git a/plugins/solar/deye b/plugins/solar/deye index f4d5c410..a96f8314 100644 --- a/plugins/solar/deye +++ b/plugins/solar/deye @@ -15,6 +15,7 @@ Dependencies: - wget - awk - sed + - bc plugin config: @@ -22,6 +23,8 @@ plugin config: env.user env.password env.ip + env.serial_number 2XXXXXXXXX6-1 + =head1 AUTHOR @@ -57,77 +60,88 @@ EOF # check if inverter is reachable # inverter is off when there is not enough light to power it -# so it is safe to assume that current power etc. are zero if ping "${ip}" -c1 -W 3 2>&1 > /dev/null ; then - current_power=$(wget --quiet --user "${user}" --password "${password}" -O - "${ip}"/status.html | grep "var webdata_now_p" | awk 'BEGIN {FS="="}{print $2}' | sed 's/[^0-9]*//g') - daily_yield=$(wget --quiet --user "${user}" --password "${password}" -O - "${ip}"/status.html | grep "var webdata_today_e" | awk 'BEGIN {FS="="}{print $2}' | sed 's/[^0-9]*//g') - total_yield=$(wget --quiet --user "${user}" --password "${password}" -O - "${ip}"/status.html | grep "var webdata_total_e" | awk 'BEGIN {FS="="}{print $2}' | sed 's/[^0-9]*//g') + # get data + data=$(wget --quiet --user "${user}" --password "${password}" -O - "${ip}"/status.html) + truncate -s 0 "$MUNIN_STATEFILE" + current_power=$(echo "$data" | grep "var webdata_now_p" | awk 'BEGIN {FS="="}{print $2}' | sed 's/[^0-9]*//g' ) + daily_yield=$(echo "$data" | grep "var webdata_today_e" | awk 'BEGIN {FS="="}{print $2}' | sed 's/[^0-9\.]*//g') + total_yield=$(echo "$data" | grep "var webdata_total_e" | awk 'BEGIN {FS="="}{print $2}' | sed 's/[^0-9\.]*//g') reachable="1" + echo "$daily_yield" >> "$MUNIN_STATEFILE" + echo "$total_yield" >> "$MUNIN_STATEFILE" else current_power="0" - daily_yield=U - total_yield=U reachable="0" + daily_yield=$(cat $MUNIN_STATEFILE | head -n1) + total_yield=$(cat $MUNIN_STATEFILE | tail -n1) fi - - # wenn parameter = ... if [ "$1" = "autoconf" ]; then - echo yes + if [ ! -x "$(command -v wget)" ]; then + echo "no (wget not found)" + elif [ ! -x "$(command -v awk)" ]; then + echo "no (awk not found)" + elif [ ! -x "$(command -v sed)" ]; then + echo "no (sed not found)" + elif [ ! -x "$(command -v bc)" ]; then + echo "no (bc not found)" + fi exit 0 fi if [ "$1" = "config" ]; then # setze optionen - echo multigraph current_power - echo graph_title Deye current Power - echo 'graph_vlabel watt' - echo 'graph_category sensors' - echo 'graph_args -l 0' + echo "multigraph current_power" + echo "graph_title Current Power - Local - SN: ${serial_number}" + echo "graph_vlabel watt" + echo "graph_category sensors" + echo "graph_args -l 0" echo "graph_info Current generated power in Watt." - echo current_power.label watt + echo "current_power.label watt" - echo multigraph daily_yield - echo graph_title Deye daily Yield - echo 'graph_vlabel kWh' - echo 'graph_category sensors' - echo 'graph_args -l 0' + echo "multigraph daily_yield" + echo "graph_title Daily Yield - Local - SN: ${serial_number}" + echo "graph_vlabel kWh" + echo "graph_category sensors" + echo "graph_args -l 0" echo "graph_info Power generated today." - echo daily_yield.label kWh - echo daily_yield.draw AREA + echo "daily_yield.label kWh" + echo "daily_yield.draw AREA" - echo multigraph total_yield - echo graph_title Deye Total Yield - echo 'graph_vlabel kWh' - echo 'graph_category sensors' - echo 'graph_args -l 0' + echo "multigraph total_yield" + echo "graph_title Total Yield - Local - SN: ${serial_number}" + echo "graph_vlabel kWh" + echo "graph_category sensors" + echo "graph_args -l 0" echo "graph_info Total generated power." - echo total_yield.label kWh - echo total_yield.draw AREA + echo "total_yield.label kWh" + echo "total_yield.draw AREA" - echo multigraph reachable - echo graph_title Deye inverter reachable - echo 'graph_vlabel on/off' - echo 'graph_category sensors' - echo 'graph_args -l 0' + echo "multigraph reachable" + echo "graph_printf %6.0lf" + echo "graph_title Inverter reachable - Local - SN: ${serial_number}" + echo "graph_vlabel on/off" + echo "graph_category sensors" + echo "graph_args -l 0" echo "graph_info Is the Inverter is reachable? 1 is On, 0 is Off" - echo reachable.label on/off - echo reachable.draw AREA + echo "reachable.label on/off" + echo "reachable.draw AREA" exit 0 fi -echo multigraph current_power +echo "multigraph current_power" echo "current_power.value $current_power" -echo multigraph daily_yield +echo "multigraph daily_yield" echo "daily_yield.value $daily_yield" -echo multigraph total_yield +echo "multigraph total_yield" echo "total_yield.value $total_yield" -echo multigraph reachable +echo "multigraph reachable" echo "reachable.value $reachable" exit 0 diff --git a/plugins/solar/solarman_api_inverter b/plugins/solar/solarman_api_inverter new file mode 100644 index 00000000..04c20ec2 --- /dev/null +++ b/plugins/solar/solarman_api_inverter @@ -0,0 +1,266 @@ +#!/bin/bash +#%# family=auto +#%# capabilities=autoconf + +: << EOF +=head1 NAME + +Outputs the total and daily production, DC current, DC voltage, DC power for the inverter and the connected panels from Solarman (Smart) API. +To get the API-Keys a E-Mail to customerservice@solarmanpv.com is needed. + +=head1 CONFIGURATION + +Tested with a "Deye SUN600G3-EU-230 600W" inverter. + +If you have 4 Panels just remove the "#" from all lines with *panel[3|4]. + +Dependencies: + - curl + - jq + +plugin config: + + [solarman_api_inverter] + env.SLRM_APPID 2XXXXXXXX2 + env.SLRM_DEVICE_SN 2XXXXXXXXX6-1 + env.SLRM_MAIL "XXXX@YYY.de" + env.SLRM_PASSWORD 'aXXXXXXXXf' + env.SLRM_APPSECRET aXXXXXXXb + +=head1 AUTHOR + +Michael Grote + +=head1 LICENSE + +GPLv3 or later + +SPDX-License-Identifier: GPL-3.0-or-later + +=head1 MAGIC MARKERS + + #%# family=auto + +=cut + +EOF + + +function get_token { + # Combine Variables + ## hash password; -n is used because "echo" normally outputs a newline + SLRM_PASSWORD_SHA=$(echo -n $SLRM_PASSWORD | sha256sum | cut -f1 -d" ") + ## set url + SLRM_URL="https://api.solarmanpv.com/account/v1.0/token?appId=${SLRM_APPID}&language=en&=" + ## create request body for bearer token + SLRM_BEARER_TOKEN_REQUEST_BODY=$(jq --null-input --arg appSecret "${SLRM_APPSECRET}" --arg email "${SLRM_MAIL}" --arg password "${SLRM_PASSWORD_SHA}" '{"appSecret": $appSecret, "email": $email, "password": $password}') + ## get bearer token + SLRM_BEARER_TOKEN=$(curl --silent --request POST --url "${SLRM_URL}" --header 'Content-Type: application/json' --data "$SLRM_BEARER_TOKEN_REQUEST_BODY" | jq .access_token | sed -r 's/"//g') +} + +function get_data { + # setze zählvariablen + retry=1 + count=0 + reachable=0 + # solange count < 16 UND retry != 0 + while [[ $retry != "0" ]]; do + ## create request body for panel data + SLRM_DATA_REQUEST_BODY=$(jq --null-input --arg deviceSn "${SLRM_DEVICE_SN}" '{"deviceSn": $deviceSn}') + ## get panel data + SLRM_DATA=$(curl --silent --request POST --url "https://api.solarmanpv.com/device/v1.0/currentData?appId=${SLRM_APPID}&language=en&=" --header "Authorization: bearer ${SLRM_BEARER_TOKEN}" --header 'Content-Type: application/json' --data "${SLRM_DATA_REQUEST_BODY}") + # wenn "device not found" nicht gefunden wird, dann breche aus beiden Schleifen heraus + if [[ $(echo "$SLRM_DATA" | grep -v -i "device not found") ]] ; then + retry="0" + # Variable für reachable graph + reachable="1" + # schreibe daten in statefile + touch "$MUNIN_STATEFILE" + echo "$SLRM_DATA" > "$MUNIN_STATEFILE" + fi + if [[ $count -gt 10 ]] ; then + retry="0" + fi + # ansonsten warte n sec + sleep 1 + # erhöhe zählvariable + count=$((count + 1 )) + done +} + +# wenn parameter = ... +if [ "$1" = "autoconf" ]; then + if [ ! -x "$(command -v curl)" ]; then + echo "no (curl not found)" + elif [ ! -x "$(command -v jq)" ]; then + echo "no (jq not found)" + fi + exit 0 +fi + +if [ "$1" = "config" ]; then + # setze optionen + echo "multigraph production_total" + echo "graph_scale no" + echo "graph_title Total Yield- SN: $SLRM_DEVICE_SN" + echo "graph_vlabel kWh" + echo "graph_category sensors" + echo "graph_args -l 0 --base 1000" + echo "graph_info The total Production in kWh of Inverter SN: $SLRM_DEVICE_SN" + echo "total_inverter.label Inverter" + echo "total_panel1.label Panel 1" + echo "total_panel2.label Panel 2" + #echo "total_panel3.label Panel 3" + #echo "total_panel4.label Panel 4" + echo "total_inverter.draw AREA" + echo "total_panel1.unknown_limit 3" + echo "total_panel2.unknown_limit 3" + #echo "total_panel3.unknown_limit 3" + #echo "total_panel4.unknown_limit 3" + + echo "multigraph api_reachable" + echo "graph_scale no" + echo "graph_title API reachable/Device found" + echo "graph_category sensors" + echo "graph_args -l 0" + echo "graph_printf %6.0lf" + echo "graph_info Is the API reachable and could the device found?" + echo "reachable.label online" + echo "reachable.info 0 = offline; 1 = online" + echo "reachable.draw AREA" + echo "retries.label connection retries" + echo "retries.info how many retries were needed to get the data" + + echo "multigraph production_daily" + echo "graph_scale no" + echo "graph_title Daily Yield- SN: $SLRM_DEVICE_SN" + echo "graph_vlabel kWh" + echo "graph_category sensors" + echo "graph_args -l 0 --base 1000" + echo "graph_info The daily Production in kWh of Inverter SN: $SLRM_DEVICE_SN" + echo "daily_inverter.label Inverter" + echo "daily_panel1.label Panel 1" + echo "daily_panel2.label Panel 2" + #echo "daily_panel3.label Panel 3" + #echo "daily_panel4.label Panel 4" + echo "daily_inverter.draw AREA" + echo "daily_panel1.unknown_limit 3" + echo "daily_panel2.unknown_limit 3" + #echo "daily_panel3.unknown_limit 3" + #echo "daily_panel4.unknown_limit 3" + + echo "multigraph temp" + echo "graph_scale no" + echo "graph_title Temperature - SN: $SLRM_DEVICE_SN" + echo "graph_vlabel °C" + echo "graph_category sensors" + echo "graph_args -l 0 --base 1000" + echo "graph_info The AC Radiator Temp in Celsius of Inverter SN: $SLRM_DEVICE_SN" + echo "temp.label AC Radiator Temp" + + echo "multigraph voltage_current_input_panels" + echo "graph_scale no" + echo "graph_title DC Measurements - SN: $SLRM_DEVICE_SN" + echo "graph_vlabel V/A/W" + echo "graph_category sensors" + echo "graph_args -l 0 --base 1000" + echo "graph_info The current DC Voltage, Current and Power of Inverter SN: $SLRM_DEVICE_SN" + echo "voltage_panel1.label DC Voltage Panel 1 (Volt)" + echo "voltage_panel2.label DC Voltage Panel 2 (Volt)" + #echo "voltage_panel3.label DC Voltage Panel 3 (Volt)" + #echo "voltage_panel4.label DC Voltage Panel 4 (Volt)" + echo "current_panel1.label DC Current Panel 1 (Ampere)" + echo "current_panel2.label DC Current Panel 2 (Ampere)" + #echo "current_panel3.label DC Current Panel 3 (Ampere)" + #echo "current_panel4.label DC Current Panel 4 (Ampere)" + echo "power_panel1.label DC Power Panel 1 (Watt)" + echo "power_panel2.label DC Power Panel 2 (Watt)" + #echo "power_panel3.label DC Power Panel 3 (Watt)" + #echo "power_panel4.label DC Power Panel 4 (Watt)" + echo "voltage_panel1.unknown_limit 3" + echo "voltage_panel2.unknown_limit 3" + #echo "voltage_panel3.unknown_limit 3" + #echo "voltage_panel4.unknown_limit 3" + echo "current_panel1.unknown_limit 3" + echo "current_panel2.unknown_limit 3" + #echo "current_panel3.unknown_limit 3" + #echo "current_panel4.unknown_limit 3" + echo "power_panel1.unknown_limit 3" + echo "power_panel2.unknown_limit 3" + #echo "power_panel3.unknown_limit 3" + #echo "power_panel4.unknown_limit 3" + + echo "multigraph voltage_current_input_inverter" + echo "graph_scale no" + echo "graph_title AC Measurements - SN: $SLRM_DEVICE_SN" + echo "graph_vlabel V/A/W/H" + echo "graph_category sensors" + echo "graph_args -l 0 --base 1000" + echo "graph_info The current AC Voltage, Frequency, Current and Power of Inverter SN: $SLRM_DEVICE_SN" + echo "voltage_inverter.label AC Voltage (Volt)" + echo "current_inverter.label AC Current (Ampere)" + echo "power_inverter.label AC Output Power (Watt)" + echo "frequency_inverter.label AC Frequency (Hertz)" + echo "frequency_inverter.warning 49.82:50.18" + echo "frequency_inverter.critical 49:51.5" + echo "frequency_inverter.info www.netzfrequenz.info/aktuelle-netzfrequenz-full" + echo "voltage_inverter.warning 207:253" + echo "current_inverter.warning :14" + echo "current_inverter.critical :16" + echo "voltage_inverter.unknown_limit 3" + echo "current_inverter.unknown_limit 3" + echo "power_inverter.unknown_limit 3" + echo "frequency_inverter.unknown_limit 3" + + exit 0 +fi + +# Funktionsaufrufe +get_token +get_data + +echo "multigraph production_total" +# hier kein echo, lese werte aus STATEFILE aus, sorgt dafür das der Graph nachts nicht unterbrochen wird +echo total_inverter.value "$(cat "$MUNIN_STATEFILE" | jq -r '.dataList[]|select(.key|IN("Et_ge0"))|.value' 2> /dev/null || echo U)" +echo total_panel1.value "$(cat "$MUNIN_STATEFILE" | jq -r '.dataList[]|select(.key|IN("Et_ge1"))|.value' 2> /dev/null || echo U)" +echo total_panel2.value "$(cat "$MUNIN_STATEFILE" | jq -r '.dataList[]|select(.key|IN("Et_ge2"))|.value' 2> /dev/null || echo U)" +#echo total_panel3.value "$(cat "$MUNIN_STATEFILE" | jq -r '.dataList[]|select(.key|IN("Et_ge3"))|.value' 2> /dev/null || echo U)" +#echo total_panel4.value "$(cat "$MUNIN_STATEFILE" | jq -r '.dataList[]|select(.key|IN("Et_ge4"))|.value' 2> /dev/null || echo U)" + +echo "multigraph temp" +echo temp.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("AC_RDT_T1"))|.value' 2> /dev/null || echo U )" + +echo "multigraph production_daily" +# hier kein echo, lese werte aus STATEFILE aus, sorgt dafür das der Graph nachts nicht unterbrochen wird +echo daily_inverter.value "$(cat "$MUNIN_STATEFILE" | jq -r '.dataList[]|select(.key|IN("Etdy_ge0"))|.value' 2> /dev/null || echo U )" +echo daily_panel1.value "$(cat "$MUNIN_STATEFILE" | jq -r '.dataList[]|select(.key|IN("Etdy_ge1"))|.value' 2> /dev/null || echo U )" +echo daily_panel2.value "$(cat "$MUNIN_STATEFILE" | jq -r '.dataList[]|select(.key|IN("Etdy_ge2"))|.value' 2> /dev/null || echo U )" +#echo daily_panel3.value "$(cat "$MUNIN_STATEFILE" | jq -r '.dataList[]|select(.key|IN("Etdy_ge3"))|.value' 2> /dev/null || echo U )" +#echo daily_panel4.value "$(cat "$MUNIN_STATEFILE" | jq -r '.dataList[]|select(.key|IN("Etdy_ge4"))|.value' 2> /dev/null || echo U )" + +echo "multigraph voltage_current_input_panels" +echo voltage_panel1.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DV1"))|.value' 2> /dev/null || echo U )" +echo current_panel1.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DC1"))|.value' 2> /dev/null || echo U )" +echo power_panel1.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DP1"))|.value' 2> /dev/null || echo U )" +echo voltage_panel2.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DV2"))|.value' 2> /dev/null || echo U )" +echo current_panel2.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DC2"))|.value' 2> /dev/null || echo U )" +echo power_panel2.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DP2"))|.value' 2> /dev/null || echo U )" +#echo voltage_panel3.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DV3"))|.value' 2> /dev/null || echo U )" +#echo current_panel3.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DC3"))|.value' 2> /dev/null || echo U )" +#echo power_panel3.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DP3"))|.value' 2> /dev/null || echo U )" +#echo voltage_panel4.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DV4"))|.value' 2> /dev/null || echo U )" +#echo current_panel4.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DC4"))|.value' 2> /dev/null || echo U )" +#echo power_panel4.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("DP4"))|.value' 2> /dev/null || echo U )" + + +echo "multigraph voltage_current_input_inverter" +echo voltage_inverter.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("AV1"))|.value' 2> /dev/null || echo U )" +echo current_inverter.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("AC1"))|.value' 2> /dev/null || echo U )" +echo power_inverter.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("APo_t1"))|.value' 2> /dev/null || echo U )" +echo frequency_inverter.value "$(echo "$SLRM_DATA" | jq -r '.dataList[]|select(.key|IN("AC_Fo1"))|.value' 2> /dev/null || echo U )" + +echo "multigraph api_reachable" +echo "reachable.value $reachable" +echo "retries.value $count" + +exit 0