Skip to content
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

Deye/jinko #2083

Merged
merged 4 commits into from
Dec 19, 2024
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
30 changes: 19 additions & 11 deletions packages/modules/devices/deye/deye/bat.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,43 @@


class DeyeBat(AbstractBat):
def __init__(self, device_id: int, component_config: DeyeBatSetup) -> None:
def __init__(self, device_id: int,
component_config: DeyeBatSetup,
device_type: DeviceType) -> None:
self.component_config = dataclass_from_dict(DeyeBatSetup, 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")
self.device_type = device_type

def update(self, client: ModbusTcpClient_, device_type: DeviceType) -> None:
unit = self.component_config.configuration.modbus_id

if device_type == DeviceType.THREE_PHASE:
power = client.read_holding_registers(590, ModbusDataType.INT_16, unit=unit) * -1
soc = client.read_holding_registers(588, ModbusDataType.INT_16, unit=unit)
# 516: Geladen in kWh * 0,1
imported = client.read_holding_registers(516, ModbusDataType.UINT_16, unit=unit) * 100
# 518: Entladen in kWh * 0,1
exported = client.read_holding_registers(518, ModbusDataType.UINT_16, unit=unit) * 100
elif device_type == DeviceType.SINGLE_PHASE_STRING or device_type == DeviceType.SINGLE_PHASE_HYBRID:
if self.device_type == DeviceType.SINGLE_PHASE_STRING or self.device_type == DeviceType.SINGLE_PHASE_HYBRID:
power = client.read_holding_registers(190, ModbusDataType.INT_16, unit=unit) * -1
soc = client.read_holding_registers(184, ModbusDataType.INT_16, unit=unit)

if device_type == DeviceType.SINGLE_PHASE_HYBRID:
if self.device_type == DeviceType.SINGLE_PHASE_HYBRID:
# 516: Geladen in kWh * 0,1
imported = client.read_holding_registers(72, ModbusDataType.UINT_16, unit=unit) * 100
# 518: Entladen in kWh * 0,1
exported = client.read_holding_registers(74, ModbusDataType.UINT_16, unit=unit) * 100
elif device_type == DeviceType.SINGLE_PHASE_STRING:

elif self.device_type == DeviceType.SINGLE_PHASE_STRING:
imported, exported = self.sim_counter.sim_count(power)

else: # THREE_PHASE_LV (0x0500, 0x0005), THREE_PHASE_HV (0x0006)
power = client.read_holding_registers(590, ModbusDataType.INT_16, unit=unit) * -1

if self.device_type == DeviceType.THREE_PHASE_HV:
power = power * 10
soc = client.read_holding_registers(588, ModbusDataType.INT_16, unit=unit)
# 516: Geladen in kWh * 0,1
imported = client.read_holding_registers(516, ModbusDataType.UINT_16, unit=unit) * 100
# 518: Entladen in kWh * 0,1
exported = client.read_holding_registers(518, ModbusDataType.UINT_16, unit=unit) * 100

bat_state = BatState(
power=power,
soc=soc,
Expand Down
4 changes: 1 addition & 3 deletions packages/modules/devices/deye/deye/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
class DeyeConfiguration:
def __init__(self,
ip_address: Optional[str] = None,
port: int = 8899,
device_type: str = "three_phase"):
port: int = 8899):
self.ip_address = ip_address
self.port = port
self.device_type = device_type


class Deye:
Expand Down
36 changes: 20 additions & 16 deletions packages/modules/devices/deye/deye/counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,48 @@


class DeyeCounter(AbstractCounter):
def __init__(self, device_id: int, component_config: DeyeCounterSetup) -> None:
def __init__(self, device_id: int,
component_config: DeyeCounterSetup,
device_type: DeviceType) -> None:
self.component_config = dataclass_from_dict(DeyeCounterSetup, 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")
self.device_type = device_type

def update(self, client: ModbusTcpClient_, device_type: DeviceType):
unit = self.component_config.configuration.modbus_id

if device_type == DeviceType.THREE_PHASE:
currents = [c / 100 for c in client.read_holding_registers(613, [ModbusDataType.INT_16]*3, unit=unit)]
voltages = [v / 10 for v in client.read_holding_registers(644, [ModbusDataType.INT_16]*3, unit=unit)]
powers = client.read_holding_registers(616, [ModbusDataType.INT_16]*3, unit=unit)
power = sum(powers)
frequency = client.read_holding_registers(187, ModbusDataType.INT_32, unit=unit) * 100
if self.device_type == DeviceType.SINGLE_PHASE_STRING or self.device_type == DeviceType.SINGLE_PHASE_HYBRID:
frequency = client.read_holding_registers(79, ModbusDataType.INT_16, unit=unit) / 100

# Wenn der Import/export Netz in wh gerechnet wird => *100 !! kommt in kw/h *0.1
imported = client.read_holding_registers(522, ModbusDataType.INT_16, unit=unit) * 100
exported = client.read_holding_registers(524, ModbusDataType.INT_16, unit=unit) * 100

elif device_type == DeviceType.SINGLE_PHASE_STRING or device_type == DeviceType.SINGLE_PHASE_HYBRID:
frequency = client.read_holding_registers(79, ModbusDataType.INT_16, unit=unit) * 100

if device_type == DeviceType.SINGLE_PHASE_HYBRID:
if self.device_type == DeviceType.SINGLE_PHASE_HYBRID:
powers = [0]*3
currents = [0]*3
voltages = [0]*3
power = [0]
# High und low word vom import sind nicht in aufeinanderfolgenden Registern
imported, exported = self.sim_counter.sim_count(power)
elif device_type == DeviceType.SINGLE_PHASE_STRING:

elif self.device_type == DeviceType.SINGLE_PHASE_STRING:
currents = [c / 100 for c in client.read_holding_registers(76, [ModbusDataType.INT_16]*3, unit=unit)]
voltages = [v / 10 for v in client.read_holding_registers(70, [ModbusDataType.INT_16]*3, unit=unit)]
powers = [currents[i] * voltages[i] for i in range(0, 3)]
power = sum(powers)
imported, exported = self.sim_counter.sim_count(power)

else: # THREE_PHASE_LV (0x0500, 0x0005), THREE_PHASE_HV (0x0006)
currents = [c / 100 for c in client.read_holding_registers(613, [ModbusDataType.INT_16]*3, unit=unit)]
voltages = [v / 10 for v in client.read_holding_registers(644, [ModbusDataType.INT_16]*3, unit=unit)]
powers = client.read_holding_registers(616, [ModbusDataType.INT_16]*3, unit=unit)
power = client.read_holding_registers(625, ModbusDataType.INT_16, unit=unit)
frequency = client.read_holding_registers(609, ModbusDataType.INT_16, unit=unit) / 100

# Wenn der Import/export Netz in wh gerechnet wird => *100 !! kommt in kw/h *0.1
imported = client.read_holding_registers(522, ModbusDataType.INT_16, unit=unit) * 100
exported = client.read_holding_registers(524, ModbusDataType.INT_16, unit=unit) * 100

counter_state = CounterState(
currents=currents,
imported=imported,
Expand Down
14 changes: 10 additions & 4 deletions packages/modules/devices/deye/deye/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
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.common.modbus import ModbusDataType, ModbusTcpClient_
from modules.devices.deye.deye.bat import DeyeBat
from modules.devices.deye.deye.counter import DeyeCounter
from modules.devices.deye.deye.device_type import DeviceType
Expand All @@ -19,13 +19,19 @@

def create_device(device_config: Deye):
def create_bat_component(component_config: DeyeBatSetup):
return DeyeBat(device_config.id, component_config)
device_type = client.read_holding_registers(
0, ModbusDataType.INT_16, unit=component_config.configuration.modbus_id)
return DeyeBat(device_config.id, component_config, device_type)

def create_counter_component(component_config: DeyeCounterSetup):
return DeyeCounter(device_config.id, component_config)
device_type = client.read_holding_registers(
0, ModbusDataType.INT_16, unit=component_config.configuration.modbus_id)
return DeyeCounter(device_config.id, component_config, device_type)

def create_inverter_component(component_config: DeyeInverterSetup):
return DeyeInverter(device_config.id, component_config)
device_type = client.read_holding_registers(
0, ModbusDataType.INT_16, unit=component_config.configuration.modbus_id)
return DeyeInverter(device_config.id, component_config, device_type)

def update_components(components: Iterable[Union[DeyeBat, DeyeCounter, DeyeInverter]]):
with client as c:
Expand Down
12 changes: 7 additions & 5 deletions packages/modules/devices/deye/deye/device_type.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from enum import Enum
from enum import IntEnum


class DeviceType(Enum):
SINGLE_PHASE_HYBRID = "single_phase_hybrid"
SINGLE_PHASE_STRING = "single_phase_string"
THREE_PHASE = "three_phase"
class DeviceType(IntEnum):
SINGLE_PHASE_STRING = 0x0200
SINGLE_PHASE_HYBRID = 0x0300
THREE_PHASE_LV_0 = 0x0500
THREE_PHASE_LV_1 = 0x0005
THREE_PHASE_HV = 0x0006
18 changes: 12 additions & 6 deletions packages/modules/devices/deye/deye/inverter.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,30 @@


class DeyeInverter(AbstractInverter):
def __init__(self, device_id: int, component_config: Union[Dict, DeyeInverterSetup]) -> None:
def __init__(self, device_id: int,
component_config: Union[Dict, DeyeInverterSetup],
device_type: DeviceType) -> None:
self.component_config = dataclass_from_dict(DeyeInverterSetup, 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")
self.device_type = device_type

def update(self, client: ModbusTcpClient_, device_type: DeviceType) -> None:
unit = self.component_config.configuration.modbus_id

if device_type == DeviceType.THREE_PHASE:
# Wechselrichter hat 2 mppt Tracker
if self.device_type == DeviceType.SINGLE_PHASE_STRING or self.device_type == DeviceType.SINGLE_PHASE_HYBRID:
power = sum(client.read_holding_registers(186, [ModbusDataType.INT_16]*4, unit=unit)) * -1
exported = self.sim_counter.sim_count(power)[1]

else: # THREE_PHASE_LV (0x0500, 0x0005), THREE_PHASE_HV (0x0006)
power = sum(client.read_holding_registers(672, [ModbusDataType.INT_16]*2, unit=unit)) * -1

if self.device_type == DeviceType.THREE_PHASE_HV:
power = power * 10
# 534: Gesamt Produktion Wechselrichter unsigned integer in kWh * 0,1
exported = client.read_holding_registers(534, ModbusDataType.UINT_16, unit=unit) * 100
elif device_type == DeviceType.SINGLE_PHASE_STRING or device_type == DeviceType.SINGLE_PHASE_HYBRID:
power = sum(client.read_holding_registers(186, [ModbusDataType.INT_16]*4, unit=unit)) * -1
exported = self.sim_counter.sim_count(power)[1]

inverter_state = InverterState(
power=power,
Expand Down