Skip to content

Commit

Permalink
Merge pull request #447 from canton7/feature/kuara
Browse files Browse the repository at this point in the history
Add provisional support for the Kuara H3, which is a regular H3 underneath
  • Loading branch information
canton7 authored Oct 24, 2023
2 parents 57928dd + 75e1784 commit d58e101
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 12 deletions.
4 changes: 2 additions & 2 deletions custom_components/foxess_modbus/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@
AUX = "AUX"
LAN = "LAN"

# Inverter models. These need to match the string returned from the inverter
# Also matches config[INVERTER_BASE]
# Inverter models. These need to match config[INVERTER_BASE]
H1 = "H1"
AC1 = "AC1"
AIO_H1 = "AIO-H1"
KH = "KH"
H3 = "H3"
AC3 = "AC3"
AIO_H3 = "AIO-H3"
KUARA_H3 = "KUARA-H3"

# Platforms
SENSOR = "sensor"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from ..const import H1
from ..const import H3
from ..const import KH
from ..const import KUARA_H3
from .charge_periods import CHARGE_PERIODS
from .entity_factory import EntityFactory
from .inverter_model_spec import EntitySpec
Expand All @@ -36,7 +37,7 @@

H1_SET = [H1, AIO_H1, AC1]

H3_SET = [*H3, AIO_H3, AC3]
H3_SET = [H3, AIO_H3, AC3, KUARA_H3]

# TODO: There should be equivalent registers for the H3 somewhere
BMS_CONNECT_STATE_ADDRESS = [
Expand Down
27 changes: 19 additions & 8 deletions custom_components/foxess_modbus/inverter_profiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from .const import INVERTER_BASE
from .const import INVERTER_CONN
from .const import KH
from .const import KUARA_H3
from .const import LAN
from .entities import invalid_ranges
from .entities.charge_periods import CHARGE_PERIODS
Expand Down Expand Up @@ -93,8 +94,9 @@ def create_charge_periods(
class InverterModelProfile:
"""Describes the capabilities of an inverter model"""

def __init__(self, model: str) -> None:
def __init__(self, model: str, model_pattern: str) -> None:
self.model = model
self.model_pattern = model_pattern
self.connection_types: dict[str, InverterModelConnectionTypeProfile] = {}

def add_connection_type(
Expand All @@ -121,7 +123,7 @@ def add_connection_type(
INVERTER_PROFILES = {
x.model: x
for x in [
InverterModelProfile(H1)
InverterModelProfile(H1, r"^H1-")
.add_connection_type(
AUX,
RegisterType.INPUT,
Expand All @@ -131,7 +133,7 @@ def add_connection_type(
LAN,
RegisterType.HOLDING,
),
InverterModelProfile(AC1)
InverterModelProfile(AC1, r"^AC1-")
.add_connection_type(
AUX,
RegisterType.INPUT,
Expand All @@ -141,7 +143,7 @@ def add_connection_type(
LAN,
RegisterType.HOLDING,
),
InverterModelProfile(AIO_H1)
InverterModelProfile(AIO_H1, r"^AIO-H1-")
.add_connection_type(
AUX,
RegisterType.INPUT,
Expand All @@ -152,9 +154,9 @@ def add_connection_type(
RegisterType.HOLDING,
),
# The KH doesn't have a LAN port. It supports both input and holding over RS485
InverterModelProfile(KH).add_connection_type(AUX, RegisterType.INPUT),
InverterModelProfile(KH, r"^KH-").add_connection_type(AUX, RegisterType.INPUT),
# The H3 seems to use holding registers for everything
InverterModelProfile(H3)
InverterModelProfile(H3, r"^H3-")
.add_connection_type(
LAN,
RegisterType.HOLDING,
Expand All @@ -163,7 +165,7 @@ def add_connection_type(
AUX,
RegisterType.HOLDING,
),
InverterModelProfile(AC3)
InverterModelProfile(AC3, r"^AC3-")
.add_connection_type(
LAN,
RegisterType.HOLDING,
Expand All @@ -172,7 +174,7 @@ def add_connection_type(
AUX,
RegisterType.HOLDING,
),
InverterModelProfile(AIO_H3)
InverterModelProfile(AIO_H3, r"^AIO-H3-")
.add_connection_type(
AUX,
RegisterType.HOLDING,
Expand All @@ -181,6 +183,15 @@ def add_connection_type(
LAN,
RegisterType.HOLDING,
),
# Kuara 6.0-3-H: H3-6.0-E
# Kuara 8.0-3-H: H3-8.0-E
# Kuara 10.0-3-H: H3-10.0-E
# Kuara 12.0-3-H: H3-12.0-E
# I haven't seen any indication that these support a direct LAN connection
InverterModelProfile(KUARA_H3, r"^Kuara [^-]+-3-H$").add_connection_type(
AUX,
RegisterType.HOLDING,
),
]
}

Expand Down
3 changes: 2 additions & 1 deletion custom_components/foxess_modbus/modbus_controller.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Modbus controller"""
import logging
import re
import threading
from contextlib import contextmanager
from datetime import datetime
Expand Down Expand Up @@ -347,7 +348,7 @@ async def autodetect(client: ModbusClient, slave: int, adapter_config: dict[str,
# Take off tailing spaces and H3's leading space
full_model = full_model.strip()
for model in INVERTER_PROFILES.values():
if full_model.startswith(model.model):
if re.match(model.model_pattern, full_model):
_LOGGER.info("Autodetected inverter as '%s' (%s)", model.model, full_model)
return model.model, full_model

Expand Down

0 comments on commit d58e101

Please sign in to comment.