Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 0 additions & 44 deletions modules/bezug_e3dc/e3dc.py

This file was deleted.

2 changes: 1 addition & 1 deletion modules/bezug_e3dc/main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ else
MYLOGFILE="${RAMDISKDIR}/evu.log"
fi

bash "$OPENWBBASEDIR/packages/legacy_run.sh" "bezug_e3dc.e3dc" "${e3dcip}" >>"${MYLOGFILE}" 2>&1
bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.e3dc.device" "counter" "$e3dcip" "$e3dc2ip" "$e3dcextprod" "$pvwattmodul" "1">>"${MYLOGFILE}" 2>&1
ret=$?

openwbDebugLog ${DMOD} 2 "EVU RET: ${ret}"
Expand Down
78 changes: 0 additions & 78 deletions modules/speicher_e3dc/e3dc.py

This file was deleted.

2 changes: 1 addition & 1 deletion modules/speicher_e3dc/main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ else
MYLOGFILE="${RAMDISKDIR}/bat.log"
fi

bash "$OPENWBBASEDIR/packages/legacy_run.sh" "speicher_e3dc.e3dc" "$e3dcip" "$e3dc2ip" "$e3dcextprod" "$pvwattmodul" >>"${MYLOGFILE}" 2>&1
bash "$OPENWBBASEDIR/packages/legacy_run.sh" "modules.e3dc.device" "bat" "$e3dcip" "$e3dc2ip" "$e3dcextprod" "$pvwattmodul" "1">>"${MYLOGFILE}" 2>&1
ret=$?

openwbDebugLog "${DMOD}" 2 "BAT RET: ${ret}"
109 changes: 109 additions & 0 deletions packages/modules/e3dc/bat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env python3
from typing import Dict, Union
import logging

from dataclass_utils import dataclass_from_dict
from modules.common import modbus
from modules.common.component_state import BatState
from modules.common.component_state import InverterState
from modules.common.component_type import ComponentDescriptor
from modules.common.modbus import ModbusDataType, Endian
from modules.common.fault_state import ComponentInfo
from modules.common.store import get_bat_value_store
from modules.common.store import get_inverter_value_store
from modules.common.simcount._simcounter import SimCounter
from modules.e3dc.config import e3dcBatSetup
from modules.common.store.ramdisk import files


log = logging.getLogger(__name__)


class e3dcBat:
def __init__(self,
device_id: int,
ip_address1: str,
ip_address2: str,
read_ext: int,
pvmodul: str,
component_config: Union[Dict, e3dcBatSetup]) -> None:
self.__device_id = device_id
self.component_config = dataclass_from_dict(e3dcBatSetup, component_config)
# bat
self.__sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="speicher")
self.__store = get_bat_value_store(self.component_config.id)
self.component_info = ComponentInfo.from_component_config(self.component_config)
self.__addresses = [address for address in [ip_address1, ip_address2] if address != "none"]
self.__read_ext = read_ext
self.__pvmodul = pvmodul
self.__pvother = pvmodul != "none"

def update(self) -> None:
soc = 0
count = 0
power = 0
# pv_external - > pv Leistung
# die als externe Produktion an e3dc angeschlossen ist
# nur auslesen wenn als relevant parametrisiert
# (read_external = 1) , sonst doppelte Auslesung
pv_external = 0
# pv -> pv Leistung die direkt an e3dc angeschlossen ist
pv = 0
for address in self.__addresses:
log.debug("Ip: %s, read_ext %d pv_other %s", address,
self.__read_ext, self.__pvother)
count += 1
with modbus.ModbusTcpClient_(address, 502) as client:
# 40082 SoC
soc += client.read_holding_registers(40082, ModbusDataType.INT_16, unit=1)
# 40069 Speicherleistung
power += client.read_holding_registers(40069, ModbusDataType.INT_32, wordorder=Endian.Little, unit=1)
# 40067 PV Leistung
pv += (client.read_holding_registers(40067,
ModbusDataType.INT_32, wordorder=Endian.Little,
unit=1) * -1)
if self.__read_ext == 1:
# 40075 externe PV Leistung
pv_external += client.read_holding_registers(40075, ModbusDataType.INT_32,
wordorder=Endian.Little, unit=1)
soc = soc / count
log.debug("soc %d power %d pv %d pv_external %d c ip %d",
soc, power, pv, pv_external, count)
imported, exported = self.__sim_counter.sim_count(power)
bat_state = BatState(
power=power,
soc=soc,
imported=imported,
exported=exported
)
self.__store.set(bat_state)
# pv_other sagt aus, ob WR definiert ist,
# und dessen PV Leistung auch gilt
# wenn 0 gilt nur PV und pv_external aus e3dc
pv_total = pv + pv_external
# Wenn wr1 nicht definiert ist,
# gilt nur die PV Leistung die hier im Modul ermittelt wurde
# als gesamte PV Leistung für wr1
if not self.__pvother or pv_total != 0:
# Wenn wr1 definiert ist, gilt die bestehende PV Leistung
# aus Wr1 und das was hier im Modul ermittelt wurde
# als gesamte PV Leistung für wr1
if self.__pvother:
try:
pv_total = pv_total + files.pv[0].power.read()
except Exception:
pass
log.debug("wr update pv_other %s pv_total %d",
self.__pvother, pv_total)
# pv
self.__sim_counterpv = SimCounter(self.__device_id, self.component_config.id, prefix="pv")
self.__storepv = get_inverter_value_store(self.component_config.id)
_, exportedpv = self.__sim_counterpv.sim_count(pv_total)
inverter_state = InverterState(
power=pv_total,
exported=exportedpv
)
self.__storepv.set(inverter_state)


component_descriptor = ComponentDescriptor(configuration_factory=e3dcBatSetup)
54 changes: 54 additions & 0 deletions packages/modules/e3dc/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from modules.common.component_setup import ComponentSetup


class e3dcConfiguration:
def __init__(self, ip_address1: str = None,
ip_address2: str = None,
read_ext: int = 0,
pvmodul: str = None):
self.ip_address1 = ip_address1
self.ip_address2 = ip_address2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hier sollte nur eine Adresse sein. Die ich auch wieder nur address nennen würde, denn es könnte auch ein hostname sein.

self.read_ext = read_ext
self.pvmodul = pvmodul


class e3dc:
def __init__(self,
name: str = "e3dc",
type: str = "e3dc",
id: int = 0,
configuration: e3dcConfiguration = None) -> None:
self.name = name
self.type = type
self.id = id
self.configuration = configuration or e3dcConfiguration()


class e3dcBatConfiguration:
def __init__(self):
pass


class e3dcBatSetup(ComponentSetup[e3dcBatConfiguration]):
def __init__(self,
name: str = "e3dc Speicher",
type: str = "bat",
id: int = 0,
configuration: e3dcBatConfiguration = None) -> None:
super().__init__(name, type, id, configuration
or e3dcBatConfiguration())


class e3dcCounterConfiguration:
def __init__(self):
pass


class e3dcCounterSetup(ComponentSetup[e3dcCounterConfiguration]):
def __init__(self,
name: str = "e3dc Zähler",
type: str = "counter",
id: int = 0,
configuration: e3dcCounterConfiguration = None) -> None:
super().__init__(name, type, id, configuration or
e3dcCounterConfiguration())
74 changes: 74 additions & 0 deletions packages/modules/e3dc/counter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env python3
import logging
import os
from typing import Dict, Union

from dataclass_utils import dataclass_from_dict
from modules.common import modbus
from modules.common.component_state import CounterState
from modules.common.component_type import ComponentDescriptor
from modules.common.fault_state import ComponentInfo
from modules.common.simcount._simcounter import SimCounter
from modules.common.modbus import ModbusDataType, Endian
from modules.common.store import get_counter_value_store
from modules.e3dc.config import e3dcCounterSetup

log = logging.getLogger(__name__)


class e3dcCounter:
def __init__(self,
device_id: int,
ip_address1: str,
ip_address2: str,
read_ext: int,
pvmodul: str,
component_config: Union[Dict, e3dcCounterSetup]) -> None:
self.__device_id = device_id
self.component_config = dataclass_from_dict(e3dcCounterSetup, component_config)
self.__sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="bezug")
self.__store = get_counter_value_store(self.component_config.id)
self.component_info = ComponentInfo.from_component_config(self.component_config)
self.__ip_address1 = ip_address1

def update(self):
log.debug("Beginning EVU update")
file_adr = '/var/www/html/openWB/ramdisk/e3dc_evu_addr.'
file_adr += str(self.__ip_address1)
adr = 0
if os.path.isfile(file_adr):
with open(file_adr, 'r') as f:
adr = int(f.read())
with modbus.ModbusTcpClient_(self.__ip_address1, 502) as client:
# 40074 EVU Punkt negativ -> Einspeisung in Watt
power = client.read_holding_registers(40073, ModbusDataType.INT_32, wordorder=Endian.Little, unit=1)
# 40130 Phasenleistung in Watt
# max 6 Leistungsmesser verbaut ab 410105, typ 1 ist evu
# bei den meisten e3dc auf 40128
# for i in range (40104,40132,4):
if (adr == 0):
for i in range(40128, 40103, -4):
powers = client.read_holding_registers(i, [ModbusDataType.INT_16] * 4, unit=1)
log.debug("I: %d, p0 %d p1 a1 %d p2 a2 %d p3 a3 %d",
i, powers[0], powers[1], powers[2], powers[3])
if powers[0] == 1:
log.debug("Evu Leistungsmessung gefunden, save %d", i)
with open(file_adr, 'w') as f:
f.write(str(i))
break
else:
powers = client.read_holding_registers(adr, [ModbusDataType.INT_16] * 4, unit=1)
log.debug("adr: %d, p0 %d p1 a1 %d p2 a2 %d p3 a3 %d",
adr, powers[0], powers[1], powers[2], powers[3])
imported, exported = self.__sim_counter.sim_count(power)
counter_state = CounterState(
imported=imported,
exported=exported,
powers=powers[1:],
power=power
)
self.__store.set(counter_state)
log.debug("Update completed successfully")


component_descriptor = ComponentDescriptor(configuration_factory=e3dcCounterSetup)
Loading