diff --git a/loadvars.sh b/loadvars.sh index 804e456a0..4c7c3f205 100755 --- a/loadvars.sh +++ b/loadvars.sh @@ -1092,7 +1092,7 @@ loadvars(){ fi echo $hausverbrauch > /var/www/html/openWB/ramdisk/hausverbrauch usesimbezug=0 - if [[ $wattbezugmodul == "bezug_solarwatt" ]]|| [[ $wattbezugmodul == "bezug_rct" ]]|| [[ $wattbezugmodul == "bezug_varta" ]] || [[ $wattbezugmodul == "bezug_kostalplenticoreem300haus" ]] || [[ $wattbezugmodul == "bezug_solarlog" ]] ; then + if [[ $wattbezugmodul == "bezug_solarwatt" ]]|| [[ $wattbezugmodul == "bezug_rct" ]]|| [[ $wattbezugmodul == "bezug_kostalplenticoreem300haus" ]] || [[ $wattbezugmodul == "bezug_solarlog" ]] ; then usesimbezug=1 fi if ((usesimbezug == 1)); then @@ -1182,7 +1182,7 @@ loadvars(){ echo "$pvallwh" > /var/www/html/openWB/ramdisk/pvallwh fi - if [[ $speichermodul == "speicher_tesvoltsma" ]] || [[ $speichermodul == "speicher_solarwatt" ]] || [[ $speichermodul == "speicher_rct" ]]|| [[ $speichermodul == "speicher_kostalplenticore" ]] || [[ $speichermodul == "speicher_varta" ]] ; then + if [[ $speichermodul == "speicher_tesvoltsma" ]] || [[ $speichermodul == "speicher_solarwatt" ]] || [[ $speichermodul == "speicher_rct" ]]|| [[ $speichermodul == "speicher_kostalplenticore" ]] ; then ra='^-?[0-9]+$' watt2=$(>"${MYLOGFILE}" 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.kostal_sem.device" "${ksemip}" >>"${MYLOGFILE}" 2>&1 ret=$? openwbDebugLog ${DMOD} 2 "EVU RET: ${ret}" diff --git a/modules/bezug_ksem/readksem.py b/modules/bezug_ksem/readksem.py old mode 100755 new mode 100644 index 4706b3df7..e69de29bb --- a/modules/bezug_ksem/readksem.py +++ b/modules/bezug_ksem/readksem.py @@ -1,103 +0,0 @@ -#!/usr/bin/python -from typing import List - -from pymodbus.client.sync import ModbusTcpClient -from pymodbus.constants import Endian -from pymodbus.payload import BinaryPayloadDecoder - -from helpermodules.cli import run_using_positional_cli_args - - -class KSEM: - def __init__(self, ip): - self.client = ModbusTcpClient(ip, port="502") - - def ReadUInt32(self, addr): - data = self.client.read_holding_registers(addr, 2, unit=71) - UInt32register = BinaryPayloadDecoder.fromRegisters(data.registers, byteorder=Endian.Big, wordorder=Endian.Big) - result = UInt32register.decode_32bit_uint() - return(result) - - def ReadInt32(self, addr): - data = self.client.read_holding_registers(addr, 2, unit=71) - Int32register = BinaryPayloadDecoder.fromRegisters(data.registers, byteorder=Endian.Big, wordorder=Endian.Big) - result = Int32register.decode_32bit_int() - return(result) - - def ReadUInt64(self, addr): - data = self.client.read_holding_registers(addr, 4, unit=71) - UInt64register = BinaryPayloadDecoder.fromRegisters(data.registers, byteorder=Endian.Big, wordorder=Endian.Big) - result = UInt64register.decode_64bit_uint() - return(result) - - def write(self, filename, value): - with open(filename, 'w') as file: - file.write(str(value)) - - def run(self): - with self.client: - voltage1 = self.ReadUInt32(62) * 0.001 - self.write('/var/www/html/openWB/ramdisk/evuv1', voltage1) - - voltage2 = self.ReadUInt32(102) * 0.001 - self.write('/var/www/html/openWB/ramdisk/evuv2', voltage2) - - voltage3 = self.ReadUInt32(142) * 0.001 - self.write('/var/www/html/openWB/ramdisk/evuv3', voltage3) - - bezugkwh = self.ReadUInt64(512) * 0.1 - self.write('/var/www/html/openWB/ramdisk/bezugkwh', bezugkwh) - - bezugw1p = self.ReadUInt32(40) * 0.1 - bezugw1m = self.ReadUInt32(42) * 0.1 - bezugw1 = bezugw1p if bezugw1p >= bezugw1m else -bezugw1m - self.write('/var/www/html/openWB/ramdisk/bezugw1', bezugw1) - - bezugw2p = self.ReadUInt32(80) * 0.1 - bezugw2m = self.ReadUInt32(82) * 0.1 - bezugw2 = bezugw2p if bezugw2p >= bezugw2m else -bezugw2m - self.write('/var/www/html/openWB/ramdisk/bezugw2', bezugw2) - - bezugw3p = self.ReadUInt32(120) * 0.1 - bezugw3m = self.ReadUInt32(122) * 0.1 - bezugw3 = bezugw3p if bezugw3p >= bezugw3m else -bezugw3m - self.write('/var/www/html/openWB/ramdisk/bezugw3', bezugw3) - - bezuga1 = self.ReadUInt32(60) * 0.001 - self.write('/var/www/html/openWB/ramdisk/bezuga1', bezuga1) - - bezuga2 = self.ReadUInt32(100) * 0.001 - self.write('/var/www/html/openWB/ramdisk/bezuga2', bezuga2) - - bezuga3 = self.ReadUInt32(140) * 0.001 - self.write('/var/www/html/openWB/ramdisk/bezuga3', bezuga3) - - wattbezugp = self.ReadUInt32(0) * 0.1 - wattbezugm = self.ReadUInt32(2) * 0.1 - wattbezug = wattbezugp if wattbezugp >= wattbezugm else -wattbezugm - finalwattbezug = int(wattbezug) - self.write('/var/www/html/openWB/ramdisk/wattbezug', finalwattbezug) - - einspeisungkwh = self.ReadUInt64(516) * 0.1 - self.write('/var/www/html/openWB/ramdisk/einspeisungkwh', einspeisungkwh) - - evuhz = self.ReadUInt32(26) * 0.001 - self.write('/var/www/html/openWB/ramdisk/evuhz', evuhz) - - evupf1 = self.ReadInt32(64) * 0.001 - self.write('/var/www/html/openWB/ramdisk/evupf1', evupf1) - - evupf2 = self.ReadInt32(104) * 0.001 - self.write('/var/www/html/openWB/ramdisk/evupf2', evupf2) - - evupf3 = self.ReadInt32(144) * 0.001 - self.write('/var/www/html/openWB/ramdisk/evupf3', evupf3) - - -def update(ksemip: str): - runner = KSEM(ksemip) - runner.run() - - -def main(argv: List[str]): - run_using_positional_cli_args(update, argv) diff --git a/modules/bezug_smartme/main.sh b/modules/bezug_smartme/main.sh index 7cff2231d..a1b7fb42f 100755 --- a/modules/bezug_smartme/main.sh +++ b/modules/bezug_smartme/main.sh @@ -14,7 +14,7 @@ openwbDebugLog ${DMOD} 2 "Bezug Smartme URL: ${bezug_smartme_url}" openwbDebugLog ${DMOD} 2 "Bezug Smartme User : ${bezug_smartme_user}" openwbDebugLog ${DMOD} 2 "Bezug Smartme Passwort: ${bezug_smartme_pass}" -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "bezug_smartme.smartme" "${bezug_smartme_url}" "${bezug_smartme_user}" "${bezug_smartme_pass}" >>"$MYLOGFILE" 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.smart_me.device" "counter" "${bezug_smartme_user}" "${bezug_smartme_pass}" "${bezug_smartme_url}" >>"$MYLOGFILE" 2>&1 ret=$? openwbDebugLog ${DMOD} 2 "RET: ${ret}" diff --git a/modules/bezug_smartme/smartme.py b/modules/bezug_smartme/smartme.py old mode 100755 new mode 100644 index fcac1a53d..e69de29bb --- a/modules/bezug_smartme/smartme.py +++ b/modules/bezug_smartme/smartme.py @@ -1,110 +0,0 @@ -#!/usr/bin/env python3 -import logging -import re -import requests -import traceback -from typing import Dict, List - -from helpermodules.cli import run_using_positional_cli_args - -log = logging.getLogger("SmartMe EVU") - - -def get_power_value(key, response: Dict, file=None): - try: - value = int(response[key] * 1000) - if file is None: - return value - else: - log.debug(file+': ' + str(value)) - f = open('/var/www/html/openWB/ramdisk/'+file, 'w') - f.write(str(value)) - f.close() - except: - traceback.print_exc() - exit(1) - - -def get_im_ex_value(key, response: Dict, file): - try: - value = round(response[key] * 1000, 3) - log.debug(file+': ' + str(value)) - f = open('/var/www/html/openWB/ramdisk/'+file, 'w') - f.write(str(value)) - f.close() - except: - traceback.print_exc() - exit(1) - - -def get_value(key, response: Dict, file=None): - try: - value = response[key] - if file is None: - return value - else: - log.debug(file+': ' + str(value)) - f = open('/var/www/html/openWB/ramdisk/'+file, 'w') - f.write(str(value)) - f.close() - except: - traceback.print_exc() - exit(1) - - -def update(bezug_smartme_url: str, bezug_smartme_user: str, bezug_smartme_pass: str): - log.debug('Smartme URL: ' + bezug_smartme_url) - log.debug('Smartme User: ' + bezug_smartme_user) - log.debug('Smartme Passwort: ' + bezug_smartme_pass) - - # Daten einlesen - response = requests.get(bezug_smartme_url, auth=(bezug_smartme_user, bezug_smartme_pass), timeout=3).json() - - # Aktuelle Leistung (kW --> W) - wattbezug = get_power_value("ActivePower", response) - wattbezug1 = get_power_value("ActivePowerL1", response) - if wattbezug1 == 0: - wattbezug1 = wattbezug - get_power_value("ActivePowerL2", response, "bezugw2") - get_power_value("ActivePowerL3", response, "bezugw3") - # Zählerstand Import(kWh) - get_im_ex_value("CounterReadingImport", response, "bezugkwh") - # Zählerstand Export(kWh) - get_im_ex_value("CounterReadingExport", response, "einspeisungkwh") - - # Weitere Zählerdaten für die Statusseite (PowerFaktor, Spannung und Strom) - get_value("PowerFactorL1", response, "evupf1") - get_value("PowerFactorL2", response, "evupf2") - get_value("PowerFactorL3", response, "evupf3") - get_value("VoltageL1", response, "evuv1") - get_value("VoltageL2", response, "evuv2") - get_value("VoltageL3", response, "evuv3") - bezuga1 = get_value("CurrentL1", response) - if bezuga1 is None: - try: - bezuga1 = response["Current"] - except: - traceback.print_exc() - exit(1) - log.debug('Strom L1: ' + str(bezuga1)) - with open("/var/www/html/openWB/ramdisk/bezuga1", "w") as f: - f.write(str(bezuga1)) - get_value("CurrentL2", response, "bezuga2") - get_value("CurrentL3", response, "bezuga3") - - # Prüfen ob Werte gültig - regex = '^[-+]?[0-9]+.?[0-9]*$' - if re.search(regex, str(wattbezug)) is None: - with open("/var/www/html/openWB/ramdisk/wattbezug", "r") as f: - wattbezug = f.read() - # Ausgabe - log.debug('Leistung: ' + str(wattbezug)) - with open("/var/www/html/openWB/ramdisk/wattbezug", "w") as f: - f.write(str(wattbezug)) - log.debug('Leistung L1: ' + str(wattbezug1)) - with open("/var/www/html/openWB/ramdisk/wattbezugw1", "w") as f: - f.write(str(wattbezug1)) - - -def main(argv: List[str]): - run_using_positional_cli_args(update, argv) diff --git a/modules/bezug_solarview/main.sh b/modules/bezug_solarview/main.sh index 7d96482b6..c98ae48b3 100755 --- a/modules/bezug_solarview/main.sh +++ b/modules/bezug_solarview/main.sh @@ -10,7 +10,7 @@ else MYLOGFILE="${RAMDISKDIR}/evu.log" fi -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "bezug_solarview.solarview" "${solarview_hostname}" "${solarview_port}" "${solarview_timeout}" >>"${MYLOGFILE}" 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.solar_view.device" "counter" "${solarview_hostname}" "${solarview_port}" "${solarview_timeout}" >>"${MYLOGFILE}" 2>&1 ret=$? openwbDebugLog ${DMOD} 2 "RET: ${ret}" diff --git a/modules/bezug_solarview/solarview.py b/modules/bezug_solarview/solarview.py old mode 100755 new mode 100644 index be65fc0b8..e69de29bb --- a/modules/bezug_solarview/solarview.py +++ b/modules/bezug_solarview/solarview.py @@ -1,179 +0,0 @@ -#!/usr/bin/env python3 -# -# OpenWB-Modul für die Anbindung von SolarView über den integrierten TCP-Server -# Details zur API: https://solarview.info/solarview-fb_Installieren.pdf -# -from typing import List, Optional -import logging -import socket -import sys -import traceback - -from helpermodules.cli import run_using_positional_cli_args - - -log = logging.getLogger("Solarview EVU") - - -def write_value(value, file): - with open("/var/www/html/openWB/ramdisk/"+file, "w") as f: - f.write(str(value)) - - -def request(solarview_hostname: str, solarview_port: int, solarview_timeout: int, command): - try: - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.settimeout(solarview_timeout) - s.connect((solarview_hostname, solarview_port)) - s.sendall(command.encode("ascii")) - response = s.recv(1024).rstrip(b'\r\n') - message = response[:-2] - checksum = int.from_bytes(response[-1:], "big", signed=False) - calculated_checksum = int(sum(message)) % 256 - log.debug("message: " + str(message)) - log.debug("checksum: " + str(checksum) + " calculated: " + str(calculated_checksum)) - if checksum != calculated_checksum: - log.error("checksum failure: " + str(checksum) + " != " + str(calculated_checksum)) - except Exception as e: - log.debug("Error: request to SolarView failed. Details: return-code: " + str(e) + ", host: " + - str(solarview_hostname) + ", port: " + str(solarview_port) + ", timeout: " + - str(solarview_timeout)) - traceback.print_exc() - exit(1) - - log.debug("Raw response: " + str(response)) - # - # Format: {WR,Tag,Monat,Jahr,Stunde,Minute,KDY,KMT,KYR,KT0,PAC,UDC,IDC,UDCB,IDCB,UDCC,IDCC,UDCD,IDCD,TKK},Checksum # noqa: E501 - # Beispiele: {22,09,09,2019,10,37,0001.2,00024,000903,00007817,01365,000,000.0,000,000.0,000,000.0,000,000.0,00},: - # {21,09,09,2019,10,37,0002.3,00141,004233,00029525,01365,000,000.0,000,000.0,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 - - # Auszug aus der Doku vom 02.12.2020: - # 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 # noqa: E501 - # 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 entfernen - values = message.decode("ascii")[1:-1].split(",") - - # Werte formatiert in Variablen speichern - id = values[0] - timestamp = str(values[3]) + "-" + str(values[2]) + "-" + str(values[1]) + " " +\ - str(values[4]) + ":" + str(values[5]) - # PAC = '-0357' bedeutet: 357 W Bezug, 0 W Einspeisung - # PAC = '0246' bedeutet: 0 W Bezug, 246 W Einspeisung - power = -1 * int(values[10]) - energy_day = 1000 * float(values[6]) - energy_month = 1000 * int(values[7]) - energy_year = 1000 * int(values[8]) - energy_total = 1000 * int(values[9]) - mpptracker1_voltage = int(values[11]) - mpptracker1_current = round(float(values[12]), 1) - mpptracker2_voltage = int(values[13]) - mpptracker2_current = round(float(values[14]), 1) - mpptracker3_voltage = int(values[15]) - mpptracker3_current = round(float(values[16]), 1) - mpptracker4_voltage = int(values[17]) - mpptracker4_current = round(float(values[18]), 1) - # Kompatibilität für neue und alte Doku - if len(values) > 20: - grid1_voltage = int(values[19]) - grid1_current = round(float(values[20]), 1) - grid2_voltage = int(values[21]) - grid2_current = round(float(values[22]), 1) - grid3_voltage = int(values[23]) - grid3_current = round(float(values[24]), 1) - temperature = int(values[25]) - else: - temperature = int(values[19]) - - # Werte ausgeben - log.debug("ID: "+str(id)) - log.debug("Zeitpunkt: "+str(timestamp)) - log.debug("Temperatur: "+str(temperature)+" °C") - log.debug("Leistung: "+str(power)+" W") - log.debug("Energie:") - log.debug(" Tag: "+str(energy_day)+" Wh") - log.debug(" Monat: "+str(energy_month)+" Wh") - log.debug(" Jahr: "+str(energy_year)+" Wh") - log.debug(" Gesamt: "+str(energy_total)+" Wh") - log.debug("Generator-MPP-Tracker-1") - log.debug(" Spannung: "+str(mpptracker1_voltage)+" V") - log.debug(" Strom: "+str(mpptracker1_current)+" A") - log.debug("Generator-MPP-Tracker-2") - log.debug(" Spannung: "+str(mpptracker2_voltage)+" V") - log.debug(" Strom: "+str(mpptracker2_current)+" A") - log.debug("Generator-MPP-Tracker-3") - log.debug(" Spannung: "+str(mpptracker3_voltage)+" V") - log.debug(" Strom: "+str(mpptracker3_current)+" A") - log.debug("Generator-MPP-Tracker-4") - log.debug(" Spannung: "+str(mpptracker4_voltage)+" V") - log.debug(" Strom: "+str(mpptracker4_current)+" A") - if len(values) > 20: - log.debug("Netz:") - log.debug(" Phase 1:") - log.debug(" Spannung: "+str(grid1_voltage)+" V") - log.debug(" Strom: "+str(grid1_current)+" A") - log.debug(" Phase 2:") - log.debug(" Spannung: "+str(grid2_voltage)+" V") - log.debug(" Strom: "+str(grid2_current)+" A") - log.debug(" Phase 3:") - log.debug(" Spannung: "+str(grid3_voltage)+" V") - log.debug(" Strom: "+str(grid3_current)+" A") - - # Werte speichern - if command == '21*': - write_value(energy_total, "einspeisungkwh") - elif command == '22*': - write_value(power, "wattbezug") - write_value(energy_total, "bezugkwh") - # Kompatibilität für neue und alte Doku - if len(values) > 20: - write_value(grid1_current, "bezuga1") - write_value(grid2_current, "bezuga2") - write_value(grid3_current, "bezuga3") - write_value(grid1_voltage, "evuv1") - write_value(grid2_voltage, "evuv2") - write_value(grid3_voltage, "evuv3") - - -def update(solarview_hostname: str, solarview_port: Optional[int] = 15000, solarview_timeout: Optional[int] = 1): - # Checks - if solarview_hostname is None or solarview_hostname == "": - log.debug("Missing required variable 'solarview_hostname'") - sys.exit(1) - if solarview_port: - if solarview_port < 1 or solarview_port > 65535: - log.debug("Invalid value "+str(solarview_port)+" for variable 'solarview_port'") - sys.exit(1) - - command_bezug = '22*' - command_einspeisung = '21*' - - request(solarview_hostname, solarview_port, solarview_timeout, command_einspeisung) - request(solarview_hostname, solarview_port, solarview_timeout, command_bezug) - - -def main(argv: List[str]): - run_using_positional_cli_args(update, argv) diff --git a/modules/bezug_solarwatt/main.sh b/modules/bezug_solarwatt/main.sh index 493c1c399..8226ee75b 100755 --- a/modules/bezug_solarwatt/main.sh +++ b/modules/bezug_solarwatt/main.sh @@ -15,7 +15,7 @@ openwbDebugLog ${DMOD} 2 "Bezug Solarwatt Methode: ${solarwattmethod}" openwbDebugLog ${DMOD} 2 "Bezug Solarwatt IP1 : ${speicher1_ip}" openwbDebugLog ${DMOD} 2 "Bezug Solarwatt IP2: ${speicher1_ip2}" -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "bezug_solarwatt.solarwatt" "${solarwattmethod}" "${speicher1_ip}" "${speicher1_ip2}" >>"$MYLOGFILE" 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.solar_watt.device" "counter" "${speicher1_ip}" "${speicher1_ip2}" "${solarwattmethod}" >>"$MYLOGFILE" 2>&1 ret=$? openwbDebugLog ${DMOD} 2 "RET: ${ret}" diff --git a/modules/bezug_solarwatt/solarwatt.py b/modules/bezug_solarwatt/solarwatt.py old mode 100755 new mode 100644 index b49d2fa4f..e69de29bb --- a/modules/bezug_solarwatt/solarwatt.py +++ b/modules/bezug_solarwatt/solarwatt.py @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 -from typing import List -import logging -import requests - -from helpermodules.cli import run_using_positional_cli_args - -log = logging.getLogger("Solarwatt EVU") - - -def update(solarwattmethod: int, speicher1_ip: str, speicher1_ip2: str): - log.debug('Solarwatt Methode: ' + str(solarwattmethod)) - log.debug('Solarwatt IP1: ' + speicher1_ip) - log.debug('Solarwatt IP2: ' + speicher1_ip2) - - if solarwattmethod == 0: # Abruf über Energy Manager - json_response = requests.get('http://'+speicher1_ip+'/rest/kiwigrid/wizard/devices', timeout=3).json() - if len(str(json_response)) < 10: - with open("/var/www/html/openWB/ramdisk/wattbezug", "r") as f: - bezug_watt = f.read() - else: - for item in json_response["result"]["items"]: - try: - power_consumed = int(item["tagValues"]["PowerConsumedFromGrid"]["value"]) - break - except KeyError: - pass - else: - raise Exception("Solarwatt konnte keine EVU-Bezugsleistung ermitteln.") - - for item in json_response["result"]["items"]: - try: - power_out = int(item["tagValues"]["PowerOut"]["value"]) - break - except KeyError: - pass - else: - raise Exception("Solarwatt konnte keine EVU-Einspeiseleistung ermitteln.") - - bezug_watt = power_consumed - power_out - if solarwattmethod == 1: # Abruf über Gateway - json_response = requests.get('http://'+speicher1_ip2+':8080/', timeout=3).json() - bezug_watt = int(json_response["FData"]["PGrid"]) - - log.debug("Netzbezug: "+str(bezug_watt)+" W") - with open("/var/www/html/openWB/ramdisk/wattbezug", "w") as f: - f.write(str(bezug_watt)) - - -def main(argv: List[str]): - run_using_positional_cli_args(update, argv) diff --git a/modules/bezug_solarworld/main.sh b/modules/bezug_solarworld/main.sh index 0cb9c1ed1..ef1e92f80 100755 --- a/modules/bezug_solarworld/main.sh +++ b/modules/bezug_solarworld/main.sh @@ -12,9 +12,8 @@ fi openwbDebugLog ${DMOD} 2 "Bezug Solarworld IP: ${solarworld_emanagerip}" -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "bezug_solarworld.solarworld" "${solarworld_emanagerip}" >>"$MYLOGFILE" 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.solar_world.device" "counter" "${solarworld_emanagerip}" >>"$MYLOGFILE" 2>&1 ret=$? openwbDebugLog ${DMOD} 2 "RET: ${ret}" - cat "${RAMDISKDIR}/wattbezug" diff --git a/modules/bezug_solarworld/solarworld.py b/modules/bezug_solarworld/solarworld.py old mode 100755 new mode 100644 index 0112fccaa..e69de29bb --- a/modules/bezug_solarworld/solarworld.py +++ b/modules/bezug_solarworld/solarworld.py @@ -1,38 +0,0 @@ -#!/usr/bin/env python3 -from typing import List -import logging -import requests -import traceback - -from helpermodules.cli import run_using_positional_cli_args - -log = logging.getLogger("Solarworld EVU") - - -def update(solarworld_emanagerip: str): - log.debug('Solarworld IP: ' + solarworld_emanagerip) - - # Auslesen eines Solarworld eManagers über die integrierte JSON-API - emanagerantwort = requests.get( - 'http://'+solarworld_emanagerip+'/rest/solarworld/lpvm/powerAndBatteryData', timeout=3).json() - try: - em_in_watt = emanagerantwort["PowerIn"] - except: - traceback.print_exc() - exit(1) - try: - em_out_watt = emanagerantwort["PowerOut"] - except: - traceback.print_exc() - exit(1) - - # Bezug ist entweder -Out oder In; bei Einspeisung ist 'em_in_watt' immer 0 - bezug_watt = int(em_in_watt - em_out_watt) - - log.debug('Leistung: ' + str(bezug_watt)) - with open("/var/www/html/openWB/ramdisk/wattbezug", "w") as f: - f.write(str(bezug_watt)) - - -def main(argv: List[str]): - run_using_positional_cli_args(update, argv) diff --git a/modules/bezug_sungrow/main.sh b/modules/bezug_sungrow/main.sh index 014157688..4a7a632bb 100755 --- a/modules/bezug_sungrow/main.sh +++ b/modules/bezug_sungrow/main.sh @@ -10,8 +10,12 @@ else MYLOGFILE="$RAMDISKDIR/evu.log" fi -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.sungrow.device" "counter" "$speicher1_ip" "$sungrowspeicherport" "$sungrowspeicherid" "$sungrowsr" >>"$MYLOGFILE" 2>&1 -ret=$? +if [[ "$pvwattmodul" == "wr_sungrow" ]]; then + echo "value read at pv modul" >/dev/null +else + bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.sungrow.device" "counter" "$pv1_ipa" "$pv1_ida" "$sungrowsr" "0" "0">>"$MYLOGFILE" 2>&1 + ret=$? +fi openwbDebugLog $DMOD 2 "EVU RET: $ret" diff --git a/modules/bezug_varta/main.sh b/modules/bezug_varta/main.sh index 870c889a0..a02238615 100755 --- a/modules/bezug_varta/main.sh +++ b/modules/bezug_varta/main.sh @@ -10,7 +10,7 @@ else MYLOGFILE="${RAMDISKDIR}/evu.log" fi -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "bezug_varta.varta" "${vartaspeicherip}" >>"${MYLOGFILE}" 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.varta.device" "counter" "${vartaspeicherip}" >>"${MYLOGFILE}" 2>&1 ret=$? openwbDebugLog ${DMOD} 2 "RET: ${ret}" diff --git a/modules/bezug_varta/varta.py b/modules/bezug_varta/varta.py old mode 100755 new mode 100644 index 792a2642a..e69de29bb --- a/modules/bezug_varta/varta.py +++ b/modules/bezug_varta/varta.py @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -from typing import List -import logging -import struct -import codecs - -from pymodbus.client.sync import ModbusTcpClient - -from helpermodules.cli import run_using_positional_cli_args - -log = logging.getLogger("Varta EVU") - - -def update(ipaddress: str): - with ModbusTcpClient(ipaddress, port=502) as client: - # grid power - resp = client.read_holding_registers(1078, 1, unit=1) - value1 = resp.registers[0] - # ToDo: scale factor in register 2078 SInt16 - # power = reg(1078) * 10 ^ reg(2078) - all = format(value1, '04x') - final = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0])*-1 - log.debug("Result: %s", str(final)) - with open('/var/www/html/openWB/ramdisk/wattbezug', 'w') as f: - f.write(str(final)) - # ToDo: grid frequency in register 1082 as 0.01Hz UInt16 - - -def main(argv: List[str]): - run_using_positional_cli_args(update, argv) diff --git a/modules/speicher_solarwatt/main.sh b/modules/speicher_solarwatt/main.sh index 7a2eeff49..662cae4f9 100755 --- a/modules/speicher_solarwatt/main.sh +++ b/modules/speicher_solarwatt/main.sh @@ -15,7 +15,7 @@ openwbDebugLog ${DMOD} 2 "Speicher Methode: ${solarwattmethod}" openwbDebugLog ${DMOD} 2 "Speicher IP1: ${speicher1_ip}" openwbDebugLog ${DMOD} 2 "Speicher IP2: ${speicher1_ip2}" -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "speicher_solarwatt.solarwatt" "${solarwattmethod}" "${speicher1_ip}" "${speicher1_ip2}" >>"$MYLOGFILE" 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.solar_watt.device" "bat" "${speicher1_ip}" "${speicher1_ip2}" "${solarwattmethod}" >>"$MYLOGFILE" 2>&1 ret=$? openwbDebugLog ${DMOD} 2 "RET: ${ret}" diff --git a/modules/speicher_solarwatt/solarwatt.py b/modules/speicher_solarwatt/solarwatt.py old mode 100755 new mode 100644 index 0bd68950e..e69de29bb --- a/modules/speicher_solarwatt/solarwatt.py +++ b/modules/speicher_solarwatt/solarwatt.py @@ -1,70 +0,0 @@ -#!/usr/bin/env python3 - -from typing import List -import logging -import requests -import sys -import traceback - -from helpermodules.cli import run_using_positional_cli_args - -log = logging.getLogger("Solarwatt Speicher") - - -def get_value(key: str, json_response): - value = 0 - try: - for item in json_response["result"]["items"]: - if "tagValues" in item: - if key in item["tagValues"]: - if "value" in item["tagValues"][key]: - value = int(item["tagValues"][key]["value"]) - break - except: - traceback.print_exc() - exit(1) - return value - - -def update(solarwattmethod: int, speicher1_ip: str, speicher1_ip2: str): - log.debug('Speicher Methode: ' + str(solarwattmethod)) - log.debug('Speicher IP1: ' + speicher1_ip) - log.debug('Speicher IP2: ' + speicher1_ip2) - - if solarwattmethod == 0: # Abruf über Energy Manager - json_response = requests.get('http://'+speicher1_ip+'/rest/kiwigrid/wizard/devices', timeout=5).json() - if len(str(json_response)) < 10: - sys.exit(1) - - speicher_e = get_value("PowerConsumedFromStorage", json_response) - speicher_ein = get_value("PowerOutFromStorage", json_response) - speicher_i = get_value("PowerBuffered", json_response) - speicher_leistung = int((speicher_e + speicher_ein - speicher_i) * -1) - speicher_soc = get_value("StateOfCharge", json_response) - - elif solarwattmethod == 1: # Abruf über Gateway - json_response = requests.get('http://'+speicher1_ip2+':8080/', timeout=3).json() - if len(str(json_response)) < 10: - sys.exit(1) - speicher_strom = json_response["FData"]["IBat"] - speicher_spannung = json_response["FData"]["VBat"] - - speicher_leistung = int(speicher_strom * speicher_spannung * -1) - speicher_soc = int(json_response["SData"]["SoC"]) - log.debug('SpeicherSoC: ' + str(speicher_soc)) - if not str(speicher_soc).isnumeric(): - log.debug('SpeicherSoc nicht numerisch. -->0') - speicher_soc = 0 - else: - raise Exception("Unbekannte Abrufmethode für Solarwatt") - - log.debug("Speicherleistung: "+str(speicher_leistung)+" W") - with open("/var/www/html/openWB/ramdisk/speicherleistung", "w") as f: - f.write(str(speicher_leistung)) - log.debug("SpeicherSoC: "+str(speicher_soc)+" %") - with open("/var/www/html/openWB/ramdisk/speichersoc", "w") as f: - f.write(str(speicher_soc)) - - -def main(argv: List[str]): - run_using_positional_cli_args(update, argv) diff --git a/modules/speicher_sungrow/main.sh b/modules/speicher_sungrow/main.sh index e73f14ff3..cef18d12a 100755 --- a/modules/speicher_sungrow/main.sh +++ b/modules/speicher_sungrow/main.sh @@ -10,7 +10,7 @@ else MYLOGFILE="$RAMDISKDIR/bat.log" fi -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.sungrow.device" "bat" "$speicher1_ip" "$sungrowspeicherport" "$sungrowspeicherid" >>"$MYLOGFILE" 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.sungrow.device" "bat" "$pv1_ipa" "$pv1_ida" "0" "0">>"$MYLOGFILE" 2>&1 ret=$? openwbDebugLog $DMOD 2 "BAT RET: $ret" diff --git a/modules/speicher_varta/main.sh b/modules/speicher_varta/main.sh index 534f6ab82..ed42c639b 100755 --- a/modules/speicher_varta/main.sh +++ b/modules/speicher_varta/main.sh @@ -1,7 +1,8 @@ #!/bin/bash + OPENWBBASEDIR=$(cd "$(dirname "$0")/../../" && pwd) RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" -#DMOD="BAT" +#DMOD="BATT" DMOD="MAIN" if [ ${DMOD} == "MAIN" ]; then @@ -13,21 +14,9 @@ fi # Auslesen eines Varta Speicher über die integrierte XML-API der Batteroe. if [[ "$usevartamodbus" != "1" ]]; then - speicherwatt=$(curl --connect-timeout 3 -s "$vartaspeicherip/cgi/ems_data.xml" | grep 'P' | sed 's/.*value=//' |tr -d "'/>") - # wenn WR aus bzw. im standby (keine Antwort) ersetze leeren Wert durch eine 0 - ra='^-?[0-9]+$' - if [[ $speicherwatt =~ $ra ]] ; then - echo "$speicherwatt" > "$RAMDISKDIR/speicherleistung" - fi - speichersoc=$(curl --connect-timeout 3 -s "$vartaspeicherip/cgi/ems_data.xml" | grep 'SOC' | sed 's/.*value=//' |tr -d "'/>") - # if [[ $speichersoc -ge "101" ]]; then - speichersoc=$(echo "$speichersoc / 10" |bc) - # fi - if [[ $speichersoc =~ $ra ]] ; then - echo "$speichersoc" > "$RAMDISKDIR/speichersoc" - fi + bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.varta.device" "bat_api" "${vartaspeicherip}">>"$MYLOGFILE" 2>&1 else - bash "$OPENWBBASEDIR/packages/legacy_run.sh" "speicher_varta.varta" "${vartaspeicherip}" "${vartaspeicher2ip}" >>"$MYLOGFILE" 2>&1 - ret=$? - openwbDebugLog ${DMOD} 2 "RET: ${ret}" + bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.varta.device" "bat_modbus" "${vartaspeicherip}" "${vartaspeicher2ip}" >>"$MYLOGFILE" 2>&1 fi +ret=$? +openwbDebugLog ${DMOD} 2 "RET: ${ret}" diff --git a/modules/speicher_varta/varta.py b/modules/speicher_varta/varta.py old mode 100755 new mode 100644 index 5e8d75ad8..e69de29bb --- a/modules/speicher_varta/varta.py +++ b/modules/speicher_varta/varta.py @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -from typing import List -import logging -import struct -import codecs - -from pymodbus.client.sync import ModbusTcpClient - -from helpermodules.cli import run_using_positional_cli_args - -log = logging.getLogger("Varta Speicher") - - -def update(ipaddress: str, ip2address: str): - with ModbusTcpClient(ipaddress, port=502) as client: - # battsoc - resp = client.read_holding_registers(1068, 1, unit=1) - value1 = resp.registers[0] - all = format(value1, '04x') - sfinal = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0]) - - # battleistung - resp = client.read_holding_registers(1066, 1, unit=1) - value1 = resp.registers[0] - all = format(value1, '04x') - lfinal = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0]) - - if ip2address != 'none': - with ModbusTcpClient(ip2address, port=502) as client2: - # battsoc - resp = client2.read_holding_registers(1068, 1, unit=1) - value1 = resp.registers[0] - all = format(value1, '04x') - final = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0]) - sfinal = (sfinal+final)/2 - # battleistung - resp = client2.read_holding_registers(1066, 1, unit=1) - value1 = resp.registers[0] - all = format(value1, '04x') - final = int(struct.unpack('>h', codecs.decode(all, 'hex'))[0]) - lfinal = lfinal+final - - with open('/var/www/html/openWB/ramdisk/speichersoc', 'w') as f: - f.write(str(sfinal)) - with open('/var/www/html/openWB/ramdisk/speicherleistung', 'w') as f: - f.write(str(lfinal)) - - -def main(argv: List[str]): - run_using_positional_cli_args(update, argv) diff --git a/modules/wr2_sungrow/main.sh b/modules/wr2_sungrow/main.sh index 4ec64e43c..9acde5fbb 100755 --- a/modules/wr2_sungrow/main.sh +++ b/modules/wr2_sungrow/main.sh @@ -9,7 +9,9 @@ if [ ${DMOD} == "MAIN" ]; then else MYLOGFILE="$RAMDISKDIR/nurpv.log" fi + read_counter=0 + +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.sungrow.device" "inverter" "$pv2ip" "$pv2id" "2" "$read_counter" "$sungrow2sr">>"$MYLOGFILE" 2>&1 -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.sungrow.device" "inverter" "$pv2ip" "$pv2port" "$pv2id" "2" >>"$MYLOGFILE" 2>&1 cat "$RAMDISKDIR/pv2watt" diff --git a/modules/wr_smartme/main.sh b/modules/wr_smartme/main.sh index 4a8a6524a..c81857713 100755 --- a/modules/wr_smartme/main.sh +++ b/modules/wr_smartme/main.sh @@ -20,10 +20,9 @@ openwbDebugLog ${DMOD} 2 "WR URL: ${wr_smartme_url}" openwbDebugLog ${DMOD} 2 "WR User: ${wr_smartme_user}" openwbDebugLog ${DMOD} 2 "WR Passwort: ${wr_smartme_pass}" -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "wr_smartme.smartme" "${wr_smartme_url}" "${wr_smartme_user}" "${wr_smartme_pass}" >>$MYLOGFILE 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.smart_me.device" "inverter" "${wr_smartme_user}" "${wr_smartme_pass}" "${wr_smartme_url}" >>$MYLOGFILE 2>&1 ret=$? openwbDebugLog ${DMOD} 2 "RET: ${ret}" -pvwatt=$( W) - wattwr = response["ActivePower"] - wattwr = round(wattwr * 1000) - - # Zählerstand Export (kWh --> Wh) - pvkwh = response["CounterReadingExport"] - pvkwh = round(pvkwh * 1000, 3) - - log.debug('WR Leistung: ' + str(wattwr)) - log.debug('WR Energie: ' + str(pvkwh)) - - get_inverter_value_store(1).set(InverterState(exported=pvkwh, power=wattwr)) - - -def main(argv: List[str]): - run_using_positional_cli_args(update, argv) diff --git a/modules/wr_solarview/main.sh b/modules/wr_solarview/main.sh index 73098b1f9..a0c5d178a 100755 --- a/modules/wr_solarview/main.sh +++ b/modules/wr_solarview/main.sh @@ -16,7 +16,7 @@ openwbDebugLog ${DMOD} 2 "PV Port: ${solarview_port}" openwbDebugLog ${DMOD} 2 "PV Timeout: ${solarview_timeout}" openwbDebugLog ${DMOD} 2 "PV Command: ${solarview_command_wr}" -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "wr_solarview.solarview" "${solarview_hostname}" "${solarview_port}" "${solarview_timeout}" "${solarview_command_wr}" >>"$MYLOGFILE" 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.solar_view.device" "inverter" "${solarview_hostname}" "${solarview_port}" "${solarview_timeout}" "${solarview_command_wr}" >>"$MYLOGFILE" 2>&1 ret=$? openwbDebugLog ${DMOD} 2 "RET: ${ret}" diff --git a/modules/wr_solarview/solarview.py b/modules/wr_solarview/solarview.py old mode 100755 new mode 100644 index 720e74133..e69de29bb --- a/modules/wr_solarview/solarview.py +++ b/modules/wr_solarview/solarview.py @@ -1,157 +0,0 @@ -#!/usr/bin/env python3 -# -# OpenWB-Modul für die Anbindung von SolarView über den integrierten TCP-Server -# Details zur API: https://solarview.info/solarview-fb_Installieren.pdf -# Sende-Kommando (siehe SolarView-Dokumentation); Beispiele: -# '00*': Gesamte Anlage -# '01*': Wechselrichter 1 -# '02*': Wechselrichter 2 -# -from typing import List, Optional -import logging -import socket -import traceback - -from helpermodules.cli import run_using_positional_cli_args - -log = logging.getLogger("Solarview WR") - - -def write_value(value, file): - with open("/var/www/html/openWB/ramdisk/"+file, "w") as f: - f.write(str(value)) - - -def update(solarview_hostname: str, solarview_port: Optional[int] = 15000, solarview_timeout: Optional[int] = 1, - solarview_command_wr: Optional[str] = "00*"): - log.debug('Solarview Hostname: ' + solarview_hostname) - log.debug('Solarview Port: ' + str(solarview_port)) - log.debug('Solarview Timeout: ' + str(solarview_timeout)) - - # Checks - if solarview_hostname is None or solarview_hostname == "": - log.debug("Missing required variable 'solarview_hostname'") - exit(1) - if solarview_port: - if solarview_port < 1 or solarview_port > 65535: - log.debug("Invalid value "+str(solarview_port)+" for variable 'solarview_port'") - exit(1) - if solarview_command_wr is None or solarview_command_wr == "": - log.debug("Missing value for variable 'solarview_command_wr'") - exit(1) - - try: - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.settimeout(solarview_timeout) - s.connect((solarview_hostname, solarview_port)) - s.sendall(solarview_command_wr.encode("ascii")) - response = s.recv(1024).rstrip(b'\r\n') - message = response[:-2] - checksum = int.from_bytes(response[-1:], "big", signed=False) - calculated_checksum = int(sum(message)) % 256 - log.debug("message: " + str(message)) - log.debug("checksum: " + str(checksum) + " calculated: " + str(calculated_checksum)) - if checksum != calculated_checksum: - log.error("checksum failure: " + str(checksum) + " != " + str(calculated_checksum)) - except Exception as e: - log.debug("Error: request to SolarView failed. Details: return-code: " + str(e) + ", host: " + - str(solarview_hostname) + ", port: " + str(solarview_port) + ", timeout: " + - str(solarview_timeout)) - traceback.print_exc() - exit(1) - - log.debug("Raw response: " + str(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 # noqa: E501 - # 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},▒ # noqa: E501 - # - # 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 entfernen - values = message.decode("ascii")[1:-1].split(",") - - # Werte formatiert in Variablen speichern - id = values[0] - timestamp = str(values[3])+"-"+str(values[2])+"-"+str(values[1])+" "+str(values[4])+":"+str(values[5]) - # PAC = '-0357' bedeutet: 357 W Bezug, 0 W Einspeisung - # PAC = '0246' bedeutet: 0 W Bezug, 246 W Einspeisung - power = -1 * int(values[10]) - energy_day = 1000 * float(values[6]) - energy_month = 1000 * int(values[7]) - energy_year = 1000 * int(values[8]) - energy_total = 1000 * int(values[9]) - mpptracker1_voltage = int(values[11]) - mpptracker1_current = round(float(values[12]), 1) - mpptracker2_voltage = int(values[13]) - mpptracker2_current = round(float(values[14]), 1) - mpptracker3_voltage = int(values[15]) - mpptracker3_current = round(float(values[16]), 1) - mpptracker4_voltage = int(values[17]) - mpptracker4_current = round(float(values[18]), 1) - # Kompatibilität für neue und alte Doku - if len(values) > 20: - grid1_voltage = int(values[19]) - grid1_current = round(float(values[20]), 1) - grid2_voltage = int(values[21]) - grid2_current = round(float(values[22]), 1) - grid3_voltage = int(values[23]) - grid3_current = round(float(values[24]), 1) - temperature = int(values[25]) - else: - temperature = int(values[19]) - # Werte ausgeben - log.debug("ID: "+str(id)) - log.debug("Zeitpunkt: "+str(timestamp)) - log.debug("Temperatur: "+str(temperature)+" °C") - log.debug("Leistung: "+str(power)+" W") - log.debug("Energie:") - log.debug(" Tag: "+str(energy_day)+" Wh") - log.debug(" Monat: "+str(energy_month)+" Wh") - log.debug(" Jahr: "+str(energy_year)+" Wh") - log.debug(" Gesamt: "+str(energy_total)+" Wh") - log.debug("Generator-MPP-Tracker-1") - log.debug(" Spannung: "+str(mpptracker1_voltage)+" V") - log.debug(" Strom: "+str(mpptracker1_current)+" A") - log.debug("Generator-MPP-Tracker-2") - log.debug(" Spannung: "+str(mpptracker2_voltage)+" V") - log.debug(" Strom: "+str(mpptracker2_current)+" A") - log.debug("Generator-MPP-Tracker-3") - log.debug(" Spannung: "+str(mpptracker3_voltage)+" V") - log.debug(" Strom: "+str(mpptracker3_current)+" A") - log.debug("Generator-MPP-Tracker-4") - log.debug(" Spannung: "+str(mpptracker4_voltage)+" V") - log.debug(" Strom: "+str(mpptracker4_current)+" A") - # Kompatibilität für neue und alte Doku - if len(values) > 20: - log.debug("Netz:") - log.debug(" Phase 1:") - log.debug(" Spannung: "+str(grid1_voltage)+" V") - log.debug(" Strom: "+str(grid1_current)+" A") - log.debug(" Phase 2:") - log.debug(" Spannung: "+str(grid2_voltage)+" V") - log.debug(" Strom: "+str(grid2_current)+" A") - log.debug(" Phase 3:") - log.debug(" Spannung: "+str(grid3_voltage)+" V") - log.debug(" Strom: "+str(grid3_current)+" A") - - # Werte speichern - write_value(power, "pvwatt") - write_value(energy_total, "pvkwh") - write_value(energy_day, "daily_pvkwh") - write_value(energy_month, "monthly_pvkwh") - write_value(energy_year, "yearly_pvkwh") - - -def main(argv: List[str]): - run_using_positional_cli_args(update, argv) diff --git a/modules/wr_solarwatt/main.sh b/modules/wr_solarwatt/main.sh index 9f22f26ca..83a470e7a 100755 --- a/modules/wr_solarwatt/main.sh +++ b/modules/wr_solarwatt/main.sh @@ -13,7 +13,7 @@ fi openwbDebugLog ${DMOD} 2 "PV IP: ${speicher1_ip}" -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "wr_solarwatt.solarwatt" "${speicher1_ip}" >>"$MYLOGFILE" 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.solar_watt.device" "inverter" "${speicher1_ip}" >>"$MYLOGFILE" 2>&1 ret=$? openwbDebugLog ${DMOD} 2 "RET: ${ret}" diff --git a/modules/wr_solarwatt/solarwatt.py b/modules/wr_solarwatt/solarwatt.py old mode 100755 new mode 100644 index c85d46b63..e69de29bb --- a/modules/wr_solarwatt/solarwatt.py +++ b/modules/wr_solarwatt/solarwatt.py @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -from typing import List -import logging -import requests - -from helpermodules.cli import run_using_positional_cli_args - -log = logging.getLogger("Solarwatt WR") - - -def update(speicher1_ip: str): - log.debug('PV Solarwatt IP:' + speicher1_ip) - json_response = requests.get('http://'+speicher1_ip+'/rest/kiwigrid/wizard/devices', timeout=3).json() - - for item in json_response["result"]["items"]: - try: - pvwatt = int(item["tagValues"]["PowerProduced"]["value"]) - break - except KeyError: - pass - else: - raise Exception("Solarwatt konnte keine WR-Leistung ermitteln.") - pvwatt = pvwatt * -1 - log.debug("PV-Leistung: "+str(pvwatt)+" W") - with open("/var/www/html/openWB/ramdisk/pvwatt", "w") as f: - f.write(str(pvwatt)) - - -def main(argv: List[str]): - run_using_positional_cli_args(update, argv) diff --git a/modules/wr_solarworld/main.sh b/modules/wr_solarworld/main.sh index 4a2dff586..096fbb4e7 100755 --- a/modules/wr_solarworld/main.sh +++ b/modules/wr_solarworld/main.sh @@ -1,6 +1,6 @@ #!/bin/bash -OPENWBBASEDIR=$(cd `dirname $0`/../../ && pwd) +OPENWBBASEDIR=$(cd "$(dirname "$0")/../../" && pwd) RAMDISKDIR="${OPENWBBASEDIR}/ramdisk" #MODULEDIR=$(cd `dirname $0` && pwd) #DMOD="PV" @@ -18,11 +18,8 @@ fi openwbDebugLog ${DMOD} 2 "PV IP: ${solarworld_emanagerip}" -bash "$OPENWBBASEDIR/packages/legacy_run.sh" "wr_solarworld.solarworld" "${solarworld_emanagerip}" >>$MYLOGFILE 2>&1 +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.solar_world.device" "inverter" "${solarworld_emanagerip}" "1" >>"$MYLOGFILE" 2>&1 ret=$? openwbDebugLog ${DMOD} 2 "RET: ${ret}" - - -pvwatt=$(>"$MYLOGFILE" 2>&1 +if [[ "$wattbezugmodul" == "bezug_sungrow" ]]; then + read_counter=1 +else + read_counter=0 +fi +bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.devices.sungrow.device" "inverter" "$pv1_ipa" "$pv1_ida" "1" "$read_counter" "$sungrowsr">>"$MYLOGFILE" 2>&1 cat "$RAMDISKDIR/pvwatt" diff --git a/packages/modules/common/evse.py b/packages/modules/common/evse.py index 2d9ce42e9..2d63d3acd 100644 --- a/packages/modules/common/evse.py +++ b/packages/modules/common/evse.py @@ -62,9 +62,20 @@ def is_precise_current_active(self) -> bool: return False def activate_precise_current(self) -> None: - log.debug("Bit zur Angabe der Ströme in 0,1A-Schritten wird gesetzt.") value = self.client.read_holding_registers(2005, ModbusDataType.UINT_16, unit=self.id) - self.client.delegate.write_registers(2005, value ^ self.PRECISE_CURRENT_BIT, unit=self.id) + if value & self.PRECISE_CURRENT_BIT: + return + else: + log.debug("Bit zur Angabe der Ströme in 0,1A-Schritten wird gesetzt.") + self.client.delegate.write_registers(2005, value ^ self.PRECISE_CURRENT_BIT, unit=self.id) + + def deactivate_precise_current(self) -> None: + value = self.client.read_holding_registers(2005, ModbusDataType.UINT_16, unit=self.id) + if value & self.PRECISE_CURRENT_BIT: + log.debug("Bit zur Angabe der Ströme in 0,1A-Schritten wird zurueckgesetzt.") + self.client.delegate.write_registers(2005, value ^ self.PRECISE_CURRENT_BIT, unit=self.id) + else: + return def set_current(self, current: int) -> None: self.client.delegate.write_registers(1000, current, unit=self.id) diff --git a/packages/modules/devices/solaredge/device.py b/packages/modules/devices/solaredge/device.py index e055a6f3e..4e836912a 100644 --- a/packages/modules/devices/solaredge/device.py +++ b/packages/modules/devices/solaredge/device.py @@ -202,15 +202,19 @@ def create_inverter(modbus_id: int) -> SolaredgeInverter: total_currents = list(map(add, total_currents, state.currents)) if extprodakt: - external_inv_state = get_external_inverter_state(dev, int(slave_id0)) - total_power += external_inv_state.power + external_inv_power = get_external_inverter_state(dev, int(slave_id0)).power + total_power += external_inv_power + else: + external_inv_power = 0 if batwrsame == 1: bat_power, bat_state = get_bat_state() # WR-Leistung nur anpassen, wenn die Ladeleistung des Speichers PV-Leistung ist, dh am WR muss # DC-seitig Leistung anliegen. Der Speicher wird auch aus dem Netz geladen, um einen # Mindest-SoC zu halten. - if state.dc_power is None or state.dc_power <= 0: + # Wenn ein weiterer WR über ein Smartmeter angeschlossen ist, kann der Speicher auch über + # diesen geladen werden. + if state.dc_power is None or state.dc_power <= 0 or external_inv_power < 0: if subbat == 1: total_power -= sum(min(p, 0) for p in bat_power) else: diff --git a/packages/modules/devices/solaredge/meter.py b/packages/modules/devices/solaredge/meter.py index af3cdcc68..c759a27d0 100644 --- a/packages/modules/devices/solaredge/meter.py +++ b/packages/modules/devices/solaredge/meter.py @@ -1,3 +1,10 @@ + +import logging + + +log = logging.getLogger(__name__) + + class SolaredgeMeterRegisters: def __init__(self, internal_meter_id: int = 1, synergy_units: int = 1): # 40206: Total Real Power (sum of active phases) @@ -37,7 +44,11 @@ def _update_offset_synergy_units(self, synergy_units: int) -> None: For 3-unit three phase inverters with Synergy technology, add 70 to the default addresses. """ OFFSET = [0, 50, 70] - self._add_offset(OFFSET[synergy_units-1]) + try: + self._add_offset(OFFSET[synergy_units-1]) + except IndexError: + log.debug("Undocumented synergy units value "+str(synergy_units)+". Use synergy_units 1.") + self._add_offset(OFFSET[0]) def _add_offset(self, offset: int) -> None: for name, value in self.__dict__.items(): diff --git a/packages/modules/devices/sungrow/counter.py b/packages/modules/devices/sungrow/counter.py index 01b2aae3a..e0802c43d 100644 --- a/packages/modules/devices/sungrow/counter.py +++ b/packages/modules/devices/sungrow/counter.py @@ -27,7 +27,7 @@ def __init__(self, self.store = get_counter_value_store(self.component_config.id) self.component_info = ComponentInfo.from_component_config(self.component_config) - def update(self): + def update(self, pv_power: float): unit = self.__device_modbus_id if self.component_config.configuration.version == Version.SH: power = self.__tcp_client.read_input_registers(13009, ModbusDataType.INT_32, @@ -38,10 +38,13 @@ def update(self): # powers = [power / 10 for power in powers] # log.info("power: " + str(power) + " powers?: " + str(powers)) else: - power = self.__tcp_client.read_input_registers(5082, ModbusDataType.INT_32, - wordorder=Endian.Little, unit=unit) - if self.component_config.configuration.version == Version.SG_winet_dongle: - power = power * -1 + if pv_power != 0: + power = self.__tcp_client.read_input_registers(5082, ModbusDataType.INT_32, + wordorder=Endian.Little, unit=unit) + else: + power = self.__tcp_client.read_input_registers(5090, ModbusDataType.INT_32, + wordorder=Endian.Little, unit=unit) + # no valid data for powers per phase # powers = self.__tcp_client.read_input_registers(5084, [ModbusDataType.UINT_16] * 3, # wordorder=Endian.Little, unit=unit) diff --git a/packages/modules/devices/sungrow/device.py b/packages/modules/devices/sungrow/device.py index 40f69619b..648c28f74 100644 --- a/packages/modules/devices/sungrow/device.py +++ b/packages/modules/devices/sungrow/device.py @@ -6,7 +6,7 @@ from helpermodules.cli import run_using_positional_cli_args from modules.common import modbus from modules.common.abstract_device import AbstractDevice, DeviceDescriptor -from modules.common.component_context import SingleComponentUpdateContext +from modules.common.component_context import MultiComponentUpdateContext from modules.devices.sungrow import bat from modules.devices.sungrow import counter from modules.devices.sungrow import inverter @@ -33,7 +33,7 @@ def __init__(self, device_config: Union[Dict, Sungrow]) -> None: try: self.device_config = dataclass_from_dict(Sungrow, device_config) self.client = modbus.ModbusTcpClient_(self.device_config.configuration.ip_address, - self.device_config.configuration.port) + 502) except Exception: log.exception("Fehler im Modul "+self.device_config.name) @@ -59,10 +59,13 @@ def update(self) -> None: log.debug("Start device reading " + str(self.components)) if self.components: with self.client: - 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() + with MultiComponentUpdateContext(self.components): + for component in self.components: + if isinstance(component, inverter.SungrowInverter): + pv_power = component.update() + for component in self.components: + if isinstance(component, counter.SungrowCounter): + component.update(pv_power) else: log.warning( self.device_config.name + @@ -77,27 +80,36 @@ def update(self) -> None: } -def read_legacy(ip_address: str, port: int, modbus_id: int, component_config: dict): +def read_legacy(ip_address: str, modbus_id: int, component_config: dict): device_config = Sungrow() device_config.configuration.ip_address = ip_address - device_config.configuration.port = port + device_config.configuration.port = 502 device_config.configuration.modbus_id = modbus_id dev = Device(device_config) dev.add_component(component_config) dev.update() -def read_legacy_bat(ip_address: str, port: int, modbus_id: int, num: Optional[int] = None): - read_legacy(ip_address, port, modbus_id, bat.component_descriptor.configuration_factory(id=None)) +def read_legacy_bat(ip_address: str, modbus_id: int, num: Optional[int] = None, read_counter: Optional[int] = None, version: Optional[int] = None): + read_legacy(ip_address, modbus_id, bat.component_descriptor.configuration_factory(id=None)) -def read_legacy_counter(ip_address: str, port: int, modbus_id: int, version: int): - read_legacy(ip_address, port, modbus_id, counter.component_descriptor.configuration_factory( +def read_legacy_counter(ip_address: str, modbus_id: int, version: int, read_counter: int, unused_version: int): + read_legacy(ip_address, modbus_id, counter.component_descriptor.configuration_factory( id=None, configuration=SungrowCounterConfiguration(version=Version(version)))) -def read_legacy_inverter(ip_address: str, port: int, modbus_id: int, num: int): - read_legacy(ip_address, port, modbus_id, inverter.component_descriptor.configuration_factory(id=num)) +def read_legacy_inverter(ip_address: str, modbus_id: int, num: int, read_counter: int, version: int): + device_config = Sungrow() + device_config.configuration.ip_address = ip_address + device_config.configuration.port = 502 + device_config.configuration.modbus_id = modbus_id + dev = Device(device_config) + dev.add_component(inverter.component_descriptor.configuration_factory(id=num)) + if read_counter == 1: + dev.add_component(counter.component_descriptor.configuration_factory( + id=None, configuration=SungrowCounterConfiguration(version=Version(version)))) + dev.update() def main(argv: List[str]): diff --git a/packages/modules/devices/sungrow/inverter.py b/packages/modules/devices/sungrow/inverter.py index 0be1b1be1..375567a42 100644 --- a/packages/modules/devices/sungrow/inverter.py +++ b/packages/modules/devices/sungrow/inverter.py @@ -26,7 +26,7 @@ def __init__(self, self.store = get_inverter_value_store(self.component_config.id) self.component_info = ComponentInfo.from_component_config(self.component_config) - def update(self) -> None: + def update(self) -> float: unit = self.__device_modbus_id power = self.__tcp_client.read_input_registers(5016, ModbusDataType.UINT_32, @@ -40,6 +40,7 @@ def update(self) -> None: exported=exported ) self.store.set(inverter_state) + return power component_descriptor = ComponentDescriptor(configuration_factory=SungrowInverterSetup) diff --git a/packages/modules/internal_chargepoint_handler/chargepoint_module.py b/packages/modules/internal_chargepoint_handler/chargepoint_module.py index 4bccc0fc1..704e44871 100644 --- a/packages/modules/internal_chargepoint_handler/chargepoint_module.py +++ b/packages/modules/internal_chargepoint_handler/chargepoint_module.py @@ -83,17 +83,13 @@ def __init__(self, config: ClientConfig, parent_hostname: str) -> None: self.old_plug_state = False self.__client = ClientFactory(self.config.id, self.config.serial_client) time.sleep(0.1) - version = self.__client.evse_client.get_firmware_version() - if version < 17: - self._precise_current = False - else: - self._precise_current = self.__client.evse_client.is_precise_current_active() + self.__client.evse_client.get_firmware_version() + self.__client.evse_client.deactivate_precise_current() def set_current(self, current: float) -> None: with SingleComponentUpdateContext(self.component_info): - formatted_current = int(current*100) if self._precise_current else int(current) - if self.set_current_evse != formatted_current: - self.__client.evse_client.set_current(formatted_current) + if self.set_current_evse != current: + self.__client.evse_client.set_current(int(current)) def get_values(self, phase_switch_cp_active: bool) -> Tuple[ChargepointState, float]: try: diff --git a/packages/modules/smarthome/acthor/smartacthor.py b/packages/modules/smarthome/acthor/smartacthor.py index 811e73322..7324a29ca 100644 --- a/packages/modules/smarthome/acthor/smartacthor.py +++ b/packages/modules/smarthome/acthor/smartacthor.py @@ -1,7 +1,6 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase from typing import Dict -import subprocess import logging log = logging.getLogger(__name__) @@ -47,8 +46,7 @@ def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: str(self.devuberschuss), self._device_acthortype, self._device_acthorpower, str(forcesend)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) self.answer = self.readret() self.newwatt = int(self.answer['power']) self.newwattk = int(self.answer['powerc']) @@ -83,8 +81,7 @@ def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: str(self.device_nummer), str(self._device_ip), str(self.devuberschuss)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/avmhomeautomation/smartavm.py b/packages/modules/smarthome/avmhomeautomation/smartavm.py index c63b0743e..68753261d 100644 --- a/packages/modules/smarthome/avmhomeautomation/smartavm.py +++ b/packages/modules/smarthome/avmhomeautomation/smartavm.py @@ -1,21 +1,20 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase, Slavm -import subprocess +from typing import Dict import logging log = logging.getLogger(__name__) class Savm(Sbase): - def __init__(self): + def __init__(self) -> None: # setting super().__init__() self._old_measuretype0 = 'none' - self._smart_paramadd = {} self._device_actor = 'none' self._device_username = 'none' self._device_password = 'none' - def getwatt(self, uberschuss, uberschussoffset): + def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: self.prewatt(uberschuss, uberschussoffset) self._mydevicemeasure0.devuberschuss = self.devuberschuss self._mydevicemeasure0.getwattread() @@ -25,7 +24,7 @@ def getwatt(self, uberschuss, uberschussoffset): self.postwatt() - def updatepar(self, input_param): + def updatepar(self, input_param: Dict[str, str]) -> None: super().updatepar(input_param) self._smart_paramadd = input_param.copy() self.device_nummer = int(self._smart_paramadd.get('device_nummer', @@ -39,7 +38,7 @@ def updatepar(self, input_param): self._device_password = value else: log.info("(" + str(self.device_nummer) + ") " + - __class__.__name__ + " überlesen " + key + + " AVM überlesen " + key + " " + value) if (self._old_measuretype0 == 'none'): @@ -54,7 +53,7 @@ def updatepar(self, input_param): " update " + self.device_type) self._mydevicemeasure0.updatepar(input_param) - def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): + def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: int) -> None: self.preturn(zustand, ueberschussberechnung, updatecnt) if (zustand == 1): pname = "/on.py" @@ -69,8 +68,7 @@ def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): self._device_username, self._device_password] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/elwa/smartelwa.py b/packages/modules/smarthome/elwa/smartelwa.py index 09198e8ab..2e2f64c18 100644 --- a/packages/modules/smarthome/elwa/smartelwa.py +++ b/packages/modules/smarthome/elwa/smartelwa.py @@ -1,7 +1,6 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase from typing import Dict -import subprocess import logging log = logging.getLogger(__name__) @@ -24,8 +23,7 @@ def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: str(self.device_nummer), str(self._device_ip), str(self.devuberschuss), str(forcesend)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) self.answer = self.readret() self.newwatt = int(self.answer['power']) self.newwattk = int(self.answer['powerc']) @@ -52,8 +50,7 @@ def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: str(self.device_nummer), str(self._device_ip), str(self.devuberschuss)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/http/smarthttp.py b/packages/modules/smarthome/http/smarthttp.py index 510b5086e..ba564f5dc 100644 --- a/packages/modules/smarthome/http/smarthttp.py +++ b/packages/modules/smarthome/http/smarthttp.py @@ -1,19 +1,19 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase, Slhttp -import subprocess +from typing import Dict import logging log = logging.getLogger(__name__) class Shttp(Sbase): - def __init__(self): + def __init__(self) -> None: # setting super().__init__() self._old_measuretype0 = 'none' self._device_einschalturl = 'none' self._device_ausschalturl = 'none' - def getwatt(self, uberschuss, uberschussoffset): + def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: self.prewatt(uberschuss, uberschussoffset) self._mydevicemeasure0.devuberschuss = self.devuberschuss self._mydevicemeasure0.getwattread() @@ -25,7 +25,7 @@ def getwatt(self, uberschuss, uberschussoffset): self.temp2 = self._mydevicemeasure0.temp2 self.postwatt() - def updatepar(self, input_param): + def updatepar(self, input_param: Dict[str, str]) -> None: super().updatepar(input_param) self._smart_paramadd = input_param.copy() self.device_nummer = int(self._smart_paramadd.get('device_nummer', @@ -43,7 +43,7 @@ def updatepar(self, input_param): self._device_ausschalturl = value else: log.info("(" + str(self.device_nummer) + ") " + - __class__.__name__ + " überlesen " + key + + " http überlesen " + key + " " + value) if (self._old_measuretype0 == 'none'): self._mydevicemeasure0 = Slhttp() @@ -57,7 +57,7 @@ def updatepar(self, input_param): " update " + self.device_type) self._mydevicemeasure0.updatepar(input_param) - def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): + def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: int) -> None: self.preturn(zustand, ueberschussberechnung, updatecnt) if (zustand == 1): pname = "/on.py" @@ -70,8 +70,7 @@ def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): str(self.device_nummer), '0', str(self.devuberschuss), url] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/idm/smartidm.py b/packages/modules/smarthome/idm/smartidm.py index 4f1910b39..2d3d25941 100644 --- a/packages/modules/smarthome/idm/smartidm.py +++ b/packages/modules/smarthome/idm/smartidm.py @@ -1,19 +1,18 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase -import subprocess +from typing import Dict import logging log = logging.getLogger(__name__) class Sidm(Sbase): - def __init__(self): + def __init__(self) -> None: # setting super().__init__() - self._smart_paramadd = {} self._device_idmnav = '2' self.device_nummer = 0 - def updatepar(self, input_param): + def updatepar(self, input_param: Dict[str, str]) -> None: super().updatepar(input_param) self._smart_paramadd = input_param.copy() self.device_nummer = int(self._smart_paramadd.get('device_nummer', @@ -25,17 +24,16 @@ def updatepar(self, input_param): self._device_idmnav = value else: log.info("(" + str(self.device_nummer) + ") " + - __class__.__name__ + " überlesen " + key + + " IDM überlesen " + key + " " + value) - def getwatt(self, uberschuss, uberschussoffset): + def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: self.prewatt(uberschuss, uberschussoffset) argumentList = ['python3', self._prefixpy + 'idm/watt.py', str(self.device_nummer), str(self._device_ip), str(self.devuberschuss), str(self._device_idmnav)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) self.answer = self.readret() self.newwatt = int(self.answer['power']) self.newwattk = int(self.answer['powerc']) @@ -47,7 +45,7 @@ def getwatt(self, uberschuss, uberschussoffset): str(self._device_ip), str(e1))) self.postwatt() - def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): + def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: int) -> None: self.preturn(zustand, ueberschussberechnung, updatecnt) if (zustand == 1): pname = "/on.py" @@ -57,8 +55,7 @@ def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): str(self.device_nummer), str(self._device_ip), str(self.devuberschuss), str(self._device_idmnav)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/lambda_/smartlambda.py b/packages/modules/smarthome/lambda_/smartlambda.py index d96afd05a..e5b187ba9 100644 --- a/packages/modules/smarthome/lambda_/smartlambda.py +++ b/packages/modules/smarthome/lambda_/smartlambda.py @@ -1,16 +1,15 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase -import subprocess import logging log = logging.getLogger(__name__) class Slambda(Sbase): - def __init__(self): + def __init__(self) -> None: # setting super().__init__() - def getwatt(self, uberschuss, uberschussoffset): + def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: self.prewatt(uberschuss, uberschussoffset) forcesend = self.checkbefsend() argumentList = ['python3', self._prefixpy + 'lambda_/watt.py', @@ -18,8 +17,7 @@ def getwatt(self, uberschuss, uberschussoffset): str(self.devuberschuss), str(self.device_lambdaueb), str(forcesend)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) self.answer = self.readret() self.newwatt = int(self.answer['power']) self.newwattk = int(self.answer['powerc']) @@ -32,7 +30,7 @@ def getwatt(self, uberschuss, uberschussoffset): str(self._device_ip), str(e1))) self.postwatt() - def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): + def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: int) -> None: self.preturn(zustand, ueberschussberechnung, updatecnt) if (zustand == 1): pname = "/on.py" @@ -42,8 +40,7 @@ def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): str(self.device_nummer), str(self._device_ip), str(self.devuberschuss), str(self.device_lambdaueb)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/mqtt/smartmqtt.py b/packages/modules/smarthome/mqtt/smartmqtt.py index 4460b72e0..0921b144f 100644 --- a/packages/modules/smarthome/mqtt/smartmqtt.py +++ b/packages/modules/smarthome/mqtt/smartmqtt.py @@ -1,17 +1,17 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase, Slmqtt -import subprocess +from typing import Dict import logging log = logging.getLogger(__name__) class Smqtt(Sbase): - def __init__(self): + def __init__(self) -> None: # setting super().__init__() self._old_measuretype0 = 'none' - def getwatt(self, uberschuss, uberschussoffset): + def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: self.prewatt(uberschuss, uberschussoffset) self._mydevicemeasure0.devuberschuss = self.devuberschuss self._mydevicemeasure0.getwattread() @@ -23,7 +23,7 @@ def getwatt(self, uberschuss, uberschussoffset): self.temp2 = self._mydevicemeasure0.temp2 self.postwatt() - def updatepar(self, input_param): + def updatepar(self, input_param: Dict[str, str]) -> None: super().updatepar(input_param) if (self._old_measuretype0 == 'none'): self._mydevicemeasure0 = Slmqtt() @@ -37,7 +37,7 @@ def updatepar(self, input_param): " update " + self.device_type) self._mydevicemeasure0.updatepar(input_param) - def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): + def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: int) -> None: self.preturn(zustand, ueberschussberechnung, updatecnt) if (zustand == 1): pname = "/on.py" @@ -47,8 +47,7 @@ def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): str(self.device_nummer), str(self._device_ip), str(self.devuberschuss)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/mystrom/smartmystrom.py b/packages/modules/smarthome/mystrom/smartmystrom.py index 442562b49..1b43e19bb 100644 --- a/packages/modules/smarthome/mystrom/smartmystrom.py +++ b/packages/modules/smarthome/mystrom/smartmystrom.py @@ -1,17 +1,17 @@ #!/usr/bin/python3 -import subprocess -from smarthome.smartbase import Sbase, Slmystrom import logging +from typing import Dict +from smarthome.smartbase import Sbase, Slmystrom log = logging.getLogger(__name__) class Smystrom(Sbase): - def __init__(self): + def __init__(self) -> None: # setting super().__init__() self._old_measuretype0 = 'none' - def getwatt(self, uberschuss, uberschussoffset): + def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: self.prewatt(uberschuss, uberschussoffset) self._mydevicemeasure0.devuberschuss = self.devuberschuss self._mydevicemeasure0.getwattread() @@ -23,7 +23,7 @@ def getwatt(self, uberschuss, uberschussoffset): self.temp2 = self._mydevicemeasure0.temp2 self.postwatt() - def updatepar(self, input_param): + def updatepar(self, input_param: Dict[str, str]) -> None: super().updatepar(input_param) if (self._old_measuretype0 == 'none'): self._mydevicemeasure0 = Slmystrom() @@ -37,7 +37,7 @@ def updatepar(self, input_param): " update " + self.device_type) self._mydevicemeasure0.updatepar(input_param) - def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): + def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: int) -> None: self.preturn(zustand, ueberschussberechnung, updatecnt) if (zustand == 1): pname = "/on.py" @@ -47,8 +47,7 @@ def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): argumentList = ['python3', self._prefixpy + 'mystrom' + pname, str(self.device_nummer), str(self._device_ip), '0'] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/nxdacxx/smartnxdacxx.py b/packages/modules/smarthome/nxdacxx/smartnxdacxx.py index 9676ff22c..a7715e845 100644 --- a/packages/modules/smarthome/nxdacxx/smartnxdacxx.py +++ b/packages/modules/smarthome/nxdacxx/smartnxdacxx.py @@ -1,7 +1,6 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase from typing import Dict -import subprocess import logging log = logging.getLogger(__name__) @@ -47,8 +46,7 @@ def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: str(self._device_dacport), str(self._device_nxdacxxtype)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) self.answer = self.readret() self.newwatt = int(self.answer['power']) self.newwattk = int(self.answer['powerc']) @@ -73,8 +71,7 @@ def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: str(self._device_dacport), str(self._device_nxdacxxtype)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/ratiotherm/smartratiotherm.py b/packages/modules/smarthome/ratiotherm/smartratiotherm.py index 122b9ac40..6e2e22d9f 100644 --- a/packages/modules/smarthome/ratiotherm/smartratiotherm.py +++ b/packages/modules/smarthome/ratiotherm/smartratiotherm.py @@ -1,6 +1,5 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase -import subprocess import logging log = logging.getLogger(__name__) @@ -19,8 +18,7 @@ def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: str(self.devuberschuss), str(forcesend)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) self.answer = self.readret() self.newwatt = int(self.answer['power']) self.newwattk = int(self.answer['powerc']) @@ -43,8 +41,7 @@ def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: str(self.device_nummer), str(self._device_ip), str(self.devuberschuss)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/shelly/smartshelly.py b/packages/modules/smarthome/shelly/smartshelly.py index ae6619c0c..3f3e4f11b 100644 --- a/packages/modules/smarthome/shelly/smartshelly.py +++ b/packages/modules/smarthome/shelly/smartshelly.py @@ -1,7 +1,6 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase, Slshelly from typing import Dict -import subprocess import logging log = logging.getLogger(__name__) @@ -72,8 +71,7 @@ def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: self._device_shusername, self._device_shpassword] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/stiebel/smartstiebel.py b/packages/modules/smarthome/stiebel/smartstiebel.py index da1bd4b80..e27630c98 100644 --- a/packages/modules/smarthome/stiebel/smartstiebel.py +++ b/packages/modules/smarthome/stiebel/smartstiebel.py @@ -1,23 +1,21 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase -import subprocess import logging log = logging.getLogger(__name__) class Sstiebel(Sbase): - def __init__(self): + def __init__(self) -> None: # setting super().__init__() - def getwatt(self, uberschuss, uberschussoffset): + def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: self.prewatt(uberschuss, uberschussoffset) argumentList = ['python3', self._prefixpy + 'stiebel/watt.py', str(self.device_nummer), str(self._device_ip), str(self.devuberschuss)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) self.answer = self.readret() self.newwatt = int(self.answer['power']) self.newwattk = int(self.answer['powerc']) @@ -29,7 +27,7 @@ def getwatt(self, uberschuss, uberschussoffset): str(self._device_ip), str(e1))) self.postwatt() - def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): + def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: int) -> None: self.preturn(zustand, ueberschussberechnung, updatecnt) if (zustand == 1): pname = "/on.py" @@ -39,8 +37,7 @@ def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): str(self.device_nummer), str(self._device_ip), str(self.devuberschuss)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/tasmota/smarttasmota.py b/packages/modules/smarthome/tasmota/smarttasmota.py index e83714d83..d83c11893 100644 --- a/packages/modules/smarthome/tasmota/smarttasmota.py +++ b/packages/modules/smarthome/tasmota/smarttasmota.py @@ -1,17 +1,17 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase, Sltasmota -import subprocess import logging +from typing import Dict log = logging.getLogger(__name__) class Stasmota(Sbase): - def __init__(self): + def __init__(self) -> None: # setting super().__init__() self._old_measuretype0 = 'none' - def getwatt(self, uberschuss, uberschussoffset): + def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: self.prewatt(uberschuss, uberschussoffset) self._mydevicemeasure0.devuberschuss = self.devuberschuss self._mydevicemeasure0.getwattread() @@ -20,7 +20,7 @@ def getwatt(self, uberschuss, uberschussoffset): self.relais = self._mydevicemeasure0.relais self.postwatt() - def updatepar(self, input_param): + def updatepar(self, input_param: Dict[str, str]) -> None: super().updatepar(input_param) if (self._old_measuretype0 == 'none'): self._mydevicemeasure0 = Sltasmota() @@ -34,7 +34,7 @@ def updatepar(self, input_param): " update " + self.device_type) self._mydevicemeasure0.updatepar(input_param) - def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): + def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: int) -> None: self.preturn(zustand, ueberschussberechnung, updatecnt) if (zustand == 1): pname = "/on.py" @@ -44,8 +44,7 @@ def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): argumentList = ['python3', self._prefixpy + 'tasmota' + pname, str(self.device_nummer), str(self._device_ip), '0'] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/vampair/smartvampair.py b/packages/modules/smarthome/vampair/smartvampair.py index 1e536b1a1..86066fece 100644 --- a/packages/modules/smarthome/vampair/smartvampair.py +++ b/packages/modules/smarthome/vampair/smartvampair.py @@ -1,23 +1,21 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase -import subprocess import logging log = logging.getLogger(__name__) class Svampair(Sbase): - def __init__(self): + def __init__(self) -> None: # setting super().__init__() - def getwatt(self, uberschuss, uberschussoffset): + def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: self.prewatt(uberschuss, uberschussoffset) argumentList = ['python3', self._prefixpy + 'vampair/watt.py', str(self.device_nummer), str(self._device_ip), str(self.devuberschuss)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) self.answer = self.readret() self.newwatt = int(self.answer['power']) self.newwattk = int(self.answer['powerc']) @@ -29,7 +27,7 @@ def getwatt(self, uberschuss, uberschussoffset): str(self._device_ip), str(e1))) self.postwatt() - def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): + def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: int) -> None: self.preturn(zustand, ueberschussberechnung, updatecnt) if (zustand == 1): pname = "/on.py" @@ -39,8 +37,7 @@ def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): str(self.device_nummer), str(self._device_ip), str(self.devuberschuss)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/modules/smarthome/viessmann/smartviessmann.py b/packages/modules/smarthome/viessmann/smartviessmann.py index 7bc0c245e..088ece2b8 100644 --- a/packages/modules/smarthome/viessmann/smartviessmann.py +++ b/packages/modules/smarthome/viessmann/smartviessmann.py @@ -1,30 +1,23 @@ #!/usr/bin/python3 from smarthome.smartbase import Sbase -import subprocess -import json import logging log = logging.getLogger(__name__) class Sviessmann(Sbase): - def __init__(self): + def __init__(self) -> None: # setting super().__init__() print('__init__ Sviessmann executed') - def getwatt(self, uberschuss, uberschussoffset): + def getwatt(self, uberschuss: int, uberschussoffset: int) -> None: self.prewatt(uberschuss, uberschussoffset) argumentList = ['python3', self._prefixpy + 'viessmann/watt.py', str(self.device_nummer), str(self._device_ip), str(self.devuberschuss)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() - self.f1 = open(self._basePath+'/ramdisk/smarthome_device_ret' + - str(self.device_nummer), 'r') - self.answerj = json.load(self.f1) - self.f1.close() - self.answer = json.loads(self.answerj) + self.callpro(argumentList) + self.answer = self.readret() self.newwatt = int(self.answer['power']) self.newwattk = int(self.answer['powerc']) self.relais = int(self.answer['on']) @@ -35,7 +28,7 @@ def getwatt(self, uberschuss, uberschussoffset): str(self._device_ip), str(e1))) self.postwatt() - def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): + def turndevicerelais(self, zustand: int, ueberschussberechnung: int, updatecnt: int) -> None: self.preturn(zustand, ueberschussberechnung, updatecnt) if (zustand == 1): pname = "/on.py" @@ -45,8 +38,7 @@ def turndevicerelais(self, zustand, ueberschussberechnung, updatecnt): str(self.device_nummer), str(self._device_ip), str(self.devuberschuss)] try: - self.proc = subprocess.Popen(argumentList) - self.proc.communicate() + self.callpro(argumentList) except Exception as e1: log.warning("(" + str(self.device_nummer) + ") on / off %s %d %s Fehlermeldung: %s " diff --git a/packages/smarthome/smartbase.py b/packages/smarthome/smartbase.py index e52171d92..a7e66124b 100644 --- a/packages/smarthome/smartbase.py +++ b/packages/smarthome/smartbase.py @@ -166,7 +166,8 @@ def postwatt(self) -> None: else: self.relais = 0 self.mqtt_param = {} - pref = 'openWB/SmartHome/Devices/' + str(self.device_nummer) + '/' + # pref = 'openWB/SmartHome/Devices/' + str(self.device_nummer) + '/' + pref = '/' + str(self.device_nummer) + '/' self.mqtt_param[pref + 'RelayStatus'] = str(self.relais) if (self.c_mantime_f == 'Y') and (self.device_manual != 1): # nach Ausschalten manueller Modus mindestens 30 Sek + @@ -276,7 +277,7 @@ def updatepar(self, input_param: Dict[str, str]) -> None: elif (key == 'device_mineinschaltdauer'): self._device_mineinschaltdauer = valueint * 60 elif (key == 'device_mindayeinschaltdauer'): - self._device_mineinschaltdauer = valueint * 60 + self._device_mindayeinschaltdauer = valueint * 60 elif (key == 'device_maxeinschaltdauer'): self._device_maxeinschaltdauer = valueint * 60 elif (key == 'device_homeConsumtion'): @@ -394,7 +395,8 @@ def updatepar(self, input_param: Dict[str, str]) -> None: + "Sbase überlesen " + key + " " + value) self._first_run = 0 - pref = 'openWB/SmartHome/Devices/' + str(self.device_nummer) + '/' + # pref = 'openWB/SmartHome/Devices/' + str(self.device_nummer) + '/' + pref = '/' + str(self.device_nummer) + '/' self.mqtt_param_del[pref + 'RelayStatus'] = '0' self.mqtt_param_del[pref + 'Watt'] = '0' self.mqtt_param_del[pref + 'oncountnor'] = '0' diff --git a/packages/smarthome/smartbase0.py b/packages/smarthome/smartbase0.py index 7cf252251..0a19a6127 100644 --- a/packages/smarthome/smartbase0.py +++ b/packages/smarthome/smartbase0.py @@ -1,6 +1,9 @@ import json import time +import os +import subprocess import logging +from typing import List log = logging.getLogger(__name__) @@ -45,3 +48,15 @@ def checksend(self, answer): log.warning("(" + str(self.device_nummer) + ") checksend Fehlermeldung: %s " % (str(e1))) + + def callpro(self, argumentList: List[str]) -> None: + try: + my_env = os.environ.copy() + my_env["PYTHONPATH"] = "/var/www/html/openWB/packages" + proc = subprocess.Popen(argumentList, stderr=subprocess.PIPE, + universal_newlines=True, env=my_env) + _, errs = proc.communicate() + if errs: + log.error("%s" % (errs)) + except Exception: + log.exception("Subprocess Fehlermeldung: argumentList %s " % argumentList[1]) diff --git a/packages/smarthome/smartmeas.py b/packages/smarthome/smartmeas.py index 312b2e2f1..444d06e8a 100644 --- a/packages/smarthome/smartmeas.py +++ b/packages/smarthome/smartmeas.py @@ -3,8 +3,6 @@ from modules.common import modbus from modules.common import sdm from modules.common import lovato - -import subprocess import logging log = logging.getLogger(__name__) @@ -174,8 +172,7 @@ def _watt(self, ip: str) -> None: str(self.device_nummer), str(ip), str(self.devuberschuss)] try: - proc = subprocess.Popen(argumentList) - proc.communicate() + self.callpro(argumentList) answer = self.readret() self.newwatt = int(answer['power']) self.newwattk = int(answer['powerc']) @@ -204,8 +201,7 @@ def _watt(self, ip: str, chan: int, shaut: int, shuser: str, shpw: str) -> None: str(self.device_nummer), str(ip), '0', str(chan), str(shaut), shuser, shpw] try: - proc = subprocess.Popen(argumentList) - proc.communicate() + self.callpro(argumentList) answer = self.readret() self.newwatt = int(answer['power']) self.newwattk = int(answer['powerc']) @@ -260,8 +256,7 @@ def _watt(self, ip: str, act: str, user: str, pw: str) -> None: '0', '0', act, user, pw] try: - proc = subprocess.Popen(argumentList) - proc.communicate() + self.callpro(argumentList) answer = self.readret() self.newwatt = int(answer['power']) self.newwattk = int(answer['powerc']) @@ -287,8 +282,7 @@ def _watt(self, ip: str) -> None: argumentList = ['python3', self._prefixpy + 'tasmota/watt.py', str(self.device_nummer), str(ip), '0'] try: - proc = subprocess.Popen(argumentList) - proc.communicate() + self.callpro(argumentList) answer = self.readret() self.newwatt = int(answer['power']) self.newwattk = int(answer['powerc']) @@ -317,11 +311,8 @@ def _watt(self, url: str, urlc: str, urls: str) -> None: str(self.device_nummer), '0', str(self.devuberschuss), url, urlc, '0', '0', urls] - proc = subprocess.Popen(argumentList) - proc.communicate() try: - proc = subprocess.Popen(argumentList) - proc.communicate() + self.callpro(argumentList) answer = self.readret() self.newwatt = int(answer['power']) self.newwattk = int(answer['powerc']) @@ -347,8 +338,7 @@ def _watt(self, ip: str) -> None: argumentList = ['python3', self._prefixpy + 'mystrom/watt.py', str(self.device_nummer), str(ip), '0'] try: - proc = subprocess.Popen(argumentList) - proc.communicate() + self.callpro(argumentList) answer = self.readret() self.newwatt = int(answer['power']) self.newwattk = int(answer['powerc']) @@ -376,8 +366,7 @@ def sepwattread(self) -> Tuple[int, int]: str(self._device_measuresmaser), str(self._device_measuresmaage)] try: - proc = subprocess.Popen(argumentList) - proc.communicate() + self.callpro(argumentList) answer = self.readret() self.newwatt = int(answer['power']) self.newwattk = int(answer['powerc']) @@ -398,8 +387,7 @@ def sepwattread(self) -> Tuple[int, int]: str(self.device_nummer), str(self._device_measureip), str(self._device_measureid)] try: - proc = subprocess.Popen(argumentList) - proc.communicate() + self.callpro(argumentList) answer = self.readret() self.newwatt = int(answer['power']) self.newwattk = int(answer['powerc']) @@ -422,8 +410,7 @@ def sepwattread(self) -> Tuple[int, int]: self._device_measurejsonpower, self._device_measurejsoncounter] try: - proc = subprocess.Popen(argumentList) - proc.communicate() + self.callpro(argumentList) answer = self.readret() self.newwatt = int(answer['power']) self.newwattk = int(answer['powerc']) @@ -443,8 +430,7 @@ def sepwattread(self) -> Tuple[int, int]: str(self.device_nummer), str(self._device_measureip), str(self._device_measureid)] try: - proc = subprocess.Popen(argumentList) - proc.communicate() + self.callpro(argumentList) answer = self.readret() self.newwatt = int(answer['power']) self.newwattk = int(answer['powerc']) diff --git a/runs/evsewritemodbus.py b/runs/evsewritemodbus.py index 80a486ea1..ca6e62ade 100755 --- a/runs/evsewritemodbus.py +++ b/runs/evsewritemodbus.py @@ -1,10 +1,23 @@ #!/usr/bin/python3 +import os import sys -from pymodbus.client.sync import ModbusSerialClient + +from modules.common.evse import Evse +from modules.common.modbus import ModbusSerialClient_ seradd = str(sys.argv[1]) evseid = int(sys.argv[2]) lla = int(sys.argv[3]) -client = ModbusSerialClient(method="rtu", port=seradd, baudrate=9600, stopbits=1, bytesize=8, timeout=1) -rq = client.write_registers(1000, lla, unit=evseid) + +RAMDSIK_PATH = "/var/www/html/openWB/ramdisk/" +EVSE_CONFIGURED_FILE = RAMDSIK_PATH+"evse_configured_"+str(seradd[-4:])+"_"+str(evseid) + +evse = Evse(evseid, ModbusSerialClient_(seradd)) + +if os.path.isfile(EVSE_CONFIGURED_FILE) is False: + evse.deactivate_precise_current() + with open(EVSE_CONFIGURED_FILE, 'w+') as f: + f.write("1") + +rq = evse.set_current(lla) diff --git a/runs/mqttsub.py b/runs/mqttsub.py index 6c15feb91..d44865ea9 100755 --- a/runs/mqttsub.py +++ b/runs/mqttsub.py @@ -152,8 +152,8 @@ def map_run(message: str, device_number: int, option: str): "device_measureip": create_topic_handler(ip_address_validator), "device_name": create_topic_handler((min_length_validator(4), regex_match_validator(name_allowed))), "device_type": create_topic_handler( - equals_one_of_validator("none", "shelly", "tasmota", "acthor", "lambda", "elwa", "idm", "vampair", - "stiebel", "http", "avm", "mystrom", "viessmann", "mqtt", "NXDACXX", "ratiotherm", + equals_one_of_validator("none", "shelly", "tasmota", "acthor", "lambda", "elwa", "askoheat", "idm", "vampair", + "stiebel", "http", "avm", "mystrom", "viessmann", "mqtt", "NXDACXX", "ratiotherm" )), "device_measureType": create_topic_handler( equals_one_of_validator("shelly", "tasmota", "http", "mystrom", "sdm630", "lovato", "we514", "fronius", diff --git a/runs/set-current.sh b/runs/set-current.sh index 182e17c9b..6140c0adc 100755 --- a/runs/set-current.sh +++ b/runs/set-current.sh @@ -94,7 +94,7 @@ function setChargingCurrentModbus () { modbusevsesource=$2 modbusevseid=$3 # set desired charging current - sudo python /var/www/html/openWB/runs/evsewritemodbus.py "$modbusevsesource" "$modbusevseid" "$current" + sudo PYTHONPATH=/var/www/html/openWB/packages python3 /var/www/html/openWB/runs/evsewritemodbus.py "$modbusevsesource" "$modbusevseid" "$current" } function setChargingCurrentBuchse () { diff --git a/runs/smarthomemq.py b/runs/smarthomemq.py index b0997ab9a..2ea53a76a 100755 --- a/runs/smarthomemq.py +++ b/runs/smarthomemq.py @@ -1,34 +1,28 @@ -#!/usr/bin/env python3 -import paho.mqtt.client as mqtt +#!/usr/bin/python3 +from smarthome.smartcommon import mainloop, initparam import time -import re -import os import logging -import math -from typing import Dict, Any, List -from smarthome.global0 import log -from smarthome.smartbase import Sbase -from modules.smarthome.avmhomeautomation.smartavm import Savm -from modules.smarthome.acthor.smartacthor import Sacthor -from modules.smarthome.nxdacxx.smartnxdacxx import Snxdacxx -from modules.smarthome.elwa.smartelwa import Selwa -from modules.smarthome.idm.smartidm import Sidm -from modules.smarthome.http.smarthttp import Shttp -from modules.smarthome.mqtt.smartmqtt import Smqtt -from modules.smarthome.mystrom.smartmystrom import Smystrom -from modules.smarthome.shelly.smartshelly import Sshelly -from modules.smarthome.stiebel.smartstiebel import Sstiebel -from modules.smarthome.vampair.smartvampair import Svampair -from modules.smarthome.lambda_.smartlambda import Slambda -from modules.smarthome.tasmota.smarttasmota import Stasmota -from modules.smarthome.viessmann.smartviessmann import Sviessmann -from modules.smarthome.ratiotherm.smartratiotherm import Sratiotherm +log = logging.getLogger("smarthome") +# openwb 1.9 spec +mqttcg = 'openWB/config/get/SmartHome/' +mqttcs = 'openWB/config/set/SmartHome/' +mqttsdevstat = 'openWB/SmartHome/Devices' +mqttsglobstat = 'openWB/SmartHome/Status/' +mqtttopicdisengageable = 'openWB/SmartHome/Status/wattschalt' +ramdiskwrite = True +mqttport = 1883 +# +# openwb 2.0 spec +# mqttcg = 'openWB/LegacySmartHome/config/get/' +# mqttcs = 'openWB/LegacySmartHome/config/set/' +# mqttsdevstat = 'openWB/LegacySmartHome/Devices' +# mqttsglobstat = 'openWB/LegacySmartHome/Status/' +# mqtttopicdisengageable = 'openWB/set/counter/set/disengageable_smarthome_power' +# ramdiskwrite = False +# mqttport = 1886 +# -mqtt_cache = {} # type: Dict[str, str] -parammqtt = [] # type: List[Any] -mydevices = [] # type: List[Any] bp = '/var/www/html/openWB' -numberOfSupportedDevices = 9 # limit number of smarthome devices def initlog() -> None: @@ -40,64 +34,6 @@ def initlog() -> None: log.addHandler(fh) -def on_connect(client, userdata, flags, rc) -> None: - # client.subscribe("openWB/config/get/SmartHome/Devices/#", 2) - client.subscribe("openWB/config/get/SmartHome/#", 2) - client.subscribe("openWB/SmartHome/Devices/#", 2) - - -def logmq(topic: str, devicenumb: int, keyword: str, value: str) -> None: - global parammqtt - # richtig topic single - if (devicenumb < 1) or (devicenumb > numberOfSupportedDevices): - pass - else: - log.info("(" + str(devicenumb) + ") Key " + str(keyword) + " Value " + str(value)) - parammqtt.append([devicenumb, keyword, value]) - with open(bp+'/ramdisk/smartparam.sh', 'a') as f: - print('%s' % - ('mosquitto_pub -p 1886 -t ' + - '"' + topic + '/' + str(devicenumb) + '/' + keyword + - '" -r -m "' + str(value) + '"'),file=f) -def logmqgl(keyword: str, value: str) -> None: - # richtig topic global - log.info("( global ) Key " + str(keyword) + " Value " + str(value)) - with open(bp+'/ramdisk/smartparam.sh', 'a') as f: - print('%s' % - ('mosquitto_pub -p 1886 -t ' + - '"openWB/config/get/SmartHome/' + keyword + - '" -r -m "' + str(value) + '"'),file=f) - -def on_message(client, userdata, msg) -> None: - # wenn exception hier wird mit nächster msg weitergemacht - # macht paho unter phyton 3 immer so - # für neuer python 3.7 version gibt es absturz - global maxspeicher - try: - devicenumb = int(re.sub(r'\D', '', msg.topic)) - except Exception: - devicenumb = 0 - value = msg.payload.decode("utf-8") - try: - valueint = int(value) - except Exception: - valueint = 0 - if ("openWB/config/get/SmartHome/Devices" in msg.topic): - keyword = re.sub('openWB/config/get/SmartHome/Devices/' - + str(devicenumb) + '/', '', msg.topic) - logmq("openWB/config/get/SmartHome/Devices",devicenumb, keyword, value) - elif ("openWB/SmartHome/Devices" in msg.topic): - keyword = re.sub('openWB/SmartHome/Devices/' - + str(devicenumb) + '/', '', msg.topic) - logmq("openWB/SmartHome/Devices",devicenumb, keyword, value) - elif ("openWB/config/get/SmartHome/maxBatteryPower" in msg.topic): - keyword = re.sub('openWB/config/get/SmartHome/', '', msg.topic) - logmqgl(keyword, value) - maxspeicher = valueint - else: - log.warning(" Skipped msg " + msg.topic + " Value " + value) - - def checkbootdone() -> int: try: with open(bp+'/ramdisk/bootinprogress', 'r') as value: @@ -126,401 +62,42 @@ def checkbootdone() -> int: time.sleep(30) return 0 return 1 -# Lese aus der Ramdisk Regelrelevante Werte ein - - -def loadregelvars() -> None: - global uberschuss - global uberschussoffset - global speicherleistung - global speichersoc - global speichervorhanden - global wattbezug - global numberOfSupportedDevices - global maxspeicher - global mydevices - try: - with open(bp+'/ramdisk/speichervorhanden', 'r') as value: - speichervorhanden = int(value.read()) - if (speichervorhanden == 1): - with open(bp+'/ramdisk/speicherleistung', 'r') as value: - speicherleistung = int(float(value.read())) - with open(bp+'/ramdisk/speichersoc', 'r') as value: - speichersoc = int(float(value.read())) - else: - speicherleistung = 0 - speichersoc = 100 - except Exception as e: - log.warning("Fehler beim Auslesen der Ramdisk " + - "(speichervorhanden,speicherleistung,speichersoc): " + - str(e)) - speichervorhanden = 0 - speicherleistung = 0 - speichersoc = 100 - try: - with open(bp+'/ramdisk/wattbezug', 'r') as value: - wattbezug = int(float(value.read())) * -1 - except Exception as e: - log.warning("Fehler beim Auslesen der Ramdisk (wattbezug):" - + str(e)) - wattbezug = 0 - uberschuss = wattbezug + speicherleistung - uberschussoffset = wattbezug + speicherleistung - maxspeicher - log.info("EVU Bezug(-)/Einspeisung(+): " + str(wattbezug) + - " max Speicherladung: " + str(maxspeicher)) - log.info("Uberschuss: " + str(uberschuss) + - " Uberschuss mit Offset: " + str(uberschussoffset)) - log.info("Speicher Entladung(-)/Ladung(+): " + - str(speicherleistung) + " SpeicherSoC: " + str(speichersoc)) - reread = 0 - try: - with open(bp+'/ramdisk/rereadsmarthomedevices', 'r') as value: - reread = int(value.read()) - except Exception: - reread = 1 - if (reread == 1): - with open(bp+'/ramdisk/rereadsmarthomedevices', 'w') as f: - f.write(str(0)) - readmq() - - for i in range(1, (numberOfSupportedDevices+1)): - try: - with open(bp+'/ramdisk/smarthome_device_manual_' - + str(i), 'r') as value: - for mydevice in mydevices: - if (str(i) == str(mydevice.device_nummer)): - mydevice.device_manual = int(value.read()) - except Exception: - pass - try: - with open(bp+'/ramdisk/smarthome_device_manual_control_' - + str(i), 'r') as value: - for mydevice in mydevices: - if (str(i) == str(mydevice.device_nummer)): - mydevice.device_manual_control = int(value.read()) - except Exception: - pass - - -def getdevicevalues() -> None: - global mydevices - global uberschuss - global uberschussoffset - totalwatt = 0 - totalwattot = 0 - totalminhaus = 0 - # dyn daten einschaltgruppe - Sbase.ausschaltwatt = 0 - Sbase.einrelais = 0 - Sbase.eindevstatus = 0 - mqtt_all = {} - for mydevice in mydevices: - mydevice.getwatt(uberschuss, uberschussoffset) - watt = mydevice.newwatt - wattk = mydevice.newwattk - relais = mydevice.relais - # temp0 = mydevice.temp0 - # temp1 = mydevice.temp1 - # temp2 = mydevice.temp2 - if ((mydevice.abschalt == 1) and (relais == 1) - and (mydevice.device_manual != 1)): - totalwatt = totalwatt + watt - else: - totalwattot = totalwattot + watt - if (mydevice.device_homeconsumtion == 0): - totalminhaus = totalminhaus + watt - log.info("(" + str(mydevice.device_nummer) + ") " + - str(mydevice.device_name) + " rel: " + str(relais) + - " oncnt/onstandby/time: " + str(mydevice.oncountnor) + "/" - + str(mydevice.oncntstandby) + "/" + - str(mydevice.runningtime) + " Status/Üeb: " + - str(mydevice.devstatus) + "/" + - str(mydevice.ueberschussberechnung) + " akt: " + str(watt) + - " Z: " + str(wattk)) - mqtt_all.update(mydevice.mqtt_param) - # device_total_watt is needed for calculation the proper überschuss - # (including switchable smarthomedevices) - - with open(bp+'/ramdisk/devicetotal_watt', 'w') as f: - f.write(str(totalwatt)) - with open(bp+'/ramdisk/devicetotal_watt_other', 'w') as f: - f.write(str(totalwattot)) - with open(bp+'/ramdisk/devicetotal_watt_hausmin', 'w') as f: - f.write(str(totalminhaus)) - log.info("Total Watt abschaltbarer smarthomedevices: " + - str(totalwatt)) - log.info("Total Watt nichtabschaltbarer smarthomedevices: " - + str(totalwattot)) - log.info("Total Watt nicht im Hausverbrauch: " + - str(totalminhaus)) - log.info("Anzahl devices in Auschaltgruppe: " + - str(Sbase.ausdevices) + " akt: " + str(Sbase.ausschaltwatt) + - " Anzahl devices in Einschaltgruppe: " + str(Sbase.eindevices) - ) - nurhh = math.floor(Sbase.nureinschaltinsec / 3600) - nurmm = math.floor((Sbase.nureinschaltinsec - (nurhh * 3600)) / 60) - nurss = (Sbase.nureinschaltinsec - (nurhh * 3600) - (nurmm * 60)) - log.info("Einschaltgruppe rel: " + str(Sbase.einrelais) + - " Summe Einschaltschwelle: " + - str(Sbase.einschwelle) + " max Einschaltverzögerung " + - str(Sbase.einverz) + " nur Einschaltgruppe prüfen bis: " + - str('%.2d' % nurhh) + ":" + str('%.2d' % nurmm) + ":" + - str('%.2d' % nurss) + - " in Total sec " + str(Sbase.nureinschaltinsec) - ) - mqtt_all['openWB/SmartHome/Status/maxspeicherladung'] = maxspeicher - mqtt_all['openWB/SmartHome/Status/wattschalt'] = totalwatt - mqtt_all['openWB/SmartHome/Status/wattnichtschalt'] = totalwattot - mqtt_all['openWB/SmartHome/Status/wattnichtHaus'] = totalminhaus - mqtt_all['openWB/SmartHome/Status/uberschuss'] = uberschuss - mqtt_all['openWB/SmartHome/Status/uberschussoffset'] = uberschussoffset - sendmq(mqtt_all) - - -def sendmq(mqtt_input: Dict[str, str]) -> None: - global mqtt_cache - client = mqtt.Client("openWB-SmartHome-bulkpublisher-" + str(os.getpid())) - client.connect("localhost") - for key, value in mqtt_input.items(): - valueold = mqtt_cache.get(key, 'not in cache') - if (valueold == value): - pass - else: - log.info("Mq pub " + str(key) + "=" + - str(value) + " old " + str(valueold)) - mqtt_cache[key] = value - client.publish(key, payload=value, qos=0, retain=True) - client.loop(timeout=2.0) - client.disconnect() - - -def conditions() -> None: - global mydevices - global speichersoc - for mydevice in mydevices: - mydevice.conditions(speichersoc) - - -def update_devices() -> None: - global parammqtt - global mydevices - global mqtt_cache - client = mqtt.Client("openWB-SmartHome-bulkpublisher-" + str(os.getpid())) - client.connect("localhost") - # statische daten einschaltgruppe - Sbase.ausdevices = 0 - Sbase.eindevices = 0 - Sbase.einverz = 0 - Sbase.einschwelle = 0 - # Nur einschaltgruppe in Sekunden - Sbase.nureinschaltinsec = 0 - for i in range(1, numberOfSupportedDevices+1): - device_configured = 0 - device_type = 'none' - input_param = {} - input_param['device_nummer'] = str(i) - for devicenumb, keyword, value in parammqtt: - if (str(i) == str(devicenumb)): - if (keyword == 'device_configured'): - device_configured = value - if (keyword == 'device_type'): - device_type = value - input_param[keyword] = value - if (device_configured == "1"): - createnew = 1 - for mydevice in mydevices: - if (str(i) == str(mydevice.device_nummer)): - log.info("(" + str(i) + ") " + - "Device bereits erzeugt") - if (device_type == mydevice.device_type): - log.info("(" + str(i) + ") " + - "Typ gleich, nur Parameter update") - createnew = 0 - mydevice.updatepar(input_param) - else: - log.info("(" + str(i) + ") " + - "Typ ungleich " + mydevice.device_type) - mydevice.device_nummer = 0 - mydevice._device_configured = '9' - # del mydevice - mydevices.remove(mydevice) - log.info("(" + str(i) + ") " + - "Device gelöscht") - break - if (createnew == 1): - log.info("(" + str(i) + - ") Neues Devices oder Typänderung: " + - str(device_type)) - if (device_type == 'shelly'): - mydevice = Sshelly() - elif (device_type == 'stiebel'): - mydevice = Sstiebel() - elif (device_type == 'vampair'): - mydevice = Svampair() - elif (device_type == 'lambda'): - mydevice = Slambda() - elif (device_type == 'ratiotherm'): - mydevice = Sratiotherm() - elif (device_type == 'tasmota'): - mydevice = Stasmota() - elif (device_type == 'avm'): - mydevice = Savm() - elif (device_type == 'viessmann'): - mydevice = Sviessmann() - elif (device_type == 'acthor'): - mydevice = Sacthor() - elif (device_type == 'NXDACXX'): - mydevice = Snxdacxx() - elif (device_type == 'elwa'): - mydevice = Selwa() - elif (device_type == 'idm'): - mydevice = Sidm() - elif (device_type == 'mqtt'): - mydevice = Smqtt() - elif (device_type == 'http'): - mydevice = Shttp() - elif (device_type == 'mystrom'): - mydevice = Smystrom() - else: - mydevice = Sbase() - mydevice.updatepar(input_param) - mydevices.append(mydevice) - else: - log.info("(" + str(i) + ") " + - "Device nicht (länger) definiert") - for mydevice in mydevices: - if (str(i) == str(mydevice.device_nummer)): - # cleant up mqtt - for key, value in mydevice.mqtt_param_del.items(): - valueold = mqtt_cache.pop(key, 'not in cache') - log.info("Mq pub " + str(key) + "=" + - str(value) + " old " + str(valueold)) - client.publish(key, payload=value, qos=0, retain=True) - client.loop(timeout=2.0) - mydevice.device_nummer = 0 - mydevice._device_configured = '9' - # del mydevice - mydevices.remove(mydevice) - log.info("(" + str(i) + ") " + - "Device gelöscht") - client.disconnect() - - -def readmq() -> None: - global parammqtt - global mydevices - log.info("Config reRead start / Parameter check") - with open(bp+'/ramdisk/smartparam.sh', 'w') as f: - print('%s' % ('#!/bin/bash'),file=f) - parammqtt = [] - client = mqtt.Client("openWB-mqttsmarthome") - client.on_connect = on_connect - client.on_message = on_message - startTime = time.time() - waitTime = 5 - client.connect("localhost") - while True: - client.loop() - elapsedTime = time.time() - startTime - if elapsedTime > waitTime: - client.disconnect() - break - log.info("Config reRead / Parameter check done") - update_devices() - log.info("Config reRead done") - - -def resetmaxeinschaltdauerfunc() -> None: - global resetmaxeinschaltdauer - global numberOfSupportedDevices - global mydevices - mqtt_reset = {} - hour = time.strftime("%H") - if (int(hour) == 0): - if (int(resetmaxeinschaltdauer) == 0): - for i in range(1, (numberOfSupportedDevices+1)): - for mydevice in mydevices: - if (str(i) == str(mydevice.device_nummer)): - pref = 'openWB/SmartHome/Devices/' + str(i) + '/' - mydevice.runningtime = 0 - mqtt_reset[pref + 'RunningTimeToday'] = '0' - log.info("(" + str(i) + - ") RunningTime auf 0 gesetzt") - mydevice.oncountnor = '0' - mqtt_reset[pref + 'oncountnor'] = '0' - # Sofern Anlauferkennung laueft counter nicht zuruecksetzen - if (mydevice.devstatus != 20): - mydevice.oncntstandby = '0' - mqtt_reset[pref + 'OnCntStandby'] = '0' - mydevice.c_oldstampeinschaltdauer = 0 - mydevice.c_oldstampeinschaltdauer_f = 'N' - pref = 'openWB/config/set/SmartHome/Devices/' + str(i) + '/' - if ((mydevice.device_setauto == 1) and - (mydevice.device_manual == 1)): - log.info("(" + str(i) + - ") Umschaltung auf automatisch Modus ") - mqtt_reset[pref + 'mode'] = '0' - resetmaxeinschaltdauer = 1 - # Nur einschaltgruppe in Sekunden für neuen Tag zurücksetzten - Sbase.nureinschaltinsec = 0 - sendmq(mqtt_reset) - if (int(hour) == 1): - resetmaxeinschaltdauer = 0 +# Lese aus der Ramdisk Regelrelevante Werte ein if __name__ == "__main__": - resetmaxeinschaltdauer = 0 - maxspeicher = 0 - speicherleistung = 0 - speichersoc = 100 - speichervorhanden = 0 - wattbezug = 0 - uberschuss = 0 - uberschussoffset = 0 initlog() - log.info("*** Smarthome mq Start ***") + log.info("*** Smarthome mq openWB 1.9 Start ***") + initparam(mqttcg, mqttcs, mqttsdevstat, mqttsglobstat, mqtttopicdisengageable, ramdiskwrite, mqttport) while True: if (checkbootdone() == 1): break time.sleep(5) - readmq() - time.sleep(5) while True: - # update_devices() - mqtt_man = {} - sendmess = 0 - loadregelvars() - resetmaxeinschaltdauerfunc() - getdevicevalues() - conditions() - # do the manual stuff - for i in range(1, (numberOfSupportedDevices+1)): - for mydevice in mydevices: - if (str(i) == str(mydevice.device_nummer)): - if (mydevice.device_manual == 1): - if (mydevice.device_manual_control == 0): - if (mydevice.relais == 1): - mydevice.turndevicerelais(0, 0, 1) - if (mydevice.device_manual_control == 1): - if (mydevice.relais == 0): - mydevice.turndevicerelais(1, 0, 1) - mydevice.c_mantime_f = 'Y' - mydevice.c_mantime = time.time() - log.info("(" + str(i) + ") " + - mydevice.device_name + - " manueller Modus aktiviert, keine Regelung") - for i in range(1, (numberOfSupportedDevices+1)): - pref = 'openWB/config/set/SmartHome/Devices/' + str(i) + '/' - for mydevice in mydevices: - if (str(i) == str(mydevice.device_nummer)): - mydevice.updatebutton() - if (mydevice.btchange == 1): - sendmess = 1 - mqtt_man[pref + 'mode'] = mydevice.newdevice_manual - if (mydevice.btchange == 2): - sendmess = 1 - workman = mydevice.newdevice_manual_control - mqtt_man[pref + 'device_manual_control'] = workman - if (sendmess == 1): - sendmq(mqtt_man) - time.sleep(5) + try: + with open(bp+'/ramdisk/speichervorhanden', 'r') as value: + speichervorhanden = int(value.read()) + if (speichervorhanden == 1): + with open(bp+'/ramdisk/speicherleistung', 'r') as value: + speicherleistung = int(float(value.read())) + with open(bp+'/ramdisk/speichersoc', 'r') as value: + speichersoc = int(float(value.read())) + else: + speicherleistung = 0 + speichersoc = 100 + except Exception as e: + log.warning("Fehler beim Auslesen der Ramdisk " + + "(speichervorhanden,speicherleistung,speichersoc): " + + str(e)) + speichervorhanden = 0 + speicherleistung = 0 + speichersoc = 100 + try: + with open(bp+'/ramdisk/wattbezug', 'r') as value: + wattbezug = int(float(value.read())) * -1 + except Exception as e: + log.warning("Fehler beim Auslesen der Ramdisk (wattbezug):" + + str(e)) + wattbezug = 0 + mainloop(wattbezug, speicherleistung, speichersoc) + diff --git a/web/settings/modulconfigbat.php b/web/settings/modulconfigbat.php index 117b0ac93..724568b7e 100644 --- a/web/settings/modulconfigbat.php +++ b/web/settings/modulconfigbat.php @@ -90,7 +90,7 @@ - + @@ -261,22 +261,11 @@ function visibility_solarwatt_ip2() {
-
- -
- - Hier kann ein abweichender Netzwerk-Port angegeben werden, auf dem die Modbus/TCP Verbindung aufgebaut wird.Standard ist 502. -
-
-
- -
- - Gültige Werte 1-254. Standard ist 1. -
+
+ Bitte halten Sie zur Fehlervermeidung die Firmware des Sungrow Wechselrichters und Wii Net Dongels aktuell.
- Es muss Sungrow als PV und EVU Modul gewählt werden. + Es muss Sungrow Variante SH im Modul PV1 und gegebenenfalls Sungrow als EVU Modul gewählt werden.
@@ -801,7 +790,6 @@ function display_speichermodul() { } if($('#speichermodul').val() == 'speicher_sungrow') { - showSection('#divspeicherip'); showSection('#divspeichersungrow'); } if($('#speichermodul').val() == 'speicher_good_we') { diff --git a/web/settings/modulconfigevu.php b/web/settings/modulconfigevu.php index 2a60aed7d..caba28113 100644 --- a/web/settings/modulconfigevu.php +++ b/web/settings/modulconfigevu.php @@ -101,7 +101,7 @@ - + @@ -141,17 +141,7 @@
- Konfiguration im zugehörigen Speichermodul des Sungrow erforderlich! -
-
- -
- -
+ Konfiguration im zugehörigen PV-Modul 1 mit Auswahl Sungrow erforderlich!
diff --git a/web/settings/modulconfigpv.php b/web/settings/modulconfigpv.php index ee11376e2..64332849b 100644 --- a/web/settings/modulconfigpv.php +++ b/web/settings/modulconfigpv.php @@ -162,6 +162,20 @@
+
+ +
+ +
+
+ 1) Die Variante SH mit Batterie nur über die LAN IP mit OPenWB nutzbar (Hierzu hinter dem WiNet den Lan Anschluss nutzen). WiNet zusätzlich ins Heimnetz (per Lan oder Wlan) einbinden um ISolarCloud nutzen zu können. + 2) Bitte halten Sie zur Fehlervermeidung die Firmware des Sungrow Wechselrichters und WiNet-Dongls aktuell. +
+
Konfiguration im zugehörigen Speichermodul des Sungrow erforderlich!
@@ -1118,6 +1132,8 @@ function display_pvwattmodul() { showSection('#pvbatterx'); } if($('#pvwattmodul').val() == 'wr_sungrow') { + showSection('#pvip'); + showSection('#pvid'); showSection('#pvsungrow'); } if($('#pvwattmodul').val() == 'wr_sonneneco') { @@ -1357,6 +1373,22 @@ function display_pvwattmodul() {
+
+
+ +
+ +
+
+ 1) Die Variante SH kann bei PV2 nur ohne Batterie berücksichtigt werden. Mit angeschlossener Batterie und Sungrow EVU nur an PV1 nutzbar. + 2) Bitte halten Sie zur Fehlervermeidung die Firmware des Sungrow Wechselrichters und WiNet-Dongls aktuell. +
+
+
@@ -1439,8 +1471,9 @@ function display_pv2wattmodul() { } if($('#pv2wattmodul').val() == 'wr2_sungrow') { showSection('#pv2ipdiv'); - showSection('#pv2portdiv'); showSection('#pv2iddiv'); + showSection('#pv2sungrow'); + } if($('#pv2wattmodul').val() == 'wr2_kostalpiko') { diff --git a/web/settings/smarthomeconfig.php b/web/settings/smarthomeconfig.php index 8d8391125..56f51a07a 100644 --- a/web/settings/smarthomeconfig.php +++ b/web/settings/smarthomeconfig.php @@ -94,6 +94,7 @@ + Dieser Gerätetyp wird nicht in die Regelung eingebunden und es können keine Schalthandlungen ausgeführt oder Sensoren eingelesen werden. Es ist jedoch eine separate Leistungsmessung möglich, um reine Verbraucher zu erfassen. @@ -155,6 +156,15 @@ Die Warmwassersicherstellung in Elwa kann genutzt werden. OpenWB erkennt dieses am Status und überträgt dann keinen Überschuss. Wenn Elwa als Gerät 1 oder 2 definiert ist, wird die Warmwassertemperatur als Temp1 angezeigt (Modbusadresse 1001). + + Heizstab Askoheat+ der Firma ASKOMA AG
+ Im web Frontend vom Heizstab muss unter Expertsetup / Setup 3 eine Statische IP Adresse und der Modbus TCP Port 502 (nicht 520) erfasst werden. + Wenn die Einschaltbedingung erreicht ist wird alle 30 Sekunden der gerechnete Überschuss übertragen. + Mit dem Parameter Updategerät kann eine abweichende Sekundenzahl angegeben werden. + Wenn die Ausschaltbedingung erreicht ist wird einmalig 0 als Überschuss übertragen. + Die Ausschaltschwelle/ Ausschaltverzögerung in OpenWB ist sinnvoll zu wählen (z.B. 500 / 3) um die Regelung von Askoheat+ nicht zu stören. + Wenn Askoheat+ als Gerät 1 oder 2 definiert ist, wird die Temperatur von internen Sensort als Temp1 angezeigt (Modbusadresse 638). +
Wärmepumpe der Firma IDM mit Navigatorregelung 1.7/2.0
Im Web Frontend muss unter "Heizungsbauerebene / Konfiguration / PV-Signal": Auswahl "Gebäudeleittechnik / Smartfox" und unter "Heizungsbauerebene / Gebäudeleittechnik" der Parameter "Modbus TCP = Ein" und unter "Einstellungen / Photovoltaik" der Parameter "PV Überschuss = 0" gesetzt werden @@ -288,7 +298,7 @@
-
+

@@ -417,7 +427,7 @@
-
+

@@ -722,7 +732,7 @@
Parameter in % Ladezustand. 0% deaktiviert die Funktion. Bei deaktivierter Funktion oder wenn der Ladezustand grösser gleich dem Parameter ist, wird die Speicherleistung bei der Berechnung der Ein- und Ausschaltschwelle berücksichtigt.
- Unterhalb dieses Wertes ist für die Berechnung der Ein und Ausschaltschwelle nur die aktuelle Leisung am EVU Punkt und die maximal mögliche Speicherladung (als Offset) relevant.
+ Unterhalb dieses Wertes ist für die Berechnung der Ein und Ausschaltschwelle nur die aktuelle Leistung am EVU Punkt und die maximal mögliche Speicherladung (als Offset) relevant.
diff --git a/web/themes/colors/powerdata.js b/web/themes/colors/powerdata.js index 03417e311..beab30e75 100644 --- a/web/themes/colors/powerdata.js +++ b/web/themes/colors/powerdata.js @@ -49,6 +49,7 @@ class WbData { "charging": { name: "Laden", power: 0, energy: 0, energyPv: 0, energyBat: 0, pvPercentage: 0, color: "white", icon: "\uf5e7" }, "devices": { name: "Geräte", power: 0, energy: 0, energyPv: 0, energyBat: 0, pvPercentage: 0, color: "white", icon: "\uf1e6" }, }; + this.historicSummary = { "evuIn": { name: "Netz", power: 0, energy: 0, energyPv: 0, energyBat: 0, pvPercentage: 0, color: "white", icon: "\uf275" }, @@ -60,7 +61,15 @@ class WbData { "charging": { name: "Laden", power: 0, energy: 0, energyPv: 0, energyBat: 0, pvPercentage: 0, color: "white", icon: "\uf5e7" }, "devices": { name: "Geräte", power: 0, energy: 0, energyPv: 0, energyBat: 0, pvPercentage: 0, color: "white", icon: "\uf1e6" }, }; - + this.chargePoint.map ((cp,i) => { + this.usageSummary['lp'+i] = cp + this.historicSummary['lp'+i] = cp + + }) + this.shDevice.map ((sh,i) => { + this.usageSummary['sh'+i] = sh + this.historicSummary['sh'+i] = sh + }) this.usageDetails = [this.usageSummary.evuOut]; this.graphPreference = "live"; this.graphMode = "live"; @@ -70,6 +79,7 @@ class WbData { this.usageStackOrder = 0; this.decimalPlaces = 1; this.smartHomeColors = "normal"; + this.chargepointSummary = true; this.smartHomeSummary = true; this.preferWideBoxes = false; this.preferredLayout = 'dynamic'; @@ -281,6 +291,9 @@ class WbData { case 'soc': powerMeter.update(); break; + case 'name': + this.chargePoint[index-1]['icon'] = value + break default: break; } @@ -355,6 +368,7 @@ class WbData { updateUsageDetails() { this.usageDetails = [this.usageSummary.evuOut, this.usageSummary.batIn, this.usageSummary.house, this.usageSummary.charging] + .concat(this.chargePoint.filter(row => (row.configured))) .concat(this.shDevice.filter(row => (row.configured && row.showInGraph))) .concat(this.consumer.filter(row => (row.configured))); } @@ -378,6 +392,7 @@ class WbData { this.prefs.showGr = this.showGrid; this.prefs.decimalP = this.decimalPlaces; this.prefs.smartHomeC = this.smartHomeColors; + this.prefs.chargepointSum = this.chargepointSummary; this.prefs.smartHomeSum = this.smartHomeSummary; this.prefs.wideBoxes = this.preferWideBoxes; this.prefs.layout = this.preferredLayout; @@ -416,6 +431,9 @@ class WbData { if ('smartHomeC' in this.prefs) { this.smartHomeColors = this.prefs.smartHomeC; } + if ('chargepointSum' in this.prefs) { + this.chargepointSummary = this.prefs.chargepointSum; + } if ('smartHomeSum' in this.prefs) { this.smartHomeSummary = this.prefs.smartHomeSum; } @@ -452,8 +470,11 @@ class ChargePoint { constructor(index, name = "", power = 0, dailyYield = 0, configured = false, isSocConfigured = false, isSocManual = false) { this.id = index; this.name = name; + this.icon = name; this.power = power; this.energy = dailyYield; + this.energyPv = 0; + this.energyBat = 0; this.configured = configured; this.isSocConfigured = isSocConfigured; this.isSocManual = isSocManual; @@ -690,13 +711,18 @@ function switchSmartHomeColors() { wbdata.persistGraphPreferences(); } +function toggleChargepointSummary() { + wbdata.chargepointSummary = !wbdata.chargepointSummary + yieldMeter.update() + wbdata.persistGraphPreferences(); +} + function toggleSmartHomeSummary() { wbdata.smartHomeSummary = !wbdata.smartHomeSummary yieldMeter.update() wbdata.persistGraphPreferences(); } - function toggleMonthView() { switch (wbdata.graphMode) { case 'year': diff --git a/web/themes/colors/powergraph.js b/web/themes/colors/powergraph.js index dc6f83056..4d82745e1 100644 --- a/web/themes/colors/powergraph.js +++ b/web/themes/colors/powergraph.js @@ -29,7 +29,7 @@ class PowerGraph { init() { var style = getComputedStyle(document.body); - this.colors.housePower = 'var(--color-house)'; + this.colors.house = 'var(--color-house)'; this.colors.batIn = 'var(--color-battery)'; this.colors.inverter = 'var(--color-pv)'; this.gridColors[0] = 'var(--color-battery)'; @@ -57,6 +57,10 @@ class PowerGraph { } this.colors.co0 = 'var(--color-co1)'; this.colors.co1 = 'var(--color-co2)'; + this.consumerCategories = ['charging', 'house', 'batIn', 'devices', + 'sh0', 'sh1', 'sh2', 'sh3', 'sh4', 'sh5', 'sh6', 'sh7', 'sh8', + 'lp0', 'lp1', 'lp2', 'lp3', 'lp4', 'lp5', 'lp6', 'lp7', 'lp8'] + var figure = d3.select("figure#powergraph"); this.svg = figure.append("svg") @@ -127,7 +131,7 @@ class PowerGraph { heading = formatMonth(wbdata.graphMonth.month, wbdata.graphMonth.year); break; case 'year': - heading = wbdata.graphYear; + heading = wbdata.graphYear; break; default: break; } @@ -248,12 +252,10 @@ class PowerGraph { } if (this.initCounter == 12) {// Initialization complete unsubscribeDayGraph(); - let chargingPv = 0 - let chargingBat = 0 - let shPv = 0 - let shBat = 0 - let housePv = 0 - let houseBat = 0 + this.consumerCategories.map(cat => { + wbdata.usageSummary[cat].energyPv = 0 + wbdata.usageSummary[cat].energyBat = 0 + }) let calculatedHouseEnergy = 0; this.initCounter = 0; this.staging.map(segment => @@ -263,19 +265,19 @@ class PowerGraph { if (i > 0) { const values = this.extractDayValues(line, a[i - 1]); this.graphData.push(values); - chargingPv += (values.chargingPv / 12) - chargingBat += (values.chargingBat / 12) - shPv += (values.shPv / 12) - shBat += (values.shBat / 12) - housePv += (values.housePv / 12) - houseBat += (values.houseBat / 12) - calculatedHouseEnergy += (values.housePower / 12) - } else { - // const values = this.extractValues(line, []); + this.consumerCategories.map(cat => { + wbdata.usageSummary[cat].energyPv += (values[cat + 'Pv'] / 12) + wbdata.usageSummary[cat].energyBat += (values[cat + 'Bat'] / 12) + }) + calculatedHouseEnergy += (values.house / 12) } }); + this.consumerCategories.map(cat => { + wbdata.usageSummary[cat].energyPv = Math.round (wbdata.usageSummary[cat].energyPv /10) / 100 + wbdata.usageSummary[cat].energyBat = Math.round (wbdata.usageSummary[cat].energyBat /10) / 100 + }) this.updateGraph(); - this.updateEnergyValues(chargingPv, chargingBat, shPv, shBat, housePv, houseBat, calculatedHouseEnergy/1000); + this.updateEnergyValues(/* chargingPv, chargingBat, shPv, shBat, housePv, houseBat, */ calculatedHouseEnergy / 1000); wbdata.dayGraphUpdated(); setTimeout(() => this.activateDay(), 300000) } @@ -284,7 +286,6 @@ class PowerGraph { updateMonth(topic, payload) { if (payload != 'empty') { const serialNo = topic.substring(29, topic.length); - var segment = payload.toString().split("\n"); if (segment[0] == "") { segment = []; @@ -295,7 +296,6 @@ class PowerGraph { this.initCounter++; } } - if (this.initCounter == 12) {// Initialization complete unsubscribeMonthGraph(); this.initCounter = 0; @@ -317,7 +317,6 @@ class PowerGraph { } } }); - this.updateGraph(); this.updateMonthlyEnergyValues(); wbdata.monthGraphUpdated(); @@ -355,10 +354,9 @@ class PowerGraph { if (values.date.getFullYear() == wbdata.graphYear) { this.graphData.push(values); let va = line.split(',') - this.monthlyAmounts = this.monthlyAmounts.map((e,i)=>e+parseFloat(va[i])) + this.monthlyAmounts = this.monthlyAmounts.map((e, i) => e + parseFloat(va[i])) } } - }); this.updateGraph(); this.updateAnnualEnergyValues(); @@ -367,7 +365,7 @@ class PowerGraph { } } - updateEnergyValues(chargingPv, chargingBat, shPv, shBat, housePv, houseBat, calculatedHouse) { + updateEnergyValues(/* chargingPv, chargingBat, shPv, shBat, housePv, houseBat, */ calculatedHouse) { if (this.rawData.length) { const startValues = this.rawData[0].split(','); const endValues = this.rawData[this.rawData.length - 1].split(','); @@ -391,31 +389,18 @@ class PowerGraph { wbdata.historicSummary.batIn.energy = (endValues[8] - startValues[8]) / 1000; wbdata.historicSummary.house.energy = wbdata.historicSummary.evuIn.energy + wbdata.historicSummary.pv.energy + wbdata.historicSummary.batOut.energy - wbdata.historicSummary.evuOut.energy - wbdata.historicSummary.batIn.energy - wbdata.historicSummary.charging.energy - wbdata.historicSummary.devices.energy; - wbdata.historicSummary.charging.energyPv = chargingPv / 1000; - wbdata.historicSummary.charging.energyBat = chargingBat / 1000; - wbdata.usageSummary.charging.energyPv = chargingPv / 1000; - wbdata.usageSummary.charging.energyBat = chargingBat / 1000; - wbdata.usageSummary.charging.pvPercentage = Math.round((wbdata.usageSummary.charging.energyPv + wbdata.usageSummary.charging.energyBat) / (wbdata.usageSummary.charging.energy) * 100) - wbdata.historicSummary.charging.pvPercentage = Math.round((wbdata.historicSummary.charging.energyPv + wbdata.historicSummary.charging.energyBat) / (wbdata.historicSummary.charging.energy) * 100) - wbdata.historicSummary.devices.energyPv = shPv / 1000; - wbdata.usageSummary.devices.energyPv = shPv / 1000; - wbdata.historicSummary.devices.energyBat = shBat / 1000; - wbdata.usageSummary.devices.energyBat = shBat / 1000; - wbdata.usageSummary.devices.pvPercentage = Math.round((wbdata.usageSummary.devices.energyPv + wbdata.usageSummary.devices.energyBat) / (wbdata.usageSummary.devices.energy) * 100) - wbdata.historicSummary.devices.pvPercentage = Math.round((wbdata.historicSummary.devices.energyPv + wbdata.historicSummary.devices.energyBat) / (wbdata.historicSummary.devices.energy) * 100) - // correct for incorrect calculations of PV or Bat portion - if (calculatedHouse > wbdata.historicSummary.house.energy) { - housePv = housePv / calculatedHouse * wbdata.historicSummary.house.energy - houseBat = houseBat / calculatedHouse * wbdata.historicSummary.house.energy - } - wbdata.historicSummary.house.energyPv = housePv / 1000; - wbdata.usageSummary.house.energyPv = housePv / 1000; - wbdata.historicSummary.house.energyBat = houseBat / 1000; - wbdata.usageSummary.house.energyBat = houseBat / 1000; - wbdata.usageSummary.house.pvPercentage = Math.round((wbdata.usageSummary.house.energyPv + wbdata.usageSummary.house.energyBat) / (wbdata.usageSummary.house.energy) * 100) - wbdata.historicSummary.house.pvPercentage = Math.round((wbdata.historicSummary.house.energyPv + wbdata.historicSummary.house.energyBat) / (wbdata.historicSummary.house.energy) * 100) + // correct for incorrect calculations of PV or Bat portionif (calculatedHouse > wbdata.historicSummary.house.energy) { + wbdata.usageSummary.house.energyPv = wbdata.usageSummary.house.energyPv / calculatedHouse * wbdata.usageSummary.house.energy + wbdata.usageSummary.house.energyBat = wbdata.usageSummary.house.energyBat / calculatedHouse * wbdata.usageSummary.house.energy } + this.consumerCategories.map(cat => { + wbdata.usageSummary[cat].pvPercentage = Math.round((wbdata.usageSummary[cat].energyPv + wbdata.usageSummary[cat].energyBat) / (wbdata.usageSummary[cat].energy) * 100) + wbdata.historicSummary[cat].energyPv = wbdata.usageSummary[cat].energyPv + wbdata.historicSummary[cat].energyBat = wbdata.usageSummary[cat].energyBat + wbdata.historicSummary[cat].pvPercentage = wbdata.usageSummary[cat].pvPercentage + }) } + updateMonthlyEnergyValues() { if (this.rawData.length) { wbdata.historicSummary.pv.energy = +this.monthlyAmounts[3]; @@ -462,14 +447,6 @@ class PowerGraph { } updateAnnualEnergyValues() { if (this.rawData.length) { - const startValues = this.rawData[0].split(','); - const endValues = this.rawData[this.rawData.length - 1].split(','); - /* wbdata.historicSummary.pv.energy = (endValues[3] - startValues[3]) / 1000; - wbdata.historicSummary.evuIn.energy = (endValues[1] - startValues[1]) / 1000; - wbdata.historicSummary.batOut.energy = (endValues[18] - startValues[18]) / 1000; - wbdata.historicSummary.evuOut.energy = (endValues[2] - startValues[2]) / 1000; - wbdata.historicSummary.charging.energy = (endValues[7] - startValues[7]) / 1000; */ - wbdata.historicSummary.pv.energy = +this.monthlyAmounts[3]; wbdata.historicSummary.evuIn.energy = +this.monthlyAmounts[1]; wbdata.historicSummary.batOut.energy = +this.monthlyAmounts[18]; @@ -541,7 +518,7 @@ class PowerGraph { values.inverter = -elements[3] } // calculated values - values.housePower = +elements[11]; + values.house = +elements[11]; values.selfUsage = values.solarPower - values.gridPush; if (values.selfUsage < 0) { values.selfUsage = 0; @@ -582,7 +559,6 @@ class PowerGraph { return values; } - extractDayValues(payload, oldPayload) { const elements = payload.split(","); const oldElements = oldPayload.split(","); @@ -625,36 +601,26 @@ class PowerGraph { values.batOut = this.calcValue(9, elements, oldElements); values.batterySoc = +elements[20]; // calculated values - values.housePower = values.gridPull + values.solarPower + values.batOut + values.house = values.gridPull + values.solarPower + values.batOut - values.gridPush - values.batIn - values.charging - values.co0 - values.co1 - values.sh0 - values.sh1 - values.sh2 - values.sh3 - values.sh4 - values.sh5 - values.sh6 - values.sh7 - values.sh8; - if (values.housePower < 0) { values.housePower = 0; }; + if (values.house < 0) { values.house = 0; }; values.selfUsage = values.solarPower - values.gridPush; if (values.selfUsage < 0) { values.selfUsage = 0; }; if ((values.solarPower + values.gridPull + values.batOut) > 0) { - values.chargingPv = this.calcPvFraction(values.charging, values) - values.chargingBat = this.calcBatFraction(values.charging, values) - values.shPv = this.calcPvFraction(values.devices, values) - values.shBat = this.calcBatFraction(values.devices, values) - values.housePv = this.calcPvFraction(values.housePower, values) - values.houseBat = this.calcBatFraction(values.housePower, values) - + this.consumerCategories.map(cat => this.calcAutFraction(cat, values)) } else { - values.chargingPv = 0; - values.chargingBat = 0; - values.shPv = 0; - values.shBat = 0; - values.housePv = 0; - values.houseBat = 0; + this.consumerCategories.map(cat => { + values[cat + 'Pv'] = 0 + values[cat + 'Bat'] = 0 + }) } return values; } - calcPvFraction(energy, values) { - return Math.floor((energy * (values.solarPower - values.gridPush) / (values.solarPower -values.gridPush + values.gridPull + values.batOut))) - } - calcBatFraction(energy, values) { - return Math.floor((energy * values.batOut / (values.solarPower -values.gridPush + values.gridPull + values.batOut))) + calcAutFraction(cat, values) { + values[cat + 'Pv'] = Math.floor((values[cat] * (values.solarPower - values.gridPush) / (values.solarPower - values.gridPush + values.gridPull + values.batOut))) + values[cat + 'Bat'] = Math.floor((values[cat] * (values.batOut) / (values.solarPower - values.gridPush + values.gridPull + values.batOut))) } extractMonthValues(payload) { @@ -693,20 +659,16 @@ class PowerGraph { values.batOut = this.calcMonthlyValue(18, elements); values.batterySoc = +elements[20]; // calculated values - values.housePower = values.gridPull + values.solarPower + values.batOut + values.house = values.gridPull + values.solarPower + values.batOut - values.gridPush - values.batIn - values.charging - values.co0 - values.co1 - - values.sh0 - values.sh1 - values.sh2 - values.sh3 - values.sh4 - values.sh5 - values.sh6 - values.sh7 - values.sh8 - values.sh9; if (values.housePower < 0) { values.housePower = 0; }; + - values.sh0 - values.sh1 - values.sh2 - values.sh3 - values.sh4 - values.sh5 - values.sh6 - values.sh7 - values.sh8 - values.sh9; if (values.house < 0) { values.house = 0; }; values.selfUsage = values.solarPower - values.gridPush; if (values.selfUsage < 0) { values.selfUsage = 0; }; if ((values.solarPower + values.gridPull + values.batOut) > 0) { - values.chargingPv = this.calcPvFraction(values.charging, values) - values.chargingBat = this.calcBatFraction(values.charging, values) - values.shPv = this.calcPvFraction(values.devices, values) - values.shBat = this.calcBatFraction(values.devices, values) - values.housePv = this.calcPvFraction(values.housePower, values) - values.houseBat = this.calcBatFraction(values.housePower, values) - - } else { + this.calcAutFraction("charging", values) + this.calcAutFraction("devices", values) + this.calcAutFraction("house", values) + } else { values.chargingPv = 0; values.chargingBat = 0; values.shPv = 0; @@ -812,10 +774,10 @@ class PowerGraph { .paddingInner(0.4); break; case 'year': - const monthRange = d3.extent(this.graphData, (d => months[d.date.getMonth()+1])) + const monthRange = d3.extent(this.graphData, (d => months[d.date.getMonth() + 1])) this.xScale = d3.scaleBand() //.domain(Array.from({ length: (monthRange[1] - monthRange[0] + 1) }, (v, k) => k + monthRange[0])) - .domain (months) + .domain(months) .paddingInner(0.4); break; default: @@ -827,9 +789,9 @@ class PowerGraph { const extent = d3.extent(this.graphData, (d) => Math.max(d.solarPower + d.gridPull + d.batOut, d.selfUsage + d.gridPush)); - - yScale.domain([0, Math.ceil(extent[1] / 1000) * 1000]); - + + yScale.domain([0, Math.ceil(extent[1] / 1000) * 1000]); + const stackGen = d3.stack().keys(keys); const stackedSeries = stackGen(this.graphData); @@ -870,7 +832,7 @@ class PowerGraph { .x((d, i) => this.xScale(this.graphData[i].date)) .y0((d) => yScale(d[0])) .y1((d) => yScale(d[1]))) - .attr("fill", (d, i) => this.colors[keys[i]]); + .attr("fill", (d, i) => this.colors[keys[i]]); break; } @@ -881,9 +843,9 @@ class PowerGraph { .ticks(4) .tickFormat((d, i) => { if (wbdata.graphMode == 'year') { - return ((d == 0) ? "" : (Math.round(d / 100000)/10)) + return ((d == 0) ? "" : (Math.round(d / 100000) / 10)) } else { - return ((d == 0) ? "" : (Math.round(d / 100) / 10)) + return ((d == 0) ? "" : (Math.round(d / 100) / 10)) } }) ); @@ -906,7 +868,7 @@ class PowerGraph { const months = ['Jan', 'Feb', 'März', 'April', 'Mai', 'Juni', 'Juli', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']; const yScale = d3.scaleLinear().range([height + 10, 2 * height]); const extent = d3.extent(this.graphData, (d) => - (d.housePower + d.lp0 + d.lp1 + d.lp2 + d.lp3 + d.lp4 + (d.house + d.lp0 + d.lp1 + d.lp2 + d.lp3 + d.lp4 + d.lp5 + d.lp6 + d.lp7 + d.sh0 + d.sh1 + d.sh2 + d.sh3 + d.sh4 + d.sh5 + d.sh6 + d.sh7 + d.sh8 + d.co0 + d.co1 + d.batIn + d.inverter) ); @@ -914,13 +876,13 @@ class PowerGraph { const keys = [["lp0", "lp1", "lp2", "lp3", "lp4", "lp5", "lp6", "lp7", "sh0", "sh1", "sh2", "sh3", "sh4", - "sh5", "sh6", "sh7", "sh8", "co0", "co1", "housePower", "batIn", "inverter"], - ["housePower", "lp0", "lp1", "lp2", "lp3", "lp4", + "sh5", "sh6", "sh7", "sh8", "co0", "co1", "house", "batIn", "inverter"], + ["house", "lp0", "lp1", "lp2", "lp3", "lp4", "lp5", "lp6", "lp7", "sh0", "sh1", "sh2", "sh3", "sh4", "sh5", "sh6", "sh7", "sh8", "co0", "co1", "batIn", "inverter"], ["sh0", "sh1", "sh2", "sh3", "sh4", - "sh5", "sh6", "sh7", "sh8", "co0", "co1", "housePower", "lp0", "lp1", "lp2", "lp3", "lp4", + "sh5", "sh6", "sh7", "sh8", "co0", "co1", "house", "lp0", "lp1", "lp2", "lp3", "lp4", "lp5", "lp6", "lp7", "batIn", "inverter"] ]; @@ -977,9 +939,9 @@ class PowerGraph { .ticks(4) .tickFormat((d, i) => { if (wbdata.graphMode == 'year') { - return ((d == 0) ? "" : (Math.round(d / 100000)/10)) + return ((d == 0) ? "" : (Math.round(d / 100000) / 10)) } else { - return ((d == 0) ? "" : (Math.round(d / 100) / 10)) + return ((d == 0) ? "" : (Math.round(d / 100) / 10)) } }) //.tickFormat((d, i) => (d == 0) ? "" : (Math.round(d / 100) / 10)) diff --git a/web/themes/colors/preview.png b/web/themes/colors/preview.png index bfa29cbe4..40492aae0 100644 Binary files a/web/themes/colors/preview.png and b/web/themes/colors/preview.png differ diff --git a/web/themes/colors/theme.html b/web/themes/colors/theme.html index 955bc09af..005780f93 100644 --- a/web/themes/colors/theme.html +++ b/web/themes/colors/theme.html @@ -104,10 +104,10 @@ $('head').append(''); - + - - + + @@ -188,7 +188,9 @@

Aktuelle Leistung

class="fa fa-sliders-h px-0"> Dezimalstellen kW & kWh ändern Farbschema Smart-Home-Geräte ändern - Ladepunkt-Zusammenfassung an/aus + Smarthome-Zusammenfassung an/aus Breite Widgets an/aus diff --git a/web/themes/colors/yieldmeter.js b/web/themes/colors/yieldmeter.js index 822958904..9ae084445 100644 --- a/web/themes/colors/yieldmeter.js +++ b/web/themes/colors/yieldmeter.js @@ -122,17 +122,11 @@ class YieldMeter { plotfilter(row) { if (row.energy > 0) { - if (row.name == "Geräte") { - if (wbdata.smartHomeSummary) { - return true - } else { - return false - } - } else { - return true + switch (row.name) { + case "Geräte": return(wbdata.smartHomeSummary) + case "Laden": return (wbdata.chargepointSummary) + default: return true } - } else { - return false } } createOrUpdateSvg() { diff --git a/web/version b/web/version index 04152b9e7..a880170e5 100644 --- a/web/version +++ b/web/version @@ -1 +1 @@ -1.9.301 +1.9.301.1