From 547d01b8c5e5687b42368485f64e6a7037e025ca Mon Sep 17 00:00:00 2001 From: gustavoio Date: Wed, 13 Sep 2023 19:03:38 +0100 Subject: [PATCH] Ad support for solax x1-hybrid-gen5 --- solax/inverters/__init__.py | 2 + solax/inverters/x1_hybrid_gen5.py | 65 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 solax/inverters/x1_hybrid_gen5.py diff --git a/solax/inverters/__init__.py b/solax/inverters/__init__.py index 883e9d3..8bc8f4e 100644 --- a/solax/inverters/__init__.py +++ b/solax/inverters/__init__.py @@ -2,6 +2,7 @@ from .x1 import X1 from .x1_boost import X1Boost from .x1_hybrid_gen4 import X1HybridGen4 +from .x1_hybrid_gen5 import X1HybridGen5 from .x1_mini import X1Mini from .x1_mini_v34 import X1MiniV34 from .x1_smart import X1Smart @@ -23,5 +24,6 @@ "X3", "X1Boost", "X1HybridGen4", + "X1HybridGen5", "X3MicProG2", ] diff --git a/solax/inverters/x1_hybrid_gen5.py b/solax/inverters/x1_hybrid_gen5.py new file mode 100644 index 0000000..e62046d --- /dev/null +++ b/solax/inverters/x1_hybrid_gen5.py @@ -0,0 +1,65 @@ +import voluptuous as vol + +from solax import utils +from solax.inverter import Inverter, InverterHttpClient, Method, ResponseParser +from solax.units import Total, Units +from solax.utils import div10, div100, pack_u16, to_signed + + +class X1HybridGen5(Inverter): + # pylint: disable=duplicate-code + _schema = vol.Schema( + { + vol.Required("type"): vol.All(int, 15), + vol.Required( + "sn", + ): str, + vol.Required("ver"): str, + vol.Required("Data"): vol.Schema( + vol.All( + [vol.Coerce(float)], + vol.Length(min=300, max=300), + ) + ), + vol.Required("Information"): vol.Schema(vol.All(vol.Length(min=9, max=10))), + }, + extra=vol.REMOVE_EXTRA, + ) + + @classmethod + def _build(cls, host, port, pwd="", params_in_query=True): + url = utils.to_url(host, port) + http_client = InverterHttpClient(url, Method.POST, pwd).with_default_data() + + response_parser = ResponseParser(cls._schema, cls.response_decoder()) + return cls(http_client, response_parser) + + @classmethod + def build_all_variants(cls, host, port, pwd=""): + versions = [cls._build(host, port, pwd)] + return versions + + @classmethod + def response_decoder(cls): + return { + "AC voltage R": (0, Units.V, div10), + "AC current": (1, Units.A, div10), + "AC power": (2, Units.W), + "Grid frequency": (3, Units.HZ, div100), + "PV1 voltage": (4, Units.V, div10), + "PV2 voltage": (5, Units.V, div10), + "PV1 current": (6, Units.A, div10), + "PV2 current": (7, Units.A, div10), + "PV1 power": (8, Units.W), + "PV2 power": (9, Units.W), + "On-grid total yield": (pack_u16(11, 12), Total(Units.KWH), div10), + "On-grid daily yield": (13, Units.KWH, div10), + "Battery voltage": (14, Units.V, div100), + "Battery current": (15, Units.A, div100), + "Battery power": (16, Units.W), + "Battery temperature": (17, Units.C), + "Battery SoC": (18, Units.PERCENT), + "Grid power": (32, Units.W, to_signed), + "Total feed-in energy": (pack_u16(34, 35), Total(Units.KWH), div100), + "Total consumption": (pack_u16(36, 37), Total(Units.KWH), div100), + }