Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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: 38 additions & 6 deletions packages/modules/devices/solis/solis/bat.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
#!/usr/bin/env python3
import logging
from typing import TypedDict, Any
from typing import TypedDict, Any, Optional

from modules.common.abstract_device import AbstractBat
from modules.common.component_state import BatState
from modules.common.component_type import ComponentDescriptor
from modules.common.fault_state import ComponentInfo, FaultState
from modules.common.modbus import ModbusDataType, ModbusTcpClient_
from modules.common.simcount import SimCounter
from modules.common.store import get_bat_value_store
from modules.devices.solis.solis.config import SolisBatSetup
from modules.devices.solis.solis.version import SolisVersion
from modules.common.utils.peak_filter import PeakFilter
from modules.common.component_type import ComponentType

Expand All @@ -17,6 +19,8 @@

class KwargsDict(TypedDict):
client: ModbusTcpClient_
device_id: int
version: SolisVersion


class SolisBat(AbstractBat):
Expand All @@ -26,6 +30,8 @@ def __init__(self, component_config: SolisBatSetup, **kwargs: Any) -> None:

def initialize(self) -> None:
self.client: ModbusTcpClient_ = self.kwargs['client']
self.version: SolisVersion = self.kwargs['version']
self.sim_counter = SimCounter(self.kwargs['device_id'], self.component_config.id, prefix="speicher")
self.store = get_bat_value_store(self.component_config.id)
Comment on lines 20 to 35

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

erledigt

self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))
self.peak_filter = PeakFilter(ComponentType.BAT, self.component_config.id, self.fault_state)
Expand All @@ -35,19 +41,45 @@ def update(self) -> None:

power = self.client.read_input_registers(33149, ModbusDataType.INT_32, unit=unit)
soc = self.client.read_input_registers(33139, ModbusDataType.UINT_16, unit=unit)
# Geladen in kWh
imported = self.client.read_input_registers(33161, ModbusDataType.UINT_32, unit=unit) * 1000
# Entladen in kWh
exported = self.client.read_input_registers(33165, ModbusDataType.UINT_32, unit=unit) * 1000
bat_current = self.client.read_input_registers(33134, ModbusDataType.INT_16, unit=unit) * -0.1

imported, exported = self.peak_filter.check_values(power, imported, exported)
currents = [bat_current / 3] * 3

self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
bat_state = BatState(
power=power,
soc=soc,
currents=currents,
imported=imported,
exported=exported
)
self.store.set(bat_state)

def set_power_limit(self, power_limit: Optional[int]) -> None:
unit = self.component_config.configuration.modbus_id

if power_limit is None:
self.client.write_register(43135, 0, data_type=ModbusDataType.UINT_16, unit=unit)
log.debug("Keine Batteriesteuerung, Selbstregelung durch Wechselrichter")
elif power_limit == 0:
self.client.write_register(43135, 1, data_type=ModbusDataType.UINT_16, unit=unit)
self.client.write_register(43136, 0, data_type=ModbusDataType.UINT_16, unit=unit)
log.debug("Aktive Batteriesteuerung. Batterie wird auf Stop gesetzt und nicht geladen/entladen")
elif power_limit < 0:
self.client.write_register(43135, 2, data_type=ModbusDataType.UINT_16, unit=unit)
power_value = int(abs(power_limit) / 10)
self.client.write_register(43129, power_value, data_type=ModbusDataType.UINT_16, unit=unit)
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W entladen für den Hausverbrauch")
Comment on lines +69 to +73

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@seaspotter Ist das richtig?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Ja Copilot hat rechts es muss der absolut Wert übergeben werden, es gibt für Charging und Discharging 2 Register jeweils u16 also erwarten beide einen positiven Wert

elif power_limit > 0:
self.client.write_register(43135, 1, data_type=ModbusDataType.UINT_16, unit=unit)
power_value = int(power_limit / 10)
self.client.write_register(43136, power_value, data_type=ModbusDataType.UINT_16, unit=unit)
log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W geladen")

def power_limit_controllable(self) -> bool:
# Nur die S-Serie sollte die Speichersteuerung können
return self.version == SolisVersion.hybrid_s


component_descriptor = ComponentDescriptor(configuration_factory=SolisBatSetup)
2 changes: 0 additions & 2 deletions packages/modules/devices/solis/solis/counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ def initialize(self) -> None:
self.version: SolisVersion = self.kwargs['version']
self.store = get_counter_value_store(self.component_config.id)
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))
self.version = self.kwargs['version']
self.client = self.kwargs['client']
self.peak_filter = PeakFilter(ComponentType.COUNTER, self.component_config.id, self.fault_state)

def update(self):
Expand Down
13 changes: 8 additions & 5 deletions packages/modules/devices/solis/solis/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from modules.devices.solis.solis.counter import SolisCounter
from modules.devices.solis.solis.inverter import SolisInverter
from modules.devices.solis.solis.config import Solis, SolisBatSetup, SolisCounterSetup, SolisInverterSetup
from modules.devices.solis.solis.version import SolisVersion

log = logging.getLogger(__name__)

Expand All @@ -20,17 +19,21 @@ def create_device(device_config: Solis):

def create_bat_component(component_config: SolisBatSetup):
nonlocal client
return SolisBat(component_config, client=client)
return SolisBat(component_config,
client=client,
device_id=device_config.id,
version=device_config.configuration.version)

Comment on lines 20 to 26

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

erledigt

def create_counter_component(component_config: SolisCounterSetup):
nonlocal client
return SolisCounter(component_config, version=SolisVersion(device_config.configuration.version), client=client)
return SolisCounter(component_config, client=client, version=device_config.configuration.version)

def create_inverter_component(component_config: SolisInverterSetup):
nonlocal client
return SolisInverter(component_config,
version=SolisVersion(device_config.configuration.version),
client=client)
client=client,
device_id=device_config.id,
version=device_config.configuration.version)

def update_components(components: Iterable[Union[SolisBat, SolisCounter, SolisInverter]]):
nonlocal client
Expand Down
26 changes: 19 additions & 7 deletions packages/modules/devices/solis/solis/inverter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from modules.common.component_type import ComponentDescriptor
from modules.common.fault_state import ComponentInfo, FaultState
from modules.common.modbus import ModbusDataType, ModbusTcpClient_
from modules.common.simcount import SimCounter
from modules.common.store import get_inverter_value_store
from modules.devices.solis.solis.config import SolisInverterSetup
from modules.devices.solis.solis.version import SolisVersion
Expand All @@ -14,6 +15,7 @@

class KwargsDict(TypedDict):
client: ModbusTcpClient_
device_id: int
version: SolisVersion


Expand All @@ -25,6 +27,7 @@ def __init__(self, component_config: SolisInverterSetup, **kwargs: Any) -> None:
def initialize(self) -> None:
self.client: ModbusTcpClient_ = self.kwargs['client']
self.version: SolisVersion = self.kwargs['version']
self.sim_counter = SimCounter(self.kwargs['device_id'], self.component_config.id, prefix="pv")
self.store = get_inverter_value_store(self.component_config.id)
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config))
self.peak_filter = PeakFilter(ComponentType.INVERTER, self.component_config.id, self.fault_state)
Expand All @@ -33,15 +36,24 @@ def update(self) -> None:
unit = self.component_config.configuration.modbus_id

if self.version == SolisVersion.inverter:
power = self.client.read_input_registers(3004, ModbusDataType.UINT_32, unit=unit) * -1
exported = self.client.read_input_registers(3008, ModbusDataType.UINT_32, unit=unit) * 1000
elif self.version == SolisVersion.hybrid:
power = self.client.read_input_registers(33057, ModbusDataType.UINT_32, unit=unit) * -1
exported = self.client.read_input_registers(33029, ModbusDataType.UINT_32, unit=unit) * 1000

_, exported = self.peak_filter.check_values(power, None, exported)
# Für Stringwechselrichter -1 bei Modbus Registers
power = self.client.read_input_registers(3004, ModbusDataType.INT_32, unit=unit) * -1
dc_power = self.client.read_input_registers(3006, ModbusDataType.UINT_32, unit=unit) * -1
currents = self.client.read_input_registers(3036, [ModbusDataType.UINT_16]*3, unit=unit)
elif self.version in (SolisVersion.hybrid, SolisVersion.hybrid_s):
power = self.client.read_input_registers(33079, ModbusDataType.INT_32, unit=unit) * -1
dc_power = self.client.read_input_registers(33057, ModbusDataType.UINT_32, unit=unit) * -1
currents = self.client.read_input_registers(33076, [ModbusDataType.UINT_16]*3, unit=unit)
Comment on lines +40 to +46

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

passt zur Doku


currents = [value * -0.1 for value in currents]

self.peak_filter.check_values(power)
imported, exported = self.sim_counter.sim_count(power)
Comment on lines +50 to +51
inverter_state = InverterState(
power=power,
dc_power=dc_power,
currents=currents,
imported=imported,
exported=exported
)
self.store.set(inverter_state)
Expand Down
1 change: 1 addition & 0 deletions packages/modules/devices/solis/solis/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
class SolisVersion(Enum):
inverter = "inverter"
hybrid = "hybrid"
hybrid_s = "hybrid_s"
Loading