-
Notifications
You must be signed in to change notification settings - Fork 107
Marstek Venus C, E battery #2758
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
3b3a3fd
Create __init__.py
andlem74 c137b59
Create vendor.py
andlem74 f17c6e0
Create bat.py
andlem74 d186693
Create config.py
andlem74 18117aa
Create device.py
andlem74 1584ea0
Create __init__.py
andlem74 e1e16dd
Update device.py
andlem74 60b0450
Update bat.py
andlem74 336144b
Update __init__.py
andlem74 7c19234
Add files via upload
andlem74 dbb62af
Add files via upload
andlem74 3a615b5
Update bat.py
andlem74 52b8137
Update bat.py
andlem74 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| from pathlib import Path | ||
|
|
||
| from modules.common.abstract_device import DeviceDescriptor | ||
| from modules.devices.vendors import VendorGroup | ||
|
|
||
|
|
||
| class Vendor: | ||
| def __init__(self): | ||
| self.type = Path(__file__).parent.name | ||
| self.vendor = "Marstek" | ||
| self.group = VendorGroup.VENDORS.value | ||
|
|
||
|
|
||
| vendor_descriptor = DeviceDescriptor(configuration_factory=Vendor) |
Empty file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| #!/usr/bin/env python3 | ||
| from typing import Optional, TypedDict, Any, Union | ||
| 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.marstek.venus_c_e.config import VenusCEBatSetup | ||
|
|
||
|
|
||
| class KwargsDict(TypedDict): | ||
| device_id: int | ||
| client: ModbusTcpClient_ | ||
|
|
||
|
|
||
| class VenusCEBat(AbstractBat): | ||
| def __init__(self, component_config: VenusCEBatSetup, **kwargs: Any) -> None: | ||
| self.component_config = component_config | ||
| self.kwargs: KwargsDict = kwargs | ||
|
|
||
| def initialize(self) -> None: | ||
| self.__device_id: int = self.kwargs['device_id'] | ||
| self.client: ModbusTcpClient_ = self.kwargs['client'] | ||
| self.sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="speicher") | ||
| self.store = get_bat_value_store(self.component_config.id) | ||
| self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config)) | ||
|
|
||
| def _read_reg(self, addr: int, type_: ModbusDataType) -> Union[int, float]: | ||
| return self.client.read_holding_registers(addr, type_, unit=self.component_config.configuration.modbus_id) | ||
|
|
||
| def _write_reg(self, addr: int, val: int) -> None: | ||
| # Marstek Venus does not work with write_registers! | ||
| self.client._delegate.write_register(addr, val, unit=self.component_config.configuration.modbus_id) | ||
|
|
||
| def update(self) -> None: | ||
| power = -self._read_reg(32202, ModbusDataType.INT_32) | ||
| soc = self._read_reg(32104, ModbusDataType.UINT_16) | ||
|
|
||
| # Marstek Venus has internal counter but it's buggy, hence we cannot use it | ||
| imported, exported = self.sim_counter.sim_count(power) | ||
|
|
||
| bat_state = BatState( | ||
| power=power, | ||
| soc=soc, | ||
| imported=imported, | ||
| exported=exported | ||
| ) | ||
| self.store.set(bat_state) | ||
|
|
||
| def set_power_limit(self, power_limit: Optional[int]) -> None: | ||
| # Wenn der Speicher die Steuerung der Ladeleistung unterstützt, muss bei Übergabe einer Zahl auf aktive | ||
| # Speichersteurung umgeschaltet werden, sodass der Speicher mit der übergebenen Leistung lädt/entlädt. Wird | ||
| # None übergeben, muss der Speicher die Null-Punkt-Ausregelung selbst übernehmen. | ||
| if (power_limit is None): | ||
| self._write_reg(42000, 0x55bb) | ||
| else: | ||
| self._write_reg(42000, 0x55aa) | ||
| if power_limit < 0: | ||
| self._write_reg(42010, 2) | ||
| self._write_reg(42021, int(min(-power_limit, 2500))) | ||
| elif power_limit > 0: | ||
| self._write_reg(42010, 1) | ||
| self._write_reg(42020, int(min(power_limit, 2500))) | ||
| else: | ||
| self._write_reg(42010, 0) | ||
|
|
||
| def power_limit_controllable(self) -> bool: | ||
| # Wenn der Speicher die Steuerung der Ladeleistung unterstützt, muss True zurückgegeben werden. | ||
| return True | ||
|
|
||
|
|
||
| component_descriptor = ComponentDescriptor(configuration_factory=VenusCEBatSetup) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| from typing import Optional | ||
| from helpermodules.auto_str import auto_str | ||
| from modules.common.component_setup import ComponentSetup | ||
|
|
||
| from ..vendor import vendor_descriptor | ||
|
|
||
|
|
||
| @auto_str | ||
| class VenusCEConfiguration: | ||
| def __init__(self, ip_address: Optional[str] = None, port: int = 502): | ||
| self.ip_address = ip_address | ||
| self.port = port | ||
|
|
||
|
|
||
| @auto_str | ||
| class VenusCE: | ||
| def __init__(self, | ||
| name: str = "Marstek Venus C, E", | ||
| type: str = "venus_c_e", | ||
| id: int = 0, | ||
| configuration: VenusCEConfiguration = None) -> None: | ||
| self.name = name | ||
| self.type = type | ||
| self.vendor = vendor_descriptor.configuration_factory().type | ||
| self.id = id | ||
| self.configuration = configuration or VenusCEConfiguration() | ||
|
|
||
|
|
||
| @auto_str | ||
| class VenusCEBatConfiguration: | ||
| def __init__(self, modbus_id: int = 1): | ||
| self.modbus_id = modbus_id | ||
|
|
||
|
|
||
| @auto_str | ||
| class VenusCEBatSetup(ComponentSetup[VenusCEBatConfiguration]): | ||
| def __init__(self, | ||
| name: str = "Marstek Venus C, E Speicher", | ||
| type: str = "bat", | ||
| id: int = 0, | ||
| configuration: VenusCEBatConfiguration = None) -> None: | ||
| super().__init__(name, type, id, configuration or VenusCEBatConfiguration()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| #!/usr/bin/env python3 | ||
| import logging | ||
| from typing import Iterable | ||
|
|
||
| from modules.common.abstract_device import DeviceDescriptor | ||
| from modules.common.component_context import SingleComponentUpdateContext | ||
| from modules.common.configurable_device import ConfigurableDevice, ComponentFactoryByType, MultiComponentUpdater | ||
| from modules.common.modbus import ModbusTcpClient_ | ||
| from modules.devices.marstek.venus_c_e.bat import VenusCEBat | ||
| from modules.devices.marstek.venus_c_e.config import VenusCE, VenusCEBatSetup | ||
|
|
||
| log = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def create_device(device_config: VenusCE): | ||
| client = None | ||
|
|
||
| def create_bat_component(component_config: VenusCEBatSetup): | ||
| nonlocal client | ||
| return VenusCEBat(component_config, device_id=device_config.id, client=client) | ||
|
|
||
| def update_components(components: Iterable[VenusCEBat]): | ||
| with client: | ||
| for component in components: | ||
| with SingleComponentUpdateContext(component.fault_state): | ||
| component.update() | ||
|
|
||
| def initializer(): | ||
| nonlocal client | ||
| client = ModbusTcpClient_(device_config.configuration.ip_address, device_config.configuration.port) | ||
|
|
||
| return ConfigurableDevice( | ||
| device_config=device_config, | ||
| initializer=initializer, | ||
| component_factory=ComponentFactoryByType( | ||
| bat=create_bat_component, | ||
| ), | ||
| component_updater=MultiComponentUpdater(update_components) | ||
| ) | ||
|
|
||
|
|
||
| device_descriptor = DeviceDescriptor(configuration_factory=VenusCE) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wie in der in PR #2683 beschriebenen Doku und Umsetzung braucht der SoC noch einen Faktor.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Die Doku ist hier inkorrekt bzw. veraltet. Zumindest bei meinem Venus-C mit aktueller Firmware darf nicht mit 0.1 multipliziert werden, sonst stimmt der angezeigte SoC in openWB nicht. Ich gehe davon aus, dass der Venus-E sich genauso verhält.
Falls @seaspotter wirklich mit einem Venus-E getestet hat und sicher ist, dass dieser den Faktor 0.1 tatsächlich benötigt, so wie es der Doku entspricht, sollten wir hier eine Variante einführen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok