From 3147fb527ac92bd0639c0a78e3622f99926ff2c4 Mon Sep 17 00:00:00 2001 From: "Georg v. Zezschwitz" Date: Mon, 11 Oct 2021 21:51:17 +0200 Subject: [PATCH 01/66] Patch for u1p3p.sh to stop "flapping" 1/3 phases --- u1p3p.sh | 92 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/u1p3p.sh b/u1p3p.sh index 1159c6259..4888d0d77 100644 --- a/u1p3p.sh +++ b/u1p3p.sh @@ -11,6 +11,10 @@ u1p3pswitch(){ fi uhwaittime=$(( $u1p3schaltparam * 60 )) urwaittime=$(( (16 - $u1p3schaltparam) * 60 )) + # Schaltschwelle 1P -> 3P bei 16A max je Phase + mindestuberschuss3ph=$(( (3 * 6 * 230) + 100)) + # Schaltschwelle 3P -> 1P bei 16A max je Phase + mindestuberschuss3pr=$(( (3 * 6 * 230) - 100)) openwbDebugLog "MAIN" 1 "automatische Umschaltung aktiv" openwbDebugLog "MAIN" 1 "Timing Umschaltung: $uhwaittime / $urwaittime" if (( ladestatus == 0)); then @@ -165,7 +169,7 @@ u1p3pswitch(){ maximalstromstaerke=$schieflastmaxa fi if (( ladeleistung < 100 )); then - if (( uberschuss > ((3 * mindestuberschuss) + 1000) )); then + if (( uberschuss >= mindestuberschuss3ph )); then openwbDebugLog "MAIN" 1 "Min PV Laden derzeit $u1p3pstat Phasen, auf MinPV Automatik konfiguriert, aendere auf 3 Phasen da viel Überschuss vorhanden..." echo 1 > ramdisk/blockall runs/u1p3pcheck.sh stop @@ -180,19 +184,9 @@ u1p3pswitch(){ if (( oldll == maximalstromstaerke )); then uhcounter=$( 500 )); then - uhcounter=$((uhcounter + 10)) - echo $uhcounter > /var/www/html/openWB/ramdisk/uhcounter - openwbDebugLog "MAIN" 1 "Umschaltcounter Erhoehung auf $uhcounter erhoeht fuer Min PV Automatik Phasenumschaltung, genug uberschuss fuer 3 Phasen Ladung" - else - openwbDebugLog "MAIN" 1 "Umschaltcounter nicht erhöht fuer Min PV Automatik Phasenumschaltung, fehlender uberschuss fuer 3 Phasen Ladung" - fi - else - uhcounter=$((uhcounter + 10)) - echo $uhcounter > /var/www/html/openWB/ramdisk/uhcounter - openwbDebugLog "MAIN" 1 "Umschaltcounter Erhoehung auf $uhcounter erhoeht fuer Min PV Automatik Phasenumschaltung" - fi + uhcounter=$((uhcounter + 10)) + echo $uhcounter > /var/www/html/openWB/ramdisk/uhcounter + openwbDebugLog "MAIN" 1 "Umschaltcounter Erhoehung auf $uhcounter erhoeht fuer Min PV Automatik Phasenumschaltung" else openwbDebugLog "MAIN" 1 "Min PV Laden derzeit $u1p3pstat Phasen, auf MinPV Automatik konfiguriert, unterbreche Ladung und aendere auf 3 Phasen..." echo 1 > ramdisk/blockall @@ -210,7 +204,7 @@ u1p3pswitch(){ fi else if (( ladeleistung < 100 )); then - if (( uberschuss < (3 * mindestuberschuss) )); then + if (( uberschuss < mindestuberschuss3ph )); then echo 0 > /var/www/html/openWB/ramdisk/urcounter echo 1 > ramdisk/blockall runs/u1p3pcheck.sh stop @@ -269,7 +263,7 @@ u1p3pswitch(){ maximalstromstaerke=$schieflastmaxa fi if (( ladeleistung < 100 )); then - if (( uberschuss > ((3 * mindestuberschuss) + 1000) )); then + if (( uberschuss >= mindestuberschuss3ph )); then openwbDebugLog "MAIN" 1 "Nur PV Laden derzeit $u1p3pstat Phasen, auf NurPV Automatik konfiguriert, aendere auf 3 Phasen da viel Überschuss vorhanden..." echo 1 > ramdisk/blockall runs/u1p3pcheck.sh stop @@ -282,21 +276,27 @@ u1p3pswitch(){ fi fi if (( oldll == maximalstromstaerke )); then - uhcounter=$( /var/www/html/openWB/ramdisk/uhcounter - openwbDebugLog "MAIN" 1 "Umschaltcounter Erhoehung auf $uhcounter erhoeht fuer PV Automatik Phasenumschaltung" + if (( uberschuss + ladeleistung >= mindestuberschuss3ph )); then + uhcounter=$( /var/www/html/openWB/ramdisk/uhcounter + openwbDebugLog "MAIN" 1 "Umschaltcounter Erhoehung auf $uhcounter erhoeht fuer PV Automatik Phasenumschaltung" + else + openwbDebugLog "MAIN" 1 "Nur PV Laden derzeit $u1p3pstat Phasen, auf NurPV Automatik konfiguriert, unterbreche Ladung und aendere auf 3 Phasen..." + echo 1 > ramdisk/blockall + runs/u1p3pcheck.sh stop + sleep 8 + runs/u1p3pcheck.sh 3 + sleep 20 + runs/u1p3pcheck.sh startslow + (sleep 25 && echo 0 > ramdisk/blockall)& + openwbDebugLog "MAIN" 1 "auf 3 Phasen NurPV Automatik geaendert" + echo 0 > /var/www/html/openWB/ramdisk/uhcounter + fi else - openwbDebugLog "MAIN" 1 "Nur PV Laden derzeit $u1p3pstat Phasen, auf NurPV Automatik konfiguriert, unterbreche Ladung und aendere auf 3 Phasen..." - echo 1 > ramdisk/blockall - runs/u1p3pcheck.sh stop - sleep 8 - runs/u1p3pcheck.sh 3 - sleep 20 - runs/u1p3pcheck.sh startslow - (sleep 25 && echo 0 > ramdisk/blockall)& - openwbDebugLog "MAIN" 1 "auf 3 Phasen NurPV Automatik geaendert" + llplusuberschuss=$(( $ladeleistung + $uberschuss )) + openwbDebugLog "MAIN" 1 "Maximum 1P erreicht, aber nicht ausreichend fuer 3P ($mindestuberschuss3ph W min vs $llplusuberschuss W)" echo 0 > /var/www/html/openWB/ramdisk/uhcounter fi else @@ -317,21 +317,27 @@ u1p3pswitch(){ fi fi if (( oldll == minimalapv )); then - urcounter=$( /var/www/html/openWB/ramdisk/urcounter - openwbDebugLog "MAIN" 1 "Umschaltcounter Reduzierung auf $urcounter erhoeht fuer PV Automatik Phasenumschaltung" + if (( uberschuss < -100 && maximalstromstaerke<=18)); then + urcounter=$( /var/www/html/openWB/ramdisk/urcounter + openwbDebugLog "MAIN" 1 "Umschaltcounter Reduzierung auf $urcounter erhoeht fuer PV Automatik Phasenumschaltung ($oldll == $minimalapv, $uberschuss)" + else + echo 0 > /var/www/html/openWB/ramdisk/urcounter + echo 1 > ramdisk/blockall + runs/u1p3pcheck.sh stop + sleep 8 + runs/u1p3pcheck.sh 1 + sleep 20 + runs/u1p3pcheck.sh startslow + (sleep 25 && echo 0 > ramdisk/blockall)& + openwbDebugLog "MAIN" 1 "auf 1 Phasen NurPV Automatik geaendert" + fi else + llplusuberschuss=$(( $ladeleistung + $uberschuss )) + openwbDebugLog "MAIN" 1 "Minimum 3P erreicht, aber noch ausreichend fuer 3P ($mindestuberschuss3pr W min vs $llplusuberschuss W, max 1P $maximalstromstaerke)" echo 0 > /var/www/html/openWB/ramdisk/urcounter - echo 1 > ramdisk/blockall - runs/u1p3pcheck.sh stop - sleep 8 - runs/u1p3pcheck.sh 1 - sleep 20 - runs/u1p3pcheck.sh startslow - (sleep 25 && echo 0 > ramdisk/blockall)& - openwbDebugLog "MAIN" 1 "auf 1 Phasen NurPV Automatik geaendert" fi else echo 0 > /var/www/html/openWB/ramdisk/urcounter From 52b2614c29eaa3975b7bfe7962483f109bc9fd8b Mon Sep 17 00:00:00 2001 From: "Georg v. Zezschwitz" Date: Thu, 14 Oct 2021 16:58:38 +0200 Subject: [PATCH 02/66] Alle 3 Vorschlaege: 1P3P-Flapping, 16A-Start bei 3P, 6/7-Flapping bei manueller Regel NurPV --- nurpv.sh | 8 ++------ u1p3p.sh | 12 ++++++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/nurpv.sh b/nurpv.sh index 865694b53..d26ff7cd1 100755 --- a/nurpv.sh +++ b/nurpv.sh @@ -244,14 +244,10 @@ nurpvlademodus(){ llneu=$(( llalt + ( uberschuss / 230 / anzahlphasen))) fi else - if (( llalt == minimalapv )); then + if (( nurpvslowup == 1 )) && (( uberschuss - schaltschwelle > 230 )); then llneu=$(( llalt + 1 )) else - if (( nurpvslowup == 1 )); then - llneu=$(( llalt + 1 )) - else - llneu=$(( llalt + ( (uberschuss - schaltschwelle) / 230 / anzahlphasen))) - fi + llneu=$(( llalt + ( (uberschuss - schaltschwelle) / 230 / anzahlphasen))) fi fi if (( llneu > maximalstromstaerke )); then diff --git a/u1p3p.sh b/u1p3p.sh index 4888d0d77..eab7cff1c 100644 --- a/u1p3p.sh +++ b/u1p3p.sh @@ -12,9 +12,9 @@ u1p3pswitch(){ uhwaittime=$(( $u1p3schaltparam * 60 )) urwaittime=$(( (16 - $u1p3schaltparam) * 60 )) # Schaltschwelle 1P -> 3P bei 16A max je Phase - mindestuberschuss3ph=$(( (3 * 6 * 230) + 100)) + mindestuberschuss3ph=$(( 3 * minimalapv * 230 )) # Schaltschwelle 3P -> 1P bei 16A max je Phase - mindestuberschuss3pr=$(( (3 * 6 * 230) - 100)) + mindestuberschuss3pr=$(( 3 * minimalapv * 230 )) openwbDebugLog "MAIN" 1 "automatische Umschaltung aktiv" openwbDebugLog "MAIN" 1 "Timing Umschaltung: $uhwaittime / $urwaittime" if (( ladestatus == 0)); then @@ -179,6 +179,7 @@ u1p3pswitch(){ runs/u1p3pcheck.sh startslow (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 3 Phasen MinPV Automatik geaendert" + exit 0 fi fi if (( oldll == maximalstromstaerke )); then @@ -198,6 +199,7 @@ u1p3pswitch(){ (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 3 Phasen MinPV Automatik geaendert" echo 0 > /var/www/html/openWB/ramdisk/uhcounter + exit 0 fi else echo 0 > /var/www/html/openWB/ramdisk/uhcounter @@ -214,6 +216,7 @@ u1p3pswitch(){ runs/u1p3pcheck.sh startslow (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 1 Phasen MinPV Automatik geaendert da geringerer Überschuss" + exit 0 fi fi if (( oldll == minimalampv )); then @@ -232,6 +235,7 @@ u1p3pswitch(){ runs/u1p3pcheck.sh startslow (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 1 Phasen MinPV Automatik geaendert" + exit 0 fi else echo 0 > /var/www/html/openWB/ramdisk/urcounter @@ -273,6 +277,7 @@ u1p3pswitch(){ runs/u1p3pcheck.sh startslow (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 3 Phasen NurPV Automatik geaendert" + exit 0 fi fi if (( oldll == maximalstromstaerke )); then @@ -293,6 +298,7 @@ u1p3pswitch(){ (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 3 Phasen NurPV Automatik geaendert" echo 0 > /var/www/html/openWB/ramdisk/uhcounter + exit 0 fi else llplusuberschuss=$(( $ladeleistung + $uberschuss )) @@ -314,6 +320,7 @@ u1p3pswitch(){ runs/u1p3pcheck.sh startslow (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 1 Phasen NurPV Automatik geaendert da geringerer Überschuss" + exit 0 fi fi if (( oldll == minimalapv )); then @@ -333,6 +340,7 @@ u1p3pswitch(){ runs/u1p3pcheck.sh startslow (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 1 Phasen NurPV Automatik geaendert" + exit 0 fi else llplusuberschuss=$(( $ladeleistung + $uberschuss )) From dfcc2b332d981fe9dc95cfca5a8eac7c5d1b0b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= <46440437+matzempc@users.noreply.github.com> Date: Tue, 19 Oct 2021 12:53:09 +0200 Subject: [PATCH 03/66] Update update.sh update from fork --- runs/update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runs/update.sh b/runs/update.sh index e585ac19d..c9d5ac7f9 100755 --- a/runs/update.sh +++ b/runs/update.sh @@ -60,8 +60,8 @@ cp modules/soc_eq/soc_eq_acc_lp2 /tmp/soc_eq_acc_lp2 cp openwb.conf /tmp/openwb.conf # fetch new release from GitHub -sudo git fetch origin -sudo git reset --hard origin/$train +sudo git fetch matzempc +sudo git reset --hard matzempc/$train # set permissions cd /var/www/html/ From b43bd488b458d54af546b1b10cd9c7adb6b4fe07 Mon Sep 17 00:00:00 2001 From: matzempc Date: Thu, 21 Oct 2021 19:55:01 +0200 Subject: [PATCH 04/66] Revert "Merge remote-tracking branch 'gvzdus/master'" This reverts commit 14df0113fb1c2484972bf553c4b860ded94375d5, reversing changes made to dfcc2b332d981fe9dc95cfca5a8eac7c5d1b0b5b. --- nurpv.sh | 8 +++-- u1p3p.sh | 100 ++++++++++++++++++++++++------------------------------- 2 files changed, 49 insertions(+), 59 deletions(-) diff --git a/nurpv.sh b/nurpv.sh index d26ff7cd1..865694b53 100755 --- a/nurpv.sh +++ b/nurpv.sh @@ -244,10 +244,14 @@ nurpvlademodus(){ llneu=$(( llalt + ( uberschuss / 230 / anzahlphasen))) fi else - if (( nurpvslowup == 1 )) && (( uberschuss - schaltschwelle > 230 )); then + if (( llalt == minimalapv )); then llneu=$(( llalt + 1 )) else - llneu=$(( llalt + ( (uberschuss - schaltschwelle) / 230 / anzahlphasen))) + if (( nurpvslowup == 1 )); then + llneu=$(( llalt + 1 )) + else + llneu=$(( llalt + ( (uberschuss - schaltschwelle) / 230 / anzahlphasen))) + fi fi fi if (( llneu > maximalstromstaerke )); then diff --git a/u1p3p.sh b/u1p3p.sh index eab7cff1c..1159c6259 100644 --- a/u1p3p.sh +++ b/u1p3p.sh @@ -11,10 +11,6 @@ u1p3pswitch(){ fi uhwaittime=$(( $u1p3schaltparam * 60 )) urwaittime=$(( (16 - $u1p3schaltparam) * 60 )) - # Schaltschwelle 1P -> 3P bei 16A max je Phase - mindestuberschuss3ph=$(( 3 * minimalapv * 230 )) - # Schaltschwelle 3P -> 1P bei 16A max je Phase - mindestuberschuss3pr=$(( 3 * minimalapv * 230 )) openwbDebugLog "MAIN" 1 "automatische Umschaltung aktiv" openwbDebugLog "MAIN" 1 "Timing Umschaltung: $uhwaittime / $urwaittime" if (( ladestatus == 0)); then @@ -169,7 +165,7 @@ u1p3pswitch(){ maximalstromstaerke=$schieflastmaxa fi if (( ladeleistung < 100 )); then - if (( uberschuss >= mindestuberschuss3ph )); then + if (( uberschuss > ((3 * mindestuberschuss) + 1000) )); then openwbDebugLog "MAIN" 1 "Min PV Laden derzeit $u1p3pstat Phasen, auf MinPV Automatik konfiguriert, aendere auf 3 Phasen da viel Überschuss vorhanden..." echo 1 > ramdisk/blockall runs/u1p3pcheck.sh stop @@ -179,15 +175,24 @@ u1p3pswitch(){ runs/u1p3pcheck.sh startslow (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 3 Phasen MinPV Automatik geaendert" - exit 0 fi fi if (( oldll == maximalstromstaerke )); then uhcounter=$( /var/www/html/openWB/ramdisk/uhcounter - openwbDebugLog "MAIN" 1 "Umschaltcounter Erhoehung auf $uhcounter erhoeht fuer Min PV Automatik Phasenumschaltung" + if (( maximalstromstaerke == 16 )); then + if (( uberschuss > 500 )); then + uhcounter=$((uhcounter + 10)) + echo $uhcounter > /var/www/html/openWB/ramdisk/uhcounter + openwbDebugLog "MAIN" 1 "Umschaltcounter Erhoehung auf $uhcounter erhoeht fuer Min PV Automatik Phasenumschaltung, genug uberschuss fuer 3 Phasen Ladung" + else + openwbDebugLog "MAIN" 1 "Umschaltcounter nicht erhöht fuer Min PV Automatik Phasenumschaltung, fehlender uberschuss fuer 3 Phasen Ladung" + fi + else + uhcounter=$((uhcounter + 10)) + echo $uhcounter > /var/www/html/openWB/ramdisk/uhcounter + openwbDebugLog "MAIN" 1 "Umschaltcounter Erhoehung auf $uhcounter erhoeht fuer Min PV Automatik Phasenumschaltung" + fi else openwbDebugLog "MAIN" 1 "Min PV Laden derzeit $u1p3pstat Phasen, auf MinPV Automatik konfiguriert, unterbreche Ladung und aendere auf 3 Phasen..." echo 1 > ramdisk/blockall @@ -199,14 +204,13 @@ u1p3pswitch(){ (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 3 Phasen MinPV Automatik geaendert" echo 0 > /var/www/html/openWB/ramdisk/uhcounter - exit 0 fi else echo 0 > /var/www/html/openWB/ramdisk/uhcounter fi else if (( ladeleistung < 100 )); then - if (( uberschuss < mindestuberschuss3ph )); then + if (( uberschuss < (3 * mindestuberschuss) )); then echo 0 > /var/www/html/openWB/ramdisk/urcounter echo 1 > ramdisk/blockall runs/u1p3pcheck.sh stop @@ -216,7 +220,6 @@ u1p3pswitch(){ runs/u1p3pcheck.sh startslow (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 1 Phasen MinPV Automatik geaendert da geringerer Überschuss" - exit 0 fi fi if (( oldll == minimalampv )); then @@ -235,7 +238,6 @@ u1p3pswitch(){ runs/u1p3pcheck.sh startslow (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 1 Phasen MinPV Automatik geaendert" - exit 0 fi else echo 0 > /var/www/html/openWB/ramdisk/urcounter @@ -267,7 +269,7 @@ u1p3pswitch(){ maximalstromstaerke=$schieflastmaxa fi if (( ladeleistung < 100 )); then - if (( uberschuss >= mindestuberschuss3ph )); then + if (( uberschuss > ((3 * mindestuberschuss) + 1000) )); then openwbDebugLog "MAIN" 1 "Nur PV Laden derzeit $u1p3pstat Phasen, auf NurPV Automatik konfiguriert, aendere auf 3 Phasen da viel Überschuss vorhanden..." echo 1 > ramdisk/blockall runs/u1p3pcheck.sh stop @@ -277,32 +279,24 @@ u1p3pswitch(){ runs/u1p3pcheck.sh startslow (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 3 Phasen NurPV Automatik geaendert" - exit 0 fi fi if (( oldll == maximalstromstaerke )); then - if (( uberschuss + ladeleistung >= mindestuberschuss3ph )); then - uhcounter=$( /var/www/html/openWB/ramdisk/uhcounter - openwbDebugLog "MAIN" 1 "Umschaltcounter Erhoehung auf $uhcounter erhoeht fuer PV Automatik Phasenumschaltung" - else - openwbDebugLog "MAIN" 1 "Nur PV Laden derzeit $u1p3pstat Phasen, auf NurPV Automatik konfiguriert, unterbreche Ladung und aendere auf 3 Phasen..." - echo 1 > ramdisk/blockall - runs/u1p3pcheck.sh stop - sleep 8 - runs/u1p3pcheck.sh 3 - sleep 20 - runs/u1p3pcheck.sh startslow - (sleep 25 && echo 0 > ramdisk/blockall)& - openwbDebugLog "MAIN" 1 "auf 3 Phasen NurPV Automatik geaendert" - echo 0 > /var/www/html/openWB/ramdisk/uhcounter - exit 0 - fi + uhcounter=$( /var/www/html/openWB/ramdisk/uhcounter + openwbDebugLog "MAIN" 1 "Umschaltcounter Erhoehung auf $uhcounter erhoeht fuer PV Automatik Phasenumschaltung" else - llplusuberschuss=$(( $ladeleistung + $uberschuss )) - openwbDebugLog "MAIN" 1 "Maximum 1P erreicht, aber nicht ausreichend fuer 3P ($mindestuberschuss3ph W min vs $llplusuberschuss W)" + openwbDebugLog "MAIN" 1 "Nur PV Laden derzeit $u1p3pstat Phasen, auf NurPV Automatik konfiguriert, unterbreche Ladung und aendere auf 3 Phasen..." + echo 1 > ramdisk/blockall + runs/u1p3pcheck.sh stop + sleep 8 + runs/u1p3pcheck.sh 3 + sleep 20 + runs/u1p3pcheck.sh startslow + (sleep 25 && echo 0 > ramdisk/blockall)& + openwbDebugLog "MAIN" 1 "auf 3 Phasen NurPV Automatik geaendert" echo 0 > /var/www/html/openWB/ramdisk/uhcounter fi else @@ -320,32 +314,24 @@ u1p3pswitch(){ runs/u1p3pcheck.sh startslow (sleep 25 && echo 0 > ramdisk/blockall)& openwbDebugLog "MAIN" 1 "auf 1 Phasen NurPV Automatik geaendert da geringerer Überschuss" - exit 0 fi fi if (( oldll == minimalapv )); then - if (( uberschuss < -100 && maximalstromstaerke<=18)); then - urcounter=$( /var/www/html/openWB/ramdisk/urcounter - openwbDebugLog "MAIN" 1 "Umschaltcounter Reduzierung auf $urcounter erhoeht fuer PV Automatik Phasenumschaltung ($oldll == $minimalapv, $uberschuss)" - else - echo 0 > /var/www/html/openWB/ramdisk/urcounter - echo 1 > ramdisk/blockall - runs/u1p3pcheck.sh stop - sleep 8 - runs/u1p3pcheck.sh 1 - sleep 20 - runs/u1p3pcheck.sh startslow - (sleep 25 && echo 0 > ramdisk/blockall)& - openwbDebugLog "MAIN" 1 "auf 1 Phasen NurPV Automatik geaendert" - exit 0 - fi + urcounter=$( /var/www/html/openWB/ramdisk/urcounter + openwbDebugLog "MAIN" 1 "Umschaltcounter Reduzierung auf $urcounter erhoeht fuer PV Automatik Phasenumschaltung" else - llplusuberschuss=$(( $ladeleistung + $uberschuss )) - openwbDebugLog "MAIN" 1 "Minimum 3P erreicht, aber noch ausreichend fuer 3P ($mindestuberschuss3pr W min vs $llplusuberschuss W, max 1P $maximalstromstaerke)" echo 0 > /var/www/html/openWB/ramdisk/urcounter + echo 1 > ramdisk/blockall + runs/u1p3pcheck.sh stop + sleep 8 + runs/u1p3pcheck.sh 1 + sleep 20 + runs/u1p3pcheck.sh startslow + (sleep 25 && echo 0 > ramdisk/blockall)& + openwbDebugLog "MAIN" 1 "auf 1 Phasen NurPV Automatik geaendert" fi else echo 0 > /var/www/html/openWB/ramdisk/urcounter From ba954f2198540f0cb8d62237a58978696ca51475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Wed, 3 Nov 2021 12:22:13 +0100 Subject: [PATCH 05/66] fix/beautify log output --- modules/smarthome/http/on.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/smarthome/http/on.py b/modules/smarthome/http/on.py index f26371444..a28a23107 100644 --- a/modules/smarthome/http/on.py +++ b/modules/smarthome/http/on.py @@ -22,6 +22,6 @@ f = open( file_string , 'a') else: f = open( file_string , 'w') -print ('%s devicenr %s url %s)' % (time_string,devicenumber,url),file=f) +print ('%s devicenr %s url %s' % (time_string,devicenumber,url),file=f) f.close() urllib.request.urlopen(url, timeout=5) \ No newline at end of file From aa8178ef6df915de99c1d233830144d1c5ed2606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Wed, 3 Nov 2021 12:27:00 +0100 Subject: [PATCH 06/66] go-e: read RFID also if go-e is second LP --- modules/goelp2/main.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/goelp2/main.sh b/modules/goelp2/main.sh index 70d508a9b..e830d6e97 100755 --- a/modules/goelp2/main.sh +++ b/modules/goelp2/main.sh @@ -41,6 +41,12 @@ if [[ $? == "0" ]] ; then if [[ $llkwh =~ $rekwh ]] ; then echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs1 fi + rfid=$(echo $output | jq -r '.uby') + oldrfid=$( /var/www/html/openWB/ramdisk/readtag + echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp2rfid + fi #car status 1 Ladestation bereit, kein Auto #car status 2 Auto lädt #car status 3 Warte auf Fahrzeug From f6cd24603d51e5ed382b56a9b368dbeafb0aa97a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Wed, 3 Nov 2021 15:10:40 +0100 Subject: [PATCH 07/66] goe: added RFID capability also for LP3 --- modules/goelp3/main.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/goelp3/main.sh b/modules/goelp3/main.sh index 5fc385595..c468058dd 100755 --- a/modules/goelp3/main.sh +++ b/modules/goelp3/main.sh @@ -41,6 +41,12 @@ if [[ $? == "0" ]] ; then if [[ $llkwh =~ $rekwh ]] ; then echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs2 fi + rfid=$(echo $output | jq -r '.uby') + oldrfid=$( /var/www/html/openWB/ramdisk/readtag + echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp3rfid + fi #car status 1 Ladestation bereit, kein Auto #car status 2 Auto lädt #car status 3 Warte auf Fahrzeug From f3ca4966c65b7f8a6c6bd71a9c57ecc7d8297392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Thu, 4 Nov 2021 08:03:00 +0100 Subject: [PATCH 08/66] 1phase-3phases switch for goe (HW V3) --- runs/u1p3pgoe.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 runs/u1p3pgoe.py diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py new file mode 100644 index 000000000..cb3bd9763 --- /dev/null +++ b/runs/u1p3pgoe.py @@ -0,0 +1,48 @@ +#!/usr/bin/python +import requests +import sys +import os +import time +import argparse +import traceback + +parser = argparse.ArgumentParser() +parser.add_argument("-a", "--address", required=True, type=str, help="ip address") +parser.add_argument("-p", "--phases", required=True, type=int, choices=[1, 3], help="phases to activate") +parser.add_argument("-v", "--verbose", required=False, action="store_true", help="verbose debug output") +args = parser.parse_args() + +if(args.verbose): + print("Go-e mit IP %s Umschaltung auf %d Phasen"%(args.address, args.phases)) + +status_goe = requests.get('http://'+args.address+'/status', timeout = 5).json() +if(args.verbose): + try: + print ("go-e serial number: %s"%(status_goe['sse'])) + except: + traceback.print_exc() + exit(1) + +if ( "fsp" in status_goe): + try: + if(args.verbose): + print ("fsp before: %d"%(int(status_goe['fsp']))) + except: + traceback.print_exc() + exit(1) + if ( args.phases == 1 ): + set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=0', timeout = 5).json() + try: + if (int(set_fsp_goe['fsp']) == 0 and args.verbose): + print ("Switch to 1Phase succeeded: fsp=%d"%(int(set_fsp_goe['fsp']))) + except: + traceback.print_exc() + exit(1) + if ( args.phases == 3 ): + set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=1', timeout = 5).json() + try: + if (int(set_fsp_goe['fsp']) == 1 and args.verbose): + print ("Switch to 3Phases succeeded: fsp=%d"%(int(set_fsp_goe['fsp']))) + except: + traceback.print_exc() + exit(1) \ No newline at end of file From 41f7be89a345fed42fa19113d2ada33237ca7724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Thu, 4 Nov 2021 08:04:50 +0100 Subject: [PATCH 09/66] 1phase-3phases switch for goe (HW V3) II --- runs/u1p3pcheck.sh | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/runs/u1p3pcheck.sh b/runs/u1p3pcheck.sh index 56cac9929..2eeb4686f 100755 --- a/runs/u1p3pcheck.sh +++ b/runs/u1p3pcheck.sh @@ -13,6 +13,9 @@ if [[ "$1" == "1" ]]; then if [[ $evsecon == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep1ip -m "1" fi + if [[ $evsecon == "goe" ]]; then + sudo python runs/u1p3pgoe.py -a $goeiplp1 -p 1 + fi # chargepoint 2 if [[ $lastmanagement == 1 && $evsecons1 == "modbusevse" && $u1p3plp2aktiv == "1" ]]; then openwbDebugLog "MAIN" 0 "Pause nach Umschaltung: ${u1p3ppause}s" @@ -24,6 +27,9 @@ if [[ "$1" == "1" ]]; then if [[ $lastmanagement == 1 && $evsecons1 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep2ip -m "1" fi + if [[ $lastmanagement == 1 && $evsecons1 == "goe" ]]; then + sudo python runs/u1p3pgoe.py -a $goeiplp2 -p 1 + fi # chargepoint 3 if [[ $lastmanagements2 == 1 && $evsecons2 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep3ip -m "1" @@ -31,6 +37,9 @@ if [[ "$1" == "1" ]]; then if [[ $lastmanagements2 == 1 && $evsecons2 == "ipevse" && $u1p3plp3aktiv == "1" ]]; then sudo python runs/u1p3premote.py -a $evseiplp3 -i $u1p3plp3id -p 1 -d $u1p3ppause fi + if [[ $lastmanagements2 == 1 && $evsecons2 == "goe" ]]; then + sudo python runs/u1p3pgoe.py -a $goeiplp3 -p 1 + fi # chargepoint 4 if [[ $lastmanagementlp4 == 1 && $evseconlp4 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep4ip -m "1" @@ -127,6 +136,15 @@ if [[ "$1" == "3" ]]; then if [[ $lastmanagementlp8 == 1 && $evseconlp8 == "ipevse" && $u1p3plp8aktiv == "1" ]]; then sudo python runs/u1p3premote.py -a $evseiplp8 -i $u1p3plp8id -p 3 -d $u1p3ppause fi + if [[ $evsecon == "goe" ]]; then + sudo python runs/u1p3pgoe.py -a $goeiplp1 -p 3 + fi + if [[ $lastmanagement == 1 && $evsecons1 == "goe" ]]; then + sudo python runs/u1p3pgoe.py -a $goeiplp2 -p 3 + fi + if [[ $lastmanagements2 == 1 && $evsecons2 == "goe" ]]; then + sudo python runs/u1p3pgoe.py -a $goeiplp3 -p 3 + fi echo 3 > ramdisk/u1p3pstat fi @@ -146,6 +164,11 @@ if [[ "$1" == "stop" ]]; then oldll=$( ramdisk/tmpllsoll fi + if [[ $evsecon == "goe" ]]; then + oldll=$( ramdisk/tmpllsoll + runs/set-current.sh 0 m + fi if [[ $lastmanagement == 1 && $evsecons1 == "daemon" ]]; then oldlls1=$( ramdisk/tmpllsolls1 @@ -156,11 +179,21 @@ if [[ "$1" == "stop" ]]; then echo $oldlls1 > ramdisk/tmpllsolls1 mosquitto_pub -r -t openWB/set/isss/Current -h $chargep2ip -m "0" fi + if [[ $lastmanagement == 1 && $evsecons1 == "goe" ]]; then + oldlls1=$( ramdisk/tmpllsolls1 + runs/set-current.sh 0 s1 + fi if [[ $lastmanagements2 == 1 && $evsecons2 == "extopenwb" ]]; then oldlls2=$( ramdisk/tmpllsolls2 mosquitto_pub -r -t openWB/set/isss/Current -h $chargep3ip -m "0" fi + if [[ $lastmanagements2 == 1 && $evsecons2 == "goe" ]]; then + oldlls2=$( ramdisk/tmpllsolls2 + runs/set-current.sh 0 s2 + fi if [[ $lastmanagementlp4 == 1 && $evseconlp4 == "extopenwb" ]]; then oldlllp4=$( ramdisk/tmpllsolllp4 @@ -252,6 +285,9 @@ if [[ "$1" == "start" ]]; then oldll=$( Date: Thu, 4 Nov 2021 08:11:59 +0100 Subject: [PATCH 10/66] 1phase-3phases switch for goe (HW V3) III --- runs/u1p3pgoe.py | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py index cb3bd9763..36ef04243 100644 --- a/runs/u1p3pgoe.py +++ b/runs/u1p3pgoe.py @@ -23,26 +23,24 @@ traceback.print_exc() exit(1) +# check whether fsp param exists => go-e charger has HW V3 and therefore 1to3 phase switch capability if ( "fsp" in status_goe): try: if(args.verbose): - print ("fsp before: %d"%(int(status_goe['fsp']))) + print ("Phaseneinstellung fsp vorher: %d"%(int(status_goe['fsp']))) + if ( args.phases == 1 and int(status_goe['fsp']) != 1): + set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=1', timeout = 5).json() + #Using API V2 the respective call would be /api/set?psm=1 + if (int(set_fsp_goe['fsp']) == 1 and args.verbose): + print ("Umschaltung auf 1 Phase erfolgreich: fsp=%d"%(int(set_fsp_goe['fsp']))) + if ( args.phases == 3 and int(status_goe['fsp']) != 0 ): + set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=0', timeout = 5).json() + #Using API V2 the respective call would be /api/set?psm=2 + if (int(set_fsp_goe['fsp']) == 0 and args.verbose): + print ("Umschaltung auf 3 Phasen erfolgreich: fsp=%d"%(int(set_fsp_goe['fsp']))) except: traceback.print_exc() exit(1) - if ( args.phases == 1 ): - set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=0', timeout = 5).json() - try: - if (int(set_fsp_goe['fsp']) == 0 and args.verbose): - print ("Switch to 1Phase succeeded: fsp=%d"%(int(set_fsp_goe['fsp']))) - except: - traceback.print_exc() - exit(1) - if ( args.phases == 3 ): - set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=1', timeout = 5).json() - try: - if (int(set_fsp_goe['fsp']) == 1 and args.verbose): - print ("Switch to 3Phases succeeded: fsp=%d"%(int(set_fsp_goe['fsp']))) - except: - traceback.print_exc() - exit(1) \ No newline at end of file +else : + if(args.verbose): + print ("Phasenumschaltung von go-e Charger nicht unterstuetzt (V2 HW ?!)") \ No newline at end of file From 1d7e751849b117f30e9cfb3cee0cce8434f34349 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Thu, 4 Nov 2021 11:17:07 +0100 Subject: [PATCH 11/66] u1p3pcheck.sh - commented out goe start,stop,slowstart - could raise problems on older goe chargers which don't support phase switch - goe handles phase switch automatically (stop,start,...) --- runs/u1p3pcheck.sh | 70 +++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/runs/u1p3pcheck.sh b/runs/u1p3pcheck.sh index 2eeb4686f..6d32751d3 100755 --- a/runs/u1p3pcheck.sh +++ b/runs/u1p3pcheck.sh @@ -164,11 +164,11 @@ if [[ "$1" == "stop" ]]; then oldll=$( ramdisk/tmpllsoll fi - if [[ $evsecon == "goe" ]]; then - oldll=$( ramdisk/tmpllsoll - runs/set-current.sh 0 m - fi + #if [[ $evsecon == "goe" ]]; then + # oldll=$( ramdisk/tmpllsoll + # runs/set-current.sh 0 m + #fi if [[ $lastmanagement == 1 && $evsecons1 == "daemon" ]]; then oldlls1=$( ramdisk/tmpllsolls1 @@ -179,21 +179,21 @@ if [[ "$1" == "stop" ]]; then echo $oldlls1 > ramdisk/tmpllsolls1 mosquitto_pub -r -t openWB/set/isss/Current -h $chargep2ip -m "0" fi - if [[ $lastmanagement == 1 && $evsecons1 == "goe" ]]; then - oldlls1=$( ramdisk/tmpllsolls1 - runs/set-current.sh 0 s1 - fi + #if [[ $lastmanagement == 1 && $evsecons1 == "goe" ]]; then + # oldlls1=$( ramdisk/tmpllsolls1 + # runs/set-current.sh 0 s1 + #fi if [[ $lastmanagements2 == 1 && $evsecons2 == "extopenwb" ]]; then oldlls2=$( ramdisk/tmpllsolls2 mosquitto_pub -r -t openWB/set/isss/Current -h $chargep3ip -m "0" fi - if [[ $lastmanagements2 == 1 && $evsecons2 == "goe" ]]; then - oldlls2=$( ramdisk/tmpllsolls2 - runs/set-current.sh 0 s2 - fi + #if [[ $lastmanagements2 == 1 && $evsecons2 == "goe" ]]; then + # oldlls2=$( ramdisk/tmpllsolls2 + # runs/set-current.sh 0 s2 + #fi if [[ $lastmanagementlp4 == 1 && $evseconlp4 == "extopenwb" ]]; then oldlllp4=$( ramdisk/tmpllsolllp4 @@ -285,9 +285,9 @@ if [[ "$1" == "start" ]]; then oldll=$( Date: Fri, 5 Nov 2021 13:13:11 +0100 Subject: [PATCH 12/66] goe: lower ampere to min ampere PV on switching from 1 to 3 phases --- runs/u1p3pcheck.sh | 6 +++--- runs/u1p3pgoe.py | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/runs/u1p3pcheck.sh b/runs/u1p3pcheck.sh index 6d32751d3..4476c498f 100755 --- a/runs/u1p3pcheck.sh +++ b/runs/u1p3pcheck.sh @@ -137,13 +137,13 @@ if [[ "$1" == "3" ]]; then sudo python runs/u1p3premote.py -a $evseiplp8 -i $u1p3plp8id -p 3 -d $u1p3ppause fi if [[ $evsecon == "goe" ]]; then - sudo python runs/u1p3pgoe.py -a $goeiplp1 -p 3 + sudo python runs/u1p3pgoe.py -a $goeiplp1 -p 3 -m $minimalapv fi if [[ $lastmanagement == 1 && $evsecons1 == "goe" ]]; then - sudo python runs/u1p3pgoe.py -a $goeiplp2 -p 3 + sudo python runs/u1p3pgoe.py -a $goeiplp2 -p 3 -m $minimalapv fi if [[ $lastmanagements2 == 1 && $evsecons2 == "goe" ]]; then - sudo python runs/u1p3pgoe.py -a $goeiplp3 -p 3 + sudo python runs/u1p3pgoe.py -a $goeiplp3 -p 3 -m $minimalapv fi echo 3 > ramdisk/u1p3pstat fi diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py index 36ef04243..e68f22461 100644 --- a/runs/u1p3pgoe.py +++ b/runs/u1p3pgoe.py @@ -9,6 +9,7 @@ parser = argparse.ArgumentParser() parser.add_argument("-a", "--address", required=True, type=str, help="ip address") parser.add_argument("-p", "--phases", required=True, type=int, choices=[1, 3], help="phases to activate") +parser.add_argument("-m", "--minampere", required=False, type=int, help="minimum ampere") parser.add_argument("-v", "--verbose", required=False, action="store_true", help="verbose debug output") args = parser.parse_args() @@ -21,7 +22,7 @@ print ("go-e serial number: %s"%(status_goe['sse'])) except: traceback.print_exc() - exit(1) + exit(1) # check whether fsp param exists => go-e charger has HW V3 and therefore 1to3 phase switch capability if ( "fsp" in status_goe): @@ -38,6 +39,11 @@ #Using API V2 the respective call would be /api/set?psm=2 if (int(set_fsp_goe['fsp']) == 0 and args.verbose): print ("Umschaltung auf 3 Phasen erfolgreich: fsp=%d"%(int(set_fsp_goe['fsp']))) + if (args.minampere and args.minampere >= 5 and args.minampere <= 32): + set_amx_goe = requests.get('http://'+args.address+'/mqtt?payload=amx='+str(args.minampere), timeout = 5).json() + #Using API V2 the respective call would be /api/set?ama=args.minampere + if (int(set_amx_goe['amx']) == args.minampere and args.verbose): + print ("Setzen von MinAmpere erfolgreich: amx=%d"%(int(set_amx_goe['amx']))) except: traceback.print_exc() exit(1) From 77d48d094e5ea87159469722b8db7115c698f69f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 6 Nov 2021 11:51:57 +0100 Subject: [PATCH 13/66] goe u1p3p: set minampere BEFORE fsp cause switching phases takes some seconds and inbetween no amx setting is allowed --- runs/u1p3pgoe.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py index e68f22461..18f5d9640 100644 --- a/runs/u1p3pgoe.py +++ b/runs/u1p3pgoe.py @@ -35,15 +35,15 @@ if (int(set_fsp_goe['fsp']) == 1 and args.verbose): print ("Umschaltung auf 1 Phase erfolgreich: fsp=%d"%(int(set_fsp_goe['fsp']))) if ( args.phases == 3 and int(status_goe['fsp']) != 0 ): - set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=0', timeout = 5).json() - #Using API V2 the respective call would be /api/set?psm=2 - if (int(set_fsp_goe['fsp']) == 0 and args.verbose): - print ("Umschaltung auf 3 Phasen erfolgreich: fsp=%d"%(int(set_fsp_goe['fsp']))) if (args.minampere and args.minampere >= 5 and args.minampere <= 32): set_amx_goe = requests.get('http://'+args.address+'/mqtt?payload=amx='+str(args.minampere), timeout = 5).json() #Using API V2 the respective call would be /api/set?ama=args.minampere if (int(set_amx_goe['amx']) == args.minampere and args.verbose): print ("Setzen von MinAmpere erfolgreich: amx=%d"%(int(set_amx_goe['amx']))) + set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=0', timeout = 5).json() + #Using API V2 the respective call would be /api/set?psm=2 + if (int(set_fsp_goe['fsp']) == 0 and args.verbose): + print ("Umschaltung auf 3 Phasen erfolgreich: fsp=%d"%(int(set_fsp_goe['fsp']))) except: traceback.print_exc() exit(1) From 10053d90764e4ab3e84c87b95fdf5a37658e5500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 6 Nov 2021 12:49:44 +0100 Subject: [PATCH 14/66] u1p3pgoe.py - PEP8 corrections --- runs/u1p3pgoe.py | 66 ++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py index 18f5d9640..636e6ab26 100644 --- a/runs/u1p3pgoe.py +++ b/runs/u1p3pgoe.py @@ -14,39 +14,39 @@ args = parser.parse_args() if(args.verbose): - print("Go-e mit IP %s Umschaltung auf %d Phasen"%(args.address, args.phases)) - -status_goe = requests.get('http://'+args.address+'/status', timeout = 5).json() + print("Go-e mit IP %s Umschaltung auf %d Phasen" % (args.address, args.phases)) + +status_goe = requests.get('http://'+args.address+'/status', timeout=5).json() if(args.verbose): - try: - print ("go-e serial number: %s"%(status_goe['sse'])) - except: - traceback.print_exc() - exit(1) + try: + print("go-e serial number: %s" % (status_goe['sse'])) + except: + traceback.print_exc() + exit(1) # check whether fsp param exists => go-e charger has HW V3 and therefore 1to3 phase switch capability -if ( "fsp" in status_goe): - try: - if(args.verbose): - print ("Phaseneinstellung fsp vorher: %d"%(int(status_goe['fsp']))) - if ( args.phases == 1 and int(status_goe['fsp']) != 1): - set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=1', timeout = 5).json() - #Using API V2 the respective call would be /api/set?psm=1 - if (int(set_fsp_goe['fsp']) == 1 and args.verbose): - print ("Umschaltung auf 1 Phase erfolgreich: fsp=%d"%(int(set_fsp_goe['fsp']))) - if ( args.phases == 3 and int(status_goe['fsp']) != 0 ): - if (args.minampere and args.minampere >= 5 and args.minampere <= 32): - set_amx_goe = requests.get('http://'+args.address+'/mqtt?payload=amx='+str(args.minampere), timeout = 5).json() - #Using API V2 the respective call would be /api/set?ama=args.minampere - if (int(set_amx_goe['amx']) == args.minampere and args.verbose): - print ("Setzen von MinAmpere erfolgreich: amx=%d"%(int(set_amx_goe['amx']))) - set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=0', timeout = 5).json() - #Using API V2 the respective call would be /api/set?psm=2 - if (int(set_fsp_goe['fsp']) == 0 and args.verbose): - print ("Umschaltung auf 3 Phasen erfolgreich: fsp=%d"%(int(set_fsp_goe['fsp']))) - except: - traceback.print_exc() - exit(1) -else : - if(args.verbose): - print ("Phasenumschaltung von go-e Charger nicht unterstuetzt (V2 HW ?!)") \ No newline at end of file +if ("fsp" in status_goe): + try: + if(args.verbose): + print("Phaseneinstellung fsp vorher: %d" % (int(status_goe['fsp']))) + if (args.phases == 1 and int(status_goe['fsp']) != 1): + set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=1', timeout=5).json() + # Using API V2 the respective call would be /api/set?psm=1 + if (int(set_fsp_goe['fsp']) == 1 and args.verbose): + print("Umschaltung auf 1 Phase erfolgreich: fsp=%d" % (int(set_fsp_goe['fsp']))) + if (args.phases == 3 and int(status_goe['fsp']) != 0): + if (args.minampere and args.minampere >= 5 and args.minampere <= 32): + set_amx_goe = requests.get('http://'+args.address+'/mqtt?payload=amx='+str(args.minampere), timeout=5).json() + # Using API V2 the respective call would be /api/set?ama=args.minampere + if (int(set_amx_goe['amx']) == args.minampere and args.verbose): + print("Setzen von MinAmpere erfolgreich: amx=%d" % (int(set_amx_goe['amx']))) + set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=0', timeout=5).json() + # Using API V2 the respective call would be /api/set?psm=2 + if (int(set_fsp_goe['fsp']) == 0 and args.verbose): + print("Umschaltung auf 3 Phasen erfolgreich: fsp=%d" % (int(set_fsp_goe['fsp']))) + except: + traceback.print_exc() + exit(1) +else: + if(args.verbose): + print("Phasenumschaltung von go-e Charger nicht unterstuetzt (V2 HW ?!)") From 7d6eab171950919a2ce4813c94afa826cc56d037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Tue, 9 Nov 2021 21:34:59 +0100 Subject: [PATCH 15/66] goe: use new api V2 on main.sh --- modules/goelp2/main.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/goelp2/main.sh b/modules/goelp2/main.sh index e830d6e97..d485acdfb 100755 --- a/modules/goelp2/main.sh +++ b/modules/goelp2/main.sh @@ -2,7 +2,7 @@ re='^-?[0-9]+$' rekwh='^[-+]?[0-9]+\.?[0-9]*$' -output=$(curl --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/status) +output=$(curl --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/api/status) if [[ $? == "0" ]] ; then watt=$(echo $output | jq -r '.nrg[11]') watt=$(echo "scale=0;$watt * 10 /1" |bc) @@ -37,11 +37,11 @@ if [[ $? == "0" ]] ; then echo $llv3 > /var/www/html/openWB/ramdisk/llvs13 fi llkwh=$(echo $output | jq -r '.eto') - llkwh=$(echo "scale=3;$llkwh / 10" |bc) + llkwh=$(echo "scale=3;$llkwh / 1000" |bc) if [[ $llkwh =~ $rekwh ]] ; then echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs1 fi - rfid=$(echo $output | jq -r '.uby') + rfid=$(echo $output | jq -r '.trx') oldrfid=$( /var/www/html/openWB/ramdisk/readtag @@ -52,10 +52,10 @@ if [[ $? == "0" ]] ; then #car status 3 Warte auf Fahrzeug #car status 4 Ladung beendet, Fahrzeug verbunden car=$(echo $output | jq -r '.car') - if [[ $car == "1" ]] ; then - echo 0 > /var/www/html/openWB/ramdisk/plugstats1 - else + if [[ $car == "2" ]] || [[ $car == "3" ]] || [[ $car == "4" ]] ; then echo 1 > /var/www/html/openWB/ramdisk/plugstats1 + else + echo 0 > /var/www/html/openWB/ramdisk/plugstats1 fi if [[ $car == "2" ]] ; then echo 1 > /var/www/html/openWB/ramdisk/chargestats1 From d56807fcffbc0def2ba1823568743007f4ef2ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Tue, 9 Nov 2021 21:51:12 +0100 Subject: [PATCH 16/66] u1p3pgoe.py PEP8 fixes --- runs/u1p3pgoe.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py index 636e6ab26..5a2f43f97 100644 --- a/runs/u1p3pgoe.py +++ b/runs/u1p3pgoe.py @@ -16,11 +16,16 @@ if(args.verbose): print("Go-e mit IP %s Umschaltung auf %d Phasen" % (args.address, args.phases)) -status_goe = requests.get('http://'+args.address+'/status', timeout=5).json() +try: + status_goe = requests.get('http://'+args.address+'/status', timeout=5).json() +except requests.exceptions.ConnectionError: + print("Connection to go-e failed") + exit(1) + if(args.verbose): try: print("go-e serial number: %s" % (status_goe['sse'])) - except: + except KeyError: traceback.print_exc() exit(1) From 9d4fa559df35403336ac235770258070f0ab64a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Fri, 12 Nov 2021 15:31:21 +0100 Subject: [PATCH 17/66] goe: automatically select using API V1 or V2 --- modules/goelp2/main.sh | 184 ++++++++++++++++++++++++++++------------- 1 file changed, 126 insertions(+), 58 deletions(-) diff --git a/modules/goelp2/main.sh b/modules/goelp2/main.sh index d485acdfb..df0332194 100755 --- a/modules/goelp2/main.sh +++ b/modules/goelp2/main.sh @@ -2,64 +2,132 @@ re='^-?[0-9]+$' rekwh='^[-+]?[0-9]+\.?[0-9]*$' -output=$(curl --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/api/status) +output=$(curl --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/status) if [[ $? == "0" ]] ; then - watt=$(echo $output | jq -r '.nrg[11]') - watt=$(echo "scale=0;$watt * 10 /1" |bc) - if [[ $watt =~ $re ]] ; then - echo $watt > /var/www/html/openWB/ramdisk/llaktuells1 - fi - lla1=$(echo $output | jq -r '.nrg[4]') - lla1=$(echo "scale=0;$lla1 / 10" |bc) - if [[ $lla1 =~ $re ]] ; then - echo $lla1 > /var/www/html/openWB/ramdisk/llas11 - fi - lla2=$(echo $output | jq -r '.nrg[5]') - lla2=$(echo "scale=0;$lla2 / 10" |bc) - if [[ $lla2 =~ $re ]] ; then - echo $lla2 > /var/www/html/openWB/ramdisk/llas12 - fi - lla3=$(echo $output | jq -r '.nrg[6]') - lla3=$(echo "scale=0;$lla3 / 10" |bc) - if [[ $lla3 =~ $re ]] ; then - echo $lla3 > /var/www/html/openWB/ramdisk/llas13 - fi - llv1=$(echo $output | jq -r '.nrg[0]') - if [[ $llv1 =~ $re ]] ; then - echo $llv1 > /var/www/html/openWB/ramdisk/llvs11 - fi - llv2=$(echo $output | jq -r '.nrg[1]') - if [[ $llv2 =~ $re ]] ; then - echo $llv2 > /var/www/html/openWB/ramdisk/llvs12 - fi - llv3=$(echo $output | jq -r '.nrg[2]') - if [[ $llv3 =~ $re ]] ; then - echo $llv3 > /var/www/html/openWB/ramdisk/llvs13 - fi - llkwh=$(echo $output | jq -r '.eto') - llkwh=$(echo "scale=3;$llkwh / 1000" |bc) - if [[ $llkwh =~ $rekwh ]] ; then - echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs1 - fi - rfid=$(echo $output | jq -r '.trx') - oldrfid=$( /var/www/html/openWB/ramdisk/readtag - echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp2rfid - fi - #car status 1 Ladestation bereit, kein Auto - #car status 2 Auto lädt - #car status 3 Warte auf Fahrzeug - #car status 4 Ladung beendet, Fahrzeug verbunden - car=$(echo $output | jq -r '.car') - if [[ $car == "2" ]] || [[ $car == "3" ]] || [[ $car == "4" ]] ; then - echo 1 > /var/www/html/openWB/ramdisk/plugstats1 - else - echo 0 > /var/www/html/openWB/ramdisk/plugstats1 - fi - if [[ $car == "2" ]] ; then - echo 1 > /var/www/html/openWB/ramdisk/chargestats1 - else - echo 0 > /var/www/html/openWB/ramdisk/chargestats1 + #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 + fsp=$(echo $output | jq -r '.fsp') + if [[ ! $fsp =~ $re ]] ; then + openwbDebugLog "RFID" 0 "alte API: $fsp" + watt=$(echo $output | jq -r '.nrg[11]') + watt=$(echo "scale=0;$watt * 10 /1" |bc) + if [[ $watt =~ $re ]] ; then + echo $watt > /var/www/html/openWB/ramdisk/llaktuells1 + fi + lla1=$(echo $output | jq -r '.nrg[4]') + lla1=$(echo "scale=0;$lla1 / 10" |bc) + if [[ $lla1 =~ $re ]] ; then + echo $lla1 > /var/www/html/openWB/ramdisk/llas11 + fi + lla2=$(echo $output | jq -r '.nrg[5]') + lla2=$(echo "scale=0;$lla2 / 10" |bc) + if [[ $lla2 =~ $re ]] ; then + echo $lla2 > /var/www/html/openWB/ramdisk/llas12 + fi + lla3=$(echo $output | jq -r '.nrg[6]') + lla3=$(echo "scale=0;$lla3 / 10" |bc) + if [[ $lla3 =~ $re ]] ; then + echo $lla3 > /var/www/html/openWB/ramdisk/llas13 + fi + llv1=$(echo $output | jq -r '.nrg[0]') + if [[ $llv1 =~ $re ]] ; then + echo $llv1 > /var/www/html/openWB/ramdisk/llvs11 + fi + llv2=$(echo $output | jq -r '.nrg[1]') + if [[ $llv2 =~ $re ]] ; then + echo $llv2 > /var/www/html/openWB/ramdisk/llvs12 + fi + llv3=$(echo $output | jq -r '.nrg[2]') + if [[ $llv3 =~ $re ]] ; then + echo $llv3 > /var/www/html/openWB/ramdisk/llvs13 + fi + llkwh=$(echo $output | jq -r '.eto') + llkwh=$(echo "scale=3;$llkwh / 10" |bc) + if [[ $llkwh =~ $rekwh ]] ; then + echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs1 + fi + rfid=$(echo $output | jq -r '.uby') + oldrfid=$( /var/www/html/openWB/ramdisk/readtag + echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp2rfid + fi + #car status 1 Ladestation bereit, kein Auto + #car status 2 Auto lädt + #car status 3 Warte auf Fahrzeug + #car status 4 Ladung beendet, Fahrzeug verbunden + car=$(echo $output | jq -r '.car') + if [[ $car == "1" ]] ; then + echo 0 > /var/www/html/openWB/ramdisk/plugstats1 + else + echo 1 > /var/www/html/openWB/ramdisk/plugstats1 + fi + if [[ $car == "2" ]] ; then + echo 1 > /var/www/html/openWB/ramdisk/chargestats1 + else + echo 0 > /var/www/html/openWB/ramdisk/chargestats1 + fi + else + openwbDebugLog "RFID" 0 "neue API: $fsp" + output=$(curl --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/api/status) + if [[ $? == "0" ]] ; then + watt=$(echo $output | jq -r '.nrg[11]') + watt=$(echo "scale=0;$watt * 10 /1" |bc) + if [[ $watt =~ $re ]] ; then + echo $watt > /var/www/html/openWB/ramdisk/llaktuells1 + fi + lla1=$(echo $output | jq -r '.nrg[4]') + lla1=$(echo "scale=0;$lla1 / 10" |bc) + if [[ $lla1 =~ $re ]] ; then + echo $lla1 > /var/www/html/openWB/ramdisk/llas11 + fi + lla2=$(echo $output | jq -r '.nrg[5]') + lla2=$(echo "scale=0;$lla2 / 10" |bc) + if [[ $lla2 =~ $re ]] ; then + echo $lla2 > /var/www/html/openWB/ramdisk/llas12 + fi + lla3=$(echo $output | jq -r '.nrg[6]') + lla3=$(echo "scale=0;$lla3 / 10" |bc) + if [[ $lla3 =~ $re ]] ; then + echo $lla3 > /var/www/html/openWB/ramdisk/llas13 + fi + llv1=$(echo $output | jq -r '.nrg[0]') + if [[ $llv1 =~ $re ]] ; then + echo $llv1 > /var/www/html/openWB/ramdisk/llvs11 + fi + llv2=$(echo $output | jq -r '.nrg[1]') + if [[ $llv2 =~ $re ]] ; then + echo $llv2 > /var/www/html/openWB/ramdisk/llvs12 + fi + llv3=$(echo $output | jq -r '.nrg[2]') + if [[ $llv3 =~ $re ]] ; then + echo $llv3 > /var/www/html/openWB/ramdisk/llvs13 + fi + llkwh=$(echo $output | jq -r '.eto') + llkwh=$(echo "scale=3;$llkwh / 1000" |bc) + if [[ $llkwh =~ $rekwh ]] ; then + echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs1 + fi + rfid=$(echo $output | jq -r '.trx') + oldrfid=$( /var/www/html/openWB/ramdisk/readtag + echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp2rfid + fi + #car status 1 Ladestation bereit, kein Auto + #car status 2 Auto lädt + #car status 3 Warte auf Fahrzeug + #car status 4 Ladung beendet, Fahrzeug verbunden + car=$(echo $output | jq -r '.car') + if [[ $car == "2" ]] || [[ $car == "3" ]] || [[ $car == "4" ]] ; then + echo 1 > /var/www/html/openWB/ramdisk/plugstats1 + else + echo 0 > /var/www/html/openWB/ramdisk/plugstats1 + fi + if [[ $car == "2" ]] ; then + echo 1 > /var/www/html/openWB/ramdisk/chargestats1 + else + echo 0 > /var/www/html/openWB/ramdisk/chargestats1 + fi + fi fi fi \ No newline at end of file From 765b6b71354fa2c4655587e69e374c19cf3ba427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Fri, 12 Nov 2021 15:51:45 +0100 Subject: [PATCH 18/66] goe: fixes for API V2 --- modules/goelp2/main.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/goelp2/main.sh b/modules/goelp2/main.sh index df0332194..a54c920b8 100755 --- a/modules/goelp2/main.sh +++ b/modules/goelp2/main.sh @@ -71,23 +71,23 @@ if [[ $? == "0" ]] ; then output=$(curl --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/api/status) if [[ $? == "0" ]] ; then watt=$(echo $output | jq -r '.nrg[11]') - watt=$(echo "scale=0;$watt * 10 /1" |bc) + watt=$(echo "scale=0;$watt /1" |bc) if [[ $watt =~ $re ]] ; then echo $watt > /var/www/html/openWB/ramdisk/llaktuells1 fi lla1=$(echo $output | jq -r '.nrg[4]') - lla1=$(echo "scale=0;$lla1 / 10" |bc) - if [[ $lla1 =~ $re ]] ; then + lla1=$(echo "scale=0;$lla1" |bc) + if [[ $lla1 =~ $rekwh ]] ; then echo $lla1 > /var/www/html/openWB/ramdisk/llas11 fi lla2=$(echo $output | jq -r '.nrg[5]') - lla2=$(echo "scale=0;$lla2 / 10" |bc) - if [[ $lla2 =~ $re ]] ; then + lla2=$(echo "scale=0;$lla2" |bc) + if [[ $lla2 =~ $rekwh ]] ; then echo $lla2 > /var/www/html/openWB/ramdisk/llas12 fi lla3=$(echo $output | jq -r '.nrg[6]') - lla3=$(echo "scale=0;$lla3 / 10" |bc) - if [[ $lla3 =~ $re ]] ; then + lla3=$(echo "scale=0;$lla3" |bc) + if [[ $lla3 =~ $rekwh ]] ; then echo $lla3 > /var/www/html/openWB/ramdisk/llas13 fi llv1=$(echo $output | jq -r '.nrg[0]') From ec4013ac20f64bcabd0101d0421b4e18edf96a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Fri, 12 Nov 2021 16:11:15 +0100 Subject: [PATCH 19/66] goe: remove debug messages --- modules/goelp2/main.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/goelp2/main.sh b/modules/goelp2/main.sh index a54c920b8..a6492efbf 100755 --- a/modules/goelp2/main.sh +++ b/modules/goelp2/main.sh @@ -7,7 +7,6 @@ if [[ $? == "0" ]] ; then #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 fsp=$(echo $output | jq -r '.fsp') if [[ ! $fsp =~ $re ]] ; then - openwbDebugLog "RFID" 0 "alte API: $fsp" watt=$(echo $output | jq -r '.nrg[11]') watt=$(echo "scale=0;$watt * 10 /1" |bc) if [[ $watt =~ $re ]] ; then @@ -67,7 +66,6 @@ if [[ $? == "0" ]] ; then echo 0 > /var/www/html/openWB/ramdisk/chargestats1 fi else - openwbDebugLog "RFID" 0 "neue API: $fsp" output=$(curl --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/api/status) if [[ $? == "0" ]] ; then watt=$(echo $output | jq -r '.nrg[11]') From 46a534e77372c8bc46eda7861477403722c3f879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Fri, 12 Nov 2021 16:19:28 +0100 Subject: [PATCH 20/66] goe: APIv2 set rfidtag to 0 if null from goE (which means no transaction) --- modules/goelp2/main.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/goelp2/main.sh b/modules/goelp2/main.sh index a6492efbf..80c9ac97c 100755 --- a/modules/goelp2/main.sh +++ b/modules/goelp2/main.sh @@ -106,8 +106,12 @@ if [[ $? == "0" ]] ; then echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs1 fi rfid=$(echo $output | jq -r '.trx') + if [[ $rfid == "null" ]] ; then + rfid="0" + fi oldrfid=$( /var/www/html/openWB/ramdisk/readtag echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp2rfid fi From 65eff0634630699103bfc063572877a7ee0fd477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Fri, 12 Nov 2021 16:20:22 +0100 Subject: [PATCH 21/66] goe: remove debug --- modules/goelp2/main.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/goelp2/main.sh b/modules/goelp2/main.sh index 80c9ac97c..592a0c0f7 100755 --- a/modules/goelp2/main.sh +++ b/modules/goelp2/main.sh @@ -111,7 +111,6 @@ if [[ $? == "0" ]] ; then fi oldrfid=$( /var/www/html/openWB/ramdisk/readtag echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp2rfid fi From f6531902dc6802f85a4597f377b2e9517be6142a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Fri, 12 Nov 2021 16:48:29 +0100 Subject: [PATCH 22/66] goe: autodetect whether APIv2 is useable and use it if so --- goecheck.sh | 58 +++++++++++++++++++++++++++++++-------------- runs/set-current.sh | 53 ++++++++++++++++++++++++++++------------- 2 files changed, 76 insertions(+), 35 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index 53b4dcbbd..e9410d91c 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -33,26 +33,48 @@ goecheck(){ if [[ $evsecons1 == "goe" ]]; then output=$(curl --connect-timeout 1 -s http://$goeiplp2/status) if [[ $? == "0" ]] ; then - state=$(echo $output | jq -r '.alw') - if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss1"; then - lp2enabled=$( /dev/null + #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 + fsp=$(echo $output | jq -r '.fsp') + if [[ ! $fsp =~ $re ]] ; then + state=$(echo $output | jq -r '.alw') + if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss1"; then + lp2enabled=$( /dev/null + fi fi - fi - if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatuss1"; then - if ((state == "1")) ; then - curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/mqtt?payload=alw=0 > /dev/null + if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatuss1"; then + if ((state == "1")) ; then + curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/mqtt?payload=alw=0 > /dev/null + fi fi - fi - fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") - oldcurrent=$(echo $output | jq -r '.amp') - current=$(= 40)) ; then - curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/mqtt?payload=amx=$current > /dev/null - else - curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/mqtt?payload=amp=$current > /dev/null + fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") + oldcurrent=$(echo $output | jq -r '.amp') + current=$(= 40)) ; then + curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/mqtt?payload=amx=$current > /dev/null + else + curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/mqtt?payload=amp=$current > /dev/null + fi + fi + else + state=$(echo $output | jq -r '.frc') + if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss1"; then + lp2enabled=$( /dev/null + fi + fi + if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatuss1"; then + if ((state == "2")) ; then + curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/api/set?frc=1 > /dev/null + fi + fi + oldcurrent=$(echo $output | jq -r '.amp') + current=$( /dev/null fi fi fi diff --git a/runs/set-current.sh b/runs/set-current.sh index f6ff73a95..598bd8de6 100755 --- a/runs/set-current.sh +++ b/runs/set-current.sh @@ -187,25 +187,44 @@ function setChargingCurrenthttp () { # 3: goeiplp1 function setChargingCurrentgoe () { if [[ $evsecon == "goe" ]]; then - if [[ $current -eq 0 ]]; then - output=$(curl --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/status) - state=$(echo $output | jq -r '.alw') - if ((state == "1")) ; then - curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=alw=0 > /dev/null + output=$(curl --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/status) + #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 + fsp=$(echo $output | jq -r '.fsp') + if [[ ! $fsp =~ $re ]] ; then + if [[ $current -eq 0 ]]; then + state=$(echo $output | jq -r '.alw') + if ((state == "1")) ; then + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=alw=0 > /dev/null + fi + else + fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") + state=$(echo $output | jq -r '.alw') + if ((state == "0")) ; then + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=alw=1 > /dev/null + fi + oldgoecurrent=$(echo $output | jq -r '.amp') + if (( oldgoecurrent != $current )) ; then + if (($fwv >= 40)) ; then + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=amx=$current > /dev/null + else + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=amp=$current > /dev/null + fi + fi fi else - output=$(curl --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/status) - fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") - state=$(echo $output | jq -r '.alw') - if ((state == "0")) ; then - curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=alw=1 > /dev/null - fi - oldgoecurrent=$(echo $output | jq -r '.amp') - if (( oldgoecurrent != $current )) ; then - if (($fwv >= 40)) ; then - curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=amx=$current > /dev/null - else - curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=amp=$current > /dev/null + if [[ $current -eq 0 ]]; then + state=$(echo $output | jq -r '.frc') + if ((state == "2")) ; then + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?frc=1 > /dev/null + fi + else + state=$(echo $output | jq -r '.frc') + if ((state == "1")) ; then + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?frc=2 > /dev/null + fi + oldgoecurrent=$(echo $output | jq -r '.amp') + if (( oldgoecurrent != $current )) ; then + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?amp=$current > /dev/null fi fi fi From 266fc3e17e4923ca08bc1c9400c781a275b45957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 13 Nov 2021 14:36:05 +0100 Subject: [PATCH 23/66] go-e: fixing new APIv2 --- goecheck.sh | 9 +++++++-- runs/set-current.sh | 13 +++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index e9410d91c..aaea109db 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -36,6 +36,7 @@ goecheck(){ #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 fsp=$(echo $output | jq -r '.fsp') if [[ ! $fsp =~ $re ]] ; then + openwbDebugLog "MAIN" 0 "GoeCheck OldApi: $fsp" state=$(echo $output | jq -r '.alw') if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss1"; then lp2enabled=$( /dev/null + openwbDebugLog "MAIN" 0 "GoeCheck enabling Go-e" + curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/api/set?frc=0 > /dev/null fi fi if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatuss1"; then - if ((state == "2")) ; then + if ((state == "0")) ; then + openwbDebugLog "MAIN" 0 "GoeCheck disabling Go-e" curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/api/set?frc=1 > /dev/null fi fi oldcurrent=$(echo $output | jq -r '.amp') current=$( /dev/null fi fi diff --git a/runs/set-current.sh b/runs/set-current.sh index 598bd8de6..462868588 100755 --- a/runs/set-current.sh +++ b/runs/set-current.sh @@ -191,6 +191,7 @@ function setChargingCurrentgoe () { #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 fsp=$(echo $output | jq -r '.fsp') if [[ ! $fsp =~ $re ]] ; then + openwbDebugLog "MAIN" 0 "set-current OldApi: $fsp" if [[ $current -eq 0 ]]; then state=$(echo $output | jq -r '.alw') if ((state == "1")) ; then @@ -212,18 +213,22 @@ function setChargingCurrentgoe () { fi fi else + output=$(curl --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/status) + openwbDebugLog "MAIN" 0 "set-current NewApi: $fsp" + state=$(echo $output | jq -r '.frc') if [[ $current -eq 0 ]]; then - state=$(echo $output | jq -r '.frc') - if ((state == "2")) ; then + if ((state == "0")) ; then + openwbDebugLog "MAIN" 0 "set-current disabling Go-e" curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?frc=1 > /dev/null fi else - state=$(echo $output | jq -r '.frc') if ((state == "1")) ; then - curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?frc=2 > /dev/null + openwbDebugLog "MAIN" 0 "set-current enabling Go-e" + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?frc=0 > /dev/null fi oldgoecurrent=$(echo $output | jq -r '.amp') if (( oldgoecurrent != $current )) ; then + openwbDebugLog "MAIN" 0 "set-current amp=$current" curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?amp=$current > /dev/null fi fi From 0ccaeb854fffe980e9eb581ba1ea5cc33a99c006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 13 Nov 2021 15:13:25 +0100 Subject: [PATCH 24/66] goe 1p3p: use new APIv2 for setting values --- runs/u1p3pgoe.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py index 636e6ab26..07d60e656 100644 --- a/runs/u1p3pgoe.py +++ b/runs/u1p3pgoe.py @@ -30,18 +30,15 @@ if(args.verbose): print("Phaseneinstellung fsp vorher: %d" % (int(status_goe['fsp']))) if (args.phases == 1 and int(status_goe['fsp']) != 1): - set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=1', timeout=5).json() - # Using API V2 the respective call would be /api/set?psm=1 + set_fsp_goe = requests.get('http://'+args.address+'/api/set?psm=1', timeout=5).json() if (int(set_fsp_goe['fsp']) == 1 and args.verbose): print("Umschaltung auf 1 Phase erfolgreich: fsp=%d" % (int(set_fsp_goe['fsp']))) if (args.phases == 3 and int(status_goe['fsp']) != 0): if (args.minampere and args.minampere >= 5 and args.minampere <= 32): - set_amx_goe = requests.get('http://'+args.address+'/mqtt?payload=amx='+str(args.minampere), timeout=5).json() - # Using API V2 the respective call would be /api/set?ama=args.minampere + set_amx_goe = requests.get('http://'+args.address+'/api/set?amp='+str(args.minampere), timeout=5).json() if (int(set_amx_goe['amx']) == args.minampere and args.verbose): print("Setzen von MinAmpere erfolgreich: amx=%d" % (int(set_amx_goe['amx']))) - set_fsp_goe = requests.get('http://'+args.address+'/mqtt?payload=fsp=0', timeout=5).json() - # Using API V2 the respective call would be /api/set?psm=2 + set_fsp_goe = requests.get('http://'+args.address+'/api/set?psm=2', timeout=5).json() if (int(set_fsp_goe['fsp']) == 0 and args.verbose): print("Umschaltung auf 3 Phasen erfolgreich: fsp=%d" % (int(set_fsp_goe['fsp']))) except: From 32e3e4c9f4bf5f04dd5635c42148113b615a922c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 13 Nov 2021 15:59:17 +0100 Subject: [PATCH 25/66] goe: APIv2 remove debug messages --- goecheck.sh | 4 ---- runs/set-current.sh | 5 ----- 2 files changed, 9 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index aaea109db..dbb5ff678 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -36,7 +36,6 @@ goecheck(){ #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 fsp=$(echo $output | jq -r '.fsp') if [[ ! $fsp =~ $re ]] ; then - openwbDebugLog "MAIN" 0 "GoeCheck OldApi: $fsp" state=$(echo $output | jq -r '.alw') if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss1"; then lp2enabled=$( /dev/null fi fi if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatuss1"; then if ((state == "0")) ; then - openwbDebugLog "MAIN" 0 "GoeCheck disabling Go-e" curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/api/set?frc=1 > /dev/null fi fi oldcurrent=$(echo $output | jq -r '.amp') current=$( /dev/null fi fi diff --git a/runs/set-current.sh b/runs/set-current.sh index 462868588..dd2c25958 100755 --- a/runs/set-current.sh +++ b/runs/set-current.sh @@ -191,7 +191,6 @@ function setChargingCurrentgoe () { #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 fsp=$(echo $output | jq -r '.fsp') if [[ ! $fsp =~ $re ]] ; then - openwbDebugLog "MAIN" 0 "set-current OldApi: $fsp" if [[ $current -eq 0 ]]; then state=$(echo $output | jq -r '.alw') if ((state == "1")) ; then @@ -214,21 +213,17 @@ function setChargingCurrentgoe () { fi else output=$(curl --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/status) - openwbDebugLog "MAIN" 0 "set-current NewApi: $fsp" state=$(echo $output | jq -r '.frc') if [[ $current -eq 0 ]]; then if ((state == "0")) ; then - openwbDebugLog "MAIN" 0 "set-current disabling Go-e" curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?frc=1 > /dev/null fi else if ((state == "1")) ; then - openwbDebugLog "MAIN" 0 "set-current enabling Go-e" curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?frc=0 > /dev/null fi oldgoecurrent=$(echo $output | jq -r '.amp') if (( oldgoecurrent != $current )) ; then - openwbDebugLog "MAIN" 0 "set-current amp=$current" curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?amp=$current > /dev/null fi fi From 388ccced94ae822f312cab140f86016174a2cbc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 13 Nov 2021 16:10:11 +0100 Subject: [PATCH 26/66] u1p3pgoe: fix change to APIv2 *argl* --- runs/u1p3pgoe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py index 07d60e656..e934a3e45 100644 --- a/runs/u1p3pgoe.py +++ b/runs/u1p3pgoe.py @@ -36,7 +36,7 @@ if (args.phases == 3 and int(status_goe['fsp']) != 0): if (args.minampere and args.minampere >= 5 and args.minampere <= 32): set_amx_goe = requests.get('http://'+args.address+'/api/set?amp='+str(args.minampere), timeout=5).json() - if (int(set_amx_goe['amx']) == args.minampere and args.verbose): + if (int(set_amx_goe['amp']) == args.minampere and args.verbose): print("Setzen von MinAmpere erfolgreich: amx=%d" % (int(set_amx_goe['amx']))) set_fsp_goe = requests.get('http://'+args.address+'/api/set?psm=2', timeout=5).json() if (int(set_fsp_goe['fsp']) == 0 and args.verbose): From 2f2d2df8a102600e08238a9c81ece7a3fb864dbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 13 Nov 2021 16:22:14 +0100 Subject: [PATCH 27/66] u1p3pgoe: fix change to APIv2 *argl* II --- runs/u1p3pgoe.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py index e934a3e45..08f199174 100644 --- a/runs/u1p3pgoe.py +++ b/runs/u1p3pgoe.py @@ -31,7 +31,7 @@ print("Phaseneinstellung fsp vorher: %d" % (int(status_goe['fsp']))) if (args.phases == 1 and int(status_goe['fsp']) != 1): set_fsp_goe = requests.get('http://'+args.address+'/api/set?psm=1', timeout=5).json() - if (int(set_fsp_goe['fsp']) == 1 and args.verbose): + if (int(set_fsp_goe['psm']) == 1 and args.verbose): print("Umschaltung auf 1 Phase erfolgreich: fsp=%d" % (int(set_fsp_goe['fsp']))) if (args.phases == 3 and int(status_goe['fsp']) != 0): if (args.minampere and args.minampere >= 5 and args.minampere <= 32): @@ -39,7 +39,7 @@ if (int(set_amx_goe['amp']) == args.minampere and args.verbose): print("Setzen von MinAmpere erfolgreich: amx=%d" % (int(set_amx_goe['amx']))) set_fsp_goe = requests.get('http://'+args.address+'/api/set?psm=2', timeout=5).json() - if (int(set_fsp_goe['fsp']) == 0 and args.verbose): + if (int(set_fsp_goe['psm']) == 0 and args.verbose): print("Umschaltung auf 3 Phasen erfolgreich: fsp=%d" % (int(set_fsp_goe['fsp']))) except: traceback.print_exc() From fc59fd1c58692711acc1d58915eba587a0c4aa0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 13 Nov 2021 16:27:15 +0100 Subject: [PATCH 28/66] u1p3pgoe: fix change to APIv2 *argl* III --- runs/u1p3pgoe.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py index 08f199174..686764085 100644 --- a/runs/u1p3pgoe.py +++ b/runs/u1p3pgoe.py @@ -32,15 +32,15 @@ if (args.phases == 1 and int(status_goe['fsp']) != 1): set_fsp_goe = requests.get('http://'+args.address+'/api/set?psm=1', timeout=5).json() if (int(set_fsp_goe['psm']) == 1 and args.verbose): - print("Umschaltung auf 1 Phase erfolgreich: fsp=%d" % (int(set_fsp_goe['fsp']))) + print("Umschaltung auf 1 Phase erfolgreich: psm=%d" % (int(set_fsp_goe['fsp']))) if (args.phases == 3 and int(status_goe['fsp']) != 0): if (args.minampere and args.minampere >= 5 and args.minampere <= 32): set_amx_goe = requests.get('http://'+args.address+'/api/set?amp='+str(args.minampere), timeout=5).json() if (int(set_amx_goe['amp']) == args.minampere and args.verbose): - print("Setzen von MinAmpere erfolgreich: amx=%d" % (int(set_amx_goe['amx']))) + print("Setzen von MinAmpere erfolgreich: amp=%d" % (int(set_amx_goe['amx']))) set_fsp_goe = requests.get('http://'+args.address+'/api/set?psm=2', timeout=5).json() if (int(set_fsp_goe['psm']) == 0 and args.verbose): - print("Umschaltung auf 3 Phasen erfolgreich: fsp=%d" % (int(set_fsp_goe['fsp']))) + print("Umschaltung auf 3 Phasen erfolgreich: psm=%d" % (int(set_fsp_goe['fsp']))) except: traceback.print_exc() exit(1) From 6e71bb76f55f57dc0d202d6e7801cf1afe7f1751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 13 Nov 2021 18:07:32 +0100 Subject: [PATCH 29/66] goecheck: use new APIv2 also if goe is LP1 oder LP3 --- goecheck.sh | 90 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 22 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index dbb5ff678..98de4e0ac 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -5,26 +5,49 @@ goecheck(){ if [[ $evsecon == "goe" ]]; then output=$(curl --connect-timeout 1 -s http://$goeiplp1/status) if [[ $? == "0" ]] ; then - state=$(echo $output | jq -r '.alw') - if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatus"; then - lp1enabled=$( /dev/null + #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 + fsp=$(echo $output | jq -r '.fsp') + if [[ ! $fsp =~ $re ]] ; then + state=$(echo $output | jq -r '.alw') + if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatus"; then + lp2enabled=$( /dev/null + fi fi - fi - if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatus"; then - if ((state == "1")) ; then - curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=alw=0 > /dev/null + if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatus"; then + if ((state == "1")) ; then + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=alw=0 > /dev/null + fi fi - fi - fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") - oldcurrent=$(echo $output | jq -r '.amp') - current=$(= 40)) ; then - curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=amx=$current > /dev/null - else - curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=amp=$current > /dev/null + fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") + oldcurrent=$(echo $output | jq -r '.amp') + current=$(= 40)) ; then + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=amx=$current > /dev/null + else + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=amp=$current > /dev/null + fi + fi + else + output=$(curl --connect-timeout 1 -s http://$goeiplp1/api/status) + state=$(echo $output | jq -r '.frc') + if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatus"; then + lp2enabled=$( /dev/null + fi + fi + if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatus"; then + if ((state == "0")) ; then + curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?frc=1 > /dev/null + fi + fi + oldcurrent=$(echo $output | jq -r '.amp') + current=$( /dev/null fi fi fi @@ -82,12 +105,15 @@ goecheck(){ fi if [[ $lastmanagements2 == "1" ]]; then if [[ $evsecons2 == "goe" ]]; then - output=$(curl --connect-timeout 1 -s http://$goeiplp3/status) - if [[ $? == "0" ]] ; then + output=$(curl --connect-timeout 1 -s http://$goeiplp3/status) + if [[ $? == "0" ]] ; then + #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 + fsp=$(echo $output | jq -r '.fsp') + if [[ ! $fsp =~ $re ]] ; then state=$(echo $output | jq -r '.alw') if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss2"; then - lp3enabled=$( /dev/null fi fi @@ -106,8 +132,28 @@ goecheck(){ curl --silent --connect-timeout $goetimeoutlp3 -s http://$goeiplp3/mqtt?payload=amp=$current > /dev/null fi fi + else + output=$(curl --connect-timeout 1 -s http://$goeiplp3/api/status) + state=$(echo $output | jq -r '.frc') + if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss2"; then + lp2enabled=$( /dev/null + fi + fi + if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatuss2"; then + if ((state == "0")) ; then + curl --silent --connect-timeout $goetimeoutlp3 -s http://$goeiplp3/api/set?frc=1 > /dev/null + fi + fi + oldcurrent=$(echo $output | jq -r '.amp') + current=$( /dev/null + fi fi fi + fi fi fi } From c5d0d9f1ecff1f20f0e10a14bf68e7a1cab07faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 13 Nov 2021 18:44:31 +0100 Subject: [PATCH 30/66] u1p3pgoe: further fixes for APIv2 --- runs/u1p3pgoe.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py index 18c7aa387..43ae572ef 100644 --- a/runs/u1p3pgoe.py +++ b/runs/u1p3pgoe.py @@ -5,6 +5,7 @@ import time import argparse import traceback +import json parser = argparse.ArgumentParser() parser.add_argument("-a", "--address", required=True, type=str, help="ip address") @@ -35,17 +36,17 @@ if(args.verbose): print("Phaseneinstellung fsp vorher: %d" % (int(status_goe['fsp']))) if (args.phases == 1 and int(status_goe['fsp']) != 1): - set_fsp_goe = requests.get('http://'+args.address+'/api/set?psm=1', timeout=5).json() - if (int(set_fsp_goe['psm']) == 1 and args.verbose): - print("Umschaltung auf 1 Phase erfolgreich: psm=%d" % (int(set_fsp_goe['fsp']))) + set_psm_goe = requests.get('http://'+args.address+'/api/set?psm=1', timeout=5).json() + if (set_psm_goe['psm'] == True and args.verbose): + print("Umschaltung auf 1 Phase erfolgreich!") if (args.phases == 3 and int(status_goe['fsp']) != 0): if (args.minampere and args.minampere >= 5 and args.minampere <= 32): - set_amx_goe = requests.get('http://'+args.address+'/api/set?amp='+str(args.minampere), timeout=5).json() - if (int(set_amx_goe['amp']) == args.minampere and args.verbose): - print("Setzen von MinAmpere erfolgreich: amp=%d" % (int(set_amx_goe['amx']))) - set_fsp_goe = requests.get('http://'+args.address+'/api/set?psm=2', timeout=5).json() - if (int(set_fsp_goe['psm']) == 0 and args.verbose): - print("Umschaltung auf 3 Phasen erfolgreich: psm=%d" % (int(set_fsp_goe['fsp']))) + set_amp_goe = requests.get('http://'+args.address+'/api/set?amp='+str(args.minampere), timeout=5).json() + if (set_amp_goe['amp'] == True and args.verbose): + print("Setzen von MinAmpere erfolgreich!") + set_psm_goe = requests.get('http://'+args.address+'/api/set?psm=2', timeout=5).json() + if (set_psm_goe['psm'] == True and args.verbose): + print("Umschaltung auf 3 Phasen erfolgreich!") except: traceback.print_exc() exit(1) From 57ea9b5bbe34d3e3c06cb9cb64e6663df7d73c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 13 Nov 2021 18:51:35 +0100 Subject: [PATCH 31/66] u1p3pgoe: beautification --- runs/u1p3pgoe.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/runs/u1p3pgoe.py b/runs/u1p3pgoe.py index 43ae572ef..1c01aeb04 100644 --- a/runs/u1p3pgoe.py +++ b/runs/u1p3pgoe.py @@ -5,7 +5,6 @@ import time import argparse import traceback -import json parser = argparse.ArgumentParser() parser.add_argument("-a", "--address", required=True, type=str, help="ip address") @@ -27,7 +26,7 @@ try: print("go-e serial number: %s" % (status_goe['sse'])) except KeyError: - traceback.print_exc() + print("Unable to fetch serial number (sse not in json answer - KeyError)") exit(1) # check whether fsp param exists => go-e charger has HW V3 and therefore 1to3 phase switch capability @@ -37,15 +36,15 @@ print("Phaseneinstellung fsp vorher: %d" % (int(status_goe['fsp']))) if (args.phases == 1 and int(status_goe['fsp']) != 1): set_psm_goe = requests.get('http://'+args.address+'/api/set?psm=1', timeout=5).json() - if (set_psm_goe['psm'] == True and args.verbose): + if (set_psm_goe['psm'] is True and args.verbose): print("Umschaltung auf 1 Phase erfolgreich!") if (args.phases == 3 and int(status_goe['fsp']) != 0): if (args.minampere and args.minampere >= 5 and args.minampere <= 32): set_amp_goe = requests.get('http://'+args.address+'/api/set?amp='+str(args.minampere), timeout=5).json() - if (set_amp_goe['amp'] == True and args.verbose): + if (set_amp_goe['amp'] is True and args.verbose): print("Setzen von MinAmpere erfolgreich!") set_psm_goe = requests.get('http://'+args.address+'/api/set?psm=2', timeout=5).json() - if (set_psm_goe['psm'] == True and args.verbose): + if (set_psm_goe['psm'] is True and args.verbose): print("Umschaltung auf 3 Phasen erfolgreich!") except: traceback.print_exc() From 451b17483ca5a0654e37ce7952e7dd99eb340bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= <46440437+matzempc@users.noreply.github.com> Date: Mon, 15 Nov 2021 07:47:49 +0100 Subject: [PATCH 32/66] goe: Fix check for APIv1 vs. APIv2 --- runs/set-current.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runs/set-current.sh b/runs/set-current.sh index dd2c25958..b6af8764b 100755 --- a/runs/set-current.sh +++ b/runs/set-current.sh @@ -189,8 +189,9 @@ function setChargingCurrentgoe () { if [[ $evsecon == "goe" ]]; then output=$(curl --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/status) #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 + digit = ^[0-9]$ fsp=$(echo $output | jq -r '.fsp') - if [[ ! $fsp =~ $re ]] ; then + if [[ ! $fsp =~ $digit ]] ; then if [[ $current -eq 0 ]]; then state=$(echo $output | jq -r '.alw') if ((state == "1")) ; then From d816960d65006cfe886456cb95eb5ed6825a7b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= <46440437+matzempc@users.noreply.github.com> Date: Mon, 15 Nov 2021 07:49:10 +0100 Subject: [PATCH 33/66] goecheck: Fix detection of APIv1 vs. APIv2 --- goecheck.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/goecheck.sh b/goecheck.sh index 98de4e0ac..055dbb29c 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -6,8 +6,9 @@ goecheck(){ output=$(curl --connect-timeout 1 -s http://$goeiplp1/status) if [[ $? == "0" ]] ; then #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 + digit = ^[0-9]$ fsp=$(echo $output | jq -r '.fsp') - if [[ ! $fsp =~ $re ]] ; then + if [[ ! $fsp =~ $digit ]] ; then state=$(echo $output | jq -r '.alw') if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatus"; then lp2enabled=$( Date: Mon, 15 Nov 2021 07:53:59 +0100 Subject: [PATCH 34/66] goe: fix APIv1 vs. APIv2 detection --- goecheck.sh | 2 +- runs/set-current.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index 055dbb29c..9234211c2 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -6,7 +6,7 @@ goecheck(){ output=$(curl --connect-timeout 1 -s http://$goeiplp1/status) if [[ $? == "0" ]] ; then #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 - digit = ^[0-9]$ + digit = '^[0-9]$' fsp=$(echo $output | jq -r '.fsp') if [[ ! $fsp =~ $digit ]] ; then state=$(echo $output | jq -r '.alw') diff --git a/runs/set-current.sh b/runs/set-current.sh index b6af8764b..04bdc9c27 100755 --- a/runs/set-current.sh +++ b/runs/set-current.sh @@ -189,7 +189,7 @@ function setChargingCurrentgoe () { if [[ $evsecon == "goe" ]]; then output=$(curl --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/status) #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 - digit = ^[0-9]$ + digit = '^[0-9]$' fsp=$(echo $output | jq -r '.fsp') if [[ ! $fsp =~ $digit ]] ; then if [[ $current -eq 0 ]]; then From c24133b9184f0dec123f4c65ebad5890c00c5b87 Mon Sep 17 00:00:00 2001 From: "matthias.mossner@siemens.com" Date: Mon, 15 Nov 2021 07:57:05 +0100 Subject: [PATCH 35/66] goe: further fix and beautification APIv1 vs. APIv2 detection --- goecheck.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index 9234211c2..0c550d8d4 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -2,11 +2,12 @@ goecheck(){ ####################################### #goe mobility check + digit = '^[0-9]$' + if [[ $evsecon == "goe" ]]; then output=$(curl --connect-timeout 1 -s http://$goeiplp1/status) if [[ $? == "0" ]] ; then #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 - digit = '^[0-9]$' fsp=$(echo $output | jq -r '.fsp') if [[ ! $fsp =~ $digit ]] ; then state=$(echo $output | jq -r '.alw') @@ -59,7 +60,7 @@ goecheck(){ if [[ $? == "0" ]] ; then #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 fsp=$(echo $output | jq -r '.fsp') - if [[ ! $fsp =~ $re ]] ; then + if [[ ! $fsp =~ $digit ]] ; then state=$(echo $output | jq -r '.alw') if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss1"; then lp2enabled=$( new HWV3 and new API V2 fsp=$(echo $output | jq -r '.fsp') - if [[ ! $fsp =~ $re ]] ; then + if [[ ! $fsp =~ $digit ]] ; then state=$(echo $output | jq -r '.alw') if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss2"; then lp2enabled=$( Date: Mon, 15 Nov 2021 08:03:50 +0100 Subject: [PATCH 36/66] goe: fix APIv1 vs. APIv2 detection III --- goecheck.sh | 2 +- runs/set-current.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index 0c550d8d4..94d7c641d 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -2,7 +2,7 @@ goecheck(){ ####################################### #goe mobility check - digit = '^[0-9]$' + digit='^[0-9]$' if [[ $evsecon == "goe" ]]; then output=$(curl --connect-timeout 1 -s http://$goeiplp1/status) diff --git a/runs/set-current.sh b/runs/set-current.sh index 04bdc9c27..d352d9d76 100755 --- a/runs/set-current.sh +++ b/runs/set-current.sh @@ -189,7 +189,7 @@ function setChargingCurrentgoe () { if [[ $evsecon == "goe" ]]; then output=$(curl --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/status) #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 - digit = '^[0-9]$' + digit='^[0-9]$' fsp=$(echo $output | jq -r '.fsp') if [[ ! $fsp =~ $digit ]] ; then if [[ $current -eq 0 ]]; then From 5ef3db4881b195e42d6b5211263326ba964b1a60 Mon Sep 17 00:00:00 2001 From: "matthias.mossner@siemens.com" Date: Mon, 15 Nov 2021 08:06:02 +0100 Subject: [PATCH 37/66] goe: fix copy&paste bug --- goecheck.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index 94d7c641d..f0d48c501 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -114,8 +114,8 @@ goecheck(){ if [[ ! $fsp =~ $digit ]] ; then state=$(echo $output | jq -r '.alw') if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss2"; then - lp2enabled=$( /dev/null fi fi From ba6933ed829f3a93efa0be70e23b2a6f5869bce1 Mon Sep 17 00:00:00 2001 From: "matthias.mossner@siemens.com" Date: Mon, 15 Nov 2021 13:26:15 +0100 Subject: [PATCH 38/66] goecheck: further copy&paste fixes --- goecheck.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index f0d48c501..1db29202c 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -12,7 +12,7 @@ goecheck(){ if [[ ! $fsp =~ $digit ]] ; then state=$(echo $output | jq -r '.alw') if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatus"; then - lp2enabled=$( /dev/null fi @@ -36,8 +36,8 @@ goecheck(){ output=$(curl --connect-timeout 1 -s http://$goeiplp1/api/status) state=$(echo $output | jq -r '.frc') if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatus"; then - lp2enabled=$( /dev/null fi fi @@ -138,8 +138,8 @@ goecheck(){ output=$(curl --connect-timeout 1 -s http://$goeiplp3/api/status) state=$(echo $output | jq -r '.frc') if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss2"; then - lp2enabled=$( /dev/null fi fi From 1b6c97252e4a9355f9827c8defc725aa6cf2953c Mon Sep 17 00:00:00 2001 From: "matthias.mossner@siemens.com" Date: Mon, 15 Nov 2021 13:38:22 +0100 Subject: [PATCH 39/66] goe: autodetect and use APIv2 also for LP1 and LP3 --- modules/goelp1/main.sh | 185 ++++++++++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 58 deletions(-) diff --git a/modules/goelp1/main.sh b/modules/goelp1/main.sh index 80b9455ad..b8459976c 100755 --- a/modules/goelp1/main.sh +++ b/modules/goelp1/main.sh @@ -4,62 +4,131 @@ rekwh='^[-+]?[0-9]+\.?[0-9]*$' output=$(curl --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/status) if [[ $? == "0" ]] ; then - watt=$(echo $output | jq -r '.nrg[11]') - watt=$(echo "scale=0;$watt * 10 /1" |bc) - if [[ $watt =~ $re ]] ; then - echo $watt > /var/www/html/openWB/ramdisk/llaktuell - fi - lla1=$(echo $output | jq -r '.nrg[4]') - lla1=$(echo "scale=0;$lla1 / 10" |bc) - if [[ $lla1 =~ $re ]] ; then - echo $lla1 > /var/www/html/openWB/ramdisk/lla1 - fi - lla2=$(echo $output | jq -r '.nrg[5]') - lla2=$(echo "scale=0;$lla2 / 10" |bc) - if [[ $lla2 =~ $re ]] ; then - echo $lla2 > /var/www/html/openWB/ramdisk/lla2 - fi - lla3=$(echo $output | jq -r '.nrg[6]') - lla3=$(echo "scale=0;$lla3 / 10" |bc) - if [[ $lla3 =~ $re ]] ; then - echo $lla3 > /var/www/html/openWB/ramdisk/lla3 - fi - llv1=$(echo $output | jq -r '.nrg[0]') - if [[ $llv1 =~ $re ]] ; then - echo $llv1 > /var/www/html/openWB/ramdisk/llv1 - fi - llv2=$(echo $output | jq -r '.nrg[1]') - if [[ $llv2 =~ $re ]] ; then - echo $llv2 > /var/www/html/openWB/ramdisk/llv2 - fi - llv3=$(echo $output | jq -r '.nrg[2]') - if [[ $llv3 =~ $re ]] ; then - echo $llv3 > /var/www/html/openWB/ramdisk/llv3 - fi - llkwh=$(echo $output | jq -r '.eto') - llkwh=$(echo "scale=3;$llkwh / 10" |bc) - if [[ $llkwh =~ $rekwh ]] ; then - echo $llkwh > /var/www/html/openWB/ramdisk/llkwh - fi - rfid=$(echo $output | jq -r '.uby') - oldrfid=$( /var/www/html/openWB/ramdisk/readtag - echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp1rfid - fi - #car status 1 Ladestation bereit, kein Auto - #car status 2 Auto lädt - #car status 3 Warte auf Fahrzeug - #car status 4 Ladung beendet, Fahrzeug verbunden - car=$(echo $output | jq -r '.car') - if [[ $car == "1" ]] ; then - echo 0 > /var/www/html/openWB/ramdisk/plugstat - else - echo 1 > /var/www/html/openWB/ramdisk/plugstat - fi - if [[ $car == "2" ]] ; then - echo 1 > /var/www/html/openWB/ramdisk/chargestat - else - echo 0 > /var/www/html/openWB/ramdisk/chargestat - fi + #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 + fsp=$(echo $output | jq -r '.fsp') + if [[ ! $fsp =~ $re ]] ; then + watt=$(echo $output | jq -r '.nrg[11]') + watt=$(echo "scale=0;$watt * 10 /1" |bc) + if [[ $watt =~ $re ]] ; then + echo $watt > /var/www/html/openWB/ramdisk/llaktuell + fi + lla1=$(echo $output | jq -r '.nrg[4]') + lla1=$(echo "scale=0;$lla1 / 10" |bc) + if [[ $lla1 =~ $re ]] ; then + echo $lla1 > /var/www/html/openWB/ramdisk/lla1 + fi + lla2=$(echo $output | jq -r '.nrg[5]') + lla2=$(echo "scale=0;$lla2 / 10" |bc) + if [[ $lla2 =~ $re ]] ; then + echo $lla2 > /var/www/html/openWB/ramdisk/lla2 + fi + lla3=$(echo $output | jq -r '.nrg[6]') + lla3=$(echo "scale=0;$lla3 / 10" |bc) + if [[ $lla3 =~ $re ]] ; then + echo $lla3 > /var/www/html/openWB/ramdisk/lla3 + fi + llv1=$(echo $output | jq -r '.nrg[0]') + if [[ $llv1 =~ $re ]] ; then + echo $llv1 > /var/www/html/openWB/ramdisk/llv1 + fi + llv2=$(echo $output | jq -r '.nrg[1]') + if [[ $llv2 =~ $re ]] ; then + echo $llv2 > /var/www/html/openWB/ramdisk/llv2 + fi + llv3=$(echo $output | jq -r '.nrg[2]') + if [[ $llv3 =~ $re ]] ; then + echo $llv3 > /var/www/html/openWB/ramdisk/llv3 + fi + llkwh=$(echo $output | jq -r '.eto') + llkwh=$(echo "scale=3;$llkwh / 10" |bc) + if [[ $llkwh =~ $rekwh ]] ; then + echo $llkwh > /var/www/html/openWB/ramdisk/llkwh + fi + rfid=$(echo $output | jq -r '.uby') + oldrfid=$( /var/www/html/openWB/ramdisk/readtag + echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp1rfid + fi + #car status 1 Ladestation bereit, kein Auto + #car status 2 Auto lädt + #car status 3 Warte auf Fahrzeug + #car status 4 Ladung beendet, Fahrzeug verbunden + car=$(echo $output | jq -r '.car') + if [[ $car == "1" ]] ; then + echo 0 > /var/www/html/openWB/ramdisk/plugstat + else + echo 1 > /var/www/html/openWB/ramdisk/plugstat + fi + if [[ $car == "2" ]] ; then + echo 1 > /var/www/html/openWB/ramdisk/chargestat + else + echo 0 > /var/www/html/openWB/ramdisk/chargestat + fi + else + output=$(curl --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/status) + if [[ $? == "0" ]] ; then + watt=$(echo $output | jq -r '.nrg[11]') + watt=$(echo "scale=0;$watt /1" |bc) + if [[ $watt =~ $re ]] ; then + echo $watt > /var/www/html/openWB/ramdisk/llaktuell + fi + lla1=$(echo $output | jq -r '.nrg[4]') + lla1=$(echo "scale=0;$lla1" |bc) + if [[ $lla1 =~ $rekwh ]] ; then + echo $lla1 > /var/www/html/openWB/ramdisk/lla1 + fi + lla2=$(echo $output | jq -r '.nrg[5]') + lla2=$(echo "scale=0;$lla2" |bc) + if [[ $lla2 =~ $rekwh ]] ; then + echo $lla2 > /var/www/html/openWB/ramdisk/lla2 + fi + lla3=$(echo $output | jq -r '.nrg[6]') + lla3=$(echo "scale=0;$lla3" |bc) + if [[ $lla3 =~ $rekwh ]] ; then + echo $lla3 > /var/www/html/openWB/ramdisk/lla3 + fi + llv1=$(echo $output | jq -r '.nrg[0]') + if [[ $llv1 =~ $re ]] ; then + echo $llv1 > /var/www/html/openWB/ramdisk/llv1 + fi + llv2=$(echo $output | jq -r '.nrg[1]') + if [[ $llv2 =~ $re ]] ; then + echo $llv2 > /var/www/html/openWB/ramdisk/llv2 + fi + llv3=$(echo $output | jq -r '.nrg[2]') + if [[ $llv3 =~ $re ]] ; then + echo $llv3 > /var/www/html/openWB/ramdisk/llv3 + fi + llkwh=$(echo $output | jq -r '.eto') + llkwh=$(echo "scale=3;$llkwh / 1000" |bc) + if [[ $llkwh =~ $rekwh ]] ; then + echo $llkwh > /var/www/html/openWB/ramdisk/llkwh + fi + rfid=$(echo $output | jq -r '.trx') + if [[ $rfid == "null" ]] ; then + rfid="0" + fi + oldrfid=$( /var/www/html/openWB/ramdisk/readtag + echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelprfid + fi + #car status 1 Ladestation bereit, kein Auto + #car status 2 Auto lädt + #car status 3 Warte auf Fahrzeug + #car status 4 Ladung beendet, Fahrzeug verbunden + car=$(echo $output | jq -r '.car') + if [[ $car == "2" ]] || [[ $car == "3" ]] || [[ $car == "4" ]] ; then + echo 1 > /var/www/html/openWB/ramdisk/plugstat + else + echo 0 > /var/www/html/openWB/ramdisk/plugstat + fi + if [[ $car == "2" ]] ; then + echo 1 > /var/www/html/openWB/ramdisk/chargestat + else + echo 0 > /var/www/html/openWB/ramdisk/chargestat + fi + fi + fi fi \ No newline at end of file From e71a9a2afaa596d5c5ded78036f91d51b748d8b9 Mon Sep 17 00:00:00 2001 From: "matthias.mossner@siemens.com" Date: Mon, 15 Nov 2021 15:04:13 +0100 Subject: [PATCH 40/66] goe: autodetect and use APIv2 also for LP3 --- modules/goelp3/main.sh | 185 ++++++++++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 58 deletions(-) diff --git a/modules/goelp3/main.sh b/modules/goelp3/main.sh index c468058dd..912001d8e 100755 --- a/modules/goelp3/main.sh +++ b/modules/goelp3/main.sh @@ -4,62 +4,131 @@ rekwh='^[-+]?[0-9]+\.?[0-9]*$' output=$(curl --connect-timeout $goetimeoutlp3 -s http://$goeiplp3/status) if [[ $? == "0" ]] ; then - watt=$(echo $output | jq -r '.nrg[11]') - watt=$(echo "scale=0;$watt * 10 /1" |bc) - if [[ $watt =~ $re ]] ; then - echo $watt > /var/www/html/openWB/ramdisk/llaktuells2 - fi - lla1=$(echo $output | jq -r '.nrg[4]') - lla1=$(echo "scale=0;$lla1 / 10" |bc) - if [[ $lla1 =~ $re ]] ; then - echo $lla1 > /var/www/html/openWB/ramdisk/llas21 - fi - lla2=$(echo $output | jq -r '.nrg[5]') - lla2=$(echo "scale=0;$lla2 / 10" |bc) - if [[ $lla2 =~ $re ]] ; then - echo $lla2 > /var/www/html/openWB/ramdisk/llas22 - fi - lla3=$(echo $output | jq -r '.nrg[6]') - lla3=$(echo "scale=0;$lla3 / 10" |bc) - if [[ $lla3 =~ $re ]] ; then - echo $lla3 > /var/www/html/openWB/ramdisk/llas23 - fi - llv1=$(echo $output | jq -r '.nrg[0]') - if [[ $llv1 =~ $re ]] ; then - echo $llv1 > /var/www/html/openWB/ramdisk/llvs21 - fi - llv2=$(echo $output | jq -r '.nrg[1]') - if [[ $llv2 =~ $re ]] ; then - echo $llv2 > /var/www/html/openWB/ramdisk/llvs22 - fi - llv3=$(echo $output | jq -r '.nrg[2]') - if [[ $llv3 =~ $re ]] ; then - echo $llv3 > /var/www/html/openWB/ramdisk/llvs23 - fi - llkwh=$(echo $output | jq -r '.eto') - llkwh=$(echo "scale=3;$llkwh / 10" |bc) - if [[ $llkwh =~ $rekwh ]] ; then - echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs2 - fi - rfid=$(echo $output | jq -r '.uby') - oldrfid=$( /var/www/html/openWB/ramdisk/readtag - echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp3rfid - fi - #car status 1 Ladestation bereit, kein Auto - #car status 2 Auto lädt - #car status 3 Warte auf Fahrzeug - #car status 4 Ladung beendet, Fahrzeug verbunden - car=$(echo $output | jq -r '.car') - if [[ $car == "1" ]] ; then - echo 0 > /var/www/html/openWB/ramdisk/plugstatlp3 - else - echo 1 > /var/www/html/openWB/ramdisk/plugstatlp3 - fi - if [[ $car == "2" ]] ; then - echo 1 > /var/www/html/openWB/ramdisk/chargestatlp3 - else - echo 0 > /var/www/html/openWB/ramdisk/chargestatlp3 - fi + #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 + fsp=$(echo $output | jq -r '.fsp') + if [[ ! $fsp =~ $re ]] ; then + watt=$(echo $output | jq -r '.nrg[11]') + watt=$(echo "scale=0;$watt * 10 /1" |bc) + if [[ $watt =~ $re ]] ; then + echo $watt > /var/www/html/openWB/ramdisk/llaktuells2 + fi + lla1=$(echo $output | jq -r '.nrg[4]') + lla1=$(echo "scale=0;$lla1 / 10" |bc) + if [[ $lla1 =~ $re ]] ; then + echo $lla1 > /var/www/html/openWB/ramdisk/llas21 + fi + lla2=$(echo $output | jq -r '.nrg[5]') + lla2=$(echo "scale=0;$lla2 / 10" |bc) + if [[ $lla2 =~ $re ]] ; then + echo $lla2 > /var/www/html/openWB/ramdisk/llas22 + fi + lla3=$(echo $output | jq -r '.nrg[6]') + lla3=$(echo "scale=0;$lla3 / 10" |bc) + if [[ $lla3 =~ $re ]] ; then + echo $lla3 > /var/www/html/openWB/ramdisk/llas23 + fi + llv1=$(echo $output | jq -r '.nrg[0]') + if [[ $llv1 =~ $re ]] ; then + echo $llv1 > /var/www/html/openWB/ramdisk/llvs21 + fi + llv2=$(echo $output | jq -r '.nrg[1]') + if [[ $llv2 =~ $re ]] ; then + echo $llv2 > /var/www/html/openWB/ramdisk/llvs22 + fi + llv3=$(echo $output | jq -r '.nrg[2]') + if [[ $llv3 =~ $re ]] ; then + echo $llv3 > /var/www/html/openWB/ramdisk/llvs23 + fi + llkwh=$(echo $output | jq -r '.eto') + llkwh=$(echo "scale=3;$llkwh / 10" |bc) + if [[ $llkwh =~ $rekwh ]] ; then + echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs2 + fi + rfid=$(echo $output | jq -r '.uby') + oldrfid=$( /var/www/html/openWB/ramdisk/readtag + echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp3rfid + fi + #car status 1 Ladestation bereit, kein Auto + #car status 2 Auto lädt + #car status 3 Warte auf Fahrzeug + #car status 4 Ladung beendet, Fahrzeug verbunden + car=$(echo $output | jq -r '.car') + if [[ $car == "1" ]] ; then + echo 0 > /var/www/html/openWB/ramdisk/plugstatlp3 + else + echo 1 > /var/www/html/openWB/ramdisk/plugstatlp3 + fi + if [[ $car == "2" ]] ; then + echo 1 > /var/www/html/openWB/ramdisk/chargestatlp3 + else + echo 0 > /var/www/html/openWB/ramdisk/chargestatlp3 + fi + else + output=$(curl --connect-timeout $goetimeoutlp3 -s http://$goeiplp3/api/status) + if [[ $? == "0" ]] ; then + watt=$(echo $output | jq -r '.nrg[11]') + watt=$(echo "scale=0;$watt /1" |bc) + if [[ $watt =~ $re ]] ; then + echo $watt > /var/www/html/openWB/ramdisk/llaktuells2 + fi + lla1=$(echo $output | jq -r '.nrg[4]') + lla1=$(echo "scale=0;$lla1" |bc) + if [[ $lla1 =~ $rekwh ]] ; then + echo $lla1 > /var/www/html/openWB/ramdisk/llas21 + fi + lla2=$(echo $output | jq -r '.nrg[5]') + lla2=$(echo "scale=0;$lla2" |bc) + if [[ $lla2 =~ $rekwh ]] ; then + echo $lla2 > /var/www/html/openWB/ramdisk/llas22 + fi + lla3=$(echo $output | jq -r '.nrg[6]') + lla3=$(echo "scale=0;$lla3" |bc) + if [[ $lla3 =~ $rekwh ]] ; then + echo $lla3 > /var/www/html/openWB/ramdisk/llas23 + fi + llv1=$(echo $output | jq -r '.nrg[0]') + if [[ $llv1 =~ $re ]] ; then + echo $llv1 > /var/www/html/openWB/ramdisk/llvs21 + fi + llv2=$(echo $output | jq -r '.nrg[1]') + if [[ $llv2 =~ $re ]] ; then + echo $llv2 > /var/www/html/openWB/ramdisk/llvs22 + fi + llv3=$(echo $output | jq -r '.nrg[2]') + if [[ $llv3 =~ $re ]] ; then + echo $llv3 > /var/www/html/openWB/ramdisk/llvs23 + fi + llkwh=$(echo $output | jq -r '.eto') + llkwh=$(echo "scale=3;$llkwh / 1000" |bc) + if [[ $llkwh =~ $rekwh ]] ; then + echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs1 + fi + rfid=$(echo $output | jq -r '.trx') + if [[ $rfid == "null" ]] ; then + rfid="0" + fi + oldrfid=$( /var/www/html/openWB/ramdisk/readtag + echo $rfid > /var/www/html/openWB/ramdisk/tmpgoelp3rfid + fi + #car status 1 Ladestation bereit, kein Auto + #car status 2 Auto lädt + #car status 3 Warte auf Fahrzeug + #car status 4 Ladung beendet, Fahrzeug verbunden + car=$(echo $output | jq -r '.car') + if [[ $car == "2" ]] || [[ $car == "3" ]] || [[ $car == "4" ]] ; then + echo 1 > /var/www/html/openWB/ramdisk/plugstats2 + else + echo 0 > /var/www/html/openWB/ramdisk/plugstats2 + fi + if [[ $car == "2" ]] ; then + echo 1 > /var/www/html/openWB/ramdisk/chargestats2 + else + echo 0 > /var/www/html/openWB/ramdisk/chargestats2 + fi + fi + fi fi \ No newline at end of file From fcb329e789406fbe5b2f1f6e3e0b771eb9d3d8a9 Mon Sep 17 00:00:00 2001 From: "matthias.mossner@siemens.com" Date: Mon, 15 Nov 2021 15:24:00 +0100 Subject: [PATCH 41/66] goe: fix chargestat and plugstat for LP3 --- modules/goelp3/main.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/goelp3/main.sh b/modules/goelp3/main.sh index 912001d8e..bb663dd57 100755 --- a/modules/goelp3/main.sh +++ b/modules/goelp3/main.sh @@ -120,14 +120,14 @@ if [[ $? == "0" ]] ; then #car status 4 Ladung beendet, Fahrzeug verbunden car=$(echo $output | jq -r '.car') if [[ $car == "2" ]] || [[ $car == "3" ]] || [[ $car == "4" ]] ; then - echo 1 > /var/www/html/openWB/ramdisk/plugstats2 + echo 1 > /var/www/html/openWB/ramdisk/plugstatlp3 else - echo 0 > /var/www/html/openWB/ramdisk/plugstats2 + echo 0 > /var/www/html/openWB/ramdisk/plugstatlp3 fi if [[ $car == "2" ]] ; then - echo 1 > /var/www/html/openWB/ramdisk/chargestats2 + echo 1 > /var/www/html/openWB/ramdisk/chargestatlp3 else - echo 0 > /var/www/html/openWB/ramdisk/chargestats2 + echo 0 > /var/www/html/openWB/ramdisk/chargestatlp3 fi fi fi From 6eb3b2bd3db76776f3cb19c78281e2d1e54a6b1e Mon Sep 17 00:00:00 2001 From: "matthias.mossner@siemens.com" Date: Mon, 15 Nov 2021 15:29:13 +0100 Subject: [PATCH 42/66] goe: fix llkwh for LP3 --- modules/goelp3/main.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/goelp3/main.sh b/modules/goelp3/main.sh index bb663dd57..a557dfff3 100755 --- a/modules/goelp3/main.sh +++ b/modules/goelp3/main.sh @@ -103,7 +103,7 @@ if [[ $? == "0" ]] ; then llkwh=$(echo $output | jq -r '.eto') llkwh=$(echo "scale=3;$llkwh / 1000" |bc) if [[ $llkwh =~ $rekwh ]] ; then - echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs1 + echo $llkwh > /var/www/html/openWB/ramdisk/llkwhs2 fi rfid=$(echo $output | jq -r '.trx') if [[ $rfid == "null" ]] ; then From 02523bf34b6a4d9de2aae36716ef3974b30960a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Tue, 16 Nov 2021 22:21:21 +0100 Subject: [PATCH 43/66] first step: adding state URL for http smarthome module --- modules/smarthome/http/watt.py | 11 +++++++++-- runs/mqttsub.py | 5 +++++ runs/smarthomehandler.py | 7 ++++++- web/settings/smarthomeconfig.php | 12 ++++++++++++ web/settings/topicsToSubscribe_smarthomeconfig.js | 1 + 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/modules/smarthome/http/watt.py b/modules/smarthome/http/watt.py index df5a27533..b3d65b347 100644 --- a/modules/smarthome/http/watt.py +++ b/modules/smarthome/http/watt.py @@ -19,8 +19,14 @@ urlc=str(sys.argv[5]) except: urlc = "none" +try: + urlstate=str(sys.argv[6]) +except: + urlstate = "none" if not urlparse(url).scheme: url = 'http://' + url +if not urlparse(urlstate).scheme: + urlstate = 'http://' + urlstate if uberschuss < 0: uberschuss = 0 urlrep= url.replace("", str(uberschuss)) @@ -29,11 +35,12 @@ f = open( file_string , 'a') else: f = open( file_string , 'w') -print ('%s devicenr %s orig url %s replaced url %s urlc %s' % (time_string,devicenumber,url,urlrep,urlc),file=f) +print ('%s devicenr %s orig url %s replaced url %s urlc %s urlstate %s'% (time_string,devicenumber,url,urlrep,urlc,urlstate),file=f) f.close() +state = int(urllib.request.urlopen(urlstate, timeout=5).read().decode("utf-8")) aktpowerfl = float(urllib.request.urlopen(urlrep, timeout=5).read().decode("utf-8")) aktpower = int(aktpowerfl) -if aktpower > 50: +if state == 1 or aktpower > 50: relais = 1 else: relais = 0 diff --git a/runs/mqttsub.py b/runs/mqttsub.py index f6dda1101..f65d22d24 100644 --- a/runs/mqttsub.py +++ b/runs/mqttsub.py @@ -252,6 +252,11 @@ def on_message(client, userdata, msg): if ( 1 <= int(devicenumb) <= numberOfSupportedDevices ): writetoconfig(shconfigfile,'smarthomedevices','device_leistungurl_'+str(devicenumb), msg.payload.decode("utf-8")) client.publish("openWB/config/get/SmartHome/Devices/"+str(devicenumb)+"/device_leistungurl", msg.payload.decode("utf-8"), qos=0, retain=True) + if (( "openWB/config/set/SmartHome/Device" in msg.topic) and ("device_stateurl" in msg.topic)): + devicenumb=re.sub(r'\D', '', msg.topic) + if ( 1 <= int(devicenumb) <= numberOfSupportedDevices ): + writetoconfig(shconfigfile,'smarthomedevices','device_stateurl_'+str(devicenumb), msg.payload.decode("utf-8")) + client.publish("openWB/config/get/SmartHome/Devices/"+str(devicenumb)+"/device_stateurl", msg.payload.decode("utf-8"), qos=0, retain=True) if (( "openWB/config/set/SmartHome/Device" in msg.topic) and ("device_measureurlc" in msg.topic)): devicenumb=re.sub(r'\D', '', msg.topic) if ( 1 <= int(devicenumb) <= numberOfSupportedDevices ): diff --git a/runs/smarthomehandler.py b/runs/smarthomehandler.py index b9006d3fd..1e9e20f86 100644 --- a/runs/smarthomehandler.py +++ b/runs/smarthomehandler.py @@ -199,7 +199,7 @@ def sepwatt(oldwatt,oldwattk,nummer): try: configuredName = config.get('smarthomedevices', 'device_name_'+str(nummer)) except: - configuredName = "(unknown name)" + configuredName = "(unknown name if difmes == 0: newwatt = oldwatt # simcount verwenden wenn newwattk = 0 @@ -255,6 +255,11 @@ def sepwatt(oldwatt,oldwattk,nummer): argumentList.append(measureurlc) except: argumentList.append("none") + try: + device_stateurl = str(config.get('smarthomedevices', 'device_stateurl_'+str(nummer))) + argumentList.append(device_stateurl) + except: + argumentList.append("undef") elif meastyp == "json": argumentList[1] = prefixpy + 'json/watt.py' try: diff --git a/web/settings/smarthomeconfig.php b/web/settings/smarthomeconfig.php index ef7bce925..27ea29ca7 100644 --- a/web/settings/smarthomeconfig.php +++ b/web/settings/smarthomeconfig.php @@ -207,6 +207,18 @@ +
+ +
+ + + Die hier angegebene URL wird aufgerufen, um den aktuellen Status (1 = an, 0 = aus) des Geräts zu erhalten. Falls keine URL vorhanden ist, kann die folgende URL angebenen werden:
+ 127.0.0.1/openWB/modules/smarthome/http/dummyurlstate.php. Diese URL gibt immer den Wert 0 zurück.(Device immer aus)
+ 127.0.0.1/openWB/modules/smarthome/http/dummyurlstate1.php?d=nummerdevice. Diese URL gibt den Wert 0 oder 1 zurück. Je nachdem ob das Smarthomedevice gerade läuft bzw. laufen soll.
+ 127.0.0.1/openWB/modules/smarthome/http/dummyurlstate2.php. Diese URL gibt immer den Wert 1 zurück. (Device immer an)
+
+
+
diff --git a/web/settings/topicsToSubscribe_smarthomeconfig.js b/web/settings/topicsToSubscribe_smarthomeconfig.js index 558141dec..dade808ba 100644 --- a/web/settings/topicsToSubscribe_smarthomeconfig.js +++ b/web/settings/topicsToSubscribe_smarthomeconfig.js @@ -36,6 +36,7 @@ var topicsToSubscribe = [ ["openWB/config/get/SmartHome/Devices/+/device_einschalturl", 0], ["openWB/config/get/SmartHome/Devices/+/device_ausschalturl", 0], ["openWB/config/get/SmartHome/Devices/+/device_leistungurl", 0], + ["openWB/config/get/SmartHome/Devices/+/device_stateurl", 0], ["openWB/config/get/SmartHome/Devices/+/device_measureurl", 0], ["openWB/config/get/SmartHome/Devices/+/device_measureurlc", 0], ["openWB/config/get/SmartHome/Devices/+/device_username", 0], From dc36c11f03cfd1930469259af0552175f1057599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Tue, 16 Nov 2021 22:26:00 +0100 Subject: [PATCH 44/66] mqttsub: fix tabs space --- runs/mqttsub.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runs/mqttsub.py b/runs/mqttsub.py index f65d22d24..20a1dd92d 100644 --- a/runs/mqttsub.py +++ b/runs/mqttsub.py @@ -252,7 +252,7 @@ def on_message(client, userdata, msg): if ( 1 <= int(devicenumb) <= numberOfSupportedDevices ): writetoconfig(shconfigfile,'smarthomedevices','device_leistungurl_'+str(devicenumb), msg.payload.decode("utf-8")) client.publish("openWB/config/get/SmartHome/Devices/"+str(devicenumb)+"/device_leistungurl", msg.payload.decode("utf-8"), qos=0, retain=True) - if (( "openWB/config/set/SmartHome/Device" in msg.topic) and ("device_stateurl" in msg.topic)): + if (( "openWB/config/set/SmartHome/Device" in msg.topic) and ("device_stateurl" in msg.topic)): devicenumb=re.sub(r'\D', '', msg.topic) if ( 1 <= int(devicenumb) <= numberOfSupportedDevices ): writetoconfig(shconfigfile,'smarthomedevices','device_stateurl_'+str(devicenumb), msg.payload.decode("utf-8")) From d27c7b87700958f047a930cdfe29732466fe5b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Tue, 16 Nov 2021 22:29:05 +0100 Subject: [PATCH 45/66] mqttsub: fix --- runs/smarthomehandler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runs/smarthomehandler.py b/runs/smarthomehandler.py index 1e9e20f86..9ed17d41d 100644 --- a/runs/smarthomehandler.py +++ b/runs/smarthomehandler.py @@ -199,7 +199,7 @@ def sepwatt(oldwatt,oldwattk,nummer): try: configuredName = config.get('smarthomedevices', 'device_name_'+str(nummer)) except: - configuredName = "(unknown name + configuredName = "(unknown name)" if difmes == 0: newwatt = oldwatt # simcount verwenden wenn newwattk = 0 From 8cd5d34031336746fc5b891c62c0d55e0ee83a3a Mon Sep 17 00:00:00 2001 From: matzempc Date: Sat, 27 Nov 2021 10:46:14 +0100 Subject: [PATCH 46/66] smarthome http: fix and hardened urlstate handling --- modules/smarthome/http/watt.py | 9 ++++++--- runs/smarthomehandler.py | 11 ++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/modules/smarthome/http/watt.py b/modules/smarthome/http/watt.py index b3d65b347..35ec2e30e 100644 --- a/modules/smarthome/http/watt.py +++ b/modules/smarthome/http/watt.py @@ -20,12 +20,12 @@ except: urlc = "none" try: - urlstate=str(sys.argv[6]) + urlstate=str(sys.argv[8]) except: urlstate = "none" if not urlparse(url).scheme: url = 'http://' + url -if not urlparse(urlstate).scheme: +if not urlparse(urlstate).scheme and urlstate is not "none": urlstate = 'http://' + urlstate if uberschuss < 0: uberschuss = 0 @@ -37,7 +37,10 @@ f = open( file_string , 'w') print ('%s devicenr %s orig url %s replaced url %s urlc %s urlstate %s'% (time_string,devicenumber,url,urlrep,urlc,urlstate),file=f) f.close() -state = int(urllib.request.urlopen(urlstate, timeout=5).read().decode("utf-8")) +if urlstate is not "none": + state = int(urllib.request.urlopen(urlstate, timeout=5).read().decode("utf-8")) +else: + state = 0 aktpowerfl = float(urllib.request.urlopen(urlrep, timeout=5).read().decode("utf-8")) aktpower = int(aktpowerfl) if state == 1 or aktpower > 50: diff --git a/runs/smarthomehandler.py b/runs/smarthomehandler.py index 06900ebff..2e0eee563 100644 --- a/runs/smarthomehandler.py +++ b/runs/smarthomehandler.py @@ -255,11 +255,6 @@ def sepwatt(oldwatt,oldwattk,nummer): argumentList.append(measureurlc) except: argumentList.append("none") - try: - device_stateurl = str(config.get('smarthomedevices', 'device_stateurl_'+str(nummer))) - argumentList.append(device_stateurl) - except: - argumentList.append("undef") elif meastyp == "json": argumentList[1] = prefixpy + 'json/watt.py' try: @@ -725,6 +720,11 @@ def getdevicevalues(): device_homeconsumtion = int(config.get('smarthomedevices', 'device_homeconsumtion_'+str(numberOfDevices))) except: device_homeconsumtion = 0 + try: + device_stateurl = str(config.get('smarthomedevices', 'device_stateurl_'+str(numberOfDevices))) + except: + device_stateurl = "none" + pyname0 = getdir(switchtyp,devicename) try: pyname = pyname0 +"/watt.py" @@ -740,6 +740,7 @@ def getdevicevalues(): argumentList.append(device_actor) argumentList.append(device_username) argumentList.append(device_password) + argumentList.append(device_stateurl) try: proc=subprocess.Popen(argumentList) proc.communicate() From c0beed5df11c29fe9836db3e6ad4a87921d13624 Mon Sep 17 00:00:00 2001 From: matzempc Date: Sat, 27 Nov 2021 11:11:19 +0100 Subject: [PATCH 47/66] smarthome http: set stateurl input to not required - shall be only optional value --- web/settings/smarthomeconfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/settings/smarthomeconfig.php b/web/settings/smarthomeconfig.php index b6286a894..98cb3dff1 100644 --- a/web/settings/smarthomeconfig.php +++ b/web/settings/smarthomeconfig.php @@ -210,7 +210,7 @@
- + Die hier angegebene URL wird aufgerufen, um den aktuellen Status (1 = an, 0 = aus) des Geräts zu erhalten. Falls keine URL vorhanden ist, kann die folgende URL angebenen werden:
127.0.0.1/openWB/modules/smarthome/http/dummyurlstate.php. Diese URL gibt immer den Wert 0 zurück.(Device immer aus)
From 2983f3e99728350afb8780c5ef975f4e3f05b642 Mon Sep 17 00:00:00 2001 From: matzempc Date: Sat, 27 Nov 2021 11:35:05 +0100 Subject: [PATCH 48/66] smarthome http: fix stateurl handling in case of is "none" --- modules/smarthome/http/watt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 modules/smarthome/http/watt.py diff --git a/modules/smarthome/http/watt.py b/modules/smarthome/http/watt.py old mode 100644 new mode 100755 index 35ec2e30e..31ad3c3d6 --- a/modules/smarthome/http/watt.py +++ b/modules/smarthome/http/watt.py @@ -25,7 +25,7 @@ urlstate = "none" if not urlparse(url).scheme: url = 'http://' + url -if not urlparse(urlstate).scheme and urlstate is not "none": +if not urlparse(urlstate).scheme and not urlstate.startswith("none"): urlstate = 'http://' + urlstate if uberschuss < 0: uberschuss = 0 @@ -37,7 +37,7 @@ f = open( file_string , 'w') print ('%s devicenr %s orig url %s replaced url %s urlc %s urlstate %s'% (time_string,devicenumber,url,urlrep,urlc,urlstate),file=f) f.close() -if urlstate is not "none": +if not urlstate.startswith("none"): state = int(urllib.request.urlopen(urlstate, timeout=5).read().decode("utf-8")) else: state = 0 From 151ab2847424c712c0cd2250dc1e8e02480d5d34 Mon Sep 17 00:00:00 2001 From: matzempc Date: Sat, 27 Nov 2021 12:00:26 +0100 Subject: [PATCH 49/66] web smarthome settings: http stateurl - fixed and adapted description --- web/settings/smarthomeconfig.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/web/settings/smarthomeconfig.php b/web/settings/smarthomeconfig.php index 98cb3dff1..144492f30 100644 --- a/web/settings/smarthomeconfig.php +++ b/web/settings/smarthomeconfig.php @@ -212,10 +212,9 @@
- Die hier angegebene URL wird aufgerufen, um den aktuellen Status (1 = an, 0 = aus) des Geräts zu erhalten. Falls keine URL vorhanden ist, kann die folgende URL angebenen werden:
- 127.0.0.1/openWB/modules/smarthome/http/dummyurlstate.php. Diese URL gibt immer den Wert 0 zurück.(Device immer aus)
- 127.0.0.1/openWB/modules/smarthome/http/dummyurlstate1.php?d=nummerdevice. Diese URL gibt den Wert 0 oder 1 zurück. Je nachdem ob das Smarthomedevice gerade läuft bzw. laufen soll.
- 127.0.0.1/openWB/modules/smarthome/http/dummyurlstate2.php. Diese URL gibt immer den Wert 1 zurück. (Device immer an)
+ Die hier angegebene URL wird aufgerufen, um den aktuellen Status (1 = an, 0 = aus) des Geräts zu erhalten.
+ Der Parameter ist optional und kann somit auch leer gelassen werden. In diesem Fall wird der Parameter mit "none" vorbelegt und + die Erkennung, ob das Gerät angeschaltet ist, wird weiterhin über die Leistung ermittelt.
From b0b0f1df6d995d0bb2d777344d0862ec46ec9c9d Mon Sep 17 00:00:00 2001 From: matzempc Date: Sat, 27 Nov 2021 13:28:15 +0100 Subject: [PATCH 50/66] smarthome http: defensive programming / hardened watt.py on stateurl handling --- modules/smarthome/http/watt.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/modules/smarthome/http/watt.py b/modules/smarthome/http/watt.py index 31ad3c3d6..530780a7f 100755 --- a/modules/smarthome/http/watt.py +++ b/modules/smarthome/http/watt.py @@ -11,7 +11,7 @@ import urllib.request from urllib.parse import urlparse named_tuple = time.localtime() # getstruct_time -time_string = time.strftime("%m/%d/%Y, %H:%M:%S http watty.py", named_tuple) +time_string = time.strftime("%m/%d/%Y, %H:%M:%S http watt.py", named_tuple) devicenumber=str(sys.argv[1]) uberschuss=int(sys.argv[3]) url=str(sys.argv[4]) @@ -36,11 +36,23 @@ else: f = open( file_string , 'w') print ('%s devicenr %s orig url %s replaced url %s urlc %s urlstate %s'% (time_string,devicenumber,url,urlrep,urlc,urlstate),file=f) -f.close() if not urlstate.startswith("none"): - state = int(urllib.request.urlopen(urlstate, timeout=5).read().decode("utf-8")) + stateurl_response = 0 + try: + stateurl_response = urllib.request.urlopen(urlstate, timeout=5).read().decode("utf-8") + except urllib.error.HTTPError as e: + print('%s StateURL HTTP Error: %d'%(time_string,e.code),file=f) + except urllib.error.URLError as e: + print('%s StateURL URL Error: %s'%(time_string,e.reason),file=f) + try: + state = int(stateurl_response) + except ValueError: + print ('%s StateURL delivered no integer but: %s'%(time_string,stateurl_response),file=f) + state = 0 else: state = 0 +f.close() +aktpowerfl = 20 aktpowerfl = float(urllib.request.urlopen(urlrep, timeout=5).read().decode("utf-8")) aktpower = int(aktpowerfl) if state == 1 or aktpower > 50: From 057c3d32a752a297d7af1b507ce04e0cd55d42af Mon Sep 17 00:00:00 2001 From: matzempc Date: Sat, 27 Nov 2021 13:32:59 +0100 Subject: [PATCH 51/66] smarthome http: removed testvalue on watt.py --- modules/smarthome/http/watt.py | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/smarthome/http/watt.py b/modules/smarthome/http/watt.py index 530780a7f..0dc45cf70 100755 --- a/modules/smarthome/http/watt.py +++ b/modules/smarthome/http/watt.py @@ -52,7 +52,6 @@ else: state = 0 f.close() -aktpowerfl = 20 aktpowerfl = float(urllib.request.urlopen(urlrep, timeout=5).read().decode("utf-8")) aktpower = int(aktpowerfl) if state == 1 or aktpower > 50: From ea0871275a390d0c1a39fb6b9a67487386bf8363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Mon, 13 Dec 2021 20:34:26 +0100 Subject: [PATCH 52/66] Merged --- .github/workflows/github-actions-python.yml | 2 +- loadvars.sh | 6 +- modules/bezug_solax/main.sh | 22 +- modules/bezug_solax/solax.py | 61 ---- modules/bezug_sonneneco/sonneneco.py | 109 +++--- modules/bezug_sungrow/main.sh | 27 +- modules/bezug_sungrow/sungrow.py | 32 -- modules/bezug_victrongx/main.sh | 22 +- modules/bezug_victrongx/victron.py | 115 ------- modules/soc_manual/main.sh | 135 +------- modules/soc_manual/soc_manual.py | 60 ++++ modules/soc_manual/soc_manual_test.py | 60 ++++ modules/speicher_bydhv/byd.py | 80 ++--- modules/speicher_fems/fems.py | 12 +- modules/speicher_saxpower/main.sh | 21 +- modules/speicher_saxpower/saxpower.py | 34 -- modules/speicher_solax/main.sh | 20 +- modules/speicher_solax/solax.py | 36 -- modules/speicher_sonneneco/sonneneco.py | 92 ++++-- modules/speicher_studer/main.sh | 20 +- modules/speicher_studer/studer_speicher.py | 71 ---- modules/speicher_sungrow/main.sh | 20 +- modules/speicher_sungrow/sungrow.py | 37 --- modules/speicher_sunnyisland/main.sh | 20 +- modules/speicher_sunnyisland/sbs25.py | 43 --- modules/speicher_sunnyisland/sunnyisland.py | 54 --- modules/speicher_victron/main.sh | 20 +- modules/speicher_victron/victron_speicher.py | 61 ---- modules/wr2_kostalpiko/main.sh | 23 +- modules/wr2_kostalpikovar2/main.sh | 42 +-- modules/wr2_kostalsteca/kostal_steca.py | 74 +++++ modules/wr2_kostalsteca/main.sh | 56 +--- modules/wr2_solax/main.sh | 22 +- modules/wr2_solax/solax.py | 47 --- modules/wr2_sungrow/main.sh | 24 +- modules/wr2_sungrow/sungrow.py | 22 -- modules/wr2_victron/main.sh | 22 +- modules/wr2_victron/victron.py | 29 -- modules/wr_discovergy/discovergy.py | 52 +++ modules/wr_discovergy/main.sh | 32 +- modules/wr_fems/fems.py | 53 +++ modules/wr_fems/main.sh | 32 +- modules/wr_fronius/fronius.py | 110 +++++++ modules/wr_fronius/main.sh | 70 ++-- modules/wr_http/main.sh | 37 ++- modules/wr_http/read_http.py | 51 +++ modules/wr_json/read_json.py | 26 +- modules/wr_kostalpiko/kostal_piko_var1.py | 64 ++++ modules/wr_kostalpiko/main.sh | 41 ++- modules/wr_kostalpikovar2/kostal_piko_var2.py | 76 +++++ modules/wr_kostalpikovar2/main.sh | 60 ++-- modules/wr_lgessv1/lgessv1.py | 144 ++++++++ modules/wr_lgessv1/main.sh | 104 ++---- modules/wr_powerwall/main.sh | 69 ++-- modules/wr_powerwall/powerwall.py | 97 ++++++ modules/wr_shelly/main.sh | 2 +- modules/wr_shelly/shellywr.py | 14 +- modules/wr_smartme/main.sh | 48 ++- modules/wr_smartme/smartme.py | 70 ++++ modules/wr_solaredge/main.sh | 7 +- modules/wr_solaredge/solaredgeall.py | 309 +++++------------- modules/wr_solarlog/main.sh | 27 +- modules/wr_solarlog/solarlog.py | 49 +++ modules/wr_solarview/main.sh | 162 ++------- modules/wr_solarview/solarview.py | 165 ++++++++++ modules/wr_solarwatt/main.sh | 32 +- modules/wr_solarwatt/solarwatt.py | 41 +++ modules/wr_solarworld/main.sh | 31 +- modules/wr_solarworld/solarworld.py | 45 +++ modules/wr_solax/main.sh | 22 +- modules/wr_solax/solax.py | 51 --- modules/wr_studer/main.sh | 23 +- modules/wr_studer/studer_wr.py | 81 ----- modules/wr_sungrow/main.sh | 24 +- modules/wr_sungrow/sungrow.py | 23 -- modules/wr_sunwaves/main.sh | 45 ++- modules/wr_sunwaves/sunwaves.py | 48 +++ modules/wr_sunways/main.sh | 40 ++- modules/wr_sunways/sunways.py | 50 +++ modules/wr_tripower9000/main.sh | 31 +- modules/wr_tripower9000/tri9000.py | 37 --- modules/wr_tripower9000/tri90002.py | 64 ---- modules/wr_tripower9000/tri90003.py | 70 ---- modules/wr_tripower9000/tri90004.py | 87 ----- modules/wr_tripower9000/tripower.py | 101 ++++++ modules/wr_victron/main.sh | 20 +- modules/wr_victron/victron.py | 56 ---- modules/wr_youless120/main.sh | 41 +-- modules/wr_youless120/youless.py | 63 ++++ packages/helpermodules/cli/__init__.py | 1 + .../cli/_run_using_positional_cli_args.py | 19 ++ .../_run_using_positional_cli_args_test.py | 63 ++++ packages/modules/common/component_state.py | 2 +- packages/modules/common/store/__init__.py | 2 + packages/modules/common/store/_ramdisk.py | 33 +- packages/modules/saxpower/__init__.py | 0 packages/modules/saxpower/bat.py | 47 +++ packages/modules/saxpower/device.py | 96 ++++++ packages/modules/solax/__init__.py | 0 packages/modules/solax/bat.py | 47 +++ packages/modules/solax/counter.py | 41 +++ packages/modules/solax/device.py | 101 ++++++ packages/modules/solax/inverter.py | 38 +++ packages/modules/studer/__init__.py | 0 packages/modules/studer/bat.py | 41 +++ packages/modules/studer/device.py | 114 +++++++ packages/modules/studer/inverter.py | 66 ++++ packages/modules/sungrow/__init__.py | 0 packages/modules/sungrow/bat.py | 52 +++ packages/modules/sungrow/counter.py | 55 ++++ packages/modules/sungrow/device.py | 113 +++++++ packages/modules/sungrow/inverter.py | 45 +++ packages/modules/sunny_island/__init__.py | 0 packages/modules/sunny_island/bat.py | 40 +++ packages/modules/sunny_island/device.py | 97 ++++++ packages/modules/victron/__init__.py | 0 packages/modules/victron/bat.py | 47 +++ packages/modules/victron/counter.py | 49 +++ packages/modules/victron/device.py | 107 ++++++ packages/modules/victron_inverter/__init__.py | 0 packages/modules/victron_inverter/device.py | 96 ++++++ packages/modules/victron_inverter/inverter.py | 57 ++++ packages/test_utils/__init__.py | 0 packages/test_utils/mock_ramdisk.py | 42 +++ runs/atreboot.sh | 12 +- runs/cron5min.sh | 5 + runs/cronnightly.sh | 25 ++ runs/initRamdisk.sh | 1 - runs/mqttsub.py | 34 +- runs/pubmqtt.sh | 2 + runs/set-current.sh | 26 +- runs/u1p3pcheck.sh | 57 ++++ runs/updateConfig.sh | 10 + web/settings/modulconfiglp.php | 81 ++++- web/themes/colors/chargePointList.js | 2 + web/themes/colors/powerdata.js | 2 + web/themes/colors/pricechart.js | 11 +- web/themes/colors/style.css | 17 +- web/themes/colors/theme.html | 129 ++++---- 139 files changed, 4269 insertions(+), 2406 deletions(-) delete mode 100644 modules/bezug_solax/solax.py delete mode 100644 modules/bezug_sungrow/sungrow.py delete mode 100755 modules/bezug_victrongx/victron.py create mode 100644 modules/soc_manual/soc_manual.py create mode 100644 modules/soc_manual/soc_manual_test.py delete mode 100644 modules/speicher_saxpower/saxpower.py delete mode 100644 modules/speicher_solax/solax.py delete mode 100644 modules/speicher_studer/studer_speicher.py delete mode 100644 modules/speicher_sungrow/sungrow.py delete mode 100755 modules/speicher_sunnyisland/sbs25.py delete mode 100755 modules/speicher_sunnyisland/sunnyisland.py delete mode 100644 modules/speicher_victron/victron_speicher.py create mode 100755 modules/wr2_kostalsteca/kostal_steca.py mode change 100644 => 100755 modules/wr2_solax/main.sh delete mode 100644 modules/wr2_solax/solax.py delete mode 100644 modules/wr2_sungrow/sungrow.py delete mode 100644 modules/wr2_victron/victron.py create mode 100755 modules/wr_discovergy/discovergy.py create mode 100755 modules/wr_fems/fems.py create mode 100644 modules/wr_fronius/fronius.py create mode 100755 modules/wr_http/read_http.py mode change 100644 => 100755 modules/wr_json/read_json.py create mode 100755 modules/wr_kostalpiko/kostal_piko_var1.py create mode 100755 modules/wr_kostalpikovar2/kostal_piko_var2.py create mode 100755 modules/wr_lgessv1/lgessv1.py create mode 100755 modules/wr_powerwall/powerwall.py create mode 100755 modules/wr_smartme/smartme.py create mode 100755 modules/wr_solarlog/solarlog.py mode change 100755 => 100644 modules/wr_solarview/main.sh create mode 100755 modules/wr_solarview/solarview.py create mode 100644 modules/wr_solarwatt/solarwatt.py create mode 100644 modules/wr_solarworld/solarworld.py mode change 100644 => 100755 modules/wr_solax/main.sh delete mode 100644 modules/wr_solax/solax.py delete mode 100644 modules/wr_studer/studer_wr.py delete mode 100644 modules/wr_sungrow/sungrow.py create mode 100755 modules/wr_sunwaves/sunwaves.py create mode 100755 modules/wr_sunways/sunways.py delete mode 100755 modules/wr_tripower9000/tri9000.py delete mode 100755 modules/wr_tripower9000/tri90002.py delete mode 100755 modules/wr_tripower9000/tri90003.py delete mode 100755 modules/wr_tripower9000/tri90004.py create mode 100755 modules/wr_tripower9000/tripower.py delete mode 100644 modules/wr_victron/victron.py create mode 100755 modules/wr_youless120/youless.py create mode 100644 packages/helpermodules/cli/__init__.py create mode 100644 packages/helpermodules/cli/_run_using_positional_cli_args.py create mode 100644 packages/helpermodules/cli/_run_using_positional_cli_args_test.py create mode 100644 packages/modules/saxpower/__init__.py create mode 100644 packages/modules/saxpower/bat.py create mode 100644 packages/modules/saxpower/device.py create mode 100644 packages/modules/solax/__init__.py create mode 100644 packages/modules/solax/bat.py create mode 100644 packages/modules/solax/counter.py create mode 100644 packages/modules/solax/device.py create mode 100644 packages/modules/solax/inverter.py create mode 100644 packages/modules/studer/__init__.py create mode 100644 packages/modules/studer/bat.py create mode 100644 packages/modules/studer/device.py create mode 100644 packages/modules/studer/inverter.py create mode 100644 packages/modules/sungrow/__init__.py create mode 100644 packages/modules/sungrow/bat.py create mode 100644 packages/modules/sungrow/counter.py create mode 100644 packages/modules/sungrow/device.py create mode 100644 packages/modules/sungrow/inverter.py create mode 100644 packages/modules/sunny_island/__init__.py create mode 100644 packages/modules/sunny_island/bat.py create mode 100644 packages/modules/sunny_island/device.py create mode 100644 packages/modules/victron/__init__.py create mode 100644 packages/modules/victron/bat.py create mode 100644 packages/modules/victron/counter.py create mode 100644 packages/modules/victron/device.py create mode 100644 packages/modules/victron_inverter/__init__.py create mode 100644 packages/modules/victron_inverter/device.py create mode 100644 packages/modules/victron_inverter/inverter.py create mode 100644 packages/test_utils/__init__.py create mode 100644 packages/test_utils/mock_ramdisk.py diff --git a/.github/workflows/github-actions-python.yml b/.github/workflows/github-actions-python.yml index 18de6ec73..cd95e3802 100644 --- a/.github/workflows/github-actions-python.yml +++ b/.github/workflows/github-actions-python.yml @@ -21,4 +21,4 @@ jobs: path: packages - name: Test with pytest run: | - cd packages && python -m pytest + PYTHONPATH=packages python -m pytest packages modules diff --git a/loadvars.sh b/loadvars.sh index 1f944fd38..69f0c30e3 100755 --- a/loadvars.sh +++ b/loadvars.sh @@ -1028,7 +1028,7 @@ loadvars(){ echo $hausverbrauch > /var/www/html/openWB/ramdisk/hausverbrauch fronius_sm_bezug_meterlocation=$( /var/www/html/openWB/ramdisk/pvallwh fi - if [[ $speichermodul == "speicher_e3dc" ]] || [[ $speichermodul == "speicher_huawei" ]] || [[ $speichermodul == "speicher_tesvoltsma" ]] || [[ $speichermodul == "speicher_solarwatt" ]] || [[ $speichermodul == "speicher_rct" ]]|| [[ $speichermodul == "speicher_sungrow" ]] || [[ $speichermodul == "speicher_lgessv1" ]] || [[ $speichermodul == "speicher_bydhv" ]] || [[ $speichermodul == "speicher_kostalplenticore" ]] || [[ $speichermodul == "speicher_powerwall" ]] || [[ $speichermodul == "speicher_sbs25" ]] || [[ $speichermodul == "speicher_solaredge" ]] || [[ $speichermodul == "speicher_sonneneco" ]] || [[ $speichermodul == "speicher_varta" ]] || [[ $speichermodul == "speicher_saxpower" ]] || [[ $speichermodul == "speicher_victron" ]] || [[ $speichermodul == "speicher_fronius" ]] ; then + if [[ $speichermodul == "speicher_e3dc" ]] || [[ $speichermodul == "speicher_huawei" ]] || [[ $speichermodul == "speicher_tesvoltsma" ]] || [[ $speichermodul == "speicher_solarwatt" ]] || [[ $speichermodul == "speicher_rct" ]]|| [[ $speichermodul == "speicher_lgessv1" ]] || [[ $speichermodul == "speicher_bydhv" ]] || [[ $speichermodul == "speicher_kostalplenticore" ]] || [[ $speichermodul == "speicher_powerwall" ]] || [[ $speichermodul == "speicher_sbs25" ]] || [[ $speichermodul == "speicher_solaredge" ]] || [[ $speichermodul == "speicher_sonneneco" ]] || [[ $speichermodul == "speicher_varta" ]] || [[ $speichermodul == "speicher_fronius" ]] ; then ra='^-?[0-9]+$' watt2=$(>${MYLOGFILE} 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "EVU RET: ${ret}" + +wattbezug=$(<${RAMDISKDIR}/wattbezug) echo $wattbezug diff --git a/modules/bezug_solax/solax.py b/modules/bezug_solax/solax.py deleted file mode 100644 index d3555070d..000000000 --- a/modules/bezug_solax/solax.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient -from pymodbus.factory import ClientDecoder - -def unsigned32(result, addr): - low = result.registers[addr] - high = result.registers[addr + 1] - val = low +( high << 16) - return val - -def unsigned16 (result, addr): - return result.registers[addr] - -def signed16(result, addr): - val = result.registers[addr] - if val > 32767: - val -= 65535 - return val - -def signed32(result, addr): - val = unsigned32(result, addr) - if val > 2147483647: - val -= 4294967295 - return val - -ipaddress = str(sys.argv[1]) -client = ModbusTcpClient(ipaddress, port=502) - -resp=client.read_input_registers(0, 114) - -value = signed32(resp, 70) -# for SolaX negative means get power from grid -value = -value - -f = open('/var/www/html/openWB/ramdisk/wattbezug', 'w') -f.write(str(value)) -f.close() - -frequenz = unsigned16(resp,7) / 100 -print (frequenz) -f = open('/var/www/html/openWB/ramdisk/evuhz', 'w') -f.write(str(frequenz)) -f.close() - -consumed = unsigned32(resp,74) / 100 -print (consumed) -f = open('/var/www/html/openWB/ramdisk/bezugkwh', 'w') -f.write(str(consumed)) -f.close() - -einspeisung = unsigned32(resp,72) / 100 -f = open('/var/www/html/openWB/ramdisk/einspeisungkwh', 'w') -f.write(str(einspeisung)) -f.close() diff --git a/modules/bezug_sonneneco/sonneneco.py b/modules/bezug_sonneneco/sonneneco.py index 822cb2780..41b25d287 100644 --- a/modules/bezug_sonneneco/sonneneco.py +++ b/modules/bezug_sonneneco/sonneneco.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 from datetime import datetime, timezone import os +import re import requests import sys import traceback @@ -12,10 +13,21 @@ myPid = str(os.getpid()) -def DebugLog(message): +def DebugLog(message: str) -> None: local_time = datetime.now(timezone.utc).astimezone() print(local_time.strftime(format="%Y-%m-%d %H:%M:%S") + ": PID: " + myPid + ": " + message) +ra = '^-?[0-9]+(\.[0-9]+)?$' # re for valid float as str + +def check_write_value(valueString: str, file: str, fallback: str = "0") -> None: + if re.search(ra, valueString) == None: + DebugLog('invalid valueString: ' + valueString + ' setting fallback of \'' + fallback + '\'') + valueString = fallback + if Debug >= 1: + DebugLog(file+': ' + valueString) + with open("/var/www/html/openWB/ramdisk/" + file, "w") as f: + f.write(valueString) + if Debug >= 2: DebugLog('Sonneneco Alternativ: ' + sonnenecoalternativ) @@ -23,15 +35,50 @@ def DebugLog(message): # Auslesen einer Sonnbenbatterie Eco 4.5 über die integrierte JSON-API des Batteriesystems if sonnenecoalternativ == 2: - evu_bezug = int(requests.get('http://' + sonnenecoip + ':7979/rest/devices/battery/M39', timeout=5).text) - evu_einspeisung = int(requests.get('http://' + sonnenecoip + ':7979/rest/devices/battery/M38', timeout=5).text) + baseurl = 'http://' + sonnenecoip + ':7979/rest/devices/battery/' + evu_bezug = int(requests.get(baseurl + 'M39', timeout=5).text) + evu_einspeisung = int(requests.get(baseurl + 'M38', timeout=5).text) wattbezug = evu_bezug - evu_einspeisung - - with open("/var/www/html/openWB/ramdisk/wattbezug", "w") as f: - f.write(str(wattbezug)) + check_write_value(str(wattbezug), "wattbezug") else: if sonnenecoalternativ == 1: speicherantwort = requests.get("http://"+sonnenecoip+"/api/v1/status", timeout=5).json() + ''' + example data: + { + "Apparent_output": 225, + "BackupBuffer": "0", + "BatteryCharging": false, + "BatteryDischarging": false, + "Consumption_Avg": 2114, + "Consumption_W": 2101, + "Fac": 49.97200393676758, + "FlowConsumptionBattery": false, + "FlowConsumptionGrid": true, + "FlowConsumptionProduction": false, + "FlowGridBattery": false, + "FlowProductionBattery": false, + "FlowProductionGrid": false, + "GridFeedIn_W": -2106, + "IsSystemInstalled": 1, + "OperatingMode": "2", + "Pac_total_W": -5, + "Production_W": 0, + "RSOC": 6, + "RemainingCapacity_Wh": 2377, + "Sac1": 75, + "Sac2": 75, + "Sac3": 75, + "SystemStatus": "OnGrid", + "Timestamp": "2021-12-13 07:54:48", + "USOC": 0, + "Uac": 231, + "Ubat": 48, + "dischargeNotAllowed": true, + "generator_autostart": false, + "NVM_REINIT_STATUS": 0 + } + ''' try: wattbezug = speicherantwort["GridFeedIn_W"] except: @@ -73,41 +120,23 @@ def DebugLog(message): # Schreibe alle Werte in die Ramdisk. if Debug >= 1: DebugLog('Leistung: ' + str(wattbezug)) - with open("/var/www/html/openWB/ramdisk/wattbezug", "w") as f: - f.write(str(wattbezug)) - with open("/var/www/html/openWB/ramdisk/evuv1", "w") as f: - f.write(str(evuv1)) - with open("/var/www/html/openWB/ramdisk/evuv2", "w") as f: - f.write(str(evuv2)) - with open("/var/www/html/openWB/ramdisk/evuv3", "w") as f: - f.write(str(evuv3)) - with open("/var/www/html/openWB/ramdisk/bezugw1", "w") as f: - f.write(str(bezugw1)) - with open("/var/www/html/openWB/ramdisk/bezugw2", "w") as f: - f.write(str(bezugw2)) - with open("/var/www/html/openWB/ramdisk/bezugw3", "w") as f: - f.write(str(bezugw3)) - with open("/var/www/html/openWB/ramdisk/bezuga1", "w") as f: - f.write(str(bezuga1)) - with open("/var/www/html/openWB/ramdisk/bezuga2", "w") as f: - f.write(str(bezuga2)) - with open("/var/www/html/openWB/ramdisk/bezuga3", "w") as f: - f.write(str(bezuga3)) - with open("/var/www/html/openWB/ramdisk/evuhz", "w") as f: - f.write(str(evuhz)) - with open("/var/www/html/openWB/ramdisk/evupf1", "w") as f: - f.write(str(evupf1)) - with open("/var/www/html/openWB/ramdisk/evupf2", "w") as f: - f.write(str(evupf2)) - with open("/var/www/html/openWB/ramdisk/evupf3", "w") as f: - f.write(str(evupf3)) - if Debug >= 1: DebugLog('Import: ' + str(ikwh)) - with open("/var/www/html/openWB/ramdisk/bezugkwh", "w") as f: - f.write(str(ikwh)) - if Debug >= 1: DebugLog('Export: ' + str(ekwh)) - with open("/var/www/html/openWB/ramdisk/einspeisungkwh", "w") as f: - f.write(str(ekwh)) + check_write_value(str(wattbezug), "wattbezug") + check_write_value(str(evuv1), "evuv1") + check_write_value(str(evuv2), "evuv2") + check_write_value(str(evuv3), "evuv3") + check_write_value(str(bezugw1), "bezugw1") + check_write_value(str(bezugw2), "bezugw2") + check_write_value(str(bezugw3), "bezugw3") + check_write_value(str(bezuga1), "bezuga1") + check_write_value(str(bezuga2), "bezuga2") + check_write_value(str(bezuga3), "bezuga3") + check_write_value(str(evuhz), "evuhz") + check_write_value(str(evupf1), "evupf1") + check_write_value(str(evupf2), "evupf2") + check_write_value(str(evupf3), "evupf3") + check_write_value(str(ikwh), "bezugkwh") + check_write_value(str(ekwh), "einspeisungkwh") exit(0) diff --git a/modules/bezug_sungrow/main.sh b/modules/bezug_sungrow/main.sh index 366ecdcf4..c8b71c3ee 100644 --- a/modules/bezug_sungrow/main.sh +++ b/modules/bezug_sungrow/main.sh @@ -1,5 +1,24 @@ -#!/bin/bash +#!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="EVU" +DMOD="MAIN" +Debug=$debug -python /var/www/html/openWB/modules/bezug_sungrow/sungrow.py $speicher1_ip $sungrowsr -wattbezug=$(>${MYLOGFILE} 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "EVU RET: ${ret}" + +wattbezug=$(<${RAMDISKDIR}/wattbezug) +echo $wattbezug \ No newline at end of file diff --git a/modules/bezug_sungrow/sungrow.py b/modules/bezug_sungrow/sungrow.py deleted file mode 100644 index d641c2de8..000000000 --- a/modules/bezug_sungrow/sungrow.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) -srmode = int(sys.argv[2]) - -client = ModbusTcpClient(ipaddress, port=502) - -if srmode == 1: - resp= client.read_input_registers(5082,2,unit=1) - value1 = resp.registers[0] - value2 = resp.registers[1] - all = format(value2, '04x') + format(value1, '04x') - final = int(struct.unpack('>i', all.decode('hex'))[0]) -else: - resp= client.read_input_registers(13009,2,unit=1) - value1 = resp.registers[0] - value2 = resp.registers[1] - all = format(value2, '04x') + format(value1, '04x') - final = int(struct.unpack('>i', all.decode('hex'))[0]*-1) - -f = open('/var/www/html/openWB/ramdisk/wattbezug', 'w') -f.write(str(final)) -f.close() diff --git a/modules/bezug_victrongx/main.sh b/modules/bezug_victrongx/main.sh index f409bf7d6..9bef20774 100755 --- a/modules/bezug_victrongx/main.sh +++ b/modules/bezug_victrongx/main.sh @@ -1,6 +1,24 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="EVU" +DMOD="MAIN" +Debug=$debug -sudo python /var/www/html/openWB/modules/bezug_victrongx/victron.py $bezug_victronip $bezug_id +#For development only +#Debug=1 -wattbezug=$(>${MYLOGFILE} 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "EVU RET: ${ret}" + +wattbezug=$(<${RAMDISKDIR}/wattbezug) echo $wattbezug diff --git a/modules/bezug_victrongx/victron.py b/modules/bezug_victrongx/victron.py deleted file mode 100755 index 4a1f88900..000000000 --- a/modules/bezug_victrongx/victron.py +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -# import struct -# import binascii -from pymodbus.constants import Endian -from pymodbus.payload import BinaryPayloadDecoder -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) -modbid = int(sys.argv[2]) - -client = ModbusTcpClient(ipaddress, port=502) -connection = client.connect() - -# grid power -resp= client.read_holding_registers(2600,1,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -w1 = str(decoder.decode_16bit_int()) -resp= client.read_holding_registers(2601,1,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -w2 = str(decoder.decode_16bit_int()) -resp= client.read_holding_registers(2602,1,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -w3 = str(decoder.decode_16bit_int()) -watt = int(w1) + int(w2) + int(w3) -f = open('/var/www/html/openWB/ramdisk/wattbezug', 'w') -f.write(str(watt)) -f.close() - -# grid ampere -resp= client.read_holding_registers(2617,1,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -a1 = str(decoder.decode_16bit_int()) -a1 = float(a1) / 10 -resp= client.read_holding_registers(2619,1,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -a2 = str(decoder.decode_16bit_int()) -a2 = float(a2) / 10 -resp= client.read_holding_registers(2621,1,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -a3 = str(decoder.decode_16bit_int()) -a3 = float(a3) / 10 -f = open('/var/www/html/openWB/ramdisk/bezuga1', 'w') -f.write(str(a1)) -f.close() -f = open('/var/www/html/openWB/ramdisk/bezuga2', 'w') -f.write(str(a2)) -f.close() -f = open('/var/www/html/openWB/ramdisk/bezuga3', 'w') -f.write(str(a3)) -f.close() - -# grid voltage -resp= client.read_holding_registers(2616,1,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -v1 = str(decoder.decode_16bit_uint()) -v1 = float(v1) / 10 -resp= client.read_holding_registers(2618,1,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -v2 = str(decoder.decode_16bit_uint()) -v2 = float(v2) / 10 -resp= client.read_holding_registers(2620,1,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -v3 = str(decoder.decode_16bit_uint()) -v3 = float(v3) / 10 -f = open('/var/www/html/openWB/ramdisk/evuv1', 'w') -f.write(str(v1)) -f.close() -f = open('/var/www/html/openWB/ramdisk/evuv2', 'w') -f.write(str(v2)) -f.close() -f = open('/var/www/html/openWB/ramdisk/evuv3', 'w') -f.write(str(v3)) -f.close() - -# grid import -resp= client.read_holding_registers(2622,2,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -wh1 = str(decoder.decode_32bit_uint()) -resp= client.read_holding_registers(2624,2,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -wh2 = str(decoder.decode_32bit_uint()) -resp= client.read_holding_registers(2626,2,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -wh3 = str(decoder.decode_32bit_uint()) - -whs = int(wh1) + int(wh2) + int(wh3) -whs = whs * 10 -f = open('/var/www/html/openWB/ramdisk/bezugkwh', 'w') -f.write(str(whs)) -f.close() - -# grid export -resp= client.read_holding_registers(2628,2,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -whe1 = str(decoder.decode_32bit_uint()) -resp= client.read_holding_registers(2630,2,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -whe2 = str(decoder.decode_32bit_uint()) -resp= client.read_holding_registers(2632,2,unit=modbid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -whe3 = str(decoder.decode_32bit_uint()) - -whes = int(whe1) + int(whe2) + int(whe3) -whes = whes * 10 -f = open('/var/www/html/openWB/ramdisk/einspeisungkwh', 'w') -f.write(str(whes)) -f.close() - -client.close() diff --git a/modules/soc_manual/main.sh b/modules/soc_manual/main.sh index 2f6312ac8..6c84c2a59 100644 --- a/modules/soc_manual/main.sh +++ b/modules/soc_manual/main.sh @@ -2,135 +2,8 @@ OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) RAMDISKDIR="$OPENWBBASEDIR/ramdisk" -MODULEDIR=$(cd `dirname $0` && pwd) -DMOD="EVSOC" -CHARGEPOINT=$1 +CHARGEPOINT=${1:-1} -# check if config file is already in env -if [[ -z "$debug" ]]; then - echo "soc_manual: Seems like openwb.conf is not loaded. Reading file." - # try to load config - . $OPENWBBASEDIR/loadconfig.sh - # load helperFunctions - . $OPENWBBASEDIR/helperFunctions.sh -fi - -case $CHARGEPOINT in - 2) - # second charge point - manualSocFile="$RAMDISKDIR/manual_soc_lp2" - manualMeterFile="$RAMDISKDIR/manual_soc_meter_lp2" - socFile="$RAMDISKDIR/soc1" - soctimerfile="$RAMDISKDIR/soctimer1" - socIntervall=1 # update every minute if script is called every 10 seconds - meterFile="$RAMDISKDIR/llkwhs1" - akkug=$akkuglp2 - efficiency=$wirkungsgradlp2 - ;; - *) - # defaults to first charge point for backward compatibility - # set CHARGEPOINT in case it is empty (needed for logging) - CHARGEPOINT=1 - manualSocFile="$RAMDISKDIR/manual_soc_lp1" - manualMeterFile="$RAMDISKDIR/manual_soc_meter_lp1" - socFile="$RAMDISKDIR/soc" - soctimerfile="$RAMDISKDIR/soctimer" - socIntervall=1 # update every minute if script is called every 10 seconds - meterFile="$RAMDISKDIR/llkwh" - akkug=$akkuglp1 - efficiency=$wirkungsgradlp1 - ;; -esac - -incrementTimer(){ - case $dspeed in - 1) - # Regelgeschwindigkeit 10 Sekunden - ticksize=1 - ;; - 2) - # Regelgeschwindigkeit 20 Sekunden - ticksize=2 - ;; - 3) - # Regelgeschwindigkeit 60 Sekunden - ticksize=1 - ;; - *) - # Regelgeschwindigkeit unbekannt - ticksize=1 - ;; - esac - soctimer=$((soctimer+$ticksize)) - echo $soctimer > $soctimerfile -} - -soctimer=$(<$soctimerfile) -openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: timer = $soctimer" - -if (( soctimer < socIntervall )); then - openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: Nothing to do yet. Incrementing timer." - incrementTimer -else - openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: Calculating manual SoC" - # reset timer - echo 0 > $soctimerfile - - # read current meter - if [[ -f "$meterFile" ]]; then - currentMeter=$(<$meterFile) - openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: currentMeter: $currentMeter" - - # read manual Soc - if [[ -f "$manualSocFile" ]]; then - manualSoc=$(<$manualSocFile) - else - # set manualSoc to 0 as a starting point - manualSoc=0 - echo $manualSoc > $manualSocFile - fi - openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: manual SoC: $manualSoc" - - # read manualMeterFile if file exists and manualMeterFile is newer than manualSocFile - if [[ -f "$manualMeterFile" ]] && [ "$manualMeterFile" -nt "$manualSocFile" ]; then - manualMeter=$(<$manualMeterFile) - else - # manualMeterFile does not exist or is outdated - # update manualMeter with currentMeter - manualMeter=$currentMeter - echo $manualMeter > $manualMeterFile - fi - openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: manualMeter: $manualMeter" - - # read current soc - if [[ -f "$socFile" ]]; then - currentSoc=$(<$socFile) - else - currentSoc=$manualSoc - echo $currentSoc > $socFile - fi - openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: currentSoc: $currentSoc" - - # calculate newSoc - currentMeterDiff=$(echo "scale=5;$currentMeter - $manualMeter" | bc) - openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: currentMeterDiff: $currentMeterDiff" - currentEffectiveMeterDiff=$(echo "scale=5;$currentMeterDiff * $efficiency / 100" | bc) - openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: currentEffectiveMeterDiff: $currentEffectiveMeterDiff ($efficiency %)" - currentSocDiff=$(echo "scale=5;100 / $akkug * $currentEffectiveMeterDiff" | bc | awk '{printf"%d\n",$1}') - openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: currentSocDiff: $currentSocDiff" - newSoc=$(echo "$manualSoc + $currentSocDiff" | bc) - if (( newSoc > 100 )); then - newSoc=100 - fi - if (( newSoc < 0 )); then - newSoc=0 - fi - openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: newSoc: $newSoc" - echo $newSoc > $socFile - else - # no current meter value for calculation -> Exit - openwbDebugLog ${DMOD} 0 "Lp$CHARGEPOINT: ERROR: no meter value for calculation! ($meterFile)" - fi -fi - -openwbDebugLog ${DMOD} 1 "Lp$CHARGEPOINT: --- Manual SoC end ---" +efficiency_var_name=wirkungsgradlp"$CHARGEPOINT" +battery_size_var_name=akkuglp"$CHARGEPOINT" +python3 "${OPENWBBASEDIR}/modules/soc_manual/soc_manual.py" "$CHARGEPOINT" "${!efficiency_var_name}" "${!battery_size_var_name}" &>> "$RAMDISKDIR/soc.log" diff --git a/modules/soc_manual/soc_manual.py b/modules/soc_manual/soc_manual.py new file mode 100644 index 000000000..b445e6f13 --- /dev/null +++ b/modules/soc_manual/soc_manual.py @@ -0,0 +1,60 @@ +import argparse +import logging + +from helpermodules.cli import run_using_positional_cli_args +from helpermodules.log import setup_logging_stdout +from modules.common.store import ramdisk_write, ramdisk_read_float + +setup_logging_stdout() +log = logging.getLogger("SoC Manual") + + +def run(charge_point: int, battery_size: float, efficiency: float): + """ + + :param charge_point: charge point number >= 1 + :param battery_size: battery size in kWh + :param efficiency: efficiency as fraction (usually between 0 and 1) + :return: + """ + file_soc_start = "manual_soc_lp{}".format(charge_point) + file_meter_start = "manual_soc_meter_lp{}".format(charge_point) + # SoC-file contains float with SoC 0..100: + file_soc = "soc{}".format(charge_point - 1) + # meter file contains float with total energy ever charged at this charge point in kWh: + file_meter = "llkwhs{}".format(charge_point - 1) + if charge_point == 1: + # For historic reasons some file names for charge point one do not fit the usual pattern: + file_soc = "soc" + file_meter = "llkwh" + + meter_now = ramdisk_read_float(file_meter) + try: + meter_start = ramdisk_read_float(file_meter_start) + soc_start = ramdisk_read_float(file_soc_start) / 100 + except FileNotFoundError: + soc_now = ramdisk_read_float(file_soc) / 100 + log.warning("Not initialized. Begin with meter=%g kWh, soc=%g%%", meter_now, soc_now * 100) + ramdisk_write(file_meter_start, meter_now) + ramdisk_write(file_soc_start, soc_now * 100, 1) + return + + energy_counted = meter_now - meter_start + energy_battery_gain = energy_counted * efficiency + battery_soc_gain = energy_battery_gain / battery_size + soc_new = soc_start + battery_soc_gain + log.debug("Charged: %g kWh -> %g kWh = %g kWh", meter_start, meter_now, energy_counted) + log.debug( + "SoC-Gain: Charged (%g kWh) * efficiency (%g%%) / battery-size (%g kWh) = %.1f%%", + energy_counted, efficiency * 100, battery_size, battery_soc_gain * 100 + ) + log.info("%g%% + %g kWh = %g%%", soc_start * 100, energy_battery_gain, soc_new * 100) + ramdisk_write(file_soc, soc_new * 100, digits=0) + + +def run_command_line(charge_point: int, efficiency: float, battery_size: float): + run(charge_point, battery_size, efficiency / 100) + + +if __name__ == '__main__': + run_using_positional_cli_args(run_command_line) diff --git a/modules/soc_manual/soc_manual_test.py b/modules/soc_manual/soc_manual_test.py new file mode 100644 index 000000000..698248336 --- /dev/null +++ b/modules/soc_manual/soc_manual_test.py @@ -0,0 +1,60 @@ +import pytest + +import soc_manual +from test_utils.mock_ramdisk import MockRamdisk + + +@pytest.fixture(scope='function') +def mock_ramdisk(monkeypatch): + return MockRamdisk(monkeypatch) + + +def test_charge_point_1(mock_ramdisk): + # setup + mock_ramdisk["manual_soc_lp1"] = "12.6" + mock_ramdisk["manual_soc_meter_lp1"] = "42.123" + mock_ramdisk["soc"] = "42" + mock_ramdisk["llkwh"] = "52.123" + + # execution + soc_manual.run(charge_point=1, battery_size=100, efficiency=.9) + + # evaluation + assert mock_ramdisk["soc"] == "21" + + +def test_charge_point_2(mock_ramdisk): + # setup + mock_ramdisk["manual_soc_lp2"] = "12.6" + mock_ramdisk["manual_soc_meter_lp2"] = "42.123" + mock_ramdisk["soc1"] = "42" + mock_ramdisk["llkwhs1"] = "52.123" + + # execution + soc_manual.run(charge_point=2, battery_size=100, efficiency=.9) + + # evaluation + assert mock_ramdisk["soc1"] == "21" + + +@pytest.mark.parametrize( + "manual_files", + [ + {"manual_soc_meter_lp2": "42.123"}, + {"manual_soc_lp2": "15"}, + {} + ] +) +def test_reinitializes_if_state_is_missing(mock_ramdisk, manual_files: dict): + # setup + mock_ramdisk["soc1"] = "42" + mock_ramdisk["llkwhs1"] = "52.123" + mock_ramdisk.files.update(manual_files) + + # execution + soc_manual.run(charge_point=2, battery_size=100, efficiency=.9) + + # evaluation + assert mock_ramdisk["soc1"] == "42" # Expect value to be unchanged + assert mock_ramdisk["manual_soc_lp2"] == "42.0" + assert mock_ramdisk["manual_soc_meter_lp2"] == "52.123" diff --git a/modules/speicher_bydhv/byd.py b/modules/speicher_bydhv/byd.py index 436503c6b..15561e4fe 100755 --- a/modules/speicher_bydhv/byd.py +++ b/modules/speicher_bydhv/byd.py @@ -5,7 +5,6 @@ import re import requests import sys -import traceback Debug = int(os.environ.get('debug')) myPid = str(os.getpid()) @@ -14,6 +13,7 @@ bydhvuser = str(sys.argv[2]) bydhvpass = str(sys.argv[3]) + def DebugLog(message): local_time = datetime.now(timezone.utc).astimezone() print(local_time.strftime(format="%Y-%m-%d %H:%M:%S") + ": PID: " + myPid + ": " + message) @@ -24,47 +24,37 @@ def DebugLog(message): DebugLog('Speicher User: ' + bydhvuser) DebugLog('Speicher Passwort: ' + bydhvpass) -try: - response = requests.get('http://'+bydhvip+'/asp/RunData.asp', auth=(bydhvuser, bydhvpass)) - response.encoding = 'utf-8' - response = response.text - response = response.split("\n") - for line in response: - if "SOC:" in response[line]: - response = response[line:line+2] - response = ''.join(response) - break - response = response.replace("%", "") - group = re.search("^.*value=$", response).group() - soc = response.replace(group, "") - if Debug >= 1: - DebugLog('Soc: ' + str(soc)) - with open("/var/www/html/openWB/ramdisk/speichersoc", "w") as f: - f.write(str(soc)) -except: - traceback.print_exc() - exit(1) - -try: - response = requests.get('http://'+bydhvip+'/asp/Home.asp', auth=(bydhvuser, bydhvpass)) - response.encoding = 'utf-8' - response = response.text - response = response.split("\n") - for line in response: - if "Power:" in response[line]: - response = response[line:line+2] - response = ''.join(response) - break - response = response.replace(">", "") - group = re.search("^.*value=$", response).group() - speicherleistung = response.replace(group, "") - speicherleistung = int(speicherleistung*1000) - if Debug >= 1: - DebugLog('Speicherleistung: ' + str(speicherleistung)) - with open("/var/www/html/openWB/ramdisk/speicherleistung", "w") as f: - f.write(str(speicherleistung)) -except: - traceback.print_exc() - exit(1) - -exit(0) \ No newline at end of file +response = requests.get('http://'+bydhvip+'/asp/RunData.asp', auth=(bydhvuser, bydhvpass)) +response.encoding = 'utf-8' +response = response.text +response = response.split("\n") +for line in range(len(response)): + if "SOC:" in response[line]: + response = response[line:line+2] + response = ''.join(response) + response = response.replace("%", "") + group = re.search("^.*value=$", response).group() + soc = response.replace(group, "") + if Debug >= 1: + DebugLog('Soc: ' + str(soc)) + with open("/var/www/html/openWB/ramdisk/speichersoc", "w") as f: + f.write(str(soc)) + break + +response = requests.get('http://'+bydhvip+'/asp/Home.asp', auth=(bydhvuser, bydhvpass)) +response.encoding = 'utf-8' +response = response.text +response = response.split("\n") +for line in range(len(response)): + if "Power:" in response[line]: + response = response[line:line+2] + response = ''.join(response) + response = response.replace(">", "") + group = re.search("^.*value=$", response).group() + speicherleistung = response.replace(group, "") + speicherleistung = int(speicherleistung*1000) + if Debug >= 1: + DebugLog('Speicherleistung: ' + str(speicherleistung)) + with open("/var/www/html/openWB/ramdisk/speicherleistung", "w") as f: + f.write(str(speicherleistung)) + break diff --git a/modules/speicher_fems/fems.py b/modules/speicher_fems/fems.py index cbeed9f22..477e6f52a 100755 --- a/modules/speicher_fems/fems.py +++ b/modules/speicher_fems/fems.py @@ -27,11 +27,11 @@ def DebugLog(message): def write_ramdisk(value, file): try: if file == "speichersoc": - if re.search("^[-+]?[0-9]+\.?[0-9]*$", value) == None: + if re.search("^[-+]?[0-9]+\.?[0-9]*$", str(value)) == None: value = "0" if Debug >= 1: DebugLog(file+': ' + str(value)) - with open("/var/www/html/openWB/ramdisk/"+file, "") as f: + with open("/var/www/html/openWB/ramdisk/"+file, "w") as f: f.write(str(value)) except: traceback.print_exc() @@ -40,7 +40,7 @@ def write_ramdisk(value, file): if multifems == "0": try: - response = requests.get("http://x:"+femskacopw+"@"+femsip+":8084/rest/channel/ess0/(Soc|ActiveChargeEnergy|ActiveDischargeEnergy)").json() + response = requests.get("http://"+femsip+":8084/rest/channel/ess0/(Soc|ActiveChargeEnergy|ActiveDischargeEnergy)", auth=("x", femskacopw)).json() except: traceback.print_exc() exit(1) @@ -54,7 +54,7 @@ def write_ramdisk(value, file): write_ramdisk(singleValue["value"], "speicherekwh") else: try: - response = requests.get("http://x:"+femskacopw+"@"+femsip+":8084/rest/channel/ess2/(Soc|ActiveChargeEnergy|ActiveDischargeEnergy)").json() + response = requests.get("http://"+femsip+":8084/rest/channel/ess2/(Soc|ActiveChargeEnergy|ActiveDischargeEnergy)", auth=("x", femskacopw)).json() except: traceback.print_exc() exit(1) @@ -68,7 +68,7 @@ def write_ramdisk(value, file): write_ramdisk(singleValue["value"], "speicherekwh") try: - response = requests.get("http://x:"+femskacopw+"@"+femsip+":8084/rest/channel/_sum/(GridActivePower|ProductionActivePower|ConsumptionActivePower)").json() + response = requests.get("http://"+femsip+":8084/rest/channel/_sum/(GridActivePower|ProductionActivePower|ConsumptionActivePower)", auth=("x", femskacopw)).json() except: traceback.print_exc() exit(1) @@ -84,7 +84,7 @@ def write_ramdisk(value, file): leistung = grid + pv - haus ra = "^[-+]?[0-9]+\.?[0-9]*$" -if re.search(ra, leistung) == None: +if re.search(ra, str(leistung)) == None: leistung = "0" if Debug >= 1: DebugLog('Speicherleistung: ' + str(leistung)) diff --git a/modules/speicher_saxpower/main.sh b/modules/speicher_saxpower/main.sh index 9f92631c3..255a47d9f 100644 --- a/modules/speicher_saxpower/main.sh +++ b/modules/speicher_saxpower/main.sh @@ -1,2 +1,21 @@ #!/bin/bash -python /var/www/html/openWB/modules/speicher_saxpower/saxpower.py $speicher1_ip +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="BAT" +DMOD="MAIN" +Debug=$debug + +#For development only +#Debug=1 + +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/bat.log" +fi + +python3 ${OPENWBBASEDIR}/packages/modules/saxpower/device.py "bat" "${speicher1_ip}" >>${MYLOGFILE} 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "BAT RET: ${ret}" diff --git a/modules/speicher_saxpower/saxpower.py b/modules/speicher_saxpower/saxpower.py deleted file mode 100644 index 667291275..000000000 --- a/modules/speicher_saxpower/saxpower.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) - -client = ModbusTcpClient(ipaddress, port=3600) - -# Register auslesen -resp= client.read_holding_registers(46, 2,unit=64) - -# SOC -soc = resp.registers[0] -f = open('/var/www/html/openWB/ramdisk/speichersoc', 'w') -f.write(str(soc)) -f.close() - -# akt. Speicherleistung -sax_pow=resp.registers[1] -# unsigned to signed int -if sax_pow > 32767: - sax_pow -= 65535 - -# Entladen: negativ -# Laden: positiv -sax_pow *=-1 - -f = open('/var/www/html/openWB/ramdisk/speicherleistung', 'w') -f.write(str(sax_pow)) -f.close() diff --git a/modules/speicher_solax/main.sh b/modules/speicher_solax/main.sh index 0b5714991..62eb398df 100644 --- a/modules/speicher_solax/main.sh +++ b/modules/speicher_solax/main.sh @@ -1,3 +1,21 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="BAT" +DMOD="MAIN" +Debug=$debug -python /var/www/html/openWB/modules/speicher_solax/solax.py $solaxip +#For development only +#Debug=1 + +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/bat.log" +fi + +python3 ${OPENWBBASEDIR}/packages/modules/solax/device.py "bat" "${solaxip}" >>${MYLOGFILE} 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "BAT RET: ${ret}" diff --git a/modules/speicher_solax/solax.py b/modules/speicher_solax/solax.py deleted file mode 100644 index 0a3ff4b81..000000000 --- a/modules/speicher_solax/solax.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient - -def unsigned16(result, addr): - return result.registers[addr] - -def signed16(result, addr): - val = result.registers[addr] - if val > 32767: - val -= 65535 - return val - -ipaddress = str(sys.argv[1]) - -client = ModbusTcpClient(ipaddress, port=502) - -resp=client.read_input_registers(0, 114) - -# Batterie Power -value1 = signed16(resp, 22) -f = open('/var/www/html/openWB/ramdisk/speicherleistung', 'w') -f.write(str(value1)) -f.close() - -# Batterieladezustand -value2 = unsigned16(resp, 28 ) -f = open('/var/www/html/openWB/ramdisk/speichersoc', 'w') -f.write(str(value2)) -f.close() diff --git a/modules/speicher_sonneneco/sonneneco.py b/modules/speicher_sonneneco/sonneneco.py index 61f6499af..a21587016 100755 --- a/modules/speicher_sonneneco/sonneneco.py +++ b/modules/speicher_sonneneco/sonneneco.py @@ -13,7 +13,7 @@ sonnenecoalternativ = str(sys.argv[1]) sonnenecoip = str(sys.argv[2]) -def DebugLog(message): +def DebugLog(message: str) -> None: local_time = datetime.now(timezone.utc).astimezone() print(local_time.strftime(format="%Y-%m-%d %H:%M:%S") + ": PID: " + myPid + ": " + message) @@ -24,46 +24,47 @@ def DebugLog(message): ra = '^-?[0-9]+$' -def check_write_value(value, file): - global ra - if re.search(ra, value) == None: - value = "0" +def check_write_value(valueString: str, file: str, fallback: str = "0") -> None: + if re.search(ra, valueString) == None: + DebugLog('invalid valueString: ' + valueString + ' setting fallback of \'' + fallback + '\'') + valueString = fallback if Debug >= 1: - DebugLog(file+': ' + str(value)) - with open("/var/www/html/openWB/ramdisk/"+file, "w") as f: - f.write(str(value)) + DebugLog(file+': ' + valueString) + with open("/var/www/html/openWB/ramdisk/" + file, "w") as f: + f.write(valueString) # Auslesen einer Sonnbenbatterie Eco 4.5 über die integrierte JSON-API des Batteriesystems if sonnenecoalternativ == 2: - response = requests.get('http://'+sonnenecoip+':7979/rest/devices/battery/M05', timeout=5) + baseurl = 'http://' + sonnenecoip + ':7979/rest/devices/battery/' + response = requests.get(baseurl + 'M05', timeout=5) response.encoding = 'utf-8' speichersoc = response.text.replace("\n", "") speichersoc = int(speichersoc) - response = requests.get('http://'+sonnenecoip+':7979/rest/devices/battery/M01', timeout=5) + response = requests.get(baseurl + 'M01', timeout=5) response.encoding = 'utf-8' speicherentladung = response.text.replace("\n", "") - response = requests.get('http://'+sonnenecoip+':7979/rest/devices/battery/M02', timeout=5) + response = requests.get(baseurl + 'M02', timeout=5) response.encoding = 'utf-8' speicherladung = response.text.replace("\n", "") speicherladung = int(speicherladung) speicherentladung = int(speicherentladung) speicherwatt = speicherladung - speicherentladung # wenn Batterie aus bzw. keine Antwort ersetze leeren Wert durch eine 0 - check_write_value(speicherwatt, "speicherleistung") - check_write_value(speichersoc, "speichersoc") - response = requests.get('http://'+sonnenecoip+':7979/rest/devices/battery/M03', timeout=5) + check_write_value(str(speicherwatt), "speicherleistung") + check_write_value(str(speichersoc), "speichersoc") + response = requests.get(baseurl + 'M03', timeout=5) response.encoding = 'utf-8' pvwatt = response.text.replace("\n", "") pvwatt = int(pvwatt) pvwatt = pvwatt * -1 if Debug >= 1: DebugLog('PV Leistung: ' + str(pvwatt)) - with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: - f.write(str(pvwatt)) + check_write_value(str(pvwatt), "pvwatt") + else: if sonnenecoalternativ == 0: - speicherantwort = requests.get('http://'+sonnenecoip+':7979/rest/devices/battery', timeout=5).json() + speicherantwort = requests.get('http://' + sonnenecoip + ':7979/rest/devices/battery', timeout=5).json() try: speichersoc = int(speicherantwort["M05"]) except: @@ -81,10 +82,46 @@ def check_write_value(value, file): exit(1) speicherwatt = speicherladung - speicherentladung # wenn Batterie aus bzw. keine Antwort ersetze leeren Wert durch eine 0 - check_write_value(speicherwatt, "speicherleistung") - check_write_value(speichersoc, "speichersoc") + check_write_value(str(speicherwatt), "speicherleistung") + check_write_value(str(speichersoc), "speichersoc") else: - speicherantwort = requests.get("http://"+sonnenecoip+"/api/v1/status", timeout=5).json() + speicherantwort = requests.get("http://" + sonnenecoip + "/api/v1/status", timeout=5).json() + ''' + example data: + { + "Apparent_output": 225, + "BackupBuffer": "0", + "BatteryCharging": false, + "BatteryDischarging": false, + "Consumption_Avg": 2114, + "Consumption_W": 2101, + "Fac": 49.97200393676758, + "FlowConsumptionBattery": false, + "FlowConsumptionGrid": true, + "FlowConsumptionProduction": false, + "FlowGridBattery": false, + "FlowProductionBattery": false, + "FlowProductionGrid": false, + "GridFeedIn_W": -2106, + "IsSystemInstalled": 1, + "OperatingMode": "2", + "Pac_total_W": -5, + "Production_W": 0, + "RSOC": 6, + "RemainingCapacity_Wh": 2377, + "Sac1": 75, + "Sac2": 75, + "Sac3": 75, + "SystemStatus": "OnGrid", + "Timestamp": "2021-12-13 07:54:48", + "USOC": 0, + "Uac": 231, + "Ubat": 48, + "dischargeNotAllowed": true, + "generator_autostart": false, + "NVM_REINIT_STATUS": 0 + } + ''' try: speicherwatt = speicherantwort["Pac_total_W"] except: @@ -94,9 +131,7 @@ def check_write_value(value, file): speichersoc = speicherantwort["USOC"] if Debug >= 1: DebugLog('SpeicherSoC: ' + str(speichersoc)) - if not str(speichersoc).isnumeric(): - DebugLog('SpeicherSoc nicht numerisch. -->0') - speichersoc = 0 + check_write_value(str(speichersoc), "speichersoc") except: traceback.print_exc() exit(1) @@ -108,16 +143,11 @@ def check_write_value(value, file): speicherpvwatt = speicherpvwatt * -1 if Debug >= 1: DebugLog('Speicher PV Watt: ' + str(speicherpvwatt)) - with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: - f.write(str(speicherpvwatt)) - if re.search(ra, speicherwatt) == None: - speicherwatt = "0" - else: + check_write_value(str(speicherpvwatt), "pvwatt") + if re.search(ra, str(speicherwatt)) != None: speicherwatt = speicherwatt * -1 if Debug >= 1: DebugLog('Speicherleistung: ' + str(speicherwatt)) - with open("/var/www/html/openWB/ramdisk/speicherleistung", "w") as f: - f.write(str(speicherwatt)) - check_write_value(speichersoc, "speichersoc") + check_write_value(str(speicherwatt), "speicherleistung") exit(0) diff --git a/modules/speicher_studer/main.sh b/modules/speicher_studer/main.sh index 584c7c02b..99aa4c36b 100644 --- a/modules/speicher_studer/main.sh +++ b/modules/speicher_studer/main.sh @@ -1,3 +1,21 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="BAT" +DMOD="MAIN" +Debug=$debug -python /var/www/html/openWB/modules/speicher_studer/studer_speicher.py $studer_ip +#For development only +#Debug=1 + +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/bat.log" +fi + +python3 ${OPENWBBASEDIR}/packages/modules/studer/device.py "bat" "${studer_ip}" >>${MYLOGFILE} 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "BAT RET: ${ret}" diff --git a/modules/speicher_studer/studer_speicher.py b/modules/speicher_studer/studer_speicher.py deleted file mode 100644 index 5d1cd3e67..000000000 --- a/modules/speicher_studer/studer_speicher.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -# import struct -# import binascii -from pymodbus.constants import Endian -from pymodbus.payload import BinaryPayloadDecoder -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) - -client = ModbusTcpClient(ipaddress, port=502) -connection = client.connect() - -# Studer Battery Power -request = client.read_input_registers(6, 2, unit=60) -if request.isError(): - # handle error, log? - print('Modbus Error:', request) -else: - result = request.registers -decoder = BinaryPayloadDecoder.fromRegisters(result, byteorder=Endian.Big) -bw = decoder.decode_32bit_float() # type: float -f = open('/var/www/html/openWB/ramdisk/speicherleistung', 'w') -f.write(str(bw)) -f.close() - -# Studer SOC -request = client.read_input_registers(4, 2, unit=60) -if request.isError(): - # handle error, log? - print('Modbus Error:', request) -else: - result = request.registers -decoder = BinaryPayloadDecoder.fromRegisters(result, byteorder=Endian.Big) -bs = decoder.decode_32bit_float() # type: float -f = open('/var/www/html/openWB/ramdisk/speichersoc', 'w') -f.write(str(bs)) -f.close() - -# Studer charged Energy -request = client.read_input_registers(14, 2, unit=60) -if request.isError(): - # handle error, log? - print('Modbus Error:', request) -else: - result = request.registers -decoder = BinaryPayloadDecoder.fromRegisters(result, byteorder=Endian.Big) -bc = decoder.decode_32bit_float() # type: float -f = open('/var/www/html/openWB/ramdisk/speicherikwh', 'w') -f.write(str(bc*48)) -f.close() - -# Studer discharged Energy -request = client.read_input_registers(16, 2, unit=60) -if request.isError(): - # handle error, log? - print('Modbus Error:', request) -else: - result = request.registers -decoder = BinaryPayloadDecoder.fromRegisters(result, byteorder=Endian.Big) -bd = decoder.decode_32bit_float() # type: float -f = open('/var/www/html/openWB/ramdisk/speicherekwh', 'w') -f.write(str(bd*48)) -f.close() - -client.close() diff --git a/modules/speicher_sungrow/main.sh b/modules/speicher_sungrow/main.sh index c9471fdf3..7e9c0fa0e 100644 --- a/modules/speicher_sungrow/main.sh +++ b/modules/speicher_sungrow/main.sh @@ -1,3 +1,21 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="BAT" +DMOD="MAIN" +Debug=$debug -python /var/www/html/openWB/modules/speicher_sungrow/sungrow.py $speicher1_ip +#For development only +#Debug=1 + +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/bat.log" +fi + +python3 ${OPENWBBASEDIR}/packages/modules/sungrow/device.py "bat" "${speicher1_ip}" >>${MYLOGFILE} 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "BAT RET: ${ret}" diff --git a/modules/speicher_sungrow/sungrow.py b/modules/speicher_sungrow/sungrow.py deleted file mode 100644 index 2e755801b..000000000 --- a/modules/speicher_sungrow/sungrow.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) - -client = ModbusTcpClient(ipaddress, port=502) - -resp= client.read_input_registers(13022,1,unit=1) -value1 = resp.registers[0] -all = format(value1, '04x') -final = int(struct.unpack('>h', all.decode('hex'))[0] / 10 ) -f = open('/var/www/html/openWB/ramdisk/speichersoc', 'w') -f.write(str(final)) -f.close() - -resp= client.read_input_registers(13000,1,unit=1) -value1 = resp.registers[0] -binary=bin(value1)[2:].zfill(8) - -# battwatt -resp= client.read_input_registers(13021,1,unit=1) -value1 = resp.registers[0] -all = format(value1, '04x') -final = int(struct.unpack('>h', all.decode('hex'))[0]) -if (binary[5] == "1"): - final=final*-1 -f = open('/var/www/html/openWB/ramdisk/speicherleistung', 'w') -f.write(str(final)) -f.close() diff --git a/modules/speicher_sunnyisland/main.sh b/modules/speicher_sunnyisland/main.sh index 0f9193488..a451376eb 100755 --- a/modules/speicher_sunnyisland/main.sh +++ b/modules/speicher_sunnyisland/main.sh @@ -1,3 +1,21 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="BAT" +DMOD="MAIN" +Debug=$debug -sudo python /var/www/html/openWB/modules/speicher_sunnyisland/sunnyisland.py $sunnyislandip +#For development only +#Debug=1 + +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/bat.log" +fi + +python3 ${OPENWBBASEDIR}/packages/modules/sunny_island/device.py "bat" "${sunnyislandip}" >>${MYLOGFILE} 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "BAT RET: ${ret}" diff --git a/modules/speicher_sunnyisland/sbs25.py b/modules/speicher_sunnyisland/sbs25.py deleted file mode 100755 index d2089d745..000000000 --- a/modules/speicher_sunnyisland/sbs25.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) - -client = ModbusTcpClient(ipaddress, port=502) - -# print "SoC batt" -resp= client.read_holding_registers(30845,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -final = int(struct.unpack('>i', all.decode('hex'))[0]) -f = open('/var/www/html/openWB/ramdisk/speichersoc', 'w') -f.write(str(final)) -f.close() - -# print "be-entladen watt" -resp= client.read_holding_registers(31393,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -ladung = int(struct.unpack('>i', all.decode('hex'))[0]) -resp= client.read_holding_registers(31395,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -entladung = int(struct.unpack('>i', all.decode('hex'))[0]) -if ladung > 5: - final=ladung -else: - final=entladung * -1 -f = open('/var/www/html/openWB/ramdisk/speicherleistung', 'w') -f.write(str(final)) -f.close() diff --git a/modules/speicher_sunnyisland/sunnyisland.py b/modules/speicher_sunnyisland/sunnyisland.py deleted file mode 100755 index 4796a7a2e..000000000 --- a/modules/speicher_sunnyisland/sunnyisland.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) - -client = ModbusTcpClient(ipaddress, port=502) - -# print "SoC batt" -resp= client.read_holding_registers(30845,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -final = int(struct.unpack('>i', all.decode('hex'))[0]) -f = open('/var/www/html/openWB/ramdisk/speichersoc', 'w') -f.write(str(final)) -f.close() - -# print "be-entladen watt" -resp= client.read_holding_registers(30775,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -ladung = int(struct.unpack('>i', all.decode('hex'))[0]) * -1 -f = open('/var/www/html/openWB/ramdisk/speicherleistung', 'w') -f.write(str(ladung)) -f.close() - -# print "import wh" -resp= client.read_holding_registers(30595,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -ladung = int(struct.unpack('>i', all.decode('hex'))[0]) -f = open('/var/www/html/openWB/ramdisk/speicherikwh', 'w') -f.write(str(ladung)) -f.close() - -# print "exportwh" -resp= client.read_holding_registers(30597,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -ladung = int(struct.unpack('>i', all.decode('hex'))[0]) -f = open('/var/www/html/openWB/ramdisk/speicherekwh', 'w') -f.write(str(ladung)) -f.close() diff --git a/modules/speicher_victron/main.sh b/modules/speicher_victron/main.sh index 7c645e974..52b61d54e 100755 --- a/modules/speicher_victron/main.sh +++ b/modules/speicher_victron/main.sh @@ -1,3 +1,21 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="BAT" +DMOD="MAIN" +Debug=$debug -sudo python /var/www/html/openWB/modules/speicher_victron/victron_speicher.py $bezug_victronip +#For development only +#Debug=1 + +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/bat.log" +fi + +python3 ${OPENWBBASEDIR}/packages/modules/victron/device.py "bat" "${bezug_victronip}" >>${MYLOGFILE} 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "BAT RET: ${ret}" diff --git a/modules/speicher_victron/victron_speicher.py b/modules/speicher_victron/victron_speicher.py deleted file mode 100644 index 9d031b860..000000000 --- a/modules/speicher_victron/victron_speicher.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -# import struct -# import binascii -from pymodbus.constants import Endian -from pymodbus.payload import BinaryPayloadDecoder -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) - -client = ModbusTcpClient(ipaddress, port=502) -connection = client.connect() - -# Battery Voltage -# resp= client.read_holding_registers(840,1,unit=100) -# decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -# bv = str(decoder.decode_16bit_uint()) -# bv = float(bv) / 10 -# f = open('/var/www/html/openWB/ramdisk/???', 'w') -# f.write(str(watt)) -# f.close() -# print "Batteriespannung aktuell:" -# print bv - -# Battery ampere -# resp= client.read_holding_registers(841,1,unit=100) -# decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -# ba = str(decoder.decode_16bit_int()) -# ba = float(ba) / 10 -# f = open('/var/www/html/openWB/ramdisk/???', 'w') -# f.write(str(a3)) -# f.close() -# print "Batterie Ampere +/- aktuell:" -# print ba - -# Battery watt -resp= client.read_holding_registers(842,1,unit=100) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -bw = str(decoder.decode_16bit_int()) -f = open('/var/www/html/openWB/ramdisk/speicherleistung', 'w') -f.write(str(bw)) -f.close() -# print "Batterie Wirkleistung +/- aktuell:" -# print bw - -# Battery SOC -resp= client.read_holding_registers(843,1,unit=100) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -bs = str(decoder.decode_16bit_uint()) -f = open('/var/www/html/openWB/ramdisk/speichersoc', 'w') -f.write(str(bs)) -f.close() -# print "Batterie SOC aktuell:" -# print bs - -client.close() diff --git a/modules/wr2_kostalpiko/main.sh b/modules/wr2_kostalpiko/main.sh index 46616b7bb..528ac07b6 100644 --- a/modules/wr2_kostalpiko/main.sh +++ b/modules/wr2_kostalpiko/main.sh @@ -1,24 +1,5 @@ #!/bin/bash -# Auslesen eines Kostal Piko WR über die integrierte API des WR. Rückgabewert ist die aktuelle Wattleistung. -if [[ "$speichermodul" != "none" ]]; then - pvwatttmp=$(curl --connect-timeout 5 -s $pv2ip/api/dxs.json?dxsEntries=33556736'&'dxsEntries=251658753) -else - pvwatttmp=$(curl --connect-timeout 5 -s $pv2ip/api/dxs.json?dxsEntries=67109120'&'dxsEntries=251658753) -fi -# aktuelle Ausgangsleistung am WR [W] -pvwatt=$(echo $pvwatttmp | jq '.dxsEntries[0].value' | sed 's/\..*$//') - -if [ $pvwatt > 5 ] - then - pvwatt=$(echo "$pvwatt*-1" |bc) -fi +python3 /var/www/html/openWB/modules/wr_kostalpiko/kostal_piko_var1.py 2 $speichermodul $pv2ip +pvwatt=$( /var/www/html/openWB/ramdisk/pv2watt -# Gesamtzählerstand am WR [kWh] -pvkwh=$(echo $pvwatttmp | jq '.dxsEntries[1].value' | sed 's/\..*$//') -echo $pvkwh > /var/www/html/openWB/ramdisk/pv2kwhk -pvkwh=$(echo "$pvkwh*1000" |bc) -# zur weiteren verwendung im webinterface -echo $pvkwh > /var/www/html/openWB/ramdisk/pv2kwh \ No newline at end of file diff --git a/modules/wr2_kostalpikovar2/main.sh b/modules/wr2_kostalpikovar2/main.sh index efbb5f0d7..2221e50ce 100755 --- a/modules/wr2_kostalpikovar2/main.sh +++ b/modules/wr2_kostalpikovar2/main.sh @@ -1,41 +1,5 @@ #!/bin/bash -# initially created by Stefan Schefler for openWB 2019 -# modified by Kevin Wieland -# based on Homematic Script v0.2 (c) 2018 by Alchy - -# Daten einlesen -HTML=$(/usr/bin/curl -u $wr2_piko2_user:$wr2_piko2_pass --connect-timeout 10 -s -k $wr2_piko2_url | /usr/bin/tr -d '\r' | /usr/bin/tr -d '\n' | /usr/bin/tr -d ' ' | /usr/bin/tr '#' ' ') -# request html, concat to one line, remove spaces, add spaces before color changes (#) - -if [[ -n $HTML ]] # check if valid content of request -then - counter=0 - for LINE in $HTML # parse all html lines - do - if [[ $LINE =~ FFFFFF ]]; # search for white background color - then - ((counter++)) - PART2=${LINE##*F\">} # strip before number - VALUE=${PART2%%<*} # strip after number - - if [[ $counter -eq 1 ]] # pvwatt - then - if [[ $VALUE = "xxx" ]] # off-value equals zero - then - $VALUE = "0" - fi - re='^[-+]?[0-9]+\.?[0-9]*$' - if ! [[ $VALUE =~ $re ]] # check for valid number - then - VALUE=$( /var/www/html/openWB/ramdisk/pv2watt - echo $((VALUE*-1)) - elif [[ $counter -eq 2 ]] # pvkwhk - then - echo ${VALUE} > /var/www/html/openWB/ramdisk/pv2kwhk - fi - fi - done -fi +python3 /var/www/html/openWB/modules/wr_kostalpikovar2/kostal_piko_var2.py 2 $wr2_piko2_url $wr2_piko2_user $wr2_piko2_pass +pvwatt=$(= 2: + DebugLog('PV Kostal Steca IP:' + pv2ip) + + + +# call for XML file and parse it for current PV power +response = requests.get("http://"+pv2ip+"/measurements.xml", timeout=5).text +if Debug >= 1: + DebugLog("MEASURE: "+str(response)) +power_kostal_piko_MP = ET.fromstring(response).find("Measurement[@Type='AC_Power']").get("Value") + +# cut the comma and the digit behind the comma +power_kostal_piko_MP = int(float(power_kostal_piko_MP)) + +# allow only numbers +regex = '^-?[0-9]+$' +if re.search(regex, power_kostal_piko_MP) == None: + power_kostal_piko_MP = "0" + +DebugLog("'PVWatt: "+str(power_kostal_piko_MP)+"'") + +# call for XML file and parse it for total produced kwh +if Debug > 1: + yields = requests.get("http://"+pv2ip+"/yields.xml", timeout=5).text + DebugLog("YIELD: "+yields) + +response = requests.get("http://"+pv2ip+"/yields.xml", timeout=5).text +pvkwh_kostal_piko_MP = ET.fromstring(response).find("YieldValue").get("Value") + +if re.search(regex, pvkwh_kostal_piko_MP) == None: + DebugLog("PVkWh: NaN get prev. Value") + with open("/var/www/html/openWB/ramdisk/pv2kwh", "r") as f: + pvkwh_kostal_piko_MP = f.read() + +DebugLog('PVkWh: '+str(pvkwh_kostal_piko_MP)) + +# Daten in Ramdisk schreiben +if Debug >= 1: + DebugLog('WR Energie: ' + str(pvkwh_kostal_piko_MP)) +with open("/var/www/html/openWB/ramdisk/pv2kwh", "w") as f: + f.write(str(pvkwh_kostal_piko_MP)) +if Debug >= 1: + DebugLog('WR Leistung: ' + "-"+str(power_kostal_piko_MP)) +with open("/var/www/html/openWB/ramdisk/pv2watt", "w") as f: + f.write("-"+str(power_kostal_piko_MP)) + +exit(0) diff --git a/modules/wr2_kostalsteca/main.sh b/modules/wr2_kostalsteca/main.sh index d9645b1b6..b570e46ed 100644 --- a/modules/wr2_kostalsteca/main.sh +++ b/modules/wr2_kostalsteca/main.sh @@ -1,47 +1,27 @@ #!/bin/bash -# -# RainerW 8th of April 2020 -# Unfortunately Kostal has introduced the third version of interface: XML -# This script is for Kostal_Piko_MP_plus and StecaGrid coolcept (single phase inverter) -# In fact Kostal is not developing own single phase inverter anymore but is sourcing them from Steca -# If you have the chance to test this module for the latest three phase inverter from Kostal (Plenticore) or Steca (coolcept3 or coolcept XL) let us know if it works -# DetMoerk 20210323: Anpassung fuer ein- und dreiphasige WR der Serie. Anstatt eine feste Zeile aus dem Ergebnis zu schneiden wird nach der Zeile mit AC_Power gesucht. -DMOD="PV" -Debug=$debug -if (( $Debug > 1 )); then - measure=$(curl --connect-timeout 5 -s $pv2ip/measurements.xml) - openwbDebugLog ${DMOD} 2 "MEASURE: $measure" -fi -# call for XML file and parse it for current PV power -power_kostal_piko_MP=$(curl --connect-timeout 5 -s $pv2ip/measurements.xml |python3 -c 'import sys;import xml.dom.minidom;s=sys.stdin.read();print(xml.dom.minidom.parseString(s).toprettyxml())'|grep -e "Type=\"AC_Power\""| grep -Po "Value=\"\K[^\"]*" ) +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +#MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="PV" +DMOD="MAIN" +Debug=$debug -# cut the comma and the digit behind the comma -power_kostal_piko_MP=$(echo $power_kostal_piko_MP | sed 's/\..*$//') +#For Development only +#Debug=1 -# allow only numbers -re='^-?[0-9]+$' -if ! [[ $power_kostal_piko_MP =~ $re ]] ; then - power_kostal_piko_MP="0" +if [ $DMOD == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/wr2_kostalsteca.log" fi -openwbDebugLog ${DMOD} 1 "PVWatt: $power_kostal_piko_MP" -# call for XML file and parse it for total produced kwh -if (( $Debug > 1 )); then - yield=$(curl --connect-timeout 5 -s $pv2ip/yields.xml) - openwbDebugLog ${DMOD} 2 "YIELD: $yield" -fi -#pvkwh_kostal_piko_MP=$(curl --connect-timeout 5 -s $pv2ip/yields.xml | grep -Po "Value=\"\K[^\"]*" | sed -n 1p) -pvkwh_kostal_piko_MP=$(curl --connect-timeout 5 -s $pv2ip/yields.xml |python3 -c 'import sys;import xml.dom.minidom;s=sys.stdin.read();print(xml.dom.minidom.parseString(s).toprettyxml())'|grep "YieldValue" | grep -Po "Value=\"\K[^\"]*" ) -if ! [[ $pvkwh_kostal_piko_MP =~ $re ]] ; then - openwbDebugLog ${DMOD} 2 "PVkWh: NaN get prev. Value" - pvkwh_kostal_piko_MP=$(>$MYLOGFILE 2>&1 +ret=$? -## Daten in Ramdisk schreiben +openwbDebugLog ${DMOD} 2 "RET: ${ret}" -echo $pvkwh_kostal_piko_MP > /var/www/html/openWB/ramdisk/pv2kwh -echo '-'$power_kostal_piko_MP > /var/www/html/openWB/ramdisk/pv2watt -echo '-'$power_kostal_piko_MP +pvwatt=$(>${MYLOGFILE} 2>&1 + +pvwatt=$(<${RAMDISKDIR}/pvwatt) echo $pvwatt diff --git a/modules/wr2_solax/solax.py b/modules/wr2_solax/solax.py deleted file mode 100644 index d4c7b645d..000000000 --- a/modules/wr2_solax/solax.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient -from pymodbus.factory import ClientDecoder - -ipaddress = str(sys.argv[1]) - -def unsigned32(result, addr): - low = result.registers[addr] - high = result.registers[addr + 1] - val = low +( high << 16) - return val - -def unsigned16 (result, addr): - return result.registers[addr] - -def signed16(result, addr): - val = addr - if val > 32767: - val -= 65535 - return val - -client = ModbusTcpClient(ipaddress, port=502) - -resp=client.read_input_registers(10, 2) -pv1 = unsigned16(resp, 0) -pv2 = unsigned16(resp, 1) -f = open('/var/www/html/openWB/ramdisk/pv2watt', 'w') -f.write(str( (pv1 + pv2) * -1 ) ) # Erzeugung negativ -f.close() - -resp=client.read_input_registers(80, 4) -pvall = unsigned32(resp,2) # yield overall -f = open('/var/www/html/openWB/ramdisk/pv2kwh', 'w') -f.write(str(pvall)) -f.close() -f = open('/var/www/html/openWB/ramdisk/pv2kwhk', 'w') -f.write(str(pvall / 1000)) -f.close() - -client.close() diff --git a/modules/wr2_sungrow/main.sh b/modules/wr2_sungrow/main.sh index 6de76814e..dc896fe79 100644 --- a/modules/wr2_sungrow/main.sh +++ b/modules/wr2_sungrow/main.sh @@ -1,4 +1,22 @@ #!/bin/bash -python /var/www/html/openWB/modules/wr2_sungrow/sungrow.py $pv2ip -pvwatt=$(>${MYLOGFILE} 2>&1 + +pvwatt=$(<${RAMDISKDIR}/pvwatt) +echo $pvwatt \ No newline at end of file diff --git a/modules/wr2_sungrow/sungrow.py b/modules/wr2_sungrow/sungrow.py deleted file mode 100644 index 6e3b31350..000000000 --- a/modules/wr2_sungrow/sungrow.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/python -import sys -import os -import time -import getopt -import socket -import ConfigParser -import struct -import binascii -ipaddress = str(sys.argv[1]) -from pymodbus.client.sync import ModbusTcpClient -client = ModbusTcpClient(ipaddress, port=502) -resp= client.read_input_registers(5016,2,unit=1) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value2, '04x') + format(value1, '04x') -final = int(struct.unpack('>i', all.decode('hex'))[0]*-1) -if final > -100000: - f = open('/var/www/html/openWB/ramdisk/pv2watt', 'w') - f.write(str(final)) - f.close() - diff --git a/modules/wr2_victron/main.sh b/modules/wr2_victron/main.sh index 0c76ee06e..001309ff5 100755 --- a/modules/wr2_victron/main.sh +++ b/modules/wr2_victron/main.sh @@ -1,6 +1,22 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +DMOD="PV" +#DMOD="MAIN" +Debug=$debug -python /var/www/html/openWB/modules/wr2_victron/victron.py $pv2ip $pv2id -pv2watt=$(>${MYLOGFILE} 2>&1 + +pvwatt=$(<${RAMDISKDIR}/pvwatt) +echo $pvwatt diff --git a/modules/wr2_victron/victron.py b/modules/wr2_victron/victron.py deleted file mode 100644 index b2b53abde..000000000 --- a/modules/wr2_victron/victron.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -# import struct -# import binascii -from pymodbus.constants import Endian -from pymodbus.payload import BinaryPayloadDecoder -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) -mid = int(sys.argv[2]) - -client = ModbusTcpClient(ipaddress, port=502) -connection = client.connect() - -# mppt watt -resp= client.read_holding_registers(789,1,unit=mid) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -mpp_watt1 = str(decoder.decode_16bit_uint()) -mpp_watt2 = int(mpp_watt1) / 10 * -1 -f = open('/var/www/html/openWB/ramdisk/pv2watt', 'w') -f.write(str(mpp_watt2)) -f.close() - -client.close() diff --git a/modules/wr_discovergy/discovergy.py b/modules/wr_discovergy/discovergy.py new file mode 100755 index 000000000..204511845 --- /dev/null +++ b/modules/wr_discovergy/discovergy.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +from datetime import datetime, timezone +import os +import requests +import sys +import traceback + +Debug = int(os.environ.get('debug')) +myPid = str(os.getpid()) + +discovergyuser = str(sys.argv[1]) +discovergypass = str(sys.argv[2]) +discovergypvid = str(sys.argv[3]) + +def DebugLog(message): + local_time = datetime.now(timezone.utc).astimezone() + print(local_time.strftime(format = "%Y-%m-%d %H:%M:%S") + ": PID: "+ myPid +": " + message) + + +if Debug >= 2: + DebugLog('Wechselrichter Discovergy User: ' + discovergyuser) + DebugLog('Wechselrichter Discovergy Passwort: ' + discovergypass) + DebugLog('Wechselrichter Discovergy ID: ' + discovergypvid) + +params = ( + ('meterId', discovergypvid), +) +output = requests.get('https://api.discovergy.com/public/v1/last_reading', params=params, auth=(discovergyuser, discovergypass), timeout=5).json() +try: + pvwh = output["values"]["energyOut"] +except: + traceback.print_exc() + exit(1) +pvwh = pvwh / 10000000 +if Debug >= 1: + DebugLog('WR Energie: ' + str(pvwh)) +with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(pvwh)) + +try: + watt = output["values"]["power"] +except: + traceback.print_exc() + exit(1) +watt = watt / 1000 +if Debug >= 1: + DebugLog('WR Leistung: ' + str(watt)) +with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(watt)) + +exit(0) diff --git a/modules/wr_discovergy/main.sh b/modules/wr_discovergy/main.sh index bdab2c97e..c06f92aef 100755 --- a/modules/wr_discovergy/main.sh +++ b/modules/wr_discovergy/main.sh @@ -1,12 +1,28 @@ #!/bin/bash -output=$(curl --connect-timeout 5 -s -u $discovergyuser:"$discovergypass" "https://api.discovergy.com/public/v1/last_reading?meterId=$discovergypvid") +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="EVU" +DMOD="MAIN" +Debug=$debug -pvwh=$(echo $output | jq .values.energyOut) -pvwh=$(( pvwh / 10000000 )) -echo $pvwh > /var/www/html/openWB/ramdisk/pvkwh +#For development only +#Debug=1 -watt=$(echo $output | jq .values.power) -watt=$(( watt / 1000 )) -echo $watt > /var/www/html/openWB/ramdisk/pvwatt +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/wr_discovergy.log" +fi -echo $watt +openwbDebugLog ${DMOD} 2 "WR User: ${discovergyuser}" +openwbDebugLog ${DMOD} 2 "WR Passwort: ${discovergypass}" +openwbDebugLog ${DMOD} 2 "WR ID: ${discovergypvid}" + +python3 /var/www/html/openWB/modules/wr_discovergy/discovergy.py "${discovergyuser}" "${discovergypass}" "${discovergypvid}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$(= 2: + DebugLog('Wechselrichter FEMS Passwort: ' + femskacopw) + DebugLog('Wechselrichter FEMS IP: ' + femsip) + +response = requests.get('http://'+femsip+':8084/rest/channel/_sum/ProductionActivePower', auth=("x", femskacopw)).json() +try: + pvwatt = response["value"] * -1 +except: + traceback.print_exc() + exit(1) + +response = requests.get('http://'+femsip+':8084/rest/channel/_sum/ProductionActiveEnergy', + auth=("x", femskacopw)).json() +try: + pvwh = response["value"] +except: + traceback.print_exc() + exit(1) + +regex = '^-?[0-9]+$' +if re.search(regex, str(pvwatt)) == None: + pvwatt = "0" +if re.search(regex, str(pvwh)) != None: + if Debug >= 1: + DebugLog('WR Energie: ' + str(pvwh)) + with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(pvwh)) +if Debug >= 1: + DebugLog('WR Leistung: ' + str(pvwatt)) +with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(pvwatt)) + +exit(0) diff --git a/modules/wr_fems/main.sh b/modules/wr_fems/main.sh index 05cdcf157..d7b66fb04 100644 --- a/modules/wr_fems/main.sh +++ b/modules/wr_fems/main.sh @@ -1,15 +1,27 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="EVU" +DMOD="MAIN" +Debug=$debug -pvwatt=$(curl -s "http://x:$femskacopw@$femsip:8084/rest/channel/_sum/ProductionActivePower" | jq .value) -pvwatt=$(( pvwatt * -1 )) -pvwh=$(curl -s "http://x:$femskacopw@$femsip:8084/rest/channel/_sum/ProductionActiveEnergy" | jq .value) +#For development only +#Debug=1 -re='^-?[0-9]+$' -if ! [[ $pvwatt =~ $re ]] ; then - pvwatt="0" +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/wr_fems.log" fi -if [[ $pvwh =~ $re ]] ; then - echo $pvwh > /var/www/html/openWB/ramdisk/pvkwh -fi -echo $pvwatt > /var/www/html/openWB/ramdisk/pvwatt + +openwbDebugLog ${DMOD} 2 "WR Passwort: ${femskacopw}" +openwbDebugLog ${DMOD} 2 "WR IP: ${femsip}" + +python3 /var/www/html/openWB/modules/wr_fems/fems.py "${femskacopw}" "${femsip}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$(= level: + local_time = datetime.now(timezone.utc).astimezone() + print(local_time.strftime(format = "%Y-%m-%d %H:%M:%S") + ": PID: " + myPid + ": " + message) + +DebugLog(2, 'WechselrichterFronius IP: ' + wrfroniusip) +DebugLog(2, 'WechselrichterFronius Gen24: ' + str(wrfroniusisgen24)) +DebugLog(2, 'WechselrichterFronius 2 IP: ' + wrfronius2ip) + +# Auslesen eines Fronius Symo WR über die integrierte API des WR. +# Rückgabewert ist die aktuelle Wirkleistung in [W]. +params = ( + ('Scope', 'System'), +) +response = requests.get('http://'+wrfroniusip+'/solar_api/v1/GetPowerFlowRealtimeData.fcgi', params=params, timeout=3) +pvwatttmp = response.json() +DebugLog(1, 'response: ' + str(response)) +DebugLog(2, 'response_pvwatt: ' + str(pvwatttmp)) +# Ohne PV Produktion liefert der WR 'null', ersetze durch Zahl 0 +pvwatt = int(pvwatttmp["Body"]["Data"]["Site"]["P_PV"] or 0) + +if wrfroniusisgen24 == 0: + pvkwh_start = 0 + pvkwh_offset = 0 + pvkwh = int(pvwatttmp["Body"]["Data"]["Site"]["E_Total"]) + pvday = int(pvwatttmp["Body"]["Data"]["Site"]["E_Day"]) + try: + with open("/var/www/html/openWB/ramdisk/pvkwh_offset", "r") as f: + pvkwh_offset = int(f.read()) + except FileNotFoundError as e: + DebugLog(1, str(e)) + try: + with open("/var/www/html/openWB/ramdisk/pvkwh_start", "r") as f: + pvkwh_start = int(f.read()) + pvkwh_new = pvkwh_start + pvday + pvkwh_offset + if pvkwh_new > pvkwh: + if pvkwh_new - pvkwh >= 100: + # Korrigiere Abweichung + pvkwh_diff = pvkwh_new - pvkwh - 99 + pvkwh_offset -= pvkwh_diff + pvkwh_new -= pvkwh_diff + pvkwh = pvkwh_new + else: + # Berechne Abweichung als Mittelwert von aktueller und bisheriger Abweichung + pvkwh_offset = round((pvkwh_offset + pvkwh - pvkwh_start - pvday) / 2) + except FileNotFoundError as e: + DebugLog(1, str(e)) + +if wrfronius2ip != "none": + params = (('Scope', 'System'),) + response = requests.get('http://'+wrfronius2ip+'/solar_api/v1/GetPowerFlowRealtimeData.fcgi', params=params, timeout=3) + pv2watttmp = response.json() + DebugLog(1, 'response: ' + str(response)) + DebugLog(2, 'response_pv2watt: ' + str(pv2watttmp)) + # Ohne PV Produktion liefert der WR 'null', ersetze durch Zahl 0 + pv2watt = int(pv2watttmp["Body"]["Data"]["Site"]["P_PV"] or 0) + pvwatt = (pvwatt + pv2watt) * -1 + # Zur weiteren Verwendung im Webinterface + DebugLog(1, 'WR Leistung: ' + str(pvwatt)) + with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(pvwatt)) + if wrfroniusisgen24 == 0: + pv2kwh = int(pv2watttmp["Body"]["Data"]["Site"]["E_Total"]) + pvgkwh = pvkwh + pv2kwh + if pvgkwh > 0: + DebugLog(1, 'WR Energie: ' + str(pvgkwh)) + with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(pvgkwh)) + with open("/var/www/html/openWB/ramdisk/pvkwhk", "w") as f: + f.write('{:.3f}'.format(pvgkwh / 1000)) +else: + pvwatt *= -1 + # Zur weiteren Verwendung im Webinterface + DebugLog(1, 'WR Leistung: ' + str(pvwatt)) + with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(pvwatt)) + if wrfroniusisgen24 == 0 and pvkwh > 0: + if pvday == 0 and pvkwh > pvkwh_start + pvkwh_offset: + with open("/var/www/html/openWB/ramdisk/pvkwh_start", "w") as f: + f.write(str(pvkwh)) + with open("/var/www/html/openWB/ramdisk/pvkwh_offset", "w") as f: + with open("/var/www/html/openWB/ramdisk/pvkwh", "r") as ff: + pvkwh_offset = int(ff.read()) - pvkwh + pvkwh += pvkwh_offset + f.write(str(pvkwh_offset)) + else: + with open("/var/www/html/openWB/ramdisk/pvkwh_offset", "w") as f: + f.write(str(pvkwh_offset)) + DebugLog(1, 'WR Energie: ' + str(pvkwh)) + with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(pvkwh)) + pvkwhk = round(pvkwh / 1000, 3) + with open("/var/www/html/openWB/ramdisk/pvkwhk", "w") as f: + f.write(str(pvkwhk)) + +exit(0) \ No newline at end of file diff --git a/modules/wr_fronius/main.sh b/modules/wr_fronius/main.sh index 96b79b765..d069021f3 100755 --- a/modules/wr_fronius/main.sh +++ b/modules/wr_fronius/main.sh @@ -1,52 +1,28 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="EVU" +DMOD="MAIN" +Debug=$debug -# Auslesen eine Fronius Symo WR über die integrierte API des WR. Rückgabewert ist die aktuelle Wirkleistung in [W]. -pvwatttmp=$(curl --connect-timeout 3 -s "$wrfroniusip/solar_api/v1/GetPowerFlowRealtimeData.fcgi?Scope=System") -pvwatt=$(echo $pvwatttmp | jq '.Body.Data.Site.P_PV' | sed 's/\..*$//') +#For development only +#Debug=1 -# Wenn WR aus bzw. im Standby (keine Antwort), ersetze leeren Wert durch eine 0 -re='^-?[0-9]+$' -if ! [[ $pvwatt =~ $re ]] ; then - pvwatt="0" -fi -if [[ $wrfroniusisgen24 == 0 ]]; then - pvkwh=$(echo $pvwatttmp | jq '.Body.Data.Site.E_Total' | sed 's/\..*$//') -fi -if [[ $wrfronius2ip != "none" ]]; then - pv2watttmp=$(curl --connect-timeout 3 -s "$wrfronius2ip/solar_api/v1/GetPowerFlowRealtimeData.fcgi?Scope=System") - pv2watt=$(echo $pv2watttmp | jq '.Body.Data.Site.P_PV' | sed 's/\..*$//') - # Wenn WR aus bzw. im Standby (keine Antwort), ersetze leeren Wert durch eine 0 - re='^-?[0-9]+$' - if ! [[ $pv2watt =~ $re ]] ; then - pv2watt="0" - fi - pvwatt=$(echo "($pvwatt + $pv2watt) * -1" | bc) - echo $pvwatt - # Zur weiteren Verwendung im Webinterface - echo $pvwatt > /var/www/html/openWB/ramdisk/pvwatt - if [[ $wrfroniusisgen24 == 0 ]]; then - pv2kwh=$(echo $pv2watttmp | jq '.Body.Data.Site.E_Total' | sed 's/\..*$//') - pvgkwh=$(echo "$pvkwh + $pv2kwh" | bc) - if [[ $pvgkwh =~ $re ]] ; then - if (( pvgkwh > 0 )); then - echo $pvgkwh > /var/www/html/openWB/ramdisk/pvkwh - pvkwhk=$(echo "scale=3; $pvgkwh / 1000" | bc) - echo $pvkwhk > /var/www/html/openWB/ramdisk/pvkwhk - fi - fi - fi +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" else - pvwatt=$(echo "$pvwatt * -1" | bc) - echo $pvwatt - # Zur weiteren Verwendung im Webinterface - echo $pvwatt > /var/www/html/openWB/ramdisk/pvwatt - if [[ $wrfroniusisgen24 == 0 ]]; then - if [[ $pvkwh =~ $re ]] ; then - if (( pvkwh > 0 )); then - echo $pvkwh > /var/www/html/openWB/ramdisk/pvkwh - pvkwhk=$(echo "scale=3; $pvkwh / 1000" | bc) - echo $pvkwhk > /var/www/html/openWB/ramdisk/pvkwhk - fi - fi - fi + MYLOGFILE="${RAMDISKDIR}/wr_fronius.log" fi + +openwbDebugLog ${DMOD} 2 "WR IP: ${wrfroniusip}" +openwbDebugLog ${DMOD} 2 "WR Gen 24: ${wrfroniusisgen24}" +openwbDebugLog ${DMOD} 2 "WR IP2: ${wrfronius2ip}" + +python3 /var/www/html/openWB/modules/wr_fronius/fronius.py "${wrfroniusip}" "${wrfroniusisgen24}" "${wrfronius2ip}" &>>$MYLOGFILE +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$( 3 )); then - wattwr=$(( wattwr * -1 )) -fi -echo $wattwr -echo $wattwr > /var/www/html/openWB/ramdisk/pvwatt -if [[ $wr_http_kwh_url != "none" ]]; then - ekwh=$(curl --connect-timeout 5 -s $wr_http_kwh_url) - echo $ekwh > /var/www/html/openWB/ramdisk/pvkwh - pvkwhk=$(echo "scale=3;$ekwh / 1000" |bc) - echo $pvkwhk > /var/www/html/openWB/ramdisk/pvkwhk -fi +openwbDebugLog ${DMOD} 2 "WR Leistung URL: ${wr_http_w_url}" +openwbDebugLog ${DMOD} 2 "WR Energie URL: ${wr_http_kwh_url}" + +python3 /var/www/html/openWB/modules/wr_http/read_http.py "${wr_http_w_url}" "${wr_http_kwh_url}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$(= 2: + DebugLog('Wechselrichter http URL Leistung: ' + wr_http_w_url) + DebugLog('Wechselrichter http URL Energie: ' + wr_http_kwh_url) + +response = requests.get(wr_http_w_url, timeout=10) +response.encoding = 'utf-8' +wattwr = response.text.replace("\n", "") +regex = '^-?[0-9]+$' +if re.search(regex, wattwr) == None: + wattwr = 0 + +if wattwr > 3: + wattwr = wattwr * -1 + +if Debug >= 1: + DebugLog('WR Leistung: ' + str(wattwr)) +with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(wattwr)) + +if wr_http_kwh_url != "none": + response = requests.get(wr_http_kwh_url, timeout=5) + response.encoding = 'utf-8' + ekwh = response.text.replace("\n", "") + if Debug >= 1: + DebugLog('WR Energie: ' + str(ekwh)) + with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(ekwh)) + pvkwhk = round(ekwh / 1000, 3) + with open("/var/www/html/openWB/ramdisk/pvkwhk", "w") as f: + f.write(str(pvkwhk)) + +exit(0) \ No newline at end of file diff --git a/modules/wr_json/read_json.py b/modules/wr_json/read_json.py old mode 100644 new mode 100755 index 2e27874e0..90141f174 --- a/modules/wr_json/read_json.py +++ b/modules/wr_json/read_json.py @@ -8,12 +8,12 @@ from datetime import datetime, timezone import os -Debug = int(os.environ.get('debug')) -myPid = str(os.getpid()) +Debug = int(os.environ.get('debug')) +myPid = str(os.getpid()) #renumeric ='^-?[0-9]+$' -renumeric ='^[-+]?[0-9]+\.?[0-9]*$' +renumeric = '^[-+]?[0-9]+\.?[0-9]*$' jsonurl = str(sys.argv[1]) @@ -21,11 +21,13 @@ jsonkwh = str(sys.argv[3]) numpv = int(str(sys.argv[4])) -RAMDISKDIR='/var/www/html/openWB/ramdisk/' +RAMDISKDIR = '/var/www/html/openWB/ramdisk/' + def DebugLog(message): local_time = datetime.now(timezone.utc).astimezone() - print(local_time.strftime(format = "%Y-%m-%d %H:%M:%S") + ": PID: "+ myPid +": " + message) + print(local_time.strftime(format="%Y-%m-%d %H:%M:%S") + ": PID: " + myPid + ": " + message) + numcheck = re.compile(renumeric) @@ -36,25 +38,25 @@ def DebugLog(message): response = requests.get(jsonurl, timeout=5).json() -if Debug>=2: +if Debug >= 2: DebugLog('JSON Response: ' + str(response)) try: watt = jq.compile(jsonwatt).input(response).first() - if Debug>=1: + if Debug >= 1: DebugLog('Leistung: ' + str(watt)) if not numcheck.match(str(watt)): DebugLog('Leistung (Watt) nicht numerisch. Bitte Filterausdruck ueberpruefen -->0') - watt=0 + watt = 0 - watt=int(watt) + watt = int(watt) if watt >= 0: watt = watt*(-1) if numpv == 1: with open(RAMDISKDIR + "pvwatt", "w") as f: f.write(str(watt)) else: - DebugLog(RAMDISKDIR + "pv" + str(numpv) + "watt"+ "W:"+str(watt)) - with open(RAMDISKDIR + "pv" + str(numpv) + "watt" , "w") as f: + DebugLog(RAMDISKDIR + "pv" + str(numpv) + "watt" + "W:"+str(watt)) + with open(RAMDISKDIR + "pv" + str(numpv) + "watt", "w") as f: f.write(str(watt)) except: traceback.print_exc() @@ -71,7 +73,7 @@ def DebugLog(message): with open(RAMDISKDIR + "pvkwh", "w") as f: f.write(str(kwh)) else: - with open(RAMDISKDIR + "pv" + str(numpv) + "kwh" , "w") as f: + with open(RAMDISKDIR + "pv" + str(numpv) + "kwh", "w") as f: f.write(str(kwh)) except: traceback.print_exc() diff --git a/modules/wr_kostalpiko/kostal_piko_var1.py b/modules/wr_kostalpiko/kostal_piko_var1.py new file mode 100755 index 000000000..784948637 --- /dev/null +++ b/modules/wr_kostalpiko/kostal_piko_var1.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 + +from datetime import datetime, timezone +import os +import requests +import sys +import traceback + +Debug = int(os.environ.get('debug')) +myPid = str(os.getpid()) + +num = int(sys.argv[1]) +speichermodul = str(sys.argv[2]) +wrkostalpikoip = str(sys.argv[3]) + + +def DebugLog(message): + local_time = datetime.now(timezone.utc).astimezone() + print(local_time.strftime(format="%Y-%m-%d %H:%M:%S") + ": PID: " + myPid + ": " + message) + + +if Debug >= 2: + DebugLog('Wechselrichter Kostal Piko Var 1 Speicher: ' + speichermodul) + DebugLog('Wechselrichter Kostal Piko Var 1 IP: ' + wrkostalpikoip) + +if num == 1: + file_ext = "" +elif num == 2: + file_ext = "2" + +# Auslesen eines Kostal Piko WR über die integrierte API des WR. Rückgabewert ist die aktuelle Wattleistung. +if speichermodul != "none": + params = (('dxsEntries', ['33556736', '251658753)']),) + pvwatttmp = requests.get('http://'+wrkostalpikoip+'/api/dxs.json', params=params, timeout=5).json() +else: + params = (('dxsEntries', ['67109120', '251658753)']),) + pvwatttmp = requests.get('http://'+wrkostalpikoip+'/api/dxs.json', params=params, timeout=5).json() + +# aktuelle Ausgangsleistung am WR [W] +try: + pvwatt = int(pvwatttmp["dxsEntries"][0]["value"]) +except: + traceback.print_exc() + exit(1) +if pvwatt > 5: + pvwatt = pvwatt*-1 + +# zur weiteren verwendung im webinterface +if Debug >= 1: + DebugLog('WR Leistung: ' + str(pvwatt)) +with open("/var/www/html/openWB/ramdisk/pv"+file_ext+"watt", "w") as f: + f.write(str(pvwatt)) +# Gesamtzählerstand am WR [kWh] +pvkwh = int(pvwatttmp['dxsEntries'][1]['value']) +with open("/var/www/html/openWB/ramdisk/pv"+file_ext+"kwhk", "w") as f: + f.write(str(pvkwh)) + +pvkwh = pvkwh*1000 +# zur weiteren verwendung im webinterface +with open("/var/www/html/openWB/ramdisk/pv"+file_ext+"kwh", "w") as f: + f.write(str(pvkwh)) + + +exit(0) diff --git a/modules/wr_kostalpiko/main.sh b/modules/wr_kostalpiko/main.sh index d42fa59f7..aa4b9ede8 100755 --- a/modules/wr_kostalpiko/main.sh +++ b/modules/wr_kostalpiko/main.sh @@ -1,23 +1,28 @@ #!/bin/bash -# Auslesen eines Kostal Piko WR über die integrierte API des WR. Rückgabewert ist die aktuelle Wattleistung. -if [[ "$speichermodul" != "none" ]]; then - pvwatttmp=$(curl --connect-timeout 5 -s $wrkostalpikoip/api/dxs.json?dxsEntries=33556736'&'dxsEntries=251658753) +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="EVU" +DMOD="MAIN" +Debug=$debug + +#For development only +#Debug=1 + +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" else - pvwatttmp=$(curl --connect-timeout 5 -s $wrkostalpikoip/api/dxs.json?dxsEntries=67109120'&'dxsEntries=251658753) -fi -# aktuelle Ausgangsleistung am WR [W] -pvwatt=$(echo $pvwatttmp | jq '.dxsEntries[0].value' | sed 's/\..*$//') -if [ $pvwatt > 5 ] - then - pvwatt=$(echo "$pvwatt*-1" |bc) + MYLOGFILE="${RAMDISKDIR}/wr_discovergy.log" fi + +openwbDebugLog ${DMOD} 2 "WR Speicher: ${speichermodul}" +openwbDebugLog ${DMOD} 2 "WR IP: ${wrkostalpikoip}" + +python3 /var/www/html/openWB/modules/wr_kostalpiko/kostal_piko_var1.py 1 "${speichermodul}" "${wrkostalpikoip}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$( /var/www/html/openWB/ramdisk/pvwatt -# Gesamtzählerstand am WR [kWh] -# pvkwh=$(echo $pvwatttmp | jq '.dxsEntries[1].value' | sed 's/\..*$//') -# echo $pvkwh > /var/www/html/openWB/ramdisk/pvkwhk -# pvkwh=$(echo "$pvkwh*1000" |bc) -# zur weiteren verwendung im webinterface -# echo $pvkwh > /var/www/html/openWB/ramdisk/pvkwh diff --git a/modules/wr_kostalpikovar2/kostal_piko_var2.py b/modules/wr_kostalpikovar2/kostal_piko_var2.py new file mode 100755 index 000000000..cfe6d440e --- /dev/null +++ b/modules/wr_kostalpikovar2/kostal_piko_var2.py @@ -0,0 +1,76 @@ +# initially created by Stefan Schefler for openWB 2019 +# modified by Kevin Wieland +# modified by Lena Kuemmel +# based on Homematic Script v0.2 (c) 2018 by Alchy + +#!/usr/bin/env python3 + +from datetime import datetime, timezone +import os +import re +import requests +import sys + +Debug = int(os.environ.get('debug')) +myPid = str(os.getpid()) + +num = int(sys.argv[1]) +wr_piko2_url = str(sys.argv[2]) +wr_piko2_user = str(sys.argv[3]) +wr_piko2_pass = str(sys.argv[4]) + +def DebugLog(message): + local_time = datetime.now(timezone.utc).astimezone() + print(local_time.strftime(format = "%Y-%m-%d %H:%M:%S") + ": PID: "+ myPid +": " + message) + + +if Debug >= 2: + DebugLog('Wechselrichter Kostal Piko Var 2 User: ' + wr_piko2_user) + DebugLog('Wechselrichter Kostal Piko Var 2 Passwort: ' + wr_piko2_pass) + DebugLog('Wechselrichter Kostal Piko Var 2 URL: ' + wr_piko2_url) + +if num == 1: + file_ext = "" +elif num == 2: + file_ext = "2" + +# Daten einlesen +response = requests.get(wr_piko2_url, verify=False, auth=(wr_piko2_user, wr_piko2_pass), timeout=10) +# request html, concat to one line, remove spaces, add spaces before color changes (#) +response.encoding = 'utf-8' +HTML = response.text +HTML = HTML.replace("\r", "") +HTML = HTML.replace("\n", "") +HTML = HTML.replace(" ", "") +HTML = HTML.replace("#", " ") + +if HTML != "": # check if valid content of request + counter = 0 + for LINE in HTML: # parse all html lines + if re.search("FFFFFF", LINE) != None: # search for white background color + counter = counter + 1 + # PART2=${LINE##*F\">} # strip before number + # VALUE=${PART2%%<*} # strip after number + VALUE = re.search('^[0-9]+\.?[0-9]*$', LINE).group() + + if counter == 1: # pvwatt + if VALUE == "xxx": # off-value equals zero + VALUE = "0" + regex = '^[-+]?[0-9]+\.?[0-9]*$' + if re.search(regex, VALUE) == None: # check for valid number + with open("/var/www/html/openWB/ramdisk/pv"+file_ext+"watt", "r") as f: + VALUE = f.read() + if Debug >= 1: + DebugLog('WR Leistung: ' + str(VALUE*-1)) + with open("/var/www/html/openWB/ramdisk/pv"+file_ext+"watt", "w") as f: + f.write(str(VALUE*-1)) + elif counter == 2: # pvkwhk + if Debug >= 1: + DebugLog('WR Energie: ' + str(VALUE)) + with open("/var/www/html/openWB/ramdisk/pv"+file_ext+"kwhk", "w") as f: + f.write(str(VALUE)) + if num == 1: + with open("/var/www/html/openWB/ramdisk/pv"+file_ext+"kwh", "w") as f: + f.write(str(VALUE*1000)) + +exit(0) \ No newline at end of file diff --git a/modules/wr_kostalpikovar2/main.sh b/modules/wr_kostalpikovar2/main.sh index 80654ef49..457d83936 100755 --- a/modules/wr_kostalpikovar2/main.sh +++ b/modules/wr_kostalpikovar2/main.sh @@ -1,41 +1,29 @@ #!/bin/bash -# initially created by Stefan Schefler for openWB 2019 -# modified by Kevin Wieland -# based on Homematic Script v0.2 (c) 2018 by Alchy -# Daten einlesen -HTML=$(/usr/bin/curl -u $wr_piko2_user:$wr_piko2_pass --connect-timeout 10 -s -k $wr_piko2_url | /usr/bin/tr -d '\r' | /usr/bin/tr -d '\n' | /usr/bin/tr -d ' ' | /usr/bin/tr '#' ' ') -# request html, concat to one line, remove spaces, add spaces before color changes (#) +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="EVU" +DMOD="MAIN" +Debug=$debug -if [[ -n $HTML ]] # check if valid content of request -then - counter=0 - for LINE in $HTML # parse all html lines - do - if [[ $LINE =~ FFFFFF ]]; # search for white background color - then - ((counter++)) - PART2=${LINE##*F\">} # strip before number - VALUE=${PART2%%<*} # strip after number +#For development only +#Debug=1 - if [[ $counter -eq 1 ]] # pvwatt - then - if [[ $VALUE = "xxx" ]] # off-value equals zero - then - $VALUE = "0" - fi - re='^[-+]?[0-9]+\.?[0-9]*$' - if ! [[ $VALUE =~ $re ]] # check for valid number - then - VALUE=$( /var/www/html/openWB/ramdisk/pvwatt - echo $((VALUE*-1)) - elif [[ $counter -eq 2 ]] # pvkwhk - then - echo ${VALUE} > /var/www/html/openWB/ramdisk/pvkwhk - echo $((VALUE*1000)) > /var/www/html/openWB/ramdisk/pvkwh - fi - fi - done +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/wr_kostalpikovar2.log" fi + +openwbDebugLog ${DMOD} 2 "WR User: ${wr_piko2_user}" +openwbDebugLog ${DMOD} 2 "WR Passwort: ${wr_piko2_pass}" +openwbDebugLog ${DMOD} 2 "WR URL: ${wr_piko2_url}" + +python3 /var/www/html/openWB/modules/wr_kostalpikovar2/kostal_piko_var2.py 1 "${wr_piko2_url}" "${wr_piko2_user}" "${wr_piko2_pass}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$(= 2: + DebugLog('Wechselrichter LG IP: ' + lgessv1ip) + DebugLog('Wechselrichter LG Passwort: ' + ess_pass) + DebugLog('Wechselrichter LG Version: ' + ess_api_ver) + +# +# Flag für unterschiedliche API-Versionen der Firmware +# +if ess_api_ver == "10.2019": + arr_pos = "13" +else: + arr_pos = "1" + +# +# Prüfen, ob ein Sessionkey in der Ramdisk vorhanden ist. Wenn nicht, +# z.b. wenn das System neu gestartet wurde, dann wird ein Dummykey an- +# gelegt +if os.path.isfile("/var/www/html/openWB/ramdisk/ess_session_key"): + with open("/var/www/html/openWB/ramdisk/ess_session_key", "r") as f: + # erste Zeile ohne Anhaengen einer neuen Zeile lesen + session_key = f.readline().strip() +else: + session_key = " " + +# +# JSON-Objekt vom PCS abholen. Es können folgende JSON-Objekte zurück gegeben werden: +# +# 1. Wenn der Sessionkey nicht korrekt bzw. wenn die Session abgelaufen ist, dann wird ein +# JSON-Objekt mit einem Attribut "auth_key" zurück gegeben +# 2. Der Sessionkey ist gültig, dann erhält man ein JSON-Objekt mit den wichtigsten Attribute. +# Beispiel JSON-Objekte liegen im Ordner lgessv1/JSON-Beispiele.txt +# +try: + headers = {'Content-Type': 'application/json', } + data = json.dumps({"auth_key": session_key}) + response = requests.post(ess_url+'/v1/user/essinfo/home', headers=headers, data=data, verify=False, timeout=5).json() + authchk = response['auth'] +except: + traceback.print_exc() + exit(1) +# +# Pruefen, ob Sessionkey ungültig ist, wenn ja, Login und neuen Sessionkey empfangen +# +if authchk == "auth_key failed" or authchk == "auth timeout" or authchk == "": + try: + headers = {'Content-Type': 'application/json', } + data = json.dumps({"password": ess_pass}) + response = requests.put(ess_url+'/v1/login', headers=headers, data=data, verify=False, timeout=5).json() + session_key = response["auth_key"] + outjson = {"auth_key": session_key} + except: + traceback.print_exc() + exit(1) + # + # aktuelle Daten aus dem PCS auslesen + # + headers = {'Content-Type': 'application/json', } + data = json.dumps(outjson) + response = requests.post(ess_url+'/v1/user/essinfo/home', headers=headers, data=data, verify=False, timeout=5).json() + # + # Sessionkey in der Ramdisk abspeichern + # + with open("/var/www/html/openWB/ramdisk/ess_session_key", "w") as f: + f.write(str(session_key)) + +# +# JSON-Objekt auswerten +# +try: + pcs_pv_total_power = response["statistics"]["pcs_pv_total_power"] +except: + traceback.print_exc() + exit(1) +# +# Daten für Langzeitlog holen +# +today = datetime.datetime.today() +jahr = today.strftime("%Y") +monat = today.strftime("%m") +arr_pos = monat + +headers = {'Content-Type': 'application/json', } +data = json.dumps({"auth_key": session_key, "year": str(jahr)}) +response = requests.post(ess_url+'/v1/user/graph/pv/year', headers=headers, data=data, verify=False, timeout=5).json() +try: + pvkwh = response["loginfo"][arr_pos]["total_generation"] + pvkwh = pvkwh.replace("kwh", "") + pvkwh = int(pvkwh) +except: + traceback.print_exc() + exit(1) +try: + ekwh = response["loginfo"][arr_pos]["total_Feed_in"] + ekwh = ekwh.replace("kwh", "") + ekwh = int(ekwh) +except: + traceback.print_exc() + exit(1) +# +# Daten in Ramdisk schreiben +# +# echo $pvkwh > /var/www/html/openWB/ramdisk/pvkwh +# echo $pvkwh > /var/www/html/openWB/ramdisk/pv1kwh_temp +# echo $ekwh > /var/www/html/openWB/ramdisk/einspeisungkwh +if Debug >= 1: + DebugLog('WR Leistung: ' + "-"+str(pcs_pv_total_power)) +with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write("-"+str(pcs_pv_total_power)) + +exit(0) \ No newline at end of file diff --git a/modules/wr_lgessv1/main.sh b/modules/wr_lgessv1/main.sh index a32f6ce65..9092ffce8 100755 --- a/modules/wr_lgessv1/main.sh +++ b/modules/wr_lgessv1/main.sh @@ -1,81 +1,29 @@ #!/bin/bash -# -## ess_url: IP/URL des LG ESS V1.0 -# -## ess_pass: Passwort, um sich in den LG ESS V1.0 einzuloggen -# Das Passwort ist standardmäßig die Registrierungsnr. -# die sich auf dem PCS (dem Hybridwechselrichter und -# Batteriemanagementsystem) befindet (Aufkleber!). Alter- -# nativ findet man die Registrierungsnr. in der App unter -# dem Menüpunkt "Systeminformationen" -# Mit der Registrierungsnr. kann man sich dann in der -# Rolle "installer" einloggen. -ess_url="https://$lgessv1ip" -ess_pass=$lgessv1pass -# -## Flag für unterschiedliche API-Versionen der Firmware -# -if [ "$ess_api_ver" == "10.2019" ]; then - arr_pos="13" -else - arr_pos="1" -fi -# -## Prüfen, ob ein Sessionkey in der Ramdisk vorhanden ist. Wenn nicht, -# z.b. wenn das System neu gestartet wurde, dann wird ein Dummykey an- -# gelegt -if test -f "/var/www/html/openWB/ramdisk/ess_session_key"; then - session_key=$(sed -n '1p' /var/www/html/openWB/ramdisk/ess_session_key) + +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="EVU" +DMOD="MAIN" +Debug=$debug + +#For development only +#Debug=1 + +if [ ${DMOD} == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" else - session_key=" " -fi -# -## JSON-Objekt vom PCS abholen. Es können folgende JSON-Objekte zurück gegeben werden: -# -# 1. Wenn der Sessionkey nicht korrekt bzw. wenn die Session abgelaufen ist, dann wird ein -# JSON-Objekt mit einem Attribut "auth_key" zurück gegeben -# 2. Der Sessionkey ist gültig, dann erhält man ein JSON-Objekt mit den wichtigsten Attribute. -# Beispiel JSON-Objekte liegen im Ordner lgessv1/JSON-Beispiele.txt -# -json=$(curl -s -k --connect-timeout 5 -d '{"auth_key":'$session_key'}' -H "Content-Type: application/json" -X POST $ess_url'/v1/user/essinfo/home') -authchk=$(echo $json | jq '.auth' | sed 's/.*://' | tr -d '\n' | sed 's/\"//' | sed 's/\"//') -# -## Prüfen, ob Sessionkey ungültig ist, wenn ja, Login und neuen Sessionkey empfangen -#echo $authchk -# -if [ "$authchk" == "auth_key failed" ] || [ "$authchk" == "auth timeout" ] || [ "$authchk" == "" ]; then - json=$(curl -s -k --connect-timeout 5 -d '{"password":"'$ess_pass'"}' -H "Content-Type: application/json" -X PUT $ess_url/v1/login) - session_key=$(echo $json | jq '.auth_key' | sed 's/.*://' | tr -d '\n' | sed 's/\"//' | sed 's/\"//') - session_key='"'$session_key'"' - outjson='{"auth_key":'$session_key'}' - # - ## aktuelle Daten aus dem PCS auslesen - # - json=$(curl -s -k --connect-timeout 5 -d $outjson -H '"Content-Type: application/json"' -X POST $ess_url/v1/user/essinfo/home) - # - ## Sessionkey in der Ramdisk abspeichern - # - echo $session_key > /var/www/html/openWB/ramdisk/ess_session_key + MYLOGFILE="${RAMDISKDIR}/wr_lgessv1.log" fi -# -## JSON-Objekt auswerten -# -pcs_pv_total_power=$(echo $json | jq '.statistics.pcs_pv_total_power' | sed 's/.*://' | tr -d '\n' | sed 's/\"//' | sed 's/\"//') -# -## Daten für Langzeitlog holen -# -jahr=$(date +%Y) -year_of_stat='"'year'"':'"'$jahr'"' -monat=$(date +%m) -arr_pos=$monat -json=$(curl -s -k --connect-timeout 5 -d '{"auth_key":'$session_key', '$year_of_stat'}' -H "Content-Type: application/json" -X POST $ess_url'/v1/user/graph/pv/year') -pvkwh=$(echo $json | jq '.loginfo['$arr_pos'].total_generation' | sed 's/.*://' | tr -d '\n' | sed 's/\"//' | sed 's/\"//' | sed 's/kwh//' | sed 's/\.//') -ekwh=$(echo $json | jq '.loginfo['$arr_pos'].total_Feed_in' | sed 's/.*://' | tr -d '\n' | sed 's/\"//' | sed 's/\"//' | sed 's/kwh//' | sed 's/\.//') -# -## Daten in Ramdisk schreiben -# -#echo $pvkwh > /var/www/html/openWB/ramdisk/pvkwh -#echo $pvkwh > /var/www/html/openWB/ramdisk/pv1kwh_temp -#echo $ekwh > /var/www/html/openWB/ramdisk/einspeisungkwh -echo '-'$pcs_pv_total_power > /var/www/html/openWB/ramdisk/pvwatt -echo '-'$pcs_pv_total_power + +openwbDebugLog ${DMOD} 2 "WR IP: ${lgessv1ip}" +openwbDebugLog ${DMOD} 2 "WR Passwort: ${ess_pass}" +openwbDebugLog ${DMOD} 2 "WR Version: ${ess_api_ver}" + +python3 /var/www/html/openWB/modules/wr_lgessv1/lgessv1.py "${lgessv1ip}" "${ess_pass}" "${ess_api_ver}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$( 0 )); then - timestamp=`date +"%Y-%m-%d %H:%M:%S"` - if (( Debug == 2 )); then - echo "$timestamp: ${MODULE}: PID:$myPid: $@" >> $LOGFILE - else - echo "$timestamp: ${MODULE}: $@" >> $LOGFILE - fi - fi -} +openwbDebugLog ${DMOD} 2 "PV Login erforderlich: ${speicherpwloginneeded}" +openwbDebugLog ${DMOD} 2 "PV User: ${speicherpwuser}" +openwbDebugLog ${DMOD} 2 "PV Passwort: ${speicherpwpass}" +openwbDebugLog ${DMOD} 2 "PV IP: ${speicherpwip}" -if (( speicherpwloginneeded == 1 )); then - # delete our login cookie after some time as it may be invalid - if [[ $(find "$COOKIEFILE" -cmin +60) ]]; then - DebugLog "Deleting saved login cookie after 1 hour as it may not be valid anymore." - rm "$COOKIEFILE" - fi - if [[ ! -f "$COOKIEFILE" ]]; then - # log in and save cookie for later use - DebugLog "Trying to authenticate..." - curl -s -k -i -c $COOKIEFILE --connect-timeout 5 -X POST -H "Content-Type: application/json" -d "{\"username\":\"customer\",\"password\":\"$speicherpwpass\", \"email\":\"$speicherpwuser\",\"force_sm_off\":false}" "https://$speicherpwip/api/login/Basic" - exitCode=$? - if (( exitCode != 0 )); then - DebugLog "Something went wrong. Curl Exit Code: $exitCode" - exit - else - DebugLog "Login successfull." - fi - else - DebugLog "Using saved login cookie." - fi - # tell next curl calls to use saved cookie - cookieOptions="-b $COOKIEFILE -c $COOKIEFILE" -fi +python3 /var/www/html/openWB/modules/wr_powerwall/powerwall.py "${OPENWBBASEDIR}" "${speicherpwloginneeded}" "${speicherpwuser}" "${speicherpwpass}" "${speicherpwip}" >>$MYLOGFILE 2>&1 +ret=$? -answer=$(curl -k $cookieOptions --connect-timeout 5 -s "https://$speicherpwip/api/meters/aggregates") -pvwatt=$(echo $answer | jq -r '.solar.instant_power' | sed 's/\..*$//') -if (( $pvwatt > 5 )); then - pvwatt=$(echo "$pvwatt*-1" |bc) -fi -echo $pvwatt -echo $pvwatt > /var/www/html/openWB/ramdisk/pvwatt -pvkwh=$(echo $answer | jq -r '.solar.energy_exported') -echo $pvkwh > /var/www/html/openWB/ramdisk/pvkwh +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$(= 1: + DebugLog(file+': ' + str(value)) + + +if Debug >= 2: + DebugLog('Powerwall IP: ' + speicherpwip) + DebugLog('Powerwall User: ' + speicherpwuser) + DebugLog('Powerwall Passwort: ' + speicherpwpass) + DebugLog('Powerwall Login: ' + speicherpwloginneeded) + +if speicherpwloginneeded == 1: + # delete our login cookie after some time as it may be invalid + if os.path.isfile(cookie_file) == True: + edited = os.stat(cookie_file).st_mtime + now = time.time() + edit_diff = now - edited + if edit_diff < 3600: + DebugLog("Deleting saved login cookie after 1 hour as it may not be valid anymore.") + os.remove(cookie_file) + if os.path.isfile(cookie_file) == False: + # log in and save cookie for later use + DebugLog("Trying to authenticate...") + headers = {'Content-Type': 'application/json', } + data = {"username": "customer", "password": speicherpwpass, "email": speicherpwuser, "force_sm_off": False} + data = json.dumps(data) + try: + response = requests.post('https://'+speicherpwip+'/api/login/Basic', headers=headers, data=data, verify=False, timeout=5) + except requests.exceptions.RequestException as e: + DebugLog("Something went wrong. RequestException: "+str(e)) + exit(1) + else: + DebugLog("Login successfull.") + cookie = response.cookies + with open(cookie_file, "w") as f: + f.write(str(requests.utils.dict_from_cookiejar(cookie))) + else: + DebugLog("Using saved login cookie.") + with open(cookie_file, "r") as f: + cookie = f.read() + + +answer = requests.get("https://"+speicherpwip+"/api/meters/aggregates", cookies=cookie, verify=False, timeout=5).json() +pvwatt=int(answer["solar"]["instant_power"]) +if pvwatt > 5: + pvwatt=pvwatt*-1 +if Debug >= 1: + DebugLog('WR Leistung: ' + str(pvwatt)) +with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(pvwatt)) + +pvkwh=answer["solar"]["energy_exported"] +if Debug >= 1: + DebugLog('WR Energie: ' + str(pvkwh)) +with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(pvkwh)) + +exit(0) \ No newline at end of file diff --git a/modules/wr_shelly/main.sh b/modules/wr_shelly/main.sh index 67bccd889..a28fa94a0 100644 --- a/modules/wr_shelly/main.sh +++ b/modules/wr_shelly/main.sh @@ -2,4 +2,4 @@ sudo python3 /var/www/html/openWB/modules/wr_shelly/shellywr.py $pv1_ipa pvwatt pvwatt=$( W) -wattwr=$(echo $json | jq .ActivePower) -wattwr=$(echo "scale=3 ; $wattwr * 1000" | bc) -wattwr=$(echo "$wattwr / 1" | bc) +#For development only +#Debug=1 -# Zählerstand Export (kWh --> Wh) -pvkwh=$(echo $json | jq .CounterReadingExport) -pvkwh=$(echo "scale=3 ; $pvkwh * 1000" | bc) -# Zur Reduzierung der Datenmenge kann die folgende Zeile eingefügt werden. -# pvkwh=$(echo "$pvkwh / 1" | bc) - -# Prüfen ob Werte gültig -re='^[-+]?[0-9]+\.?[0-9]*$' -if ! [[ $wattwr =~ $re ]] ; then - wattwr=$( /var/www/html/openWB/ramdisk/pvwatt -echo $pvkwh > /var/www/html/openWB/ramdisk/pvkwh -pvkwhk=$(echo "scale=3 ; $pvkwh / 1000" | bc) -echo $pvkwhk > /var/www/html/openWB/ramdisk/pvkwhk +openwbDebugLog ${DMOD} 2 "WR URL: ${wr_smartme_url}" +openwbDebugLog ${DMOD} 2 "WR User: ${wr_smartme_user}" +openwbDebugLog ${DMOD} 2 "WR Passwort: ${wr_smartme_pass}" + +python3 /var/www/html/openWB/modules/wr_smartme/smartme.py "${wr_smartme_url}" "${wr_smartme_user}" "${wr_smartme_pass}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$(= 2: + DebugLog('Wechselrichter smartme URL: ' + wr_smartme_url) + DebugLog('Wechselrichter smartme User: ' + wr_smartme_user) + DebugLog('Wechselrichter smartme Passwort: ' + wr_smartme_pass) + +# Daten einlesen +response = requests.get(wr_smartme_url, auth=(wr_smartme_user, wr_smartme_pass), timeout=10).json() +# Aktuelle Leistung (kW --> W) +try: + wattwr = response["ActivePower"] + wattwr = round(wattwr * 1000, 3) + wattwr = int(wattwr) +except: + traceback.print_exc() + exit(1) + +# Zählerstand Export (kWh --> Wh) +try: + pvkwh = response["CounterReadingExport"] + pvkwh = round(pvkwh * 1000, 3) +except: + traceback.print_exc() + exit(1) +# Zur Reduzierung der Datenmenge kann die folgende Zeile eingefügt werden. +# pvkwh=$(echo "$pvkwh / 1" | bc) + +# Prüfen ob Werte gültig +regex = '^[-+]?[0-9]+\.?[0-9]*$' +if re.search(regex, wattwr) == None: + with open("/var/www/html/openWB/ramdisk/pvwatt", "r") as f: + wattwr = f.read() +if re.search(regex, pvkwh) == None: + with open("/var/www/html/openWB/ramdisk/pvkwh", "r") as f: + pvkwh = f.read() + + +# Ausgabe +if Debug >= 1: + DebugLog('WR Leistung: ' + str(wattwr)) +with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(wattwr)) +if Debug >= 1: + DebugLog('WR Energie: ' + str(pvkwh)) +with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(pvkwh)) +pvkwhk = round(pvkwh / 1000, 3) +with open("/var/www/html/openWB/ramdisk/pvkwhk", "w") as f: + f.write(str(pvkwhk)) + +exit(0) \ No newline at end of file diff --git a/modules/wr_solaredge/main.sh b/modules/wr_solaredge/main.sh index fd3b795ea..9b4ef810a 100755 --- a/modules/wr_solaredge/main.sh +++ b/modules/wr_solaredge/main.sh @@ -1,4 +1,6 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" Solaredgebatwr="0" if [[ $solaredgespeicherip == $solaredgepvip ]] ; then @@ -7,8 +9,7 @@ fi if [[ $solaredgewr2ip != "none" ]]; then python /var/www/html/openWB/modules/wr_solaredge/solaredge2wr.py $solaredgepvip $solaredgepvslave1 $Solaredgebatwr $solaredgewr2ip $wr1extprod else - python /var/www/html/openWB/modules/wr_solaredge/solaredgeall.py $solaredgepvip $solaredgepvslave1 $solaredgepvslave2 $solaredgepvslave3 $solaredgepvslave4 $Solaredgebatwr $wr1extprod $solaredgezweiterspeicher $solaredgesubbat + python3 /var/www/html/openWB/modules/wr_solaredge/solaredgeall.py $solaredgepvip $solaredgepvslave1 $solaredgepvslave2 $solaredgepvslave3 $solaredgepvslave4 $Solaredgebatwr $wr1extprod $solaredgezweiterspeicher $solaredgesubbat >> "${RAMDISKDIR}/openWB.log" 2>&1 fi -pvwatt=$(HH', rr.getRegister(1), rr.getRegister(0)) - soc = int(struct.unpack('>f', raw)[0]) - try: - if zweiterspeicher == 1: - rr = client.read_holding_registers(62852, 2, unit=slave2id) - raw = struct.pack('>HH', rr.getRegister(1), rr.getRegister(0)) - soc2 = int(struct.unpack('>f', raw)[0]) - fsoc=(soc+soc2)/2 - else: - fsoc=soc - except: - fsoc=soc - f = open('/var/www/html/openWB/ramdisk/speichersoc', 'w') - f.write(str(fsoc)) - f.close() - rr = client.read_holding_registers(62836, 2, unit=slave1id) - raw = struct.pack('>HH', rr.getRegister(1), rr.getRegister(0)) - storagepower = int(struct.unpack('>f', raw)[0]) - try: - if zweiterspeicher == 1: - rr = client.read_holding_registers(62836, 2, unit=slave2id) - raw = struct.pack('>HH', rr.getRegister(1), rr.getRegister(0)) - storage2power = int(struct.unpack('>f', raw)[0]) - except: - storage2power = 0 - final=storagepower+storage2power - f = open('/var/www/html/openWB/ramdisk/speicherleistung', 'w') - f.write(str(final)) - f.close() +def update_solar_edge(client: ModbusClient, + slave_ids: List[int], + batwrsame: int, + extprodakt: int, + zweiterspeicher: int, + subbat: int): + storage_slave_ids = slave_ids[0: 1 + zweiterspeicher] + storage_powers = [] + if batwrsame == 1: + soc = mean( + client.read_holding_registers(62852, ModbusDataType.FLOAT_32, unit=slave_id) for slave_id in + storage_slave_ids + ) + storage_powers = [ + client.read_holding_registers(62836, ModbusDataType.FLOAT_32, unit=slave_id) for slave_id in + storage_slave_ids + ] + get_bat_value_store(1).set(BatState(power=sum(storage_powers), soc=soc)) -try: - resp= client.read_holding_registers(40083,2,unit=slave1id) - # read watt - watt=format(resp.registers[0], '04x') - wr1watt=int(struct.unpack('>h', watt.decode('hex'))[0]) * -1 - # read multiplier - multiplier=format(resp.registers[1], '04x') - fmultiplier=int(struct.unpack('>h', multiplier.decode('hex'))[0]) - if fmultiplier == 2: - fwr1watt = wr1watt * 100 - if fmultiplier == 1: - fwr1watt = wr1watt * 10 - if fmultiplier == 0: - fwr1watt = wr1watt - if fmultiplier == -1: - fwr1watt = wr1watt / 10 - if fmultiplier == -2: - fwr1watt = wr1watt / 100 - if fmultiplier == -3: - fwr1watt = wr1watt / 1000 - if fmultiplier == -4: - fwr1watt = wr1watt / 10000 - if fmultiplier == -5: - fwr1watt = wr1watt / 10000 - resp= client.read_holding_registers(40093,2,unit=slave1id) - value1 = resp.registers[0] - value2 = resp.registers[1] - all = format(value1, '04x') + format(value2, '04x') - final = int(struct.unpack('>i', all.decode('hex'))[0]) -except: - fwr1watt=0 -if slave2id != 0: - try: - resp= client.read_holding_registers(40083,2,unit=slave2id) - # read watt - watt=format(resp.registers[0], '04x') - wr2watt=int(struct.unpack('>h', watt.decode('hex'))[0]) * -1 - # read multiplier - multiplier=format(resp.registers[1], '04x') - fmultiplier=int(struct.unpack('>h', multiplier.decode('hex'))[0]) - if fmultiplier == 2: - fwr2watt = wr2watt * 100 - if fmultiplier == 1: - fwr2watt = wr2watt * 10 - if fmultiplier == 0: - fwr2watt = wr2watt - if fmultiplier == -1: - fwr2watt = wr2watt / 10 - if fmultiplier == -2: - fwr2watt = wr2watt / 100 - if fmultiplier == -3: - fwr2watt = wr2watt / 1000 - if fmultiplier == -4: - fwr2watt = wr2watt / 10000 - if fmultiplier == -5: - fwr2watt = wr2watt / 10000 - resp= client.read_holding_registers(40093,2,unit=slave2id) - value1 = resp.registers[0] - value2 = resp.registers[1] - all = format(value1, '04x') + format(value2, '04x') - final = final + int(struct.unpack('>i', all.decode('hex'))[0]) - except: - fwr2watt=0 -else: - fwr2watt=0 -if slave3id != 0: - try: - resp= client.read_holding_registers(40083,2,unit=slave3id) - # read watt - watt=format(resp.registers[0], '04x') - wr3watt=int(struct.unpack('>h', watt.decode('hex'))[0]) * -1 - # read multiplier - multiplier=format(resp.registers[1], '04x') - fmultiplier=int(struct.unpack('>h', multiplier.decode('hex'))[0]) - if fmultiplier == 2: - fwr3watt = wr3watt * 100 - if fmultiplier == 1: - fwr3watt = wr3watt * 10 - if fmultiplier == 0: - fwr3watt = wr3watt - if fmultiplier == -1: - fwr3watt = wr3watt / 10 - if fmultiplier == -2: - fwr3watt = wr3watt / 100 - if fmultiplier == -3: - fwr3watt = wr3watt / 1000 - if fmultiplier == -4: - fwr3watt = wr3watt / 10000 - if fmultiplier == -5: - fwr3watt = wr3watt / 10000 - resp= client.read_holding_registers(40093,2,unit=slave3id) - value1 = resp.registers[0] - value2 = resp.registers[1] - all = format(value1, '04x') + format(value2, '04x') - final = final + int(struct.unpack('>i', all.decode('hex'))[0]) - except: - fwr3watt=0 -else: - fwr3watt=0 -if slave4id != 0: - try: - resp= client.read_holding_registers(40083,2,unit=slave4id) - # read watt - watt=format(resp.registers[0], '04x') - wr4watt=int(struct.unpack('>h', watt.decode('hex'))[0]) * -1 - # read multiplier - multiplier=format(resp.registers[1], '04x') - fmultiplier=int(struct.unpack('>h', multiplier.decode('hex'))[0]) - if fmultiplier == 2: - fwr4watt = wr4watt * 100 - if fmultiplier == 1: - fwr4watt = wr4watt * 10 - if fmultiplier == 0: - fwr4watt = wr4watt - if fmultiplier == -1: - fwr4watt = wr4watt / 10 - if fmultiplier == -2: - fwr4watt = wr4watt / 100 - if fmultiplier == -3: - fwr4watt = wr4watt / 1000 - if fmultiplier == -4: - fwr4watt = wr4watt / 10000 - if fmultiplier == -5: - fwr4watt = wr4watt / 10000 - resp= client.read_holding_registers(40093,2,unit=slave4id) - value1 = resp.registers[0] - value2 = resp.registers[1] - all = format(value1, '04x') + format(value2, '04x') - final = final + int(struct.unpack('>i', all.decode('hex'))[0]) - except: - fwr4watt=0 -else: - fwr4watt=0 + total_energy = 0 + total_power = 0 + total_currents = [0, 0, 0] -if extprodakt == 1: - try: - resp= client.read_holding_registers(40380,1,unit=slave1id) - value1 = resp.registers[0] - all = format(value1, '04x') - extprod = int(struct.unpack('>h', all.decode('hex'))[0]) * -1 - except: - extprod = 0 -else: - extprod = 0 -if subbat == 1: - if storagepower > 0: - storagepower=0 - if storage2power > 0: - storage2power=0 - allwatt=fwr1watt+fwr2watt+fwr3watt+fwr4watt-storagepower-storage2power+extprod -else: - allwatt=fwr1watt+fwr2watt+fwr3watt+fwr4watt-storagepower-storage2power+extprod -if allwatt > 0: - allwatt=0 -f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w') -f.write(str(allwatt)) -f.close() -f = open('/var/www/html/openWB/ramdisk/pvkwh', 'w') -f.write(str(final)) -f.close() -pvkwhk= final / 1000 -f = open('/var/www/html/openWB/ramdisk/pvkwhk', 'w') -f.write(str(pvkwhk)) -f.close() + for slave_id in slave_ids: + # 40083 = AC Power value (Watt), 40084 = AC Power scale factor + power_base, power_scale = client.read_holding_registers(40083, [ModbusDataType.INT_16] * 2, unit=slave_id) + total_power -= power_base * math.pow(10, power_scale) + # 40093 = AC Lifetime Energy production (Watt hours) + total_energy += client.read_holding_registers(40093, ModbusDataType.INT_32, unit=slave_id) + # 40072/40073/40074 = AC Phase A/B/C Current value (Amps) + # 40075 = AC Current scale factor + currents = client.read_holding_registers( + 40072, [ModbusDataType.UINT_16] * 3 + [ModbusDataType.INT_16], unit=slave_id + ) + currents_scale = math.pow(10, currents[3]) + for i in range(3): + total_currents[i] += currents[i] * currents_scale + if extprodakt == 1: + # 40380 = "Meter 2/Total Real Power (sum of active phases)" (Watt) + total_power -= client.read_holding_registers(40380, ModbusDataType.INT_16, unit=slave_ids[0]) + if subbat == 1: + total_power -= sum(min(p, 0) for p in storage_powers) + else: + total_power -= sum(storage_powers) + + get_inverter_value_store(1).set(InverterState( + counter=total_energy, power=total_power, currents=total_currents + )) + + +def update_solar_edge_cli(ipaddress: str, + slave_id0: str, + slave_id1: str, + slave_id2: str, + slave_id3: str, + batwrsame: int, + extprodakt: int, + zweiterspeicher: int, + subbat: int): + with ModbusClient(ipaddress) as client: + update_solar_edge( + client, + list(map(int, filter(lambda id: id.isnumeric(), [slave_id0, slave_id1, slave_id2, slave_id3]))), + batwrsame, + extprodakt, + zweiterspeicher, + subbat + ) + + +if __name__ == '__main__': + run_using_positional_cli_args(update_solar_edge_cli) diff --git a/modules/wr_solarlog/main.sh b/modules/wr_solarlog/main.sh index 9cf19b28a..bb81c336e 100755 --- a/modules/wr_solarlog/main.sh +++ b/modules/wr_solarlog/main.sh @@ -4,32 +4,9 @@ DMOD="PV" Debug=$debug -re='^-?[0-9]+$' - - -answer=$(curl -d {\"801\":{\"170\":null}} --connect-timeout 5 -s $bezug_solarlog_ip/getjp) - -openwbDebugLog ${DMOD} 2 "answer: $answer" -pvwatt=$(echo $answer | jq '."801"."170"."101"' ) -openwbDebugLog ${DMOD} 2 "pvwatt: $pvwatt" -pvkwh=$(echo $answer | jq '."801"."170"."109"' ) -openwbDebugLog ${DMOD} 2 "pvkwh: $pvkwh" - -if ! [[ $pvwatt =~ $re ]] ; then - pvwatt="0" - openwbDebugLog ${DMOD} 0 "pvwatt: NaN set 0" -fi - -if (( $pvwatt > 5 )); then - pvwatt=$(echo "$pvwatt*-1" |bc) -fi -if ! [[ $pvkwh =~ $re ]] ; then - openwbDebugLog ${DMOD} 2 "PVkWh: NaN get prev. Value" - pvkwh=$( /var/www/html/openWB/ramdisk/pvwatt -echo $pvkwh > /var/www/html/openWB/ramdisk/pvkwh diff --git a/modules/wr_solarlog/solarlog.py b/modules/wr_solarlog/solarlog.py new file mode 100755 index 000000000..1b8f734ce --- /dev/null +++ b/modules/wr_solarlog/solarlog.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 + +from datetime import datetime, timezone +import os +import json +import requests +import sys +import traceback + +Debug = int(os.environ.get('debug')) +myPid = str(os.getpid()) + +bezug_solarlog_ip = str(sys.argv[1]) + +def DebugLog(message): + local_time = datetime.now(timezone.utc).astimezone() + print(local_time.strftime(format = "%Y-%m-%d %H:%M:%S") + ": PID: "+ myPid +": " + message) + + +if Debug >= 2: + DebugLog('Wechselrichter Solarlog IP: ' + bezug_solarlog_ip) + +data = {"801": {"170": None}} +data = json.dumps(data) +response = requests.post("http://"+bezug_solarlog_ip+'/getjp', data=data, timeout=5).json() +try: + pvwatt = response["801"]["170"]["101"] +except: + traceback.print_exc() + exit(1) +try: + pvkwh = response["801"]["170"]["109"] +except: + traceback.print_exc() + exit(1) + +if pvwatt > 5: + pvwatt = pvwatt*-1 + +if Debug >= 1: + DebugLog('WR Leistung: ' + str(pvwatt)) +with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(pvwatt)) +if Debug >= 1: + DebugLog('WR Energie: ' + str(pvkwh)) +with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(pvkwh)) + +exit(0) \ No newline at end of file diff --git a/modules/wr_solarview/main.sh b/modules/wr_solarview/main.sh old mode 100755 new mode 100644 index b1e137103..1221a15e8 --- a/modules/wr_solarview/main.sh +++ b/modules/wr_solarview/main.sh @@ -1,144 +1,30 @@ -#!/bin/sh - -# -# OpenWB-Modul für die Anbindung von SolarView über den integrierten TCP-Server -# Details zur API: https://solarview.info/solarview-fb_Installieren.pdf -# - -openwb_home=/var/www/html/openWB -target="$openwb_home/ramdisk" - - -# Checks -if [ -z "$solarview_hostname" ]; then - log "Missing required variable 'solarview_hostname'" - return 1 -fi -if [ "${solarview_port}" ]; then - if [ "$solarview_port" -lt 1 ] || [ "$solarview_port" -gt 65535 ]; then - log "Invalid value '$solarview_port' for variable 'solarview_port'" - return 1 - fi +#!/bin/bash + +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +#MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="PV" +DMOD="MAIN" +Debug=$debug + +#For Development only +#Debug=1 + +if [ $DMOD == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/wr_solarview.log" fi -log() { - echo "[wr_solarview] $*" >>"$target/openWB.log" -} - -request() { - command="$1" - port="${solarview_port:-15000}" - timeout="${solarview_timeout:-1}" - - response=$(echo "$command" | nc -w "$timeout" "$solarview_hostname" "$port") - return_code="$?" - if [ "$return_code" -ne 0 ]; then - log "Error: request to SolarView failed. Details: return-code: '$return_code', host: '$solarview_hostname', port: '$port', timeout: '$timeout'" - return "$return_code" - fi - - [ "$debug" -ne 0 ] && log "Raw response: $response" - # - # Format: {WR,Tag,Monat,Jahr,Stunde,Minute,KDY,KMT,KYR,KT0,PAC,UDC,IDC,UDCB,IDCB,UDCC,IDCC,UDCD,IDCD,UL1,IL1,UL2,IL2,UL3,IL3,TKK},Checksum - # Beispiel: {01,09,09,2019,08,18,0000.0,00082,002617,00018691,00104,451,000.2,000,000.0,000,000.0,000,000.0,226,000.4,000,000.0,000,000.0,00},▒ - # - # Bedeutung (siehe SolarView-Dokumentation): - # KDY= Tagesertrag (kWh) - # KMT= Monatsertrag (kWh) - # KYR= Jahresertrag (kWh) - # KT0= Gesamtertrag (kWh) - # PAC= Generatorleistung in W - # UDC, UDCB, UDCC, UDCD= Generator-Spannungen in Volt pro MPP-Tracker - # IDC, IDCB, IDCC, IDCD= Generator-Ströme in Ampere pro MPP-Tracker - # UL1, IL1= Netzspannung, Netzstrom Phase 1 - # UL2, IL2= Netzspannung, Netzstrom Phase 2 - # UL3, IL3= Netzspannung, Netzstrom Phase 3 - # TKK= Temperatur Wechselrichter - - # Geschweifte Klammern und Checksumme entfernen - values="${response#*\{}" - values="${values%\}*}" - - # Werte auslesen und verarbeiten - local LANG=C - echo "$values" | while IFS=',' read -r WR Tag Monat Jahr Stunde Minute KDY KMT KYR KT0 PAC UDC IDC UDCB IDCB UDCC IDCC UDCD IDCD UL1 IL1 UL2 IL2 UL3 IL3 TKK - do - # Werte formatiert in Variablen speichern - id="$WR" - timestamp="$Jahr-$Monat-$Tag $Stunde:$Minute" - power=$( awk "BEGIN{print -1 * $PAC}") - energy_day=$( awk "BEGIN{print 1000 * $KDY}") - energy_month=$(awk "BEGIN{print 1000 * $KMT}") - energy_year=$( awk "BEGIN{print 1000 * $KYR}") - energy_total=$(awk "BEGIN{print 1000 * $KT0}") - mpptracker1_voltage=$(printf "%.0f" "$UDC") - mpptracker1_current=$(printf "%.1f" "$IDC") - mpptracker2_voltage=$(printf "%.0f" "$UDCB") - mpptracker2_current=$(printf "%.1f" "$IDCB") - mpptracker3_voltage=$(printf "%.0f" "$UDCC") - mpptracker3_current=$(printf "%.1f" "$IDCC") - mpptracker4_voltage=$(printf "%.0f" "$UDCD") - mpptracker4_current=$(printf "%.1f" "$IDCD") - grid1_voltage=$( printf "%.0f" "$UL1") - grid1_current=$( printf "%.1f" "$IL1") - grid2_voltage=$( printf "%.0f" "$UL2") - grid2_current=$( printf "%.1f" "$IL2") - grid3_voltage=$( printf "%.0f" "$UL3") - grid3_current=$( printf "%.1f" "$IL3") - temperature=$( printf "%.0f" "$TKK") - - if [ "$debug" -ne 0 ]; then - # Werte ausgeben - log "ID: $id" - log "Zeitpunkt: $timestamp" - log "Temperatur: $temperature °C" - log "Leistung: $power W" - log "Energie:" - log " Tag: $energy_day Wh" - log " Monat: $energy_month Wh" - log " Jahr: $energy_year Wh" - log " Gesamt: $energy_total Wh" - log "Generator-MPP-Tracker-1" - log " Spannung: $mpptracker1_voltage V" - log " Strom: $mpptracker1_current A" - log "Generator-MPP-Tracker-2" - log " Spannung: $mpptracker2_voltage V" - log " Strom: $mpptracker2_current A" - log "Generator-MPP-Tracker-3" - log " Spannung: $mpptracker3_voltage V" - log " Strom: $mpptracker3_current A" - log "Generator-MPP-Tracker-4" - log " Spannung: $mpptracker4_voltage V" - log " Strom: $mpptracker4_current A" - log "Netz:" - log " Phase 1:" - log " Spannung: $grid1_voltage V" - log " Strom: $grid1_current A" - log " Phase 2:" - log " Spannung: $grid2_voltage V" - log " Strom: $grid2_current A" - log " Phase 3:" - log " Spannung: $grid3_voltage V" - log " Strom: $grid3_current A" - fi +openwbDebugLog ${DMOD} 2 "PV Hostname: ${solarview_hostname}" +openwbDebugLog ${DMOD} 2 "PV Port: ${solarview_port}" +openwbDebugLog ${DMOD} 2 "PV Timeout: ${solarview_timeout}" - # Werte speichern - echo "$power" >"$target/pvwatt" - echo "$energy_total" >"$target/pvkwh" - echo "$energy_day" >"$target/daily_pvkwh" - echo "$energy_month" >"$target/monthly_pvkwh" - echo "$energy_year" >"$target/yearly_pvkwh" - # Aktuelle Leistung an der Aufrufer zurückliefern - echo "$power" - done -} +python3 /var/www/html/openWB/modules/wr_solarview/solarview.py "${solarview_hostname}" "${solarview_port}" "${solarview_timeout}" >>$MYLOGFILE 2>&1 +ret=$? -# Sende-Kommando (siehe SolarView-Dokumentation); Beispiele: -# '00*': Gesamte Anlage -# '01*': Wechselrichter 1 -# '02*': Wechselrichter 2 -command="${1:-00*}" +openwbDebugLog ${DMOD} 2 "RET: ${ret}" -power=$(request "$command") -echo "$power" +pvwatt=$(= 2: + DebugLog('Solarview Hostname: ' + solarview_hostname) + DebugLog('Solarview Port: ' + solarview_port) + DebugLog('Solarview Timeout: ' + solarview_timeout) + +# Checks +if solarview_hostname == None or solarview_hostname == "": + DebugLog("Missing required variable 'solarview_hostname'") + exit(1) +if solarview_port: + if solarview_port < 1 or solarview_port > 65535: + DebugLog("Invalid value "+str(solarview_port)+" for variable 'solarview_port'") + exit(1) + +# Sende-Kommando (siehe SolarView-Dokumentation); Beispiele: +# '00*': Gesamte Anlage +# '01*': Wechselrichter 1 +# '02*': Wechselrichter 2 +command="1:-00*" + +request(command) + +exit(0) \ No newline at end of file diff --git a/modules/wr_solarwatt/main.sh b/modules/wr_solarwatt/main.sh index a023baf97..7a5809f0f 100644 --- a/modules/wr_solarwatt/main.sh +++ b/modules/wr_solarwatt/main.sh @@ -1,23 +1,27 @@ #!/bin/bash OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) -RAMDISKDIR="$OPENWBBASEDIR/ramdisk" -MODULE="PV" -LOGFILE="$RAMDISKDIR/openWB.log" +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +#MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="PV" +DMOD="MAIN" Debug=$debug -DebugLog(){ - if (( Debug > 0 )); then - timestamp=`date +"%Y-%m-%d %H:%M:%S"` - echo "$timestamp: ${MODULE}: $@" >> $LOGFILE - fi -} +#For Development only +#Debug=1 -sresponse=$(curl --connect-timeout 3 -s "http://${speicher1_ip}/rest/kiwigrid/wizard/devices") +if [ $DMOD == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/wr_solarwatt.log" +fi -pvwatt=$(echo $sresponse | jq '.result.items | .[] | select(.tagValues.PowerProduced.value != null) | .tagValues.PowerProduced.value' | sed 's/\..*$//') -DebugLog "PV-Leistung: ${pvwatt} W" -pvwatt=$((pvwatt * -1)) +openwbDebugLog ${DMOD} 2 "PV IP: ${speicher1_ip}" -echo $pvwatt > /var/www/html/openWB/ramdisk/pvwatt +python3 /var/www/html/openWB/modules/wr_solarwatt/solarwatt.py "${speicher1_ip}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$(= 2: + DebugLog('PV Solarwatt IP:' + speicher1_ip) + + +sresponse = requests.get('http://'+speicher1_ip+'/rest/kiwigrid/wizard/devices', timeout=3).json() + +try: + for item in sresponse["result"]["items"]: + if "tagValues" in sresponse["result"]["items"][item]: + if "PowerProduced" in sresponse["result"]["items"][item]["tagValues"]: + if "value" in sresponse["result"]["items"][item]["tagValues"]["PowerProduced"]: + pvwatt = int(sresponse["result"]["items"][item]["tagValues"]["PowerProduced"]["value"]) + break +except: + traceback.print_exc() + exit(1) +pvwatt = pvwatt * -1 +if Debug >= 1: + DebugLog("PV-Leistung: "+str(pvwatt)+" W") +with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(pvwatt)) + +exit(0) diff --git a/modules/wr_solarworld/main.sh b/modules/wr_solarworld/main.sh index 37db35ce9..e52f989aa 100644 --- a/modules/wr_solarworld/main.sh +++ b/modules/wr_solarworld/main.sh @@ -1,18 +1,27 @@ #!/bin/bash -# Auslesen eines Solarworld eManagers über die integrierte JSON-API -emanagerantwort=$(curl --connect-timeout 5 -s "$solarworld_emanagerip/rest/solarworld/lpvm/powerAndBatteryData") +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +#MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="PV" +DMOD="MAIN" +Debug=$debug -wr_watt=$(LC_ALL=C printf "%.0f\n" $(echo $emanagerantwort | jq '.PowerTotalPV')) +#For Development only +#Debug=1 -# wenn eManager aus bzw. keine Antwort ersetze leeren Wert durch eine 0 -ra='^-?[0-9]+$' - -if ! [[ $wr_watt =~ $ra ]] ; then - wr_watt="0" +if [ $DMOD == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/wr_solarworld.log" fi -# PV ezeugte Leistung muss negativ sein -pvwatt=$(echo "0 - $wr_watt" | bc) +openwbDebugLog ${DMOD} 2 "PV IP: ${solarworld_emanagerip}" + +python3 /var/www/html/openWB/modules/wr_solarworld/solarworld.py "${solarworld_emanagerip}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$( /var/www/html/openWB/ramdisk/pvwatt diff --git a/modules/wr_solarworld/solarworld.py b/modules/wr_solarworld/solarworld.py new file mode 100644 index 000000000..0ad54c2e0 --- /dev/null +++ b/modules/wr_solarworld/solarworld.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +from datetime import datetime, timezone +import os +import re +import requests +import sys +import traceback + +Debug = int(os.environ.get('debug')) +myPid = str(os.getpid()) + +solarworld_emanagerip = str(sys.argv[1]) + + +def DebugLog(message): + local_time = datetime.now(timezone.utc).astimezone() + print(local_time.strftime(format="%Y-%m-%d %H:%M:%S") + ": PID: " + myPid + ": " + message) + + +if Debug >= 2: + DebugLog('PV Solarworld IP:' + solarworld_emanagerip) + +# Auslesen eines Solarworld eManagers über die integrierte JSON-API +emanagerantwort = requests.get("http://"+solarworld_emanagerip+"/rest/solarworld/lpvm/powerAndBatteryData", timeout=5).json() + +try: + wr_watt = int(emanagerantwort["PowerTotalPV"]) +except: + traceback.print_exc() + exit(1) + +# wenn eManager aus bzw. keine Antwort ersetze leeren Wert durch eine 0 +ra = '^-?[0-9]+$' + +if re.search(ra, wr_watt) == None: + wr_watt = 0 + +# PV ezeugte Leistung muss negativ sein +pvwatt = 0 - wr_watt +if Debug >= 1: + DebugLog("PV-Leistung: "+str(pvwatt)+" W") +with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(pvwatt)) + +exit(0) diff --git a/modules/wr_solax/main.sh b/modules/wr_solax/main.sh old mode 100644 new mode 100755 index 7f32c71fc..2f48d50df --- a/modules/wr_solax/main.sh +++ b/modules/wr_solax/main.sh @@ -1,6 +1,24 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +DMOD="PV" +#DMOD="MAIN" +Debug=$debug -python /var/www/html/openWB/modules/wr_solax/solax.py $solaxip +#For development only +#Debug=1 -pvwatt=$(>${MYLOGFILE} 2>&1 + +pvwatt=$(<${RAMDISKDIR}/pvwatt) echo $pvwatt diff --git a/modules/wr_solax/solax.py b/modules/wr_solax/solax.py deleted file mode 100644 index b5bb43d30..000000000 --- a/modules/wr_solax/solax.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient -from pymodbus.factory import ClientDecoder - -ipaddress = str(sys.argv[1]) - -def unsigned32(result, addr): - low = result.registers[addr] - high = result.registers[addr + 1] - val = low +( high << 16) - return val - -def unsigned16 (result, addr): - return result.registers[addr] - -def signed16(result, addr): - val = addr - if val > 32767: - val -= 65535 - return val - -client = ModbusTcpClient(ipaddress, port=502) - -resp=client.read_input_registers(10, 2) -pv1 = unsigned16(resp, 0) -pv2 = unsigned16(resp, 1) -f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w') -f.write(str( (pv1 + pv2) * -1 ) ) # Erzeugung negativ -f.close() - -resp=client.read_input_registers(80, 4) -pvtoday = unsigned32(resp,0) / 10 # yield today -f = open('/var/www/html/openWB/ramdisk/daily_pvkwh', 'w') -f.write(str(pvtoday)) -f.close() -pvall = unsigned32(resp,2) # yield overall -f = open('/var/www/html/openWB/ramdisk/pvkwh', 'w') -f.write(str(pvall)) -f.close() -f = open('/var/www/html/openWB/ramdisk/pvkwhk', 'w') -f.write(str(pvall / 1000)) -f.close() - -client.close() diff --git a/modules/wr_studer/main.sh b/modules/wr_studer/main.sh index 813c2d2d1..e48c7c3e5 100644 --- a/modules/wr_studer/main.sh +++ b/modules/wr_studer/main.sh @@ -1,7 +1,22 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +DMOD="PV" +#DMOD="MAIN" +Debug=$debug -python /var/www/html/openWB/modules/wr_studer/studer_wr.py $studer_ip $studer_xt $studer_vc $studer_vc_type +#For development only +#Debug=1 -# Rückgabe des Wertes Gesamt-PV-Leistung -pvwatt=$(>${MYLOGFILE} 2>&1 + +pvwatt=$(<${RAMDISKDIR}/pvwatt) +echo $pvwatt \ No newline at end of file diff --git a/modules/wr_studer/studer_wr.py b/modules/wr_studer/studer_wr.py deleted file mode 100644 index 5f7e8bb35..000000000 --- a/modules/wr_studer/studer_wr.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -# import struct -# import binascii -from pymodbus.constants import Endian -from pymodbus.payload import BinaryPayloadDecoder -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) # IP-Address Modbus Gateway -xtcount = int(sys.argv[2]) # studer_xt (count XT* Devices) -vccount = int(sys.argv[3]) # studer_vc (count MPPT Devices) -studervctype = str(sys.argv[4]) # studer_vc_type (MPPT type VS or VT) - -client = ModbusTcpClient(ipaddress, port=502) - -connection = client.connect() - -def func_pvwatt(): - # loop for pvwatt - if studervctype == 'VS': - mb_unit = int(40) - mb_register = int(20) # MB:20; ID: 15010; PV power kW - elif studervctype == 'VT': - mb_unit = int(20) - mb_register = int(8) # MB:8; ID: 11004; Power of the PV generator kW - pvwatt = 0 - i = 1 - while i < vccount+1: - mb_unit_dev = mb_unit+i - request = client.read_input_registers(mb_register, 2, unit=mb_unit_dev) - if request.isError(): - # handle error, log? - print('Modbus Error:', request) - else: - result = request.registers - decoder = BinaryPayloadDecoder.fromRegisters(result, byteorder=Endian.Big) - pvwatt = pvwatt+decoder.decode_32bit_float() # type: float - i += 1 - - pvwatt = int(round(pvwatt*1000*-1, 0)) # openWB need the values as negative Values in W - # print(pvwatt) - f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w') - f.write(str(pvwatt)) - f.close() - - -def func_pvkwh(): - # loop for pvkwh - if studervctype == 'VS': - mb_unit = int(40) - mb_register = int(46) # MB:46; ID: 15023; Desc: Total PV produced energy MWh - elif studervctype == 'VT': - mb_unit = int(20) - mb_register = int(18) # MB:18; ID: 11009; Desc: Total produced energy MWh - pvkwh = 0 - i = 1 - while i < vccount + 1: - mb_unit_dev = mb_unit + i - request = client.read_input_registers(mb_register, 2, unit=mb_unit_dev) - if request.isError(): - # handle error, log? - print('Modbus Error:', request) - else: - result = request.registers - decoder = BinaryPayloadDecoder.fromRegisters(result, byteorder=Endian.Big) - pvkwh = pvkwh + decoder.decode_32bit_float() # type: float - i += 1 - # print(pvkwh) - f = open('/var/www/html/openWB/ramdisk/pvkwh', 'w') - f.write(str(pvkwh*1000000)) - f.close() - -func_pvwatt() -func_pvkwh() - -client.close() diff --git a/modules/wr_sungrow/main.sh b/modules/wr_sungrow/main.sh index e297458bf..108cc16f6 100644 --- a/modules/wr_sungrow/main.sh +++ b/modules/wr_sungrow/main.sh @@ -1,4 +1,22 @@ #!/bin/bash -python /var/www/html/openWB/modules/wr_sungrow/sungrow.py $speicher1_ip -pvwatt=$(>${MYLOGFILE} 2>&1 + +pvwatt=$(<${RAMDISKDIR}/pvwatt) +echo $pvwatt \ No newline at end of file diff --git a/modules/wr_sungrow/sungrow.py b/modules/wr_sungrow/sungrow.py deleted file mode 100644 index c071b8005..000000000 --- a/modules/wr_sungrow/sungrow.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) - -client = ModbusTcpClient(ipaddress, port=502) - -resp= client.read_input_registers(5016,2,unit=1) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value2, '04x') + format(value1, '04x') -final = int(struct.unpack('>i', all.decode('hex'))[0]*-1) -f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w') -f.write(str(final)) -f.close() diff --git a/modules/wr_sunwaves/main.sh b/modules/wr_sunwaves/main.sh index eb9a7486e..676df040f 100755 --- a/modules/wr_sunwaves/main.sh +++ b/modules/wr_sunwaves/main.sh @@ -1,20 +1,29 @@ #!/bin/bash -variable=$(curl --silent --digest -u customer:$wrsunwavespw http://$wrsunwavesip/data/ajax.txt?CAN=1) -count=0 -IFS=";" - -for v in $variable -do - if (( count == 1 ));then - pvwatt=$(echo ${v//[!0-9]/}) - pvwatt=$(echo "$pvwatt*-1" |bc) - echo $pvwatt > /var/www/html/openWB/ramdisk/pvwatt - echo $pvwatt - fi - if (( count == 16 ));then - echo $(echo "$v*1000" | bc) > /var/www/html/openWB/ramdisk/pvkwh - fi - - count=$((count+1)) -done +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +#MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="PV" +DMOD="MAIN" +Debug=$debug + +#For Development only +#Debug=1 + +if [ $DMOD == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/wr_sunwaves.log" +fi + +openwbDebugLog ${DMOD} 2 "PV IP: ${wrsunwavesip}" +openwbDebugLog ${DMOD} 2 "PV Passwort: ${wrsunwavespw}" + + +python3 /var/www/html/openWB/modules/wr_sunwaves/sunwaves.py "${wrsunwavesip}" "${wrsunwavespw}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$(= 2: + DebugLog('PV Sunwaves IP:' + wrsunwavesip) + DebugLog('PV Sunwaves Passwort:' + wrsunwavespw) + + +params = (('CAN', '1'),) +variable = requests.get("http://"+wrsunwavesip+"/data/ajax.txt", params=params, auth=HTTPDigestAuth("customer", wrsunwavespw)) +variable.encoding = 'utf-8' +variable = variable.text.replace("\n", "") + +count = 0 + +for v in variable: + if count == 1: + pvwatt = re.search('^[0-9]+$', v).group() + pvwatt = pvwatt*-1 + if Debug >= 1: + DebugLog('WR Leistung: ' + str(pvwatt)) + with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(pvwatt)) + if count == 16: + if Debug >= 1: + DebugLog('WR Energie: ' + str(v*1000)) + with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(v*1000)) + count = count+1 + +exit(0) diff --git a/modules/wr_sunways/main.sh b/modules/wr_sunways/main.sh index 281677410..c56d196ac 100755 --- a/modules/wr_sunways/main.sh +++ b/modules/wr_sunways/main.sh @@ -1,20 +1,28 @@ #!/bin/bash -variable=$(curl --silent --digest -u customer:$wrsunwayspw "http://$wrsunwaysip/data/ajax.txt?CAN=1&HASH=00200403&TYPE=1") -count=0 -IFS=";" +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +#MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="PV" +DMOD="MAIN" +Debug=$debug -for v in $variable -do - if (( count == 1 ));then - pvwatt=$(echo ${v//[!0-9]/}) - pvwatt=$(echo "$pvwatt*-1" |bc) - echo $pvwatt > /var/www/html/openWB/ramdisk/pvwatt - echo $pvwatt - fi - if (( count == 16 ));then - echo $(echo "$v*1000" | bc) > /var/www/html/openWB/ramdisk/pvkwh - fi +#For Development only +#Debug=1 - count=$((count+1)) -done +if [ $DMOD == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" +else + MYLOGFILE="${RAMDISKDIR}/wr_sunways.log" +fi + +openwbDebugLog ${DMOD} 2 "PV IP: ${wrsunwaysip}" +openwbDebugLog ${DMOD} 2 "PV Passwort: ${wrsunwayspw}" + +python3 /var/www/html/openWB/modules/wr_sunways/sunways.py "${wrsunwaysip}" "${wrsunwayspw}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$(= 2: + DebugLog('PV Sunways IP:' + wrsunwaysip) + DebugLog('PV Sunways Passwort:' + wrsunwayspw) + +params = ( + ('CAN', '1'), + ('HASH', '00200403'), + ('TYPE', '1'), +) +variable = requests.get("http://"+wrsunwaysip+"/data/ajax.txt", params=params, auth=HTTPDigestAuth("customer", wrsunwayspw)) +variable.encoding = 'utf-8' +variable = variable.text.replace("\n", "") +count = 0 + +for v in variable: + if count == 1: + pvwatt = re.search('^[0-9]+$', v).group() + pvwatt = pvwatt*-1 + if Debug >= 1: + DebugLog('WR Leistung: ' + str(pvwatt)) + with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(pvwatt)) + if count == 16: + if Debug >= 1: + DebugLog('WR Energie: ' + str(v*1000)) + with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(v*1000)) + count = count+1 + +exit(0) diff --git a/modules/wr_tripower9000/main.sh b/modules/wr_tripower9000/main.sh index 9591ffc7c..ed8b08943 100755 --- a/modules/wr_tripower9000/main.sh +++ b/modules/wr_tripower9000/main.sh @@ -1,35 +1,6 @@ #!/bin/bash -if [[ $wrsmawebbox == "1" ]]; then - rekwh='^[-+]?[0-9]+\.?[0-9]*$' - boxout=$(curl --silent --connect-timeout 3 -H "Content-Type: application/json" -X POST -d RPC='{"version": "1.0","proc": "GetPlantOverview","id": "1","format": "JSON"}' http://$tri9000ip/rpc) - if [[ $? == "0" ]] ; then - pvwatt=$(echo $boxout | jq -r '.result.overview[0].value ' | sed 's/\..*$//') - pvwatt=$(( pvwatt * -1 )) - pvkwh=$(echo $boxout | jq -r '.result.overview[2].value ') - pvwh=$(echo "scale=0;$pvkwh * 1000" |bc) - if [[ $pvwh =~ $rekwh ]]; then - echo $pvwh > /var/www/html/openWB/ramdisk/pvkwh - fi - if [[ $pvkwh =~ $rekwh ]]; then - echo $pvwatt > /var/www/html/openWB/ramdisk/pvwatt - fi - fi -else - if [[ $wrsma2ip != "none" ]] && [[ $wrsma3ip != "none" ]] && [[ $wrsma4ip != "none" ]]; then - sudo python /var/www/html/openWB/modules/wr_tripower9000/tri90004.py $tri9000ip $wrsma2ip $wrsma3ip $wrsma4ip - else - if [[ $wrsma2ip != "none" ]] && [[ $wrsma3ip != "none" ]]; then - sudo python /var/www/html/openWB/modules/wr_tripower9000/tri90003.py $tri9000ip $wrsma2ip $wrsma3ip - else - if [[ $wrsma2ip != "none" ]]; then - sudo python /var/www/html/openWB/modules/wr_tripower9000/tri90002.py $tri9000ip $wrsma2ip - else - sudo python /var/www/html/openWB/modules/wr_tripower9000/tri9000.py $tri9000ip - fi - fi - fi -fi +python3 /var/www/html/openWB/modules/wr_tripower9000/tripower.py "${wrsmawebbox}" "${tri9000ip}" "${wrsma2ip}" "${wrsma3ip}" "${wrsma4ip}" pvwatt=$(i', all.decode('hex'))[0]) -if final < 0: - final = 0 -final = final * -1 -f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w') -f.write(str(final)) -f.close() - -# pv Wh -resp= client.read_holding_registers(30529,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -final = int(struct.unpack('>i', all.decode('hex'))[0]) -f = open('/var/www/html/openWB/ramdisk/pvkwh', 'w') -f.write(str(final)) -f.close() diff --git a/modules/wr_tripower9000/tri90002.py b/modules/wr_tripower9000/tri90002.py deleted file mode 100755 index 9423b9804..000000000 --- a/modules/wr_tripower9000/tri90002.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) -ip2address = str(sys.argv[2]) - -client = ModbusTcpClient(ipaddress, port=502) -client2 = ModbusTcpClient(ip2address, port=502) - -# pv watt -resp= client.read_holding_registers(30775,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr1w = int(struct.unpack('>i', all.decode('hex'))[0]) -# if final < 0: -# final = 0 -# final = final * -1 -# f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w') -# f.write(str(final)) -# f.close() - -# pv Wh -resp= client.read_holding_registers(30529,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr1wh = int(struct.unpack('>i', all.decode('hex'))[0]) -# f = open('/var/www/html/openWB/ramdisk/pvkwh', 'w') -# f.write(str(final)) -# f.close() - -# pv watt -resp= client2.read_holding_registers(30775,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr2w = int(struct.unpack('>i', all.decode('hex'))[0]) -final = wr1w + wr2w -if final < 0: - final = 0 -final = final * -1 -f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w') -f.write(str(final)) -f.close() - -# pv Wh -resp= client2.read_holding_registers(30529,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr2wh = int(struct.unpack('>i', all.decode('hex'))[0]) -final = wr1wh + wr2wh -f = open('/var/www/html/openWB/ramdisk/pvkwh', 'w') -f.write(str(final)) -f.close() diff --git a/modules/wr_tripower9000/tri90003.py b/modules/wr_tripower9000/tri90003.py deleted file mode 100755 index 3a50333ca..000000000 --- a/modules/wr_tripower9000/tri90003.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) -ip2address = str(sys.argv[2]) -ip3address = str(sys.argv[3]) - -client = ModbusTcpClient(ipaddress, port=502) -client2 = ModbusTcpClient(ip2address, port=502) -client3 = ModbusTcpClient(ip3address, port=502) - -# pv watt -resp= client.read_holding_registers(30775,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr1w = int(struct.unpack('>i', all.decode('hex'))[0]) - -# pv Wh -resp= client.read_holding_registers(30529,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr1wh = int(struct.unpack('>i', all.decode('hex'))[0]) - -# pv watt -resp= client3.read_holding_registers(30775,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr3w = int(struct.unpack('>i', all.decode('hex'))[0]) -# pv Wh -resp= client3.read_holding_registers(30529,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr3wh = int(struct.unpack('>i', all.decode('hex'))[0]) - -# pv watt -resp= client2.read_holding_registers(30775,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr2w = int(struct.unpack('>i', all.decode('hex'))[0]) -final = wr1w + wr2w + wr3w -if final < 0: - final = 0 -final = final * -1 -f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w') -f.write(str(final)) -f.close() - -# pv Wh -resp= client2.read_holding_registers(30529,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr2wh = int(struct.unpack('>i', all.decode('hex'))[0]) -final = wr1wh + wr2wh + wr3wh -f = open('/var/www/html/openWB/ramdisk/pvkwh', 'w') -f.write(str(final)) -f.close() diff --git a/modules/wr_tripower9000/tri90004.py b/modules/wr_tripower9000/tri90004.py deleted file mode 100755 index 1d09626fd..000000000 --- a/modules/wr_tripower9000/tri90004.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -import struct -# import binascii -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) -ip2address = str(sys.argv[2]) -ip3address = str(sys.argv[3]) -ip4address = str(sys.argv[4]) - -client = ModbusTcpClient(ipaddress, port=502) -client2 = ModbusTcpClient(ip2address, port=502) -client3 = ModbusTcpClient(ip3address, port=502) -client4 = ModbusTcpClient(ip4address, port=502) - -# pv watt -resp= client.read_holding_registers(30775,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr1w = int(struct.unpack('>i', all.decode('hex'))[0]) - -# pv Wh -resp= client.read_holding_registers(30529,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr1wh = int(struct.unpack('>i', all.decode('hex'))[0]) - -# pv watt -resp= client3.read_holding_registers(30775,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr3w = int(struct.unpack('>i', all.decode('hex'))[0]) - -# pv Wh -resp= client3.read_holding_registers(30529,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr3wh = int(struct.unpack('>i', all.decode('hex'))[0]) - -# pv watt -resp= client4.read_holding_registers(30775,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr4w = int(struct.unpack('>i', all.decode('hex'))[0]) - -# pv Wh -resp= client4.read_holding_registers(30529,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr4wh = int(struct.unpack('>i', all.decode('hex'))[0]) - -# pv watt -resp= client2.read_holding_registers(30775,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr2w = int(struct.unpack('>i', all.decode('hex'))[0]) -final = wr1w + wr2w + wr3w + wr4w -if final < 0: - final = 0 -final = final * -1 -f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w') -f.write(str(final)) -f.close() - -# pv Wh -resp= client2.read_holding_registers(30529,2,unit=3) -value1 = resp.registers[0] -value2 = resp.registers[1] -all = format(value1, '04x') + format(value2, '04x') -wr2wh = int(struct.unpack('>i', all.decode('hex'))[0]) -final = wr1wh + wr2wh + wr3wh + wr4wh -f = open('/var/www/html/openWB/ramdisk/pvkwh', 'w') -f.write(str(final)) -f.close() diff --git a/modules/wr_tripower9000/tripower.py b/modules/wr_tripower9000/tripower.py new file mode 100755 index 000000000..a894bcc22 --- /dev/null +++ b/modules/wr_tripower9000/tripower.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +from datetime import datetime, timezone +import os +import re +import requests +import sys +import struct +import traceback +from pymodbus.client.sync import ModbusTcpClient + +Debug = int(os.environ.get('debug')) +myPid = str(os.getpid()) + +wrsmawebbox = int(sys.argv[1]) +tri9000ip = str(sys.argv[2]) + + +def DebugLog(message): + local_time = datetime.now(timezone.utc).astimezone() + print(local_time.strftime(format="%Y-%m-%d %H:%M:%S") + ": PID: " + myPid + ": " + message) + + +if Debug >= 2: + DebugLog('Wechselrichter Tripower Webbox: ' + str(wrsmawebbox)) + DebugLog('Wechselrichter Tripower IP: ' + tri9000ip) + +if wrsmawebbox == 1: + headers = {'Content-Type': 'application/json', } + data = {'RPC': '{"version": "1.0","proc": "GetPlantOverview","id": "1","format": "JSON"}'} + response = requests.post('http://'+tri9000ip+'/rpc', headers=headers, data=data, timeout=3).json() + rekwh = '^[-+]?[0-9]+.?[0-9]*$' + try: + pvwatt = int(response["result"]["overview"][0]["value"]) + pvwatt = pvwatt * -1 + if re.search(rekwh, str(pvwatt)): + if Debug >= 1: + DebugLog('WR Leistung: ' + str(pvwatt)) + with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(pvwatt)) + except: + traceback.print_exc() + exit(1) + + try: + pvkwh = response["result"]["overview"][2]["value"] + pvwh = int(pvkwh) * 1000 + if re.search(rekwh, str(pvwh)) != None: + if Debug >= 1: + DebugLog('WR Energie: ' + str(pvkwh)) + with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(pvwh)) + except: + traceback.print_exc() + exit(1) +else: + + power = 0 + counter = 0 + + # Länge von sys.argv = Dateiname + Webbox + IP-Adressen + for i in range(len(sys.argv)-2): + try: + ipaddress = str(sys.argv[i+2]) + if Debug >= 2: + DebugLog('Wechselrichter Tripower IP'+str(i+2)+': ' + ipaddress) + client = ModbusTcpClient(ipaddress, port=502) + + # pv watt + resp = client.read_holding_registers(30775, 2, unit=3) + value1 = resp.registers[0] + value2 = resp.registers[1] + all = format(value1, '04x') + format(value2, '04x') + power = power + int(struct.unpack('>i', all.decode('hex'))[0]) + + # pv Wh + resp = client.read_holding_registers(30529, 2, unit=3) + value1 = resp.registers[0] + value2 = resp.registers[1] + all = format(value1, '04x') + format(value2, '04x') + counter = counter + int(struct.unpack('>i', all.decode('hex'))[0]) + except: + traceback.print_exc() + exit(1) + + if power < 0: + power = 0 + power = power * -1 + if Debug >= 1: + DebugLog('WR Leistung: ' + str(power)) + f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w') + f.write(str(power)) + f.close() + + if Debug >= 1: + DebugLog('WR Energie: ' + str(counter)) + f = open('/var/www/html/openWB/ramdisk/pvkwh', 'w') + f.write(str(counter)) + f.close() + + +exit(0) diff --git a/modules/wr_victron/main.sh b/modules/wr_victron/main.sh index 6542d260b..e7c1ac3db 100755 --- a/modules/wr_victron/main.sh +++ b/modules/wr_victron/main.sh @@ -1,6 +1,22 @@ #!/bin/bash +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +MODULEDIR=$(cd `dirname $0` && pwd) +DMOD="PV" +#DMOD="MAIN" +Debug=$debug -python /var/www/html/openWB/modules/wr_victron/victron.py $pv1_ipa -pvwatt=$(>${MYLOGFILE} 2>&1 + +pvwatt=$(<${RAMDISKDIR}/pvwatt) echo $pvwatt diff --git a/modules/wr_victron/victron.py b/modules/wr_victron/victron.py deleted file mode 100644 index a284a52d3..000000000 --- a/modules/wr_victron/victron.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/python -import sys -# import os -# import time -# import getopt -# import socket -# import ConfigParser -# import struct -# import binascii -from pymodbus.constants import Endian -from pymodbus.payload import BinaryPayloadDecoder -from pymodbus.client.sync import ModbusTcpClient - -ipaddress = str(sys.argv[1]) - -client = ModbusTcpClient(ipaddress, port=502) -connection = client.connect() -# ac input connected pv -resp= client.read_holding_registers(811,1,unit=100) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -mpp1_watt1 = str(decoder.decode_16bit_uint()) -mpp1_watt2 = int(mpp1_watt1) -resp= client.read_holding_registers(812,1,unit=100) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -mpp2_watt1 = str(decoder.decode_16bit_uint()) -mpp2_watt2 = int(mpp2_watt1) -resp= client.read_holding_registers(813,1,unit=100) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -mpp3_watt1 = str(decoder.decode_16bit_uint()) -mpp3_watt2 = int(mpp3_watt1) -# ac output connected pv -resp= client.read_holding_registers(808,1,unit=100) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -empp1_watt1 = str(decoder.decode_16bit_uint()) -empp1_watt2 = int(empp1_watt1) -resp= client.read_holding_registers(809,1,unit=100) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -empp2_watt1 = str(decoder.decode_16bit_uint()) -empp2_watt2 = int(empp2_watt1) -resp= client.read_holding_registers(810,1,unit=100) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -empp3_watt1 = str(decoder.decode_16bit_uint()) -empp3_watt2 = int(empp3_watt1) - -# mppt watt -resp= client.read_holding_registers(850,1,unit=100) -decoder = BinaryPayloadDecoder.fromRegisters(resp.registers,byteorder=Endian.Big,wordorder=Endian.Big) -mpp_watt1 = str(decoder.decode_16bit_uint()) -mpp_watt2 = int(mpp_watt1) - -final=(empp1_watt2 + empp2_watt2 + empp3_watt2 + mpp1_watt2 + mpp2_watt2 + mpp3_watt2 + mpp_watt2) * -1 -f = open('/var/www/html/openWB/ramdisk/pvwatt', 'w') -f.write(str(final)) -f.close() - -client.close() diff --git a/modules/wr_youless120/main.sh b/modules/wr_youless120/main.sh index 976220f31..cfaea86ab 100755 --- a/modules/wr_youless120/main.sh +++ b/modules/wr_youless120/main.sh @@ -1,25 +1,28 @@ #!/bin/bash -# Auslesen vom S0-Eingang eines Youless LS120 Energy Monitor. -answer=$(curl --connect-timeout 5 -s $wryoulessip/a?f=j) -if [[ $wryoulessalt == 0 ]]; then - # aktuelle Ausgangsleistung am WR [W] - pvwatt=$(echo $answer | jq -r '.ps0' | sed 's/\..*$//') - # Gesamtz‰hlerstand am WR [Wh] - pvkwh=$(echo $answer | jq -r '.cs0' | sed 's/,//g') +OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" +#MODULEDIR=$(cd `dirname $0` && pwd) +#DMOD="PV" +DMOD="MAIN" +Debug=$debug + +#For Development only +#Debug=1 + +if [ $DMOD == "MAIN" ]; then + MYLOGFILE="${RAMDISKDIR}/openWB.log" else - # aktuelle Ausgangsleistung am WR [W] - pvwatt=$(echo $answer | jq -r '.pwr' | sed 's/\..*$//') - # Gesamtz‰hlerstand am WR [Wh] - pvkwh=$(echo $answer | jq -r '.cnt' | sed 's/,//g') + MYLOGFILE="${RAMDISKDIR}/wr_youless120.log" fi -if (( $pvwatt > 5 )); then - pvwatt=$(echo "$pvwatt*-1" |bc) -fi +openwbDebugLog ${DMOD} 2 "PV IP: ${wryoulessip}" +openwbDebugLog ${DMOD} 2 "PV Alternative: ${wryoulessalt}" + +python3 /var/www/html/openWB/modules/wr_youless120/youless.py "${wryoulessip}" "${wryoulessalt}" >>$MYLOGFILE 2>&1 +ret=$? + +openwbDebugLog ${DMOD} 2 "RET: ${ret}" + +pvwatt=$( /var/www/html/openWB/ramdisk/pvwatt -echo $pvkwh > /var/www/html/openWB/ramdisk/pvkwh -# Gesamtzählerstand am WR [kWh] -pvkwh=$(echo "$pvkwh/1000" |bc) -echo $pvkwh > /var/www/html/openWB/ramdisk/pvkwhk diff --git a/modules/wr_youless120/youless.py b/modules/wr_youless120/youless.py new file mode 100755 index 000000000..f8bfb093b --- /dev/null +++ b/modules/wr_youless120/youless.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +from datetime import datetime, timezone +import os +import requests +import sys +import traceback + +Debug = int(os.environ.get('debug')) +myPid = str(os.getpid()) + +wryoulessip = str(sys.argv[1]) +wryoulessalt = str(sys.argv[2]) + + +def DebugLog(message): + local_time = datetime.now(timezone.utc).astimezone() + print(local_time.strftime(format="%Y-%m-%d %H:%M:%S") + ": PID: " + myPid + ": " + message) + + +if Debug >= 2: + DebugLog('PV Youless IP:' + wryoulessip) + DebugLog('PV Youless Alternative:' + wryoulessalt) + +# Auslesen vom S0-Eingang eines Youless LS120 Energy Monitor. +params = (('f', 'j'),) +answer = requests.get("http://"+wryoulessip+'/a', params=params, timeout=5).json() +if wryoulessalt == 0: + try: + # aktuelle Ausgangsleistung am WR [W] + pvwatt = int(answer["ps0"]) + # Gesamtz‰hlerstand am WR [Wh] + pvkwh = answer["cs0"] + pvkwh = pvkwh.replace(",", "") + except: + traceback.print_exc() + exit(1) +else: + try: + # aktuelle Ausgangsleistung am WR [W] + pvwatt = int(answer["pwr"]) + # Gesamtz‰hlerstand am WR [Wh] + pvkwh = answer["cnt"] + pvkwh = pvkwh.replace(",", "") + except: + traceback.print_exc() + exit(1) + +if pvwatt > 5: + pvwatt = pvwatt*-1 +if Debug >= 1: + DebugLog('WR Leistung: ' + str(pvwatt)) +with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: + f.write(str(pvwatt)) +if Debug >= 1: + DebugLog('WR Energie: ' + str(pvkwh)) +with open("/var/www/html/openWB/ramdisk/pvkwh", "w") as f: + f.write(str(pvkwh)) +# Gesamtzählerstand am WR [kWh] +pvkwh = pvkwh/1000 +with open("/var/www/html/openWB/ramdisk/pvkwhk", "w") as f: + f.write(str(pvkwh)) + +exit(0) diff --git a/packages/helpermodules/cli/__init__.py b/packages/helpermodules/cli/__init__.py new file mode 100644 index 000000000..7ba2036a7 --- /dev/null +++ b/packages/helpermodules/cli/__init__.py @@ -0,0 +1 @@ +from helpermodules.cli._run_using_positional_cli_args import run_using_positional_cli_args diff --git a/packages/helpermodules/cli/_run_using_positional_cli_args.py b/packages/helpermodules/cli/_run_using_positional_cli_args.py new file mode 100644 index 000000000..309662b64 --- /dev/null +++ b/packages/helpermodules/cli/_run_using_positional_cli_args.py @@ -0,0 +1,19 @@ +import argparse +import inspect +from typing import Callable, Union + +NoneType = type(None) + + +def run_using_positional_cli_args(function: Callable): + arg_spec = inspect.getfullargspec(function) + parser = argparse.ArgumentParser() + for argument_name in arg_spec.args: + type = arg_spec.annotations[argument_name] + if hasattr(type, "__origin__") and type.__origin__ is Union: + type_arg, = filter(lambda candidate: candidate is not NoneType, type.__args__) + parser.add_argument(argument_name, nargs='?', type=type_arg) + else: + parser.add_argument(argument_name, type=type) + args = parser.parse_args() + function(*[getattr(args, argument_name) for argument_name in arg_spec.args]) diff --git a/packages/helpermodules/cli/_run_using_positional_cli_args_test.py b/packages/helpermodules/cli/_run_using_positional_cli_args_test.py new file mode 100644 index 000000000..40b30ae01 --- /dev/null +++ b/packages/helpermodules/cli/_run_using_positional_cli_args_test.py @@ -0,0 +1,63 @@ +import sys +from typing import Optional +from unittest.mock import Mock + +import pytest + +from helpermodules.cli import run_using_positional_cli_args + + +def create_int_arg_function(mock: Mock): + def int_arg(arg: int): + mock(arg) + return int_arg + + +def create_float_arg_function(mock: Mock): + def float_arg(arg: float): + mock(arg) + return float_arg + + +def create_str_arg_function(mock: Mock): + def str_arg(arg: str): + mock(arg) + return str_arg + + +def create_optional_arg_function(mock: Mock): + def optional_arg(arg: Optional[int]): + mock(arg) + return optional_arg + + +def create_multi_arg_function(mock: Mock): + def multi_arg(arg_str: str, arg_int: int, optional_str: Optional[str], optional_int: Optional[int]): + mock((arg_str, arg_int, optional_str, optional_int)) + return multi_arg + + +@pytest.mark.parametrize( + "function_factory,argv,arg_parsed", [ + (create_int_arg_function, ["42"], 42), + (create_float_arg_function, ["12.34"], 12.34), + (create_str_arg_function, ["some string"], "some string"), + (create_optional_arg_function, [], None), + (create_optional_arg_function, ["21"], 21), + (create_multi_arg_function, ["some string", "42"], ("some string", 42, None, None)), + (create_multi_arg_function, ["some string", "42", "other str"], ("some string", 42, "other str", None)), + (create_multi_arg_function, ["some string", "42", "other str", "21"], ("some string", 42, "other str", 21)), + ] +) +def test_run_using_cli_args_int_arg(monkeypatch, function_factory, argv, arg_parsed): + # setup + argv.insert(0, "dummy") + monkeypatch.setattr(sys, "argv", argv) + mock = Mock() + function = function_factory(mock) + + # execution + run_using_positional_cli_args(function) + + # evaluation + mock.assert_called_once_with(arg_parsed) diff --git a/packages/modules/common/component_state.py b/packages/modules/common/component_state.py index 73dc9b3aa..9019d9bc8 100644 --- a/packages/modules/common/component_state.py +++ b/packages/modules/common/component_state.py @@ -2,7 +2,7 @@ class BatState: - def __init__(self, imported: float, exported: float, power: float, soc: int = 0): + def __init__(self, imported: float = 0, exported: float = 0, power: float = 0, soc: float = 0): self.imported = imported self.exported = exported self.power = power diff --git a/packages/modules/common/store/__init__.py b/packages/modules/common/store/__init__.py index 5533c7eb8..679df0297 100644 --- a/packages/modules/common/store/__init__.py +++ b/packages/modules/common/store/__init__.py @@ -3,3 +3,5 @@ from modules.common.store._car import get_car_value_store from modules.common.store._counter import get_counter_value_store from modules.common.store._inverter import get_inverter_value_store +from modules.common.store._ramdisk import ramdisk_write, ramdisk_read, ramdisk_read_float, ramdisk_read_int, \ + RAMDISK_PATH diff --git a/packages/modules/common/store/_ramdisk.py b/packages/modules/common/store/_ramdisk.py index f9555626c..b026be73f 100644 --- a/packages/modules/common/store/_ramdisk.py +++ b/packages/modules/common/store/_ramdisk.py @@ -1,10 +1,17 @@ from pathlib import Path -from typing import Iterable, Optional +from typing import Iterable, Optional, TypeVar, Callable from modules.common.store._util import get_rounding_function_by_digits, process_error RAMDISK_PATH = Path(__file__).resolve().parents[4] / "ramdisk" +T = TypeVar('T') + + +class RamdiskReadError(Exception): + def __init__(self, file: str, content: str, message: str): + super().__init__("Error reading ramdisk file <{}>, content=<{}>: {}".format(file, content, message)) + def ramdisk_write_to_files(prefix: str, values: Iterable, digits: int = None): for index, value in enumerate(values): @@ -13,8 +20,26 @@ def ramdisk_write_to_files(prefix: str, values: Iterable, digits: int = None): def ramdisk_write(file: str, value, digits: Optional[int] = None) -> None: try: - rounding = get_rounding_function_by_digits(digits) - with open(str(RAMDISK_PATH / file), "w") as f: - f.write(str(rounding(value))) + (RAMDISK_PATH / file).write_text(str(get_rounding_function_by_digits(digits)(value))) except Exception as e: process_error(e) + + +def ramdisk_read(file: str) -> str: + return (RAMDISK_PATH / file).read_text() + + +def ramdisk_read_mapping(file: str, mapper: Callable[[str], T], error_message: str) -> T: + file_content = ramdisk_read(file) + try: + return mapper(file_content) + except ValueError as e: + raise RamdiskReadError(file, file_content, error_message) from e + + +def ramdisk_read_int(file: str) -> int: + return ramdisk_read_mapping(file, int, "expected int") + + +def ramdisk_read_float(file: str) -> float: + return ramdisk_read_mapping(file, float, "expected float") diff --git a/packages/modules/saxpower/__init__.py b/packages/modules/saxpower/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packages/modules/saxpower/bat.py b/packages/modules/saxpower/bat.py new file mode 100644 index 000000000..2d1013dd5 --- /dev/null +++ b/packages/modules/saxpower/bat.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +from helpermodules import log +from modules.common import modbus +from modules.common import simcount +from modules.common.component_state import BatState +from modules.common.modbus import ModbusDataType +from modules.common.fault_state import ComponentInfo +from modules.common.store import get_bat_value_store + + +def get_default_config() -> dict: + return { + "name": "Saxpower Speicher", + "id": 0, + "type": "bat", + "configuration": {} + } + + +class SaxpowerBat: + def __init__(self, device_id: int, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.__device_id = device_id + self.component_config = component_config + self.__tcp_client = tcp_client + self.__sim_count = simcount.SimCountFactory().get_sim_counter()() + self.__simulation = {} + self.__store = get_bat_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self) -> None: + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + + soc = self.__tcp_client.read_holding_registers(46, ModbusDataType.INT_16, unit=64) + power = self.__tcp_client.read_holding_registers(47, ModbusDataType.UINT_16, unit=64) * -1 + + topic_str = "openWB/set/system/device/" + str( + self.__device_id)+"/component/"+str(self.component_config["id"])+"/" + imported, exported = self.__sim_count.sim_count( + power, topic=topic_str, data=self.__simulation, prefix="speicher" + ) + bat_state = BatState( + power=power, + soc=soc, + imported=imported, + exported=exported + ) + self.__store.set(bat_state) diff --git a/packages/modules/saxpower/device.py b/packages/modules/saxpower/device.py new file mode 100644 index 000000000..bb8d8be49 --- /dev/null +++ b/packages/modules/saxpower/device.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +import sys +from typing import Dict, List + +from helpermodules import log +from modules.common import modbus +from modules.common.abstract_device import AbstractDevice +from modules.common.component_context import SingleComponentUpdateContext +from modules.saxpower import bat + + +def get_default_config() -> dict: + return { + "name": "Saxpower", + "type": "saxpower", + "id": 0, + "configuration": + { + "ip_address": "192.168.193.15" + } + } + + +class Device(AbstractDevice): + COMPONENT_TYPE_TO_CLASS = { + "bat": bat.SaxpowerBat + } + + def __init__(self, device_config: dict) -> None: + self._components = {} # type: Dict[str, bat.SaxpowerBat] + try: + ip_address = device_config["configuration"]["ip_address"] + self.client = modbus.ModbusClient(ip_address, 3600) + self.device_config = device_config + except Exception: + log.MainLogger().exception("Fehler im Modul "+device_config["name"]) + + def add_component(self, component_config: dict) -> None: + component_type = component_config["type"] + if component_type in self.COMPONENT_TYPE_TO_CLASS: + self._components["component"+str(component_config["id"])] = (self.COMPONENT_TYPE_TO_CLASS[component_type]( + self.device_config["id"], component_config, self.client)) + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(self.COMPONENT_TYPE_TO_CLASS.keys()) + ) + + def update(self) -> None: + log.MainLogger().debug("Start device reading " + str(self._components)) + if self._components: + for component in self._components: + # Auch wenn bei einer Komponente ein Fehler auftritt, sollen alle anderen noch ausgelesen werden. + with SingleComponentUpdateContext(self._components[component].component_info): + self._components[component].update() + else: + log.MainLogger().warning( + self.device_config["name"] + + ": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden." + ) + + +def read_legacy(argv: List[str]) -> None: + COMPONENT_TYPE_TO_MODULE = { + "bat": bat + } + component_type = argv[1] + ip_address = argv[2] + try: + num = int(argv[3]) + except IndexError: + num = None + + device_config = get_default_config() + device_config["configuration"]["ip_address"] = ip_address + dev = Device(device_config) + if component_type in COMPONENT_TYPE_TO_MODULE: + component_config = COMPONENT_TYPE_TO_MODULE[component_type].get_default_config() + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(COMPONENT_TYPE_TO_MODULE.keys()) + ) + component_config["id"] = num + dev.add_component(component_config) + + log.MainLogger().debug('Saxpower IP-Adresse: ' + str(ip_address)) + + dev.update() + + +if __name__ == "__main__": + try: + read_legacy(sys.argv) + except Exception: + log.MainLogger().exception("Fehler im Saxpower Skript") diff --git a/packages/modules/solax/__init__.py b/packages/modules/solax/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packages/modules/solax/bat.py b/packages/modules/solax/bat.py new file mode 100644 index 000000000..701974cdc --- /dev/null +++ b/packages/modules/solax/bat.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +from helpermodules import log +from modules.common import modbus +from modules.common import simcount +from modules.common.component_state import BatState +from modules.common.modbus import ModbusDataType +from modules.common.fault_state import ComponentInfo +from modules.common.store import get_bat_value_store + + +def get_default_config() -> dict: + return { + "name": "Solax Speicher", + "id": 0, + "type": "bat", + "configuration": {} + } + + +class SolaxBat: + def __init__(self, device_id: int, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.__device_id = device_id + self.component_config = component_config + self.__tcp_client = tcp_client + self.__sim_count = simcount.SimCountFactory().get_sim_counter()() + self.__simulation = {} + self.__store = get_bat_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self) -> None: + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + + power = self.__tcp_client.read_input_registers(22, ModbusDataType.INT_16) + soc = self.__tcp_client.read_input_registers(28, ModbusDataType.UINT_16) + + topic_str = "openWB/set/system/device/" + str( + self.__device_id)+"/component/"+str(self.component_config["id"])+"/" + imported, exported = self.__sim_count.sim_count( + power, topic=topic_str, data=self.__simulation, prefix="speicher" + ) + bat_state = BatState( + power=power, + soc=soc, + imported=imported, + exported=exported + ) + self.__store.set(bat_state) diff --git a/packages/modules/solax/counter.py b/packages/modules/solax/counter.py new file mode 100644 index 000000000..772969e44 --- /dev/null +++ b/packages/modules/solax/counter.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +from helpermodules import log +from modules.common import modbus +from modules.common.component_state import CounterState +from modules.common.fault_state import ComponentInfo +from modules.common.modbus import ModbusDataType +from modules.common.store import get_counter_value_store + + +def get_default_config() -> dict: + return { + "name": "Solax Zähler", + "id": 0, + "type": "counter", + "configuration": {} + } + + +class SolaxCounter: + def __init__(self, device_id: int, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.component_config = component_config + self.__tcp_client = tcp_client + self.__store = get_counter_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self): + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + + power_all = self.__tcp_client.read_input_registers(70, ModbusDataType.INT_32) * -1 + frequency = self.__tcp_client.read_input_registers(7, ModbusDataType.UINT_16) / 100 + exported, imported = [val / 100 + for val in self.__tcp_client.read_input_registers(72, [ModbusDataType.UINT_32] * 2)] + + counter_state = CounterState( + imported=imported, + exported=exported, + power_all=power_all, + frequency=frequency + ) + log.MainLogger().debug("Solax Leistung[W]: " + str(counter_state.power_all)) + self.__store.set(counter_state) diff --git a/packages/modules/solax/device.py b/packages/modules/solax/device.py new file mode 100644 index 000000000..446feaecf --- /dev/null +++ b/packages/modules/solax/device.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +import sys +from typing import Dict, List + +from helpermodules import log +from modules.common import modbus +from modules.common.abstract_device import AbstractDevice +from modules.common.component_context import SingleComponentUpdateContext +from modules.solax import bat +from modules.solax import counter +from modules.solax import inverter + + +def get_default_config() -> dict: + return { + "name": "Solax", + "type": "solax", + "id": 0, + "configuration": + { + "ip_address": "192.168.193.15" + } + } + + +class Device(AbstractDevice): + COMPONENT_TYPE_TO_CLASS = { + "bat": bat.SolaxBat, + "counter": counter.SolaxCounter, + "inverter": inverter.SolaxInverter + } + + def __init__(self, device_config: dict) -> None: + self._components = {} # type: Dict[str, counter.SolaxCounter] + try: + ip_address = device_config["configuration"]["ip_address"] + self.client = modbus.ModbusClient(ip_address, 502) + self.device_config = device_config + except Exception: + log.MainLogger().exception("Fehler im Modul "+device_config["name"]) + + def add_component(self, component_config: dict) -> None: + component_type = component_config["type"] + if component_type in self.COMPONENT_TYPE_TO_CLASS: + self._components["component"+str(component_config["id"])] = (self.COMPONENT_TYPE_TO_CLASS[component_type]( + self.device_config["id"], component_config, self.client)) + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(self.COMPONENT_TYPE_TO_CLASS.keys()) + ) + + def update(self) -> None: + log.MainLogger().debug("Start device reading " + str(self._components)) + if self._components: + for component in self._components: + # Auch wenn bei einer Komponente ein Fehler auftritt, sollen alle anderen noch ausgelesen werden. + with SingleComponentUpdateContext(self._components[component].component_info): + self._components[component].update() + else: + log.MainLogger().warning( + self.device_config["name"] + + ": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden.") + + +def read_legacy(argv: List[str]) -> None: + COMPONENT_TYPE_TO_MODULE = { + "bat": bat, + "counter": counter, + "inverter": inverter + } + component_type = argv[1] + ip_address = argv[2] + try: + num = int(argv[3]) + except IndexError: + num = None + + device_config = get_default_config() + device_config["configuration"]["ip_address"] = ip_address + dev = Device(device_config) + if component_type in COMPONENT_TYPE_TO_MODULE: + component_config = COMPONENT_TYPE_TO_MODULE[component_type].get_default_config() + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(COMPONENT_TYPE_TO_MODULE.keys()) + ) + component_config["id"] = num + dev.add_component(component_config) + + log.MainLogger().debug('Solax IP-Adresse: ' + str(ip_address)) + + dev.update() + + +if __name__ == "__main__": + try: + read_legacy(sys.argv) + except Exception: + log.MainLogger().exception("Fehler im Solax Skript") diff --git a/packages/modules/solax/inverter.py b/packages/modules/solax/inverter.py new file mode 100644 index 000000000..c025a1b2c --- /dev/null +++ b/packages/modules/solax/inverter.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 + +from helpermodules import log +from modules.common import modbus +from modules.common.component_state import InverterState +from modules.common.fault_state import ComponentInfo +from modules.common.modbus import ModbusDataType +from modules.common.store import get_inverter_value_store + + +def get_default_config() -> dict: + return { + "name": "Solax Wechselrichter", + "id": 0, + "type": "inverter", + "configuration": {} + } + + +class SolaxInverter: + def __init__(self, device_id: int, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.component_config = component_config + self.__tcp_client = tcp_client + self.__store = get_inverter_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self) -> None: + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + + power_temp = self.__tcp_client.read_input_registers(10, [ModbusDataType.UINT_16]*2) + power = sum(power_temp) * -1 + counter = self.__tcp_client.read_input_registers(82, ModbusDataType.UINT_32) + + inverter_state = InverterState( + power=power, + counter=counter + ) + self.__store.set(inverter_state) diff --git a/packages/modules/studer/__init__.py b/packages/modules/studer/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packages/modules/studer/bat.py b/packages/modules/studer/bat.py new file mode 100644 index 000000000..8fa3cfe2f --- /dev/null +++ b/packages/modules/studer/bat.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +from helpermodules import log +from modules.common import modbus +from modules.common.component_state import BatState +from modules.common.modbus import ModbusDataType +from modules.common.fault_state import ComponentInfo +from modules.common.store import get_bat_value_store + + +def get_default_config() -> dict: + return { + "name": "Studer Speicher", + "id": 0, + "type": "bat", + "configuration": {} + } + + +class StuderBat: + def __init__(self, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.component_config = component_config + self.__tcp_client = tcp_client + self.__store = get_bat_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self) -> None: + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + unit = 60 + + power = self.__tcp_client.read_input_registers(6, ModbusDataType.FLOAT_32, unit=unit) + imported = self.__tcp_client.read_input_registers(14, ModbusDataType.FLOAT_32, unit=unit) * 48 + exported = self.__tcp_client.read_input_registers(16, ModbusDataType.FLOAT_32, unit=unit) * 48 + soc = self.__tcp_client.read_input_registers(4, ModbusDataType.FLOAT_32, unit=unit) + + bat_state = BatState( + power=power, + soc=soc, + imported=imported, + exported=exported + ) + self.__store.set(bat_state) diff --git a/packages/modules/studer/device.py b/packages/modules/studer/device.py new file mode 100644 index 000000000..cec0a5cc4 --- /dev/null +++ b/packages/modules/studer/device.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +""" Modul zum Auslesen von Alpha Ess Speichern, Zählern und Wechselrichtern. +""" +import sys +from typing import Dict, List, Union + +from helpermodules import log +from modules.common import modbus +from modules.common.abstract_device import AbstractDevice +from modules.common.component_context import SingleComponentUpdateContext +from modules.studer import bat +from modules.studer import inverter + + +def get_default_config() -> dict: + return { + "name": "Studer", + "type": "studer", + "id": 0, + "configuration": + { + "ip_address": "192.168.193.15" + } + } + + +studer_component_classes = Union[bat.StuderBat, inverter.StuderInverter] + + +class Device(AbstractDevice): + COMPONENT_TYPE_TO_CLASS = { + "bat": bat.StuderBat, + "inverter": inverter.StuderInverter + } + + def __init__(self, device_config: dict) -> None: + self._components = {} # type: Dict[str, studer_component_classes] + try: + ip_address = device_config["configuration"]["ip_address"] + self.client = modbus.ModbusClient(ip_address, 502) + self.device_config = device_config + except Exception: + log.MainLogger().exception("Fehler im Modul "+device_config["name"]) + + def add_component(self, component_config: dict) -> None: + component_type = component_config["type"] + if component_type in self.COMPONENT_TYPE_TO_CLASS: + self._components["component"+str(component_config["id"])] = (self.COMPONENT_TYPE_TO_CLASS[component_type]( + component_config, self.client)) + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(self.COMPONENT_TYPE_TO_CLASS.keys()) + ) + + def update(self) -> None: + log.MainLogger().debug("Start device reading " + str(self._components)) + if self._components: + for component in self._components: + # Auch wenn bei einer Komponente ein Fehler auftritt, sollen alle anderen noch ausgelesen werden. + with SingleComponentUpdateContext(self._components[component].component_info): + self._components[component].update() + else: + log.MainLogger().warning( + self.device_config["name"] + + ": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden." + ) + + +def read_legacy(argv: List[str]) -> None: + COMPONENT_TYPE_TO_MODULE = { + "bat": bat, + "inverter": inverter + } + component_type = argv[1] + ip_address = argv[2] + + device_config = get_default_config() + device_config["configuration"]["ip_address"] = ip_address + dev = Device(device_config) + if component_type in COMPONENT_TYPE_TO_MODULE: + component_config = COMPONENT_TYPE_TO_MODULE[component_type].get_default_config() + if component_type == "bat": + try: + num = int(argv[3]) + except IndexError: + num = None + else: + vc_count = int(argv[3]) + vc_type = argv[4] + try: + num = int(argv[5]) + except IndexError: + num = None + component_config["configuration"]["vc_count"] = vc_count + component_config["configuration"]["vc_type"] = vc_type + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(COMPONENT_TYPE_TO_MODULE.keys()) + ) + component_config["id"] = num + dev.add_component(component_config) + + log.MainLogger().debug('Studer IP-Adresse: ' + str(ip_address)) + + dev.update() + + +if __name__ == "__main__": + try: + read_legacy(sys.argv) + except Exception: + log.MainLogger().exception("Fehler im Studer Skript") diff --git a/packages/modules/studer/inverter.py b/packages/modules/studer/inverter.py new file mode 100644 index 000000000..27c581ad9 --- /dev/null +++ b/packages/modules/studer/inverter.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 + +from helpermodules import log +from modules.common import modbus +from modules.common.component_state import InverterState +from modules.common.fault_state import ComponentInfo, FaultState +from modules.common.modbus import ModbusDataType +from modules.common.store import get_inverter_value_store + + +def get_default_config() -> dict: + return { + "name": "Studer Wechselrichter", + "id": 0, + "type": "inverter", + "configuration": + { + "vc_count": 1, # studer_vc (count MPPT Devices) + "vc_type": "VS" # studer_vc_type (MPPT type VS or VT) + + } + } + + +class StuderInverter: + def __init__(self, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.component_config = component_config + self.__tcp_client = tcp_client + self.__store = get_inverter_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self) -> None: + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + + vc_count = self.component_config["configuration"]["vc_count"] + vc_type = self.component_config["configuration"]["vc_type"] + + if vc_type == 'VS': + mb_unit = 40 + mb_register = 20 # MB:20; ID: 15010; PV power kW + elif vc_type == 'VT': + mb_unit = 20 + mb_register = 8 # MB:8; ID: 11004; Power of the PV generator kW + else: + raise FaultState.error("Unbekannter VC-Typ: "+str(vc_type)) + power = 0 + for i in range(1, vc_count+1): + mb_unit_dev = mb_unit+i + power += self.__tcp_client.read_input_registers(mb_register, ModbusDataType.FLOAT_32, unit=mb_unit_dev) + power = power * -1000 + + if vc_type == 'VS': + mb_register = 46 # MB:46; ID: 15023; Desc: Total PV produced energy MWh + elif vc_type == 'VT': + mb_register = 18 # MB:18; ID: 11009; Desc: Total produced energy MWh + counter = 0 + for i in range(1, vc_count + 1): + mb_unit_dev = mb_unit + i + counter += self.__tcp_client.read_input_registers(mb_register, ModbusDataType.FLOAT_32, unit=mb_unit_dev) + counter = counter * 1000000 + + inverter_state = InverterState( + power=power, + counter=counter + ) + self.__store.set(inverter_state) diff --git a/packages/modules/sungrow/__init__.py b/packages/modules/sungrow/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packages/modules/sungrow/bat.py b/packages/modules/sungrow/bat.py new file mode 100644 index 000000000..66643cae8 --- /dev/null +++ b/packages/modules/sungrow/bat.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +from helpermodules import log +from modules.common import modbus +from modules.common import simcount +from modules.common.component_state import BatState +from modules.common.modbus import ModbusDataType +from modules.common.fault_state import ComponentInfo +from modules.common.store import get_bat_value_store + + +def get_default_config() -> dict: + return { + "name": "Sungrow Speicher", + "id": 0, + "type": "bat", + "configuration": {} + } + + +class SungrowBat: + def __init__(self, device_id: int, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.__device_id = device_id + self.component_config = component_config + self.__tcp_client = tcp_client + self.__sim_count = simcount.SimCountFactory().get_sim_counter()() + self.__simulation = {} + self.__store = get_bat_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self) -> None: + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + unit = 1 + + soc = int(self.__tcp_client.read_input_registers(13022, ModbusDataType.INT_16, unit=unit) / 10) + resp = self.__tcp_client.delegate.read_input_registers(13000, 1, unit=unit) + binary = bin(resp.registers[0])[2:].zfill(8) + power = self.__tcp_client.read_input_registers(13021, ModbusDataType.INT_16, unit=unit) + if binary[5] == "1": + power = power * -1 + + topic_str = "openWB/set/system/device/" + str( + self.__device_id)+"/component/"+str(self.component_config["id"])+"/" + imported, exported = self.__sim_count.sim_count( + power, topic=topic_str, data=self.__simulation, prefix="speicher" + ) + bat_state = BatState( + power=power, + soc=soc, + imported=imported, + exported=exported + ) + self.__store.set(bat_state) diff --git a/packages/modules/sungrow/counter.py b/packages/modules/sungrow/counter.py new file mode 100644 index 000000000..ac5e71108 --- /dev/null +++ b/packages/modules/sungrow/counter.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +from helpermodules import log +from modules.common import modbus +from modules.common import simcount +from modules.common.component_state import CounterState +from modules.common.fault_state import ComponentInfo +from modules.common.modbus import ModbusDataType +from modules.common.store import get_counter_value_store + + +def get_default_config() -> dict: + return { + "name": "Sungrow Zähler", + "id": 0, + "type": "counter", + "configuration": + { + "version": 1 + } + } + + +class SungrowCounter: + def __init__(self, device_id: int, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.__device_id = device_id + self.component_config = component_config + self.__tcp_client = tcp_client + self.__sim_count = simcount.SimCountFactory().get_sim_counter()() + self.__simulation = {} + self.__store = get_counter_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self): + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + unit = 1 + if self.component_config["configuration"]["version"] == 1: + power_all = self.__tcp_client.read_input_registers(5082, ModbusDataType.INT_32, unit=unit) + else: + power_all = self.__tcp_client.read_input_registers(13009, ModbusDataType.INT_32, unit=unit) * -1 + + topic_str = "openWB/set/system/device/{}/component/{}/".format(self.__device_id, self.component_config["id"]) + imported, exported = self.__sim_count.sim_count( + power_all, + topic=topic_str, + data=self.__simulation, + prefix="bezug" + ) + + counter_state = CounterState( + imported=imported, + exported=exported, + power_all=power_all + ) + log.MainLogger().debug("Sungrow Leistung[W]: " + str(counter_state.power_all)) + self.__store.set(counter_state) diff --git a/packages/modules/sungrow/device.py b/packages/modules/sungrow/device.py new file mode 100644 index 000000000..a427590b7 --- /dev/null +++ b/packages/modules/sungrow/device.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +""" Modul zum Auslesen von Alpha Ess Speichern, Zählern und Wechselrichtern. +""" +import sys +from typing import Dict, List, Union + +from helpermodules import log +from modules.common import modbus +from modules.common.abstract_device import AbstractDevice +from modules.common.component_context import SingleComponentUpdateContext +from modules.sungrow import bat +from modules.sungrow import counter +from modules.sungrow import inverter + + +def get_default_config() -> dict: + return { + "name": "Sungrow", + "type": "sungrow", + "id": 0, + "configuration": + { + "ip_address": "192.168.193.15" + } + } + + +sungrow_component_classes = Union[bat.SungrowBat, counter.SungrowCounter, inverter.SungrowInverter] + + +class Device(AbstractDevice): + COMPONENT_TYPE_TO_CLASS = { + "bat": bat.SungrowBat, + "counter": counter.SungrowCounter, + "inverter": inverter.SungrowInverter + } + + def __init__(self, device_config: dict) -> None: + self._components = {} # type: Dict[str, sungrow_component_classes] + try: + ip_address = device_config["configuration"]["ip_address"] + self.client = modbus.ModbusClient(ip_address, 502) + self.device_config = device_config + except Exception: + log.MainLogger().exception("Fehler im Modul "+device_config["name"]) + + def add_component(self, component_config: dict) -> None: + component_type = component_config["type"] + if component_type in self.COMPONENT_TYPE_TO_CLASS: + self._components["component"+str(component_config["id"])] = (self.COMPONENT_TYPE_TO_CLASS[component_type]( + self.device_config["id"], component_config, self.client)) + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(self.COMPONENT_TYPE_TO_CLASS.keys()) + ) + + def update(self) -> None: + log.MainLogger().debug("Start device reading " + str(self._components)) + if self._components: + for component in self._components: + # Auch wenn bei einer Komponente ein Fehler auftritt, sollen alle anderen noch ausgelesen werden. + with SingleComponentUpdateContext(self._components[component].component_info): + self._components[component].update() + else: + log.MainLogger().warning( + self.device_config["name"] + + ": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden." + ) + + +def read_legacy(argv: List[str]) -> None: + COMPONENT_TYPE_TO_MODULE = { + "bat": bat, + "counter": counter, + "inverter": inverter + } + component_type = argv[1] + ip_address = argv[2] + + device_config = get_default_config() + device_config["configuration"]["ip_address"] = ip_address + dev = Device(device_config) + if component_type in COMPONENT_TYPE_TO_MODULE: + component_config = COMPONENT_TYPE_TO_MODULE[component_type].get_default_config() + if component_type == "counter": + version = int(argv[3]) + component_config["configuration"]["version"] = version + log.MainLogger().debug('Sungrow Version: ' + str(version)) + num = None + else: + version = None + try: + num = int(argv[3]) + except IndexError: + num = None + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(COMPONENT_TYPE_TO_MODULE.keys()) + ) + component_config["id"] = num + dev.add_component(component_config) + + log.MainLogger().debug('Sungrow IP-Adresse: ' + str(ip_address)) + dev.update() + + +if __name__ == "__main__": + try: + read_legacy(sys.argv) + except Exception: + log.MainLogger().exception("Fehler im Sungrow Skript") diff --git a/packages/modules/sungrow/inverter.py b/packages/modules/sungrow/inverter.py new file mode 100644 index 000000000..02332903a --- /dev/null +++ b/packages/modules/sungrow/inverter.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +from helpermodules import log +from modules.common import modbus +from modules.common import simcount +from modules.common.component_state import InverterState +from modules.common.fault_state import ComponentInfo +from modules.common.modbus import ModbusDataType +from modules.common.store import get_inverter_value_store + + +def get_default_config() -> dict: + return { + "name": "Sungrow Wechselrichter", + "id": 0, + "type": "inverter", + "configuration": {} + } + + +class SungrowInverter: + def __init__(self, device_id: int, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.__device_id = device_id + self.component_config = component_config + self.__tcp_client = tcp_client + self.__sim_count = simcount.SimCountFactory().get_sim_counter()() + self.__simulation = {} + self.__store = get_inverter_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self) -> None: + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + power = self.__tcp_client.read_holding_registers(5016, ModbusDataType.INT_32, unit=1) * -1 + + topic_str = "openWB/set/system/device/" + \ + str(self.__device_id)+"/component/" + \ + str(self.component_config["id"])+"/" + _, counter = self.__sim_count.sim_count( + power, topic=topic_str, data=self.__simulation, prefix="pv") + + inverter_state = InverterState( + power=power, + counter=counter + ) + self.__store.set(inverter_state) diff --git a/packages/modules/sunny_island/__init__.py b/packages/modules/sunny_island/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packages/modules/sunny_island/bat.py b/packages/modules/sunny_island/bat.py new file mode 100644 index 000000000..1a3b9b837 --- /dev/null +++ b/packages/modules/sunny_island/bat.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +from helpermodules import log +from modules.common import modbus +from modules.common.component_state import BatState +from modules.common.modbus import ModbusDataType +from modules.common.fault_state import ComponentInfo +from modules.common.store import get_bat_value_store + + +def get_default_config() -> dict: + return { + "name": "Sunny Island Speicher", + "id": 0, + "type": "bat", + "configuration": {} + } + + +class SunnyIslandBat: + def __init__(self, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.component_config = component_config + self.__tcp_client = tcp_client + self.__store = get_bat_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self) -> None: + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + unit = 3 + + soc = self.__tcp_client.read_holding_registers(30845, ModbusDataType.INT_32, unit=unit) + power = self.__tcp_client.read_holding_registers(30775, ModbusDataType.INT_32, unit=unit) * -1 + [imported, exported] = self.__tcp_client.read_holding_registers(30595, [ModbusDataType.INT_32]*2, unit=unit) + + bat_state = BatState( + power=power, + soc=soc, + imported=imported, + exported=exported + ) + self.__store.set(bat_state) diff --git a/packages/modules/sunny_island/device.py b/packages/modules/sunny_island/device.py new file mode 100644 index 000000000..ca8cae33b --- /dev/null +++ b/packages/modules/sunny_island/device.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +""" Modul zum Auslesen von Alpha Ess Speichern, Zählern und Wechselrichtern. +""" +import sys +from typing import Dict, List + +from helpermodules import log +from modules.common import modbus +from modules.common.abstract_device import AbstractDevice +from modules.common.component_context import SingleComponentUpdateContext +from modules.sunny_island import bat + + +def get_default_config() -> dict: + return { + "name": "Sunny Island", + "type": "sunny_island", + "id": 0, + "configuration": + { + "ip_address": "192.168.193.15" + } + } + + +class Device(AbstractDevice): + COMPONENT_TYPE_TO_CLASS = { + "bat": bat.SunnyIslandBat + } + + def __init__(self, device_config: dict) -> None: + self._components = {} # type: Dict[str, bat.SunnyIslandBat] + try: + ip_address = device_config["configuration"]["ip_address"] + self.client = modbus.ModbusClient(ip_address, 502) + self.device_config = device_config + except Exception: + log.MainLogger().exception("Fehler im Modul "+device_config["name"]) + + def add_component(self, component_config: dict) -> None: + component_type = component_config["type"] + if component_type in self.COMPONENT_TYPE_TO_CLASS: + self._components["component"+str(component_config["id"])] = (self.COMPONENT_TYPE_TO_CLASS[component_type]( + component_config, self.client)) + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(self.COMPONENT_TYPE_TO_CLASS.keys()) + ) + + def update(self) -> None: + log.MainLogger().debug("Start device reading " + str(self._components)) + if self._components: + for component in self._components: + # Auch wenn bei einer Komponente ein Fehler auftritt, sollen alle anderen noch ausgelesen werden. + with SingleComponentUpdateContext(self._components[component].component_info): + self._components[component].update() + else: + log.MainLogger().warning( + self.device_config["name"] + + ": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden." + ) + + +def read_legacy(argv: List[str]) -> None: + COMPONENT_TYPE_TO_MODULE = { + "bat": bat + } + component_type = argv[1] + ip_address = argv[2] + try: + num = int(argv[3]) + except IndexError: + num = None + + device_config = get_default_config() + device_config["configuration"]["ip_address"] = ip_address + dev = Device(device_config) + if component_type in COMPONENT_TYPE_TO_MODULE: + component_config = COMPONENT_TYPE_TO_MODULE[component_type].get_default_config() + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(COMPONENT_TYPE_TO_MODULE.keys()) + ) + component_config["id"] = num + dev.add_component(component_config) + + log.MainLogger().debug('Sunny Island IP-Adresse: ' + str(ip_address)) + dev.update() + + +if __name__ == "__main__": + try: + read_legacy(sys.argv) + except Exception: + log.MainLogger().exception("Fehler im Sunny Island Skript") diff --git a/packages/modules/victron/__init__.py b/packages/modules/victron/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packages/modules/victron/bat.py b/packages/modules/victron/bat.py new file mode 100644 index 000000000..4b451c735 --- /dev/null +++ b/packages/modules/victron/bat.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +from helpermodules import log +from modules.common import modbus +from modules.common import simcount +from modules.common.component_state import BatState +from modules.common.modbus import ModbusDataType +from modules.common.fault_state import ComponentInfo +from modules.common.store import get_bat_value_store + + +def get_default_config() -> dict: + return { + "name": "Victron Speicher", + "id": 0, + "type": "bat", + "configuration": {} + } + + +class VictronBat: + def __init__(self, device_id: int, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.__device_id = device_id + self.component_config = component_config + self.__tcp_client = tcp_client + self.__sim_count = simcount.SimCountFactory().get_sim_counter()() + self.__simulation = {} + self.__store = get_bat_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self) -> None: + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + + power = self.__tcp_client.read_holding_registers(842, ModbusDataType.INT_16, unit=100) + soc = self.__tcp_client.read_holding_registers(843, ModbusDataType.UINT_16, unit=100) + + topic_str = "openWB/set/system/device/" + str( + self.__device_id)+"/component/"+str(self.component_config["id"])+"/" + imported, exported = self.__sim_count.sim_count( + power, topic=topic_str, data=self.__simulation, prefix="speicher" + ) + bat_state = BatState( + power=power, + soc=soc, + imported=imported, + exported=exported + ) + self.__store.set(bat_state) diff --git a/packages/modules/victron/counter.py b/packages/modules/victron/counter.py new file mode 100644 index 000000000..0ab8421b4 --- /dev/null +++ b/packages/modules/victron/counter.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +from helpermodules import log +from modules.common import modbus +from modules.common.component_state import CounterState +from modules.common.fault_state import ComponentInfo +from modules.common.modbus import ModbusDataType +from modules.common.store import get_counter_value_store + + +def get_default_config() -> dict: + return { + "name": "Victron Zähler", + "id": 0, + "type": "counter", + "configuration": + { + "modbus_id": 1 + } + } + + +class VictronCounter: + def __init__(self, device_id: int, component_config: dict, tcp_client: modbus.ModbusClient) -> None: + self.component_config = component_config + self.__tcp_client = tcp_client + self.__store = get_counter_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self): + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + unit = self.component_config["configuration"]["modbus_id"] + power_all = sum(self.__tcp_client.read_holding_registers(2600, [ModbusDataType.INT_16]*3, unit=unit)) + currents_voltages = [val / 10 + for val in self.__tcp_client.read_holding_registers( + 2616, [ModbusDataType.INT_16] * 6, unit=unit)] + voltages = [currents_voltages[0], currents_voltages[2], currents_voltages[4]] + currents = [currents_voltages[1], currents_voltages[3], currents_voltages[5]] + imported = sum(self.__tcp_client.read_holding_registers(2622, [ModbusDataType.UINT_32]*3, unit=unit)) * 10 + exported = sum(self.__tcp_client.read_holding_registers(2628, [ModbusDataType.UINT_32]*3, unit=unit)) * 10 + + counter_state = CounterState( + voltages=voltages, + currents=currents, + imported=imported, + exported=exported, + power_all=power_all + ) + log.MainLogger().debug("Victron Leistung[W]: " + str(counter_state.power_all)) + self.__store.set(counter_state) diff --git a/packages/modules/victron/device.py b/packages/modules/victron/device.py new file mode 100644 index 000000000..42845834f --- /dev/null +++ b/packages/modules/victron/device.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +import sys +from typing import Dict, List, Union + +from helpermodules import log +from modules.common import modbus +from modules.common.abstract_device import AbstractDevice +from modules.common.component_context import SingleComponentUpdateContext +from modules.victron import bat +from modules.victron import counter + + +def get_default_config() -> dict: + return { + "name": "Victron", + "type": "victron", + "id": 0, + "configuration": + { + "ip_address": "192.168.193.15" + } + } + + +class Device(AbstractDevice): + COMPONENT_TYPE_TO_CLASS = { + "bat": bat.VictronBat, + "counter": counter.VictronCounter + } + + def __init__(self, device_config: dict) -> None: + self._components = {} # type: Dict[str, Union[bat.VictronBat, counter.VictronCounter]] + try: + ip_address = device_config["configuration"]["ip_address"] + self.client = modbus.ModbusClient(ip_address, 502) + self.device_config = device_config + except Exception: + log.MainLogger().exception("Fehler im Modul "+device_config["name"]) + + def add_component(self, component_config: dict) -> None: + component_type = component_config["type"] + if component_type in self.COMPONENT_TYPE_TO_CLASS: + self._components["component"+str(component_config["id"])] = ( + self.COMPONENT_TYPE_TO_CLASS[component_type](self.device_config["id"], component_config, self.client)) + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(self.COMPONENT_TYPE_TO_CLASS.keys()) + ) + + def update(self) -> None: + log.MainLogger().debug("Start device reading " + str(self._components)) + if self._components: + for component in self._components: + # Auch wenn bei einer Komponente ein Fehler auftritt, sollen alle anderen noch ausgelesen werden. + with SingleComponentUpdateContext(self._components[component].component_info): + self._components[component].update() + else: + log.MainLogger().warning( + self.device_config["name"] + + ": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden." + ) + + +def read_legacy(argv: List[str]) -> None: + COMPONENT_TYPE_TO_MODULE = { + "bat": bat, + "counter": counter + } + component_type = argv[1] + ip_address = argv[2] + + device_config = get_default_config() + device_config["configuration"]["ip_address"] = ip_address + dev = Device(device_config) + + if component_type in COMPONENT_TYPE_TO_MODULE: + component_config = COMPONENT_TYPE_TO_MODULE[component_type].get_default_config() + if component_type == "counter": + modbus_id = argv[3] + component_config["configuration"]["modbus_id"] = modbus_id + try: + num = int(argv[4]) + except IndexError: + num = None + else: + try: + num = int(argv[3]) + except IndexError: + num = None + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(COMPONENT_TYPE_TO_MODULE.keys()) + ) + component_config["id"] = num + dev.add_component(component_config) + + log.MainLogger().debug('Victron IP-Adresse: ' + str(ip_address)) + dev.update() + + +if __name__ == "__main__": + try: + read_legacy(sys.argv) + except Exception: + log.MainLogger().exception("Fehler im Victron Skript") diff --git a/packages/modules/victron_inverter/__init__.py b/packages/modules/victron_inverter/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packages/modules/victron_inverter/device.py b/packages/modules/victron_inverter/device.py new file mode 100644 index 000000000..312ff8367 --- /dev/null +++ b/packages/modules/victron_inverter/device.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +import sys +from typing import Dict, List + +from helpermodules import log +from modules.common.abstract_device import AbstractDevice +from modules.common.component_context import SingleComponentUpdateContext +from modules.victron_inverter import inverter + + +def get_default_config() -> dict: + return { + "name": "Wechselrichter Victron", + "type": "victron_inverter", + "id": 0, + "configuration": {} + } + + +class Device(AbstractDevice): + COMPONENT_TYPE_TO_CLASS = { + "inverter": inverter.VictronInverter + } + + def __init__(self, device_config: dict) -> None: + self._components = {} # type: Dict[str, inverter.VictronInverter] + try: + self.device_config = device_config + except Exception: + log.MainLogger().exception("Fehler im Modul "+device_config["name"]) + + def add_component(self, component_config: dict) -> None: + component_type = component_config["type"] + if component_type in self.COMPONENT_TYPE_TO_CLASS: + self._components["component"+str(component_config["id"])] = ( + self.COMPONENT_TYPE_TO_CLASS[component_type](self.device_config["id"], component_config)) + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(self.COMPONENT_TYPE_TO_CLASS.keys()) + ) + + def update(self) -> None: + log.MainLogger().debug("Start device reading " + str(self._components)) + if self._components: + for component in self._components: + # Auch wenn bei einer Komponente ein Fehler auftritt, sollen alle anderen noch ausgelesen werden. + with SingleComponentUpdateContext(self._components[component].component_info): + self._components[component].update() + else: + log.MainLogger().warning( + self.device_config["name"] + + ": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden." + ) + + +def read_legacy(argv: List[str]) -> None: + COMPONENT_TYPE_TO_MODULE = { + "inverter": inverter + } + component_type = argv[1] + ip_address = argv[2] + modbus_id = argv[3] + mppt = argv[4] + try: + num = int(argv[5]) + except IndexError: + num = None + + device_config = get_default_config() + dev = Device(device_config) + if component_type in COMPONENT_TYPE_TO_MODULE: + component_config = COMPONENT_TYPE_TO_MODULE[component_type].get_default_config() + else: + raise Exception( + "illegal component type " + component_type + ". Allowed values: " + + ','.join(COMPONENT_TYPE_TO_MODULE.keys()) + ) + + component_config["id"] = num + component_config["configuration"]["ip_address"] = ip_address + component_config["configuration"]["modbus_id"] = modbus_id + component_config["configuration"]["mppt"] = mppt + dev.add_component(component_config) + + log.MainLogger().debug('Victron IP-Adresse: ' + str(ip_address)) + log.MainLogger().debug('Victron Modbus-ID: ' + str(modbus_id)) + log.MainLogger().debug('Victron MPPT: ' + str(mppt)) + dev.update() + + +if __name__ == "__main__": + try: + read_legacy(sys.argv) + except Exception: + log.MainLogger().exception("Fehler im Victron Skript") diff --git a/packages/modules/victron_inverter/inverter.py b/packages/modules/victron_inverter/inverter.py new file mode 100644 index 000000000..d3b952562 --- /dev/null +++ b/packages/modules/victron_inverter/inverter.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +from helpermodules import log +from modules.common import modbus +from modules.common import simcount +from modules.common.component_state import InverterState +from modules.common.fault_state import ComponentInfo +from modules.common.modbus import ModbusDataType +from modules.common.store import get_inverter_value_store + + +def get_default_config() -> dict: + return { + "name": "Victron Wechselrichter", + "id": 0, + "type": "inverter", + "configuration": { + "ip_address": "192.168.193.15", + "modbus_id": 100, + "mppt": False + } + } + + +class VictronInverter: + def __init__(self, device_id: int, component_config: dict) -> None: + self.__device_id = device_id + self.component_config = component_config + ip_address = self.component_config["configuration"]["ip_address"] + self.__tcp_client = modbus.ModbusClient(ip_address, 502) + self.__sim_count = simcount.SimCountFactory().get_sim_counter()() + self.__simulation = {} + self.__store = get_inverter_value_store(component_config["id"]) + self.component_info = ComponentInfo.from_component_config(component_config) + + def update(self) -> None: + log.MainLogger().debug("Komponente "+self.component_config["name"]+" auslesen.") + modbus_id = self.component_config["configuration"]["modbus_id"] + + if self.component_config["configuration"]["mppt"]: + power = self.__tcp_client.read_holding_registers(789, ModbusDataType.UINT_16, unit=modbus_id) / -10 + else: + # Adresse 808-810 ac output connected pv + # Adresse 811-813 ac input connected pv + # Adresse 850 mppt Leistung + power_temp1 = self.__tcp_client.read_holding_registers(808, [ModbusDataType.UINT_16]*6, unit=100) + power_temp2 = self.__tcp_client.read_holding_registers(850, ModbusDataType.UINT_16, unit=100) + power = (sum(power_temp1)+power_temp2) * -1 + + topic_str = "openWB/set/system/device/" + str(self.__device_id)+"/component/" + \ + str(self.component_config["id"])+"/" + _, counter = self.__sim_count.sim_count(power, topic=topic_str, data=self.__simulation, prefix="pv") + inverter_state = InverterState( + power=power, + counter=counter + ) + self.__store.set(inverter_state) diff --git a/packages/test_utils/__init__.py b/packages/test_utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/packages/test_utils/mock_ramdisk.py b/packages/test_utils/mock_ramdisk.py new file mode 100644 index 000000000..bd68a2e99 --- /dev/null +++ b/packages/test_utils/mock_ramdisk.py @@ -0,0 +1,42 @@ +from pathlib import Path + +from modules.common.store import RAMDISK_PATH + + +class MockRamdisk: + def __init__(self, monkeypatch): + self.files = {} + original_read_text = Path.read_text + original_write_text = Path.write_text + + def mock_read_text(file: Path): + try: + relative = file.relative_to(RAMDISK_PATH) + except ValueError: + return original_read_text(file) + return self[str(relative)] + + def mock_write_text(file: Path, content: str): + try: + relative = file.relative_to(RAMDISK_PATH) + except ValueError: + original_write_text(file, content) + return + self[str(relative)] = content + + monkeypatch.setattr(Path, 'read_text', mock_read_text) + monkeypatch.setattr(Path, 'write_text', mock_write_text) + + def __setitem__(self, key, value): + if not isinstance(value, str): + raise TypeError("only strings are allowed") + self.files[key] = value + + def __getitem__(self, item): + try: + return self.files.__getitem__(item) + except KeyError: + raise FileNotFoundError() + + def __str__(self): + return "Mock ramdisk: " + str(self.files) diff --git a/runs/atreboot.sh b/runs/atreboot.sh index 7cfdfd30f..5cfd174ec 100755 --- a/runs/atreboot.sh +++ b/runs/atreboot.sh @@ -227,10 +227,10 @@ echo "timezone..." sudo cp /usr/share/zoneinfo/Europe/Berlin /etc/localtime -if [ ! -f /home/pi/ssl_patched ]; then - sudo apt-get update - sudo apt-get -qq install -y openssl libcurl3 curl libgcrypt20 libgnutls30 libssl1.1 libcurl3-gnutls libssl1.0.2 php7.0-cli php7.0-gd php7.0-opcache php7.0 php7.0-common php7.0-json php7.0-readline php7.0-xml php7.0-curl libapache2-mod-php7.0 - touch /home/pi/ssl_patched +if [ ! -f /home/pi/ssl_patched ]; then + sudo apt-get update + sudo apt-get -qq install -y openssl libcurl3 curl libgcrypt20 libgnutls30 libssl1.1 libcurl3-gnutls libssl1.0.2 php7.0-cli php7.0-gd php7.0-opcache php7.0 php7.0-common php7.0-json php7.0-readline php7.0-xml php7.0-curl libapache2-mod-php7.0 + touch /home/pi/ssl_patched fi @@ -367,6 +367,10 @@ curl -s https://raw.githubusercontent.com/snaptec/openWB/stable/web/version > /v # update our local version sudo git -C /var/www/html/openWB show --pretty='format:%ci [%h]' | head -n1 > /var/www/html/openWB/web/lastcommit +# and record the current commit details +commitId=`git -C /var/www/html/openWB log --format="%h" -n 1` +echo $commitId > /var/www/html/openWB/ramdisk/currentCommitHash +echo `git -C /var/www/html/openWB branch -a --contains $commitId | perl -nle 'm|.*origin/(.+).*|; print $1' | uniq | xargs` > /var/www/html/openWB/ramdisk/currentCommitBranches # update broker echo "update broker..." diff --git a/runs/cron5min.sh b/runs/cron5min.sh index 23aa49941..868596ae7 100755 --- a/runs/cron5min.sh +++ b/runs/cron5min.sh @@ -385,6 +385,11 @@ if (( $pingcheckactive == 1 )); then $OPENWBBASEDIR/runs/pingcheck.sh & fi +# record the current commit details +commitId=`git -C /var/www/html/openWB log --format="%h" -n 1` +echo "$commitId" > $RAMDISKDIR/currentCommitHash +echo `git -C /var/www/html/openWB branch -a --contains $commitId | perl -nle 'm|.*origin/(.+).*|; print $1' | uniq | xargs` > $RAMDISKDIR/currentCommitBranches + # EVSE Check openwbDebugLog "MAIN" 1 "starting evsecheck" $OPENWBBASEDIR/runs/evsecheck diff --git a/runs/cronnightly.sh b/runs/cronnightly.sh index 3b8a66823..387807972 100755 --- a/runs/cronnightly.sh +++ b/runs/cronnightly.sh @@ -135,6 +135,31 @@ if [[ ! -z $randomSleep ]] && (( `echo "$randomSleep != 0" | bc` == 1 )); then else echo "Not deleting randomSleepValue of \"$randomSleep\"" fi +#set heartbeat openWB Pro +if [[ $evsecon == "owbpro" ]]; then + curl -s -X POST --data "heartbeatenabled=1" $owbpro1ip/connect.php +fi +if [[ $evsecons1 == "owbpro" ]]; then + curl -s -X POST --data "heartbeatenabled=1" $owbpro2ip/connect.php +fi +if [[ $evsecons2 == "owbpro" ]]; then + curl -s -X POST --data "heartbeatenabled=1" $owbpro3ip/connect.php +fi +if [[ $evseconlp4 == "owbpro" ]]; then + curl -s -X POST --data "heartbeatenabled=1" $owbpro4ip/connect.php +fi +if [[ $evseconlp5 == "owbpro" ]]; then + curl -s -X POST --data "heartbeatenabled=1" $owbpro5ip/connect.php +fi +if [[ $evseconlp6 == "owbpro" ]]; then + curl -s -X POST --data "heartbeatenabled=1" $owbpro6ip/connect.php +fi +if [[ $evseconlp7 == "owbpro" ]]; then + curl -s -X POST --data "heartbeatenabled=1" $owbpro7ip/connect.php +fi +if [[ $evseconlp8 == "owbpro" ]]; then + curl -s -X POST --data "heartbeatenabled=1" $owbpro8ip/connect.php +fi # monthly . csv updaten echo "Trigger update of logfiles..." diff --git a/runs/initRamdisk.sh b/runs/initRamdisk.sh index 660b85fbf..adbcd2a62 100644 --- a/runs/initRamdisk.sh +++ b/runs/initRamdisk.sh @@ -446,7 +446,6 @@ initRamdisk(){ do for f in \ "pluggedladunglp${i}startkwh:openWB/lp/${i}/plugStartkWh:0" \ - "manual_soc_lp${i}:openWB/lp/${i}/manualSoc:0" \ "pluggedladungaktlp${i}:openWB/lp/${i}/pluggedladungakt:0" \ "lp${i}phasen::0" \ "lp${i}enabled::1" \ diff --git a/runs/mqttsub.py b/runs/mqttsub.py index fe4dda77a..ff9911774 100644 --- a/runs/mqttsub.py +++ b/runs/mqttsub.py @@ -1,6 +1,6 @@ +from pathlib import Path + import paho.mqtt.client as mqtt -from subprocess import run -# import os import sys import subprocess import time @@ -20,6 +20,7 @@ config.read(shconfigfile) numberOfSupportedDevices=9 # limit number of smarthome devices lock=threading.Lock() +RAMDISK_PATH = Path(__file__).resolve().parents[1] / "ramdisk" for i in range(1,(numberOfSupportedDevices+1)): try: @@ -459,19 +460,22 @@ def on_message(client, userdata, msg): f.close() if (( "openWB/set/lp" in msg.topic) and ("manualSoc" in msg.topic)): devicenumb=re.sub(r'\D', '', msg.topic) - if ( 1 <= int(devicenumb) <= 2 and 0 <= int(msg.payload) <= 100): - client.publish("openWB/lp/"+str(devicenumb)+"/manualSoc", msg.payload.decode("utf-8"), qos=0, retain=True) - f = open('/var/www/html/openWB/ramdisk/manual_soc_lp'+str(devicenumb), 'w') - f.write(msg.payload.decode("utf-8")) - f.close() - client.publish("openWB/lp/"+str(devicenumb)+"/%Soc", msg.payload.decode("utf-8"), qos=0, retain=True) - if ( int(devicenumb) == 1 ): - socFile = '/var/www/html/openWB/ramdisk/soc' - elif ( int(devicenumb) == 2 ): - socFile = '/var/www/html/openWB/ramdisk/soc1' - f = open(socFile, 'w') - f.write(msg.payload.decode("utf-8")) - f.close() + devicenumb_int = int(devicenumb) + soc = int(msg.payload) + if 1 <= devicenumb_int <= 2 and 0 <= soc <= 100: + if devicenumb_int == 1: + soc_suffix = "" + counter_suffix = "" + else: + soc_suffix = str(devicenumb_int - 1) + counter_suffix = "s" + soc_suffix + for soc_file in ["manual_soc_lp" + devicenumb, "soc" + soc_suffix]: + (RAMDISK_PATH / soc_file).write_text(str(soc)) + RAMDISK_PATH.joinpath("manual_soc_meter_lp" + devicenumb).write_text( + RAMDISK_PATH.joinpath("llkwh" + counter_suffix).read_text() + ) + for topic_suffix in ["manualSoc", "%Soc"]: + client.publish("openWB/lp/"+devicenumb+"/"+topic_suffix, soc, qos=0, retain=True) if (( "openWB/config/set/sofort/lp" in msg.topic) and ("energyToCharge" in msg.topic)): devicenumb=re.sub(r'\D', '', msg.topic) if ( 1 <= int(devicenumb) <= 8 and 0 <= int(msg.payload) <= 100): diff --git a/runs/pubmqtt.sh b/runs/pubmqtt.sh index febecda77..12cffc769 100755 --- a/runs/pubmqtt.sh +++ b/runs/pubmqtt.sh @@ -236,6 +236,8 @@ mqttvar["lp/5/TimeRemaining"]=restzeitlp5 mqttvar["lp/6/TimeRemaining"]=restzeitlp6 mqttvar["lp/7/TimeRemaining"]=restzeitlp7 mqttvar["lp/8/TimeRemaining"]=restzeitlp8 +mqttvar["system/CommitHash"]=currentCommitHash +mqttvar["system/CommitBranches"]=currentCommitBranches if [[ "$standardSocketInstalled" == "1" ]]; then mqttvar["config/get/slave/SocketActivated"]=socketActivated diff --git a/runs/set-current.sh b/runs/set-current.sh index d352d9d76..263b94528 100755 --- a/runs/set-current.sh +++ b/runs/set-current.sh @@ -72,6 +72,17 @@ function setChargingCurrentExtopenwb () { fi } +# function for setting the current - owbpro +# Parameters: +# 1: current +# 2: owbpro1ip + +function setChargingCurrentOwbpro () { + current=$1 + owbpro1ip=$2 + # set desired charging current + curl -s -X POST --data "ampere=$current" $owbpro1ip/connect.php > /dev/null +} # function for setting the current - modbusevse # Parameters: # 1: current @@ -298,7 +309,9 @@ function setChargingCurrent () { if [[ $evsecon == "extopenwb" ]]; then setChargingCurrentExtopenwb $current $chargep1ip $chargep1cp fi - + if [[ $evsecon == "owbpro" ]]; then + setChargingCurrentOwbpro $current $owbpro1ip + fi if [[ $evsecon == "modbusevse" ]]; then if [[ "$modbusevseid" == 0 ]]; then if [ -f /var/www/html/openWB/ramdisk/evsemodulconfig ]; then @@ -498,6 +511,7 @@ if [[ $lastmanagement == "1" ]]; then twcmanagerlp1ip=$twcmanagerlp2ip twcmanagerlp1port=$twcmanagerlp2port twcmanagerlp1httpcontrol=$twcmanagerlp2httpcontrol + owbpro1ip=$owbpro2ip # dirty call (no parameters, all is set above...) if (( lp2enabled == 0 )); then oldcurrent=$current @@ -529,6 +543,7 @@ if [[ $lastmanagements2 == "1" ]]; then ipevseid=$evseidlp3 chargep1ip=$chargep3ip chargep1cp=$chargep3cp + owbpro1ip=$owbpro3ip if (( lp3enabled == 0 )); then oldcurrent=$current current=0 @@ -550,6 +565,8 @@ if [[ $lastmanagementlp4 == "1" ]]; then ipevseid=$evseidlp4 chargep1ip=$chargep4ip chargep1cp=$chargep4cp + owbpro1ip=$owbpro4ip + if (( lp4enabled == 0 )); then oldcurrent=$current current=0 @@ -571,6 +588,8 @@ if [[ $lastmanagementlp5 == "1" ]]; then ipevseid=$evseidlp5 chargep1ip=$chargep5ip chargep1cp=$chargep5cp + owbpro1ip=$owbpro5ip + if (( lp5enabled == 0 )); then oldcurrent=$current current=0 @@ -592,6 +611,7 @@ if [[ $lastmanagementlp6 == "1" ]]; then ipevseid=$evseidlp6 chargep1ip=$chargep6ip chargep1cp=$chargep6cp + owbpro1ip=$owbpro6ip if (( lp6enabled == 0 )); then oldcurrent=$current current=0 @@ -613,6 +633,8 @@ if [[ $lastmanagementlp7 == "1" ]]; then ipevseid=$evseidlp7 chargep1ip=$chargep7ip chargep1cp=$chargep7cp + owbpro1ip=$owbpro7ip + if (( lp7enabled == 0 )); then oldcurrent=$current current=0 @@ -634,6 +656,8 @@ if [[ $lastmanagementlp8 == "1" ]]; then ipevseid=$evseidlp8 chargep1ip=$chargep8ip chargep1cp=$chargep8cp + owbpro1ip=$owbpro8ip + if (( lp8enabled == 0 )); then oldcurrent=$current current=0 diff --git a/runs/u1p3pcheck.sh b/runs/u1p3pcheck.sh index 4476c498f..8a77d6da5 100755 --- a/runs/u1p3pcheck.sh +++ b/runs/u1p3pcheck.sh @@ -15,6 +15,8 @@ if [[ "$1" == "1" ]]; then fi if [[ $evsecon == "goe" ]]; then sudo python runs/u1p3pgoe.py -a $goeiplp1 -p 1 + if [[ $evsecon == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=1" $owbpro1ip/connect.php fi # chargepoint 2 if [[ $lastmanagement == 1 && $evsecons1 == "modbusevse" && $u1p3plp2aktiv == "1" ]]; then @@ -30,10 +32,17 @@ if [[ "$1" == "1" ]]; then if [[ $lastmanagement == 1 && $evsecons1 == "goe" ]]; then sudo python runs/u1p3pgoe.py -a $goeiplp2 -p 1 fi + if [[ $lastmanagement == 1 && $evsecons1 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=1" $owbpro2ip/connect.php + fi + # chargepoint 3 if [[ $lastmanagements2 == 1 && $evsecons2 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep3ip -m "1" fi + if [[ $lastmanagements2 == 1 && $evsecons2 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=1" $owbpro3ip/connect.php + fi if [[ $lastmanagements2 == 1 && $evsecons2 == "ipevse" && $u1p3plp3aktiv == "1" ]]; then sudo python runs/u1p3premote.py -a $evseiplp3 -i $u1p3plp3id -p 1 -d $u1p3ppause fi @@ -47,6 +56,10 @@ if [[ "$1" == "1" ]]; then if [[ $lastmanagementlp4 == 1 && $evseconlp4 == "ipevse" && $u1p3plp4aktiv == "1" ]]; then sudo python runs/u1p3premote.py -a $evseiplp4 -i $u1p3plp4id -p 1 -d $u1p3ppause fi + if [[ $lastmanagementlp4 == 1 && $evseconlp4 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=1" $owbpro4ip/connect.php + fi + # chargepoint 5 if [[ $lastmanagementlp5 == 1 && $evseconlp5 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep5ip -m "1" @@ -54,6 +67,10 @@ if [[ "$1" == "1" ]]; then if [[ $lastmanagementlp5 == 1 && $evseconlp5 == "ipevse" && $u1p3plp5aktiv == "1" ]]; then sudo python runs/u1p3premote.py -a $evseiplp5 -i $u1p3plp5id -p 1 -d $u1p3ppause fi + if [[ $lastmanagementlp5 == 1 && $evseconlp5 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=1" $owbpro5ip/connect.php + fi + # chargepoint 6 if [[ $lastmanagementlp6 == 1 && $evseconlp6 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep6ip -m "1" @@ -61,6 +78,9 @@ if [[ "$1" == "1" ]]; then if [[ $lastmanagementlp6 == 1 && $evseconlp6 == "ipevse" && $u1p3plp6aktiv == "1" ]]; then sudo python runs/u1p3premote.py -a $evseiplp6 -i $u1p3plp6id -p 1 -d $u1p3ppause fi + if [[ $lastmanagementlp6 == 1 && $evseconlp6 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=1" $owbpro6ip/connect.php + fi # chargepoint 7 if [[ $lastmanagementlp7 == 1 && $evseconlp7 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep7ip -m "1" @@ -68,6 +88,10 @@ if [[ "$1" == "1" ]]; then if [[ $lastmanagementlp7 == 1 && $evseconlp7 == "ipevse" && $u1p3plp7aktiv == "1" ]]; then sudo python runs/u1p3premote.py -a $evseiplp7 -i $u1p3plp7id -p 1 -d $u1p3ppause fi + if [[ $lastmanagementlp7 == 1 && $evseconlp7 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=1" $owbpro7ip/connect.php + fi + # chargepoint 8 if [[ $lastmanagementlp8 == 1 && $evseconlp8 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep8ip -m "1" @@ -75,6 +99,10 @@ if [[ "$1" == "1" ]]; then if [[ $lastmanagementlp8 == 1 && $evseconlp8 == "ipevse" && $u1p3plp8aktiv == "1" ]]; then sudo python runs/u1p3premote.py -a $evseiplp8 -i $u1p3plp8id -p 1 -d $u1p3ppause fi + if [[ $lastmanagementlp8 == 1 && $evseconlp8 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=1" $owbpro8ip/connect.php + fi + echo 1 > ramdisk/u1p3pstat fi @@ -91,27 +119,56 @@ if [[ "$1" == "3" ]]; then if [[ $evsecon == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep1ip -m "3" fi + if [[ $evsecon == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=3" $owbpro1ip/connect.php + fi + if [[ $lastmanagement == 1 && $evsecons1 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep2ip -m "3" fi + if [[ $lastmanagement == 1 && $evsecons1 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=3" $owbpro2ip/connect.php + fi + if [[ $lastmanagements2 == 1 && $evsecons2 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep3ip -m "3" fi + if [[ $lastmanagements2 == 1 && $evsecons2 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=3" $owbpro3ip/connect.php + fi + if [[ $lastmanagementlp4 == 1 && $evseconlp4 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep4ip -m "3" fi + if [[ $lastmanagementlp4 == 1 && $evseconlp4 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=3" $owbpro4ip/connect.php + fi if [[ $lastmanagementlp5 == 1 && $evseconlp5 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep5ip -m "3" fi + if [[ $lastmanagementlp5 == 1 && $evseconlp5 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=3" $owbpro5ip/connect.php + fi + if [[ $lastmanagementlp6 == 1 && $evseconlp6 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep6ip -m "3" fi + if [[ $lastmanagementlp6 == 1 && $evseconlp6 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=3" $owbpro6ip/connect.php + fi + if [[ $lastmanagementlp7 == 1 && $evseconlp7 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep7ip -m "3" fi + if [[ $lastmanagementlp7 == 1 && $evseconlp7 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=3" $owbpro7ip/connect.php + fi if [[ $lastmanagementlp8 == 1 && $evseconlp8 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep8ip -m "3" fi + if [[ $lastmanagementlp8 == 1 && $evseconlp8 == "owbpro" ]]; then + curl -s -X POST --data "phasetarget=3" $owbpro8ip/connect.php + fi if [[ $evsecon == "ipevse" ]]; then sudo python runs/u1p3premote.py -a $evseiplp1 -i $u1p3plp2id -p 3 -d $u1p3ppause fi diff --git a/runs/updateConfig.sh b/runs/updateConfig.sh index 0c37983ac..07e7bb8ae 100755 --- a/runs/updateConfig.sh +++ b/runs/updateConfig.sh @@ -1834,6 +1834,16 @@ updateConfig(){ if ! grep -Fq "ssdisplay=" $ConfigFile; then echo "ssdisplay=0" >> $ConfigFile fi + if ! grep -Fq "owbpro1ip=" $ConfigFile; then + echo "owbpro1ip=192.168.1.100" >> $ConfigFile + echo "owbpro2ip=192.168.1.100" >> $ConfigFile + echo "owbpro3ip=192.168.1.100" >> $ConfigFile + echo "owbpro4ip=192.168.1.100" >> $ConfigFile + echo "owbpro5ip=192.168.1.100" >> $ConfigFile + echo "owbpro6ip=192.168.1.100" >> $ConfigFile + echo "owbpro7ip=192.168.1.100" >> $ConfigFile + echo "owbpro8ip=192.168.1.100" >> $ConfigFile + fi if ! grep -Fq "chargep1ip=" $ConfigFile; then echo "chargep1ip=192.168.1.100" >> $ConfigFile fi diff --git a/web/settings/modulconfiglp.php b/web/settings/modulconfiglp.php index e182d3169..4c417f17e 100644 --- a/web/settings/modulconfiglp.php +++ b/web/settings/modulconfiglp.php @@ -84,6 +84,7 @@ + @@ -229,6 +230,21 @@
+
+ +
+
+ +
+ + + Gültige Werte IP Adresse im Format: 192.168.0.12
+
+
+
+
+
+
@@ -2118,6 +2134,7 @@ function display_lp1() { hideSection('#openwbbuchse'); hideSection('#openwbdaemon'); hideSection('#evseconextopenwb'); + hideSection('#evseconowbpro'); hideSection('#evseconmqtt'); if($('#evsecon').val() == 'modbusevse') { @@ -2148,6 +2165,9 @@ function display_lp1() { if($('#evsecon').val() == 'extopenwb') { showSection('#evseconextopenwb'); } + if($('#evsecon').val() == 'owbpro') { + showSection('#evseconowbpro'); + } if($('#evsecon').val() == 'daemon') { showSection('#openwbdaemon'); } @@ -2430,6 +2450,7 @@ function display_socmodul() { + @@ -2472,6 +2493,21 @@ function display_socmodul() {
+
+ +
+
+ +
+ + + Gültige Werte IP Adresse im Format: 192.168.0.12
+
+
+
+
+
+
@@ -4102,6 +4138,7 @@ function display_lp2() { hideSection('#openwb12s1v1'); hideSection('#openwb12s1v2'); hideSection('#evseconextopenwblp2'); + hideSection('#evseconowbprolp2'); hideSection('#evsecondaemonlp2'); hideSection('#evseconipevselp2'); hideSection('#evseconmqtts1'); @@ -4142,6 +4179,10 @@ function display_lp2() { if($('#evsecons1').val() == 'extopenwb') { showSection('#evseconextopenwblp2'); } + if($('#evsecons1').val() == 'owbpro') { + showSection('#evseconowbprolp2'); + } + if($('#evsecons1').val() == 'daemon') { showSection('#evsecondaemonlp2'); } @@ -4418,6 +4459,7 @@ function display_lastmanagement() { +
+
+ +
+ + + Gültige Werte IP Adresse im Format: 192.168.0.12
+
+
+
+
+
+
@@ -4763,6 +4820,7 @@ function display_lp3 () { hideSection('#evsecongoes2'); hideSection('#evseconipevselp3'); hideSection('#evseconextopenwblp3'); + hideSection('#evseconowbprolp3'); hideSection('#evseconthirdeth'); hideSection('#evseconmqtts2'); @@ -4790,6 +4848,9 @@ function display_lp3 () { if($('#evsecons2').val() == 'extopenwb') { showSection('#evseconextopenwblp3'); } + if($('#evsecons2').val() == 'owbpro') { + showSection('#evseconowbprolp3'); + } if($('#evsecons2').val() == 'goe') { showSection('#evsecongoes2'); } @@ -4890,6 +4951,7 @@ function display_llmp3 () { @@ -4916,6 +4978,20 @@ function display_llmp3 () {
+
+
+
+ +
+ + + Gültige Werte IP Adresse im Format: 192.168.0.12
+
+
+
+
+
+
@@ -4957,7 +5033,10 @@ function display_llmp3 () { function display_lp () { hideSection('#evseconipevselp'); hideSection('#evseconextopenwblp'); - + hideSection('#evseconowbprolp'); + if($('#evseconlp').val() == 'owbpro') { + showSection('#evseconowbprolp'); + } if($('#evseconlp').val() == 'extopenwb') { showSection('#evseconextopenwblp'); } diff --git a/web/themes/colors/chargePointList.js b/web/themes/colors/chargePointList.js index b836c55c9..0085fc78f 100644 --- a/web/themes/colors/chargePointList.js +++ b/web/themes/colors/chargePointList.js @@ -72,6 +72,8 @@ class ChargePointList { .style("text-align", "center") .text("Aktueller Strompreis: " + wbdata.etPrice + " ct/kWh"); } + + d3.select ("div#chargePointConfigWidget").classed ("hide", (wbdata.chargeMode != "0" && wbdata.chargeMode != "1")) } updateValues() { diff --git a/web/themes/colors/powerdata.js b/web/themes/colors/powerdata.js index 5414cf57f..22dac12f0 100644 --- a/web/themes/colors/powerdata.js +++ b/web/themes/colors/powerdata.js @@ -184,6 +184,8 @@ class WbData { powerMeter.update(); break; case 'currentPowerPrice': + case 'chargeMode': + priceChart.update(); chargePointList.update(); default: break; diff --git a/web/themes/colors/pricechart.js b/web/themes/colors/pricechart.js index 5accc8c28..422359635 100644 --- a/web/themes/colors/pricechart.js +++ b/web/themes/colors/pricechart.js @@ -103,8 +103,13 @@ class PriceChart { xAxis.attr("transform", "translate(" + this.margin.left + "," + (height + this.margin.top) + ")"); xAxis.selectAll(".tick") .attr("font-size", 8) - .attr("color", "white"); - + .attr("color", this.bgColor); + xAxis.selectAll(".tick line") + .attr("stroke", this.bgColor) + .attr("stroke-width", "0.5"); + xAxis.select(".domain") + .attr("stroke", this.bgColor) + ; // Y Axis const yAxisGenerator = d3.axisLeft(this.yScale) .ticks(6) @@ -118,7 +123,7 @@ class PriceChart { yAxis.attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")"); yAxis.selectAll(".tick") .attr("font-size", 8) - .attr("color", "white"); + .attr("color", this.bgColor); yAxis.selectAll(".tick line") .attr("stroke", this.bgColor) diff --git a/web/themes/colors/style.css b/web/themes/colors/style.css index 2e134989c..a294d729e 100644 --- a/web/themes/colors/style.css +++ b/web/themes/colors/style.css @@ -185,6 +185,9 @@ h2 { h3 { font-size: 1.2rem; } +h4 { + font-size: 0.9rem; +} .verySmallTextSize { font-size: 0.8rem; @@ -226,6 +229,10 @@ h3 { font-size: 1.7rem; } + h4 { + font-size: 1.2rem; + } + .verySmallTextSize { font-size: 1.0rem; } @@ -273,6 +280,10 @@ h3 { font-size: 1.1rem; } + h4 { + font-size: 0.9rem; + } + .verySmallTextSize { font-size: 1.0rem; } @@ -311,9 +322,13 @@ h3 { } h3 { - font-size: 1.1rem; + font-size: 1.0rem; } + h4 { + font-size: 0.9rem; + } + .verySmallTextSize { font-size: 1.0rem; } diff --git a/web/themes/colors/theme.html b/web/themes/colors/theme.html index b4af43f82..f8448d5cc 100644 --- a/web/themes/colors/theme.html +++ b/web/themes/colors/theme.html @@ -77,7 +77,6 @@ #thegraph>div { height: 350px; } - @@ -236,7 +235,8 @@

Energie heute

-
+ +

Ladepunkte

@@ -246,9 +246,67 @@

Ladepunkte

+
+
+ + +
+

Speicher

+
+
+
+
+ + +
+

Geräte

+
+
+
+
+ + +
+

Preisbasiertes Laden

+
+
+
+
+
+
+
+ + +
+
+ +
+
+ +
+
+ +
+
+
+
+ + +
+
+
+
+
+ + +
+

Einstellungen Ladepunkte

+
-

Minimal Stromstärke

@@ -264,42 +322,6 @@

Minimal Stromstärke

- - -
-
-
-

Preisbasiertes Laden

-
-
-
-
-
-
-
-
- - -
- -
-
-
- -
-
- -
-
- -
-
-
- -

Sofortladen Stromstärke

@@ -370,7 +392,6 @@

Sofortladen Stromstärke

-

Lademengenbegrenzung

@@ -420,7 +441,6 @@

Lademengenbegrenzung

-

Lademengenbegrenzung

@@ -470,7 +490,6 @@

Lademengenbegrenzung

-

Lademengenbegrenzung

@@ -509,7 +528,6 @@

Lademengenbegrenzung

-

Lademengenbegrenzung

@@ -548,7 +566,6 @@

Lademengenbegrenzung

-

Lademengenbegrenzung

@@ -587,7 +604,6 @@

Lademengenbegrenzung

-

Lademengenbegrenzung

@@ -626,7 +642,6 @@

Lademengenbegrenzung

-

Lademengenbegrenzung

@@ -665,7 +680,6 @@

Lademengenbegrenzung

-

Lademengenbegrenzung

@@ -704,28 +718,9 @@

Lademengenbegrenzung

-
-
-
- - - - -
-

Speicher

-
-
-
- -
-
-

Geräte

-
-
-
@@ -1065,7 +1060,7 @@ var element = $('#' + $.escapeSelector(elementId)); var label = $('label[for="' + elementId + '"].valueLabel'); label.addClass('text-danger'); - + delayUserInput(elementId, function (id) { // gets executed on callback, 2000ms after last input-change // changes label color back to normal and sends input-value by mqtt From d0b0eba9c5b66e1a6f4726f63706c96fd665a54a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Mon, 13 Dec 2021 20:56:03 +0100 Subject: [PATCH 53/66] fix merge --- runs/u1p3pcheck.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/runs/u1p3pcheck.sh b/runs/u1p3pcheck.sh index 8a77d6da5..9139e3ced 100755 --- a/runs/u1p3pcheck.sh +++ b/runs/u1p3pcheck.sh @@ -15,6 +15,7 @@ if [[ "$1" == "1" ]]; then fi if [[ $evsecon == "goe" ]]; then sudo python runs/u1p3pgoe.py -a $goeiplp1 -p 1 + fi if [[ $evsecon == "owbpro" ]]; then curl -s -X POST --data "phasetarget=1" $owbpro1ip/connect.php fi From 325a45b411ae87ddf0938efb043ccba91868d941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Mon, 13 Dec 2021 21:10:44 +0100 Subject: [PATCH 54/66] fix merge again *argl* --- runs/u1p3pcheck.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/runs/u1p3pcheck.sh b/runs/u1p3pcheck.sh index 8a47a99c3..9139e3ced 100755 --- a/runs/u1p3pcheck.sh +++ b/runs/u1p3pcheck.sh @@ -13,12 +13,9 @@ if [[ "$1" == "1" ]]; then if [[ $evsecon == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep1ip -m "1" fi -<<<<<<< HEAD if [[ $evsecon == "goe" ]]; then sudo python runs/u1p3pgoe.py -a $goeiplp1 -p 1 fi -======= ->>>>>>> 3764f02bcb4061392c2a6b174ccb2c63209aa699 if [[ $evsecon == "owbpro" ]]; then curl -s -X POST --data "phasetarget=1" $owbpro1ip/connect.php fi @@ -33,12 +30,9 @@ if [[ "$1" == "1" ]]; then if [[ $lastmanagement == 1 && $evsecons1 == "extopenwb" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h $chargep2ip -m "1" fi -<<<<<<< HEAD if [[ $lastmanagement == 1 && $evsecons1 == "goe" ]]; then sudo python runs/u1p3pgoe.py -a $goeiplp2 -p 1 fi -======= ->>>>>>> 3764f02bcb4061392c2a6b174ccb2c63209aa699 if [[ $lastmanagement == 1 && $evsecons1 == "owbpro" ]]; then curl -s -X POST --data "phasetarget=1" $owbpro2ip/connect.php fi From 0da57aa541d4482f57b0599bf31d7617f5acfd08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= Date: Sat, 18 Dec 2021 08:41:08 +0100 Subject: [PATCH 55/66] wr_http: fix use http module from packages and convert pv-num to int --- modules/wr_http/main.sh | 2 +- packages/modules/http/device.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/wr_http/main.sh b/modules/wr_http/main.sh index e88ef2471..ab377bf19 100755 --- a/modules/wr_http/main.sh +++ b/modules/wr_http/main.sh @@ -16,7 +16,7 @@ else fi -python3 ${OPENWBBASEDIR}/packages/modules/openwb/device.py "inverter" "${wr_http_w_url}" "${wr_http_kwh_url}" "1">>${MYLOGFILE} 2>&1 +python3 ${OPENWBBASEDIR}/packages/modules/http/device.py "inverter" "${wr_http_w_url}" "${wr_http_kwh_url}" "1">>${MYLOGFILE} 2>&1 pvwatt=$(<${RAMDISKDIR}/pvwatt) echo $pvwatt diff --git a/packages/modules/http/device.py b/packages/modules/http/device.py index b320c1bf1..b48464b0d 100644 --- a/packages/modules/http/device.py +++ b/packages/modules/http/device.py @@ -106,7 +106,7 @@ def read_legacy(argv: List[str]) -> None: "power_path": __extract_url_path(argv[2]), "counter_path": __extract_url_path(argv[3]), } - num = argv[4] + num = int(argv[4]) else: raise Exception( "illegal component type " + component_type + ". Allowed values: " + From 1cf3679f3f8bd1d5c12d41ab3fe1c17430e9ce37 Mon Sep 17 00:00:00 2001 From: matzempc Date: Mon, 20 Dec 2021 16:42:20 +0100 Subject: [PATCH 56/66] fix: http device dictionary access --- packages/modules/http/counter.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/modules/http/counter.py b/packages/modules/http/counter.py index d781ad524..fff3436cb 100644 --- a/packages/modules/http/counter.py +++ b/packages/modules/http/counter.py @@ -25,11 +25,11 @@ def get_default_config() -> dict: class HttpCounter: def __init__(self, component_config: dict, domain: str) -> None: - self.__get_power_all = create_request_function(domain, component_config["power_all_path"]) - self.__get_imported = create_request_function(domain, component_config["imported_path"]) - self.__get_exported = create_request_function(domain, component_config["exported_path"]) + self.__get_power_all = create_request_function(domain, component_config["configuration"]["power_all_path"]) + self.__get_imported = create_request_function(domain, component_config["configuration"]["imported_path"]) + self.__get_exported = create_request_function(domain, component_config["configuration"]["exported_path"]) self.__get_powers = [ - create_request_function(domain, component_config["power_l" + str(i) + "_path"]) for i in range(1, 4) + create_request_function(domain, component_config["configuration"]["power_l" + str(i) + "_path"]) for i in range(1, 4) ] self.component_config = component_config From ab5881df4c9cadd15ba6aa49351cc531246f7004 Mon Sep 17 00:00:00 2001 From: matzempc Date: Tue, 10 May 2022 16:28:40 +0200 Subject: [PATCH 57/66] fix(goe): prevent continously reset of current when llsoll (wanted current) is zero --- goecheck.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index 1db29202c..baf98cf7f 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -25,7 +25,7 @@ goecheck(){ fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") oldcurrent=$(echo $output | jq -r '.amp') current=$(= 40)) ; then curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=amx=$current > /dev/null else @@ -48,7 +48,7 @@ goecheck(){ fi oldcurrent=$(echo $output | jq -r '.amp') current=$( /dev/null fi fi @@ -76,7 +76,7 @@ goecheck(){ fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") oldcurrent=$(echo $output | jq -r '.amp') current=$(= 40)) ; then curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/mqtt?payload=amx=$current > /dev/null else @@ -99,7 +99,7 @@ goecheck(){ fi oldcurrent=$(echo $output | jq -r '.amp') current=$( /dev/null fi fi @@ -127,7 +127,7 @@ goecheck(){ fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") oldcurrent=$(echo $output | jq -r '.amp') current=$(= 40)) ; then curl --silent --connect-timeout $goetimeoutlp3 -s http://$goeiplp3/mqtt?payload=amx=$current > /dev/null else @@ -150,7 +150,7 @@ goecheck(){ fi oldcurrent=$(echo $output | jq -r '.amp') current=$( /dev/null fi fi From 1e127dd85a5229ef08a8cb9507e1cdeeab18a04e Mon Sep 17 00:00:00 2001 From: matzempc Date: Thu, 12 May 2022 14:44:13 +0200 Subject: [PATCH 58/66] u1p3p: only switch from 3 to 1 phase if either a car is loading or really uberschuss isn't enough for 3 phases WHY: currently if no car is loading and enough uberschuss is there it is continously switched between 1 and 3 phases cause there are different criterias (1to3: enough uberschuess, 3to1: llsoll==minimalapv) --- u1p3p.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/u1p3p.sh b/u1p3p.sh index c262de230..02c75536e 100644 --- a/u1p3p.sh +++ b/u1p3p.sh @@ -222,7 +222,7 @@ u1p3pswitch(){ openwbDebugLog "MAIN" 1 "auf 1 Phasen MinPV Automatik geaendert da geringerer Überschuss" fi fi - if (( oldll == minimalampv )); then + if (((( oldll == minimalampv )) && (( ladeleistung > 100 )))) || (( uberschuss < 3 * mindestuberschuss )); then urcounter=$( 100 )); then uhcounter=$( 100 )))) || ((uberschuss < 3 * mindestuberschuss)); then urcounter=$( Date: Thu, 12 May 2022 15:30:45 +0200 Subject: [PATCH 59/66] u1p3p: avoid switching only when loading check not necessary for 1to3 phase cause current only increased before WHEN loading --- u1p3p.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/u1p3p.sh b/u1p3p.sh index 02c75536e..8b3691c7c 100644 --- a/u1p3p.sh +++ b/u1p3p.sh @@ -281,7 +281,7 @@ u1p3pswitch(){ openwbDebugLog "MAIN" 1 "auf 3 Phasen NurPV Automatik geaendert" fi fi - if (( oldll == maximalstromstaerke )) && (( ladeleistung > 100 )); then + if (( oldll == maximalstromstaerke )); then uhcounter=$( Date: Thu, 12 May 2022 20:13:29 +0200 Subject: [PATCH 60/66] goecheck: beautification --- goecheck.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index baf98cf7f..73fd345f6 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -25,7 +25,7 @@ goecheck(){ fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") oldcurrent=$(echo $output | jq -r '.amp') current=$(= 40)) ; then curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/mqtt?payload=amx=$current > /dev/null else @@ -48,7 +48,7 @@ goecheck(){ fi oldcurrent=$(echo $output | jq -r '.amp') current=$( /dev/null fi fi @@ -76,7 +76,7 @@ goecheck(){ fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") oldcurrent=$(echo $output | jq -r '.amp') current=$(= 40)) ; then curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/mqtt?payload=amx=$current > /dev/null else @@ -99,7 +99,7 @@ goecheck(){ fi oldcurrent=$(echo $output | jq -r '.amp') current=$( /dev/null fi fi From 299fd9d4501aa6f61a3ff3c92a480ee6a700e829 Mon Sep 17 00:00:00 2001 From: matzempc Date: Fri, 13 May 2022 13:19:10 +0200 Subject: [PATCH 61/66] u1p3pcheck: check for uberschuss on reducing not necessary in case of minimalpv check --- u1p3p.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/u1p3p.sh b/u1p3p.sh index 8b3691c7c..f24bcd308 100644 --- a/u1p3p.sh +++ b/u1p3p.sh @@ -222,7 +222,7 @@ u1p3pswitch(){ openwbDebugLog "MAIN" 1 "auf 1 Phasen MinPV Automatik geaendert da geringerer Überschuss" fi fi - if (((( oldll == minimalampv )) && (( ladeleistung > 100 )))) || (( uberschuss < 3 * mindestuberschuss )); then + if (( oldll == minimalampv )) && (( ladeleistung > 100 )); then urcounter=$( 100 )))) || ((uberschuss < 3 * mindestuberschuss)); then + if (( oldll == minimalapv )) && (( ladeleistung > 100 )); then urcounter=$( Date: Tue, 17 May 2022 20:35:50 +0200 Subject: [PATCH 62/66] fix http module crash: initialization of device_config done after first usage/access, wrong check for port on creating URL --- packages/modules/http/device.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/modules/http/device.py b/packages/modules/http/device.py index a1a42503b..cd2f5101a 100644 --- a/packages/modules/http/device.py +++ b/packages/modules/http/device.py @@ -39,11 +39,12 @@ class Device(AbstractDevice): def __init__(self, device_config: dict) -> None: self._components = {} # type: Dict[str, http_component_classes] try: + self.device_config = device_config port = self.device_config["configuration"]["port"] self.domain = self.device_config["configuration"]["protocol"] + \ - "://" + self.device_config["configuration"]["domain"] + \ - ":" + port if port else "" - self.device_config = device_config + "://" + self.device_config["configuration"]["domain"] + if port is not None: + self.domain = self.domain + ":" + port except Exception: log.MainLogger().exception("Fehler im Modul "+device_config["name"]) @@ -106,7 +107,10 @@ def create_legacy_device_config(url: str): device_config = get_default_config() device_config["configuration"]["protocol"] = parsed_url.scheme device_config["configuration"]["domain"] = parsed_url.hostname - device_config["configuration"]["port"] = str(parsed_url.port) + if parsed_url.port is not None: + device_config["configuration"]["port"] = str(parsed_url.port) + else: + device_config["configuration"]["port"] = None return device_config From 11c7e4295899861bf8a7edb8ccfccf6615fd3834 Mon Sep 17 00:00:00 2001 From: matzempc Date: Thu, 19 May 2022 08:57:31 +0200 Subject: [PATCH 63/66] fix(set-current): fixed merge --- runs/set-current.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/runs/set-current.sh b/runs/set-current.sh index 72513a421..88c2ee385 100755 --- a/runs/set-current.sh +++ b/runs/set-current.sh @@ -201,7 +201,6 @@ function setChargingCurrenthttp () { # 3: goeiplp1 function setChargingCurrentgoe () { if [[ $evsecon == "goe" ]]; then -<<<<<<< HEAD output=$(curl --connect-timeout "$goetimeoutlp1" -s "http://$goeiplp1/status") #check whether goe has 1to3phase switch capability => new HWV3 and new API V2 digit='^[0-9]$' From 8906be2a65d3198d04724cdf6c6d2c6127f06614 Mon Sep 17 00:00:00 2001 From: matzempc Date: Thu, 19 May 2022 09:44:44 +0200 Subject: [PATCH 64/66] chore(u1p3pcheck): fix - added goelp3 for 1 phase change, beautification on parameters, verbose output on goe switching enabled --- runs/u1p3pcheck.sh | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/runs/u1p3pcheck.sh b/runs/u1p3pcheck.sh index c363742c1..7c9fe69b4 100755 --- a/runs/u1p3pcheck.sh +++ b/runs/u1p3pcheck.sh @@ -14,7 +14,7 @@ if [[ "$1" == "1" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h "$chargep1ip" -m "1" fi if [[ $evsecon == "goe" ]]; then - sudo python runs/u1p3pgoe.py -a $goeiplp1 -p 1 + sudo python runs/u1p3pgoe.py -v -a "$goeiplp1" -p 1 fi if [[ $evsecon == "owbpro" ]]; then curl -s -X POST --data "phasetarget=1" "$owbpro1ip/connect.php" @@ -32,7 +32,7 @@ if [[ "$1" == "1" ]]; then mosquitto_pub -r -t openWB/set/isss/U1p3p -h "$chargep2ip" -m "1" fi if [[ $lastmanagement == 1 && $evsecons1 == "goe" ]]; then - sudo python runs/u1p3pgoe.py -a $goeiplp2 -p 1 + sudo python runs/u1p3pgoe.py -v -a "$goeiplp2" -p 1 fi if [[ $lastmanagement == 1 && $evsecons1 == "owbpro" ]]; then curl -s -X POST --data "phasetarget=1" "$owbpro2ip/connect.php" @@ -48,6 +48,9 @@ if [[ "$1" == "1" ]]; then if [[ $lastmanagements2 == 1 && $evsecons2 == "ipevse" && $u1p3plp3aktiv == "1" ]]; then sudo python runs/u1p3premote.py -a "$evseiplp3" -i "$u1p3plp3id" -p 1 -d "$u1p3ppause" fi + if [[ $lastmanagements2 == 1 && $evsecons2 == "goe" ]]; then + sudo python runs/u1p3pgoe.py -v -a "$goeiplp3" -p 1 + fi # chargepoint 4 if [[ $lastmanagementlp4 == 1 && $evseconlp4 == "extopenwb" ]]; then @@ -198,13 +201,13 @@ if [[ "$1" == "3" ]]; then sudo python runs/u1p3premote.py -a "$evseiplp8" -i "$u1p3plp8id" -p 3 -d "$u1p3ppause" fi if [[ $evsecon == "goe" ]]; then - sudo python runs/u1p3pgoe.py -a $goeiplp1 -p 3 -m $minimalapv + sudo python runs/u1p3pgoe.py -v -a "$goeiplp1" -p 3 -m "$minimalapv" fi if [[ $lastmanagement == 1 && $evsecons1 == "goe" ]]; then - sudo python runs/u1p3pgoe.py -a $goeiplp2 -p 3 -m $minimalapv + sudo python runs/u1p3pgoe.py -v -a "$goeiplp2" -p 3 -m "$minimalapv" fi if [[ $lastmanagements2 == 1 && $evsecons2 == "goe" ]]; then - sudo python runs/u1p3pgoe.py -a $goeiplp3 -p 3 -m $minimalapv + sudo python runs/u1p3pgoe.py -v -a "$goeiplp3" -p 3 -m "$minimalapv" fi echo 3 > ramdisk/u1p3pstat fi @@ -227,7 +230,7 @@ if [[ "$1" == "stop" ]]; then fi #if [[ $evsecon == "goe" ]]; then # oldll=$( ramdisk/tmpllsoll + # echo "$oldll" > ramdisk/tmpllsoll # runs/set-current.sh 0 m #fi if [[ $lastmanagement == 1 && $evsecons1 == "daemon" ]]; then @@ -242,7 +245,7 @@ if [[ "$1" == "stop" ]]; then fi #if [[ $lastmanagement == 1 && $evsecons1 == "goe" ]]; then # oldlls1=$( ramdisk/tmpllsolls1 + # echo "$oldlls1" > ramdisk/tmpllsolls1 # runs/set-current.sh 0 s1 #fi if [[ $lastmanagements2 == 1 && $evsecons2 == "extopenwb" ]]; then @@ -252,7 +255,7 @@ if [[ "$1" == "stop" ]]; then fi #if [[ $lastmanagements2 == 1 && $evsecons2 == "goe" ]]; then # oldlls2=$( ramdisk/tmpllsolls2 + # echo "$oldlls2" > ramdisk/tmpllsolls2 # runs/set-current.sh 0 s2 #fi if [[ $lastmanagementlp4 == 1 && $evseconlp4 == "extopenwb" ]]; then From aa1687623404303bf3e90f3a8d5a8ae3ede96024 Mon Sep 17 00:00:00 2001 From: matzempc Date: Tue, 31 May 2022 21:16:21 +0200 Subject: [PATCH 65/66] goecheck: fix merge --- goecheck.sh | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index 1d2697584..73fd345f6 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -73,7 +73,6 @@ goecheck(){ curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/mqtt?payload=alw=0 > /dev/null fi fi -<<<<<<< HEAD fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") oldcurrent=$(echo $output | jq -r '.amp') current=$( /dev/null -======= - fi - fwv=$(echo $output | jq -r '.fwv' | grep -Po "[1-9]\d{1,2}") - oldcurrent=$(echo $output | jq -r '.amp') - current=$(= 40)) ; then - curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/mqtt?payload=amx=$current > /dev/null - else - curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/mqtt?payload=amp=$current > /dev/null ->>>>>>> snaptec-master fi fi fi From b7e5f941f237747870817347adb3706bc0024f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mo=C3=9Fner?= <46440437+matzempc@users.noreply.github.com> Date: Tue, 5 Jul 2022 08:37:47 +0200 Subject: [PATCH 66/66] fix(goecheck): HW3 - set force to 1 (disabled) also on frc=2 frc=2 means force enabled and may also occur. In this case till now go-e was left charging --- goecheck.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/goecheck.sh b/goecheck.sh index 73fd345f6..33c1600ae 100644 --- a/goecheck.sh +++ b/goecheck.sh @@ -42,7 +42,7 @@ goecheck(){ fi fi if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatus"; then - if ((state == "0")) ; then + if (( state == "0" )) || (( state == "2" )) ; then curl --silent --connect-timeout $goetimeoutlp1 -s http://$goeiplp1/api/set?frc=1 > /dev/null fi fi @@ -93,7 +93,7 @@ goecheck(){ fi fi if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatuss1"; then - if ((state == "0")) ; then + if (( state == "0" )) || (( state == "2" )) ; then curl --silent --connect-timeout $goetimeoutlp2 -s http://$goeiplp2/api/set?frc=1 > /dev/null fi fi @@ -139,12 +139,12 @@ goecheck(){ state=$(echo $output | jq -r '.frc') if grep -q 1 "/var/www/html/openWB/ramdisk/ladestatuss2"; then lp3enabled=$( /dev/null fi fi if grep -q 0 "/var/www/html/openWB/ramdisk/ladestatuss2"; then - if ((state == "0")) ; then + if (( state == "0" )) || (( state == "2" )) ; then curl --silent --connect-timeout $goetimeoutlp3 -s http://$goeiplp3/api/set?frc=1 > /dev/null fi fi