-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1856 from ndrsnhs/feature-sigenergy
feature sigenergy
- Loading branch information
Showing
5 changed files
with
231 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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,40 @@ | ||
#!/usr/bin/env python3 | ||
import logging | ||
from dataclass_utils import dataclass_from_dict | ||
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.sigenergy.config import SigenergyBatSetup | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
|
||
class SigenergyBat: | ||
def __init__(self, device_id: int, component_config: SigenergyBatSetup) -> None: | ||
self.component_config = dataclass_from_dict(SigenergyBatSetup, component_config) | ||
self.store = get_bat_value_store(self.component_config.id) | ||
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config)) | ||
self.__device_id = device_id | ||
self.sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="speicher") | ||
|
||
def update(self, client: ModbusTcpClient_) -> None: | ||
unit = self.component_config.configuration.modbus_id | ||
|
||
power = client.read_holding_registers(30037, ModbusDataType.INT_32, unit=unit) * -1 | ||
# soc unit 0.1% | ||
soc = client.read_holding_registers(30014, ModbusDataType.UINT_16, unit=unit) / 10 | ||
imported, exported = self.sim_counter.sim_count(power) | ||
|
||
bat_state = BatState( | ||
power=power, | ||
soc=soc, | ||
imported=imported, | ||
exported=exported | ||
) | ||
self.store.set(bat_state) | ||
|
||
|
||
component_descriptor = ComponentDescriptor(configuration_factory=SigenergyBatSetup) |
This file contains 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,72 @@ | ||
from typing import Optional | ||
from helpermodules.auto_str import auto_str | ||
|
||
from modules.common.component_setup import ComponentSetup | ||
|
||
|
||
class SigenergyConfiguration: | ||
def __init__(self, | ||
ip_address: Optional[str] = None, | ||
port: int = 502): | ||
self.ip_address = ip_address | ||
self.port = port | ||
|
||
|
||
class Sigenergy: | ||
def __init__(self, | ||
name: str = "Sigenergy", | ||
type: str = "sigenergy", | ||
id: int = 0, | ||
configuration: SigenergyConfiguration = None) -> None: | ||
self.name = name | ||
self.type = type | ||
self.id = id | ||
self.configuration = configuration or SigenergyConfiguration() | ||
|
||
|
||
@auto_str | ||
class SigenergyBatConfiguration: | ||
def __init__(self, modbus_id: int = 247): | ||
self.modbus_id = modbus_id | ||
|
||
|
||
@auto_str | ||
class SigenergyBatSetup(ComponentSetup[SigenergyBatConfiguration]): | ||
def __init__(self, | ||
name: str = "Sigenergy Speicher", | ||
type: str = "bat", | ||
id: int = 0, | ||
configuration: SigenergyBatConfiguration = None) -> None: | ||
super().__init__(name, type, id, configuration or SigenergyBatConfiguration()) | ||
|
||
|
||
@auto_str | ||
class SigenergyCounterConfiguration: | ||
def __init__(self, modbus_id: int = 247): | ||
self.modbus_id = modbus_id | ||
|
||
|
||
@auto_str | ||
class SigenergyCounterSetup(ComponentSetup[SigenergyCounterConfiguration]): | ||
def __init__(self, | ||
name: str = "Sigenergy Zähler", | ||
type: str = "counter", | ||
id: int = 0, | ||
configuration: SigenergyCounterConfiguration = None) -> None: | ||
super().__init__(name, type, id, configuration or SigenergyCounterConfiguration()) | ||
|
||
|
||
@auto_str | ||
class SigenergyInverterConfiguration: | ||
def __init__(self, modbus_id: int = 247): | ||
self.modbus_id = modbus_id | ||
|
||
|
||
@auto_str | ||
class SigenergyInverterSetup(ComponentSetup[SigenergyInverterConfiguration]): | ||
def __init__(self, | ||
name: str = "Sigenergy Wechselrichter", | ||
type: str = "inverter", | ||
id: int = 0, | ||
configuration: SigenergyInverterConfiguration = None) -> None: | ||
super().__init__(name, type, id, configuration or SigenergyInverterConfiguration()) |
This file contains 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,36 @@ | ||
#!/usr/bin/env python3 | ||
from dataclass_utils import dataclass_from_dict | ||
from modules.common.component_state import CounterState | ||
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_counter_value_store | ||
from modules.devices.sigenergy.config import SigenergyCounterSetup | ||
|
||
|
||
class SigenergyCounter: | ||
def __init__(self, device_id: int, component_config: SigenergyCounterSetup) -> None: | ||
self.component_config = dataclass_from_dict(SigenergyCounterSetup, component_config) | ||
self.store = get_counter_value_store(self.component_config.id) | ||
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config)) | ||
self.__device_id = device_id | ||
self.sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="bezug") | ||
|
||
def update(self, client: ModbusTcpClient_): | ||
unit = self.component_config.configuration.modbus_id | ||
|
||
powers = client.read_holding_registers(30052, [ModbusDataType.INT_32]*3, unit=unit) | ||
power = client.read_holding_registers(30005, ModbusDataType.INT_32, unit=unit) | ||
imported, exported = self.sim_counter.sim_count(power) | ||
|
||
counter_state = CounterState( | ||
imported=imported, | ||
exported=exported, | ||
power=power, | ||
powers=powers | ||
) | ||
self.store.set(counter_state) | ||
|
||
|
||
component_descriptor = ComponentDescriptor(configuration_factory=SigenergyCounterSetup) |
This file contains 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,48 @@ | ||
#!/usr/bin/env python3 | ||
import logging | ||
from typing import Iterable, Union | ||
|
||
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.sigenergy.bat import SigenergyBat | ||
from modules.devices.sigenergy.counter import SigenergyCounter | ||
from modules.devices.sigenergy.inverter import SigenergyInverter | ||
from modules.devices.sigenergy.config import Sigenergy, SigenergyBatSetup, SigenergyCounterSetup, SigenergyInverterSetup | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
|
||
def create_device(device_config: Sigenergy): | ||
def create_bat_component(component_config: SigenergyBatSetup): | ||
return SigenergyBat(device_config.id, component_config) | ||
|
||
def create_counter_component(component_config: SigenergyCounterSetup): | ||
return SigenergyCounter(device_config.id, component_config) | ||
|
||
def create_inverter_component(component_config: SigenergyInverterSetup): | ||
return SigenergyInverter(device_config.id, component_config) | ||
|
||
def update_components(components: Iterable[Union[SigenergyBat, SigenergyCounter, SigenergyInverter]]): | ||
with client as c: | ||
for component in components: | ||
with SingleComponentUpdateContext(component.fault_state): | ||
component.update(c) | ||
|
||
try: | ||
client = ModbusTcpClient_(device_config.configuration.ip_address, device_config.configuration.port) | ||
except Exception: | ||
log.exception("Fehler in create_device") | ||
return ConfigurableDevice( | ||
device_config=device_config, | ||
component_factory=ComponentFactoryByType( | ||
bat=create_bat_component, | ||
counter=create_counter_component, | ||
inverter=create_inverter_component, | ||
), | ||
component_updater=MultiComponentUpdater(update_components) | ||
) | ||
|
||
|
||
device_descriptor = DeviceDescriptor(configuration_factory=Sigenergy) |
This file contains 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,35 @@ | ||
#!/usr/bin/env python3 | ||
from typing import Dict, Union | ||
|
||
from dataclass_utils import dataclass_from_dict | ||
from modules.common.component_state import InverterState | ||
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.sigenergy.config import SigenergyInverterSetup | ||
|
||
|
||
class SigenergyInverter: | ||
def __init__(self, device_id: int, component_config: Union[Dict, SigenergyInverterSetup]) -> None: | ||
self.component_config = dataclass_from_dict(SigenergyInverterSetup, component_config) | ||
self.store = get_inverter_value_store(self.component_config.id) | ||
self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config)) | ||
self.__device_id = device_id | ||
self.sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="pv") | ||
|
||
def update(self, client: ModbusTcpClient_) -> None: | ||
unit = self.component_config.configuration.modbus_id | ||
|
||
power = client.read_holding_registers(30035, ModbusDataType.INT_32, unit=unit) * -1 | ||
_, exported = self.sim_counter.sim_count(power) | ||
|
||
inverter_state = InverterState( | ||
power=power, | ||
exported=exported, | ||
) | ||
self.store.set(inverter_state) | ||
|
||
|
||
component_descriptor = ComponentDescriptor(configuration_factory=SigenergyInverterSetup) |