squishykid / solax

🌞 Solax Inverter API Wrapper
MIT License
97 stars 57 forks source link

Speedup discovery process #103

Open adambogocz opened 1 year ago

adambogocz commented 1 year ago

Hello, I have recently added X3-Hybrid-G4 support and added into the discovery list where it fits the most, unfortunately side effect for that is that discovery takes too much time, because of big timeout a number of inverters x methods... Each try trows away the data it may got, because the schema validation may have failed. If discovery would try various methods of data retrieval and then validated the result with inverter parsers, to find and select the right one, discovery would be cut drastically in time, especially if more inverters are added.

Currently I have locally added patch to prioritise REGISTRY list, so my home assistant and other testing scripts are starting fast.

def prioritise_registry():
    priority = getenv("SOLAX_DISCOVERY_PRIORITY")
    if priority:
        for priority_inverter in reversed(priority.split(",")):
            for idx, inverter in enumerate(REGISTRY):
                if inverter.__name__ == priority_inverter:
                    REGISTRY.insert(0, REGISTRY.pop(idx))
                    break

async def discover(host, port, pwd="") -> Inverter:
    prioritise_registry()

    failures = []
    for inverter in REGISTRY:
adambogocz commented 1 year ago

I could help with the implementation of course.

squishykid commented 1 year ago

Looking at what you shared in #101 and the responses in https://github.com/squishykid/solax/blob/master/tests/samples/responses.py, i think the second value in the "Information" field array corresponds to the inverter type.

So we should be able to perform the discovery with a limited number of requests, one per connection type- which would only be a few POST requests. Then once we have a response, we can use the second "Information" value to go straight to the appropriate mapping!

adambogocz commented 1 year ago

Well, just to parse the data we are good to use type field to identify what field is what, but inverters can share type, so if you want to know model that's in information, but that's just information, there is also ARM version, DSP version and other things which are metadata, not needed for data interpretation.

adambogocz commented 1 year ago

I have just dug bit more into Information field, and looks like it should be safe/better to use to detect correct data parser. So far I found out that there are 2 layouts of Information field, these are

The first is

0: inverter max power
1: inverter type
2: inverter sn
3: (unknown)
4: DSP version
5: (unknown, zero)
6: ARM version
7: (unknown, looks like version of something)
8: (unknown, zero)
9: transport type

or second is

0: inverter max power
1: inverter type
2: (unknown)
3: inverter sn
4: (unknown)
5: DSP version
6: (unknown)
7: ARM version
8: (unknown)
9: transport type
10: dongle mod type
11: dongle work mode

We can work out the details together later on.