squishykid / solax

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

Improve discovery times by decoupling http clients from inverters #119

Open squishykid opened 1 year ago

rnauber commented 1 year ago

Hi @squishykid , I tested your PR with an X3HybridG4 because the standard discovery was always timing out. And it worked perfectly after I installed the mypy package.

InverterResponse(data={'Grid 1 Voltage': 232.7, 'Grid 2 Voltage': 235.4, 'Grid 3 Voltage': 233.9, 'Grid 1 Current': 0.9, 'Grid 2 Current': 0.9, 'Grid 3 Current': 0.9, ...}, serial_number='...', version='...', type=14, inverter_type=14)

I would be very interested in getting this PR merged, let me know if I can help.

Best, Richard

squishykid commented 1 year ago

I think at this stage we just have to make the tests pass

rnauber commented 1 year ago

Well @squishykid , if you don't mind my hamfisted approach, I will try to cook something up here: https://github.com/rnauber/solax/tree/speedy-discovery

I submit a PR to you, once it is done. Best, Richard

rnauber commented 1 year ago

Hi @squishykid , it is (almost) done: The linters are happy, the test coverage is 100% and only one test fails. The reason is that "X1MiniV34" and "x1_boost" can not be distinguished by their responses yet. I am not sure how you want this to be resolved, therefore I leave it unfixed.

Best, Richard

Running black...
All done! ✨ 🍰 ✨
32 files would be left unchanged.
Running isort
Skipped 6 files
Running mypy...
Success: no issues found in 32 source files
Running flake8...
Running pylint...

--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)

Running pytest...
============================================================== test session starts ===============================================================
platform linux -- Python 3.10.12, pytest-7.4.0, pluggy-1.2.0
rootdir: /home/olg/scratch/solax
plugins: anyio-3.6.1, cov-4.1.0, httpserver-1.0.8, asyncio-0.21.1
asyncio: mode=strict
collected 112 items                                                                                                                              

tests/test_base_inverter.py .....                                                                                                          [  4%]
tests/test_discovery.py ......F..............................                                                                              [ 37%]
tests/test_smoke.py .....................................................                                                                  [ 84%]
tests/test_solax.py ..                                                                                                                     [ 86%]
tests/test_utils.py ............                                                                                                           [ 97%]
tests/test_vol.py ...                                                                                                                      [100%]

==================================================================== FAILURES ====================================================================
____________________________ test_discovery[X1Boost_http(post_query)_    X1_BOOST_RESPONSE_produces_X1_BOOST_VALUES] _____________________________

inverters_fixture = (('localhost', 42509), <class 'solax.inverters.x1_boost.X1Boost'>, 'post_query', {'AC Frequency': 60.21, 'AC Output Current': 12.6, 'AC Output Power': 2956, 'AC Voltage': 239.6, ...})

    @pytest.mark.asyncio
    async def test_discovery(inverters_fixture):
        conn, inverter_class, _, _ = inverters_fixture
        rt_api = await solax.real_time_api(*conn)
>       assert rt_api.inverter.__class__ == inverter_class
E       AssertionError: assert <class 'solax.inverters.x1_mini_v34.X1MiniV34'> == <class 'solax.inverters.x1_boost.X1Boost'>
E        +  where <class 'solax.inverters.x1_mini_v34.X1MiniV34'> = <solax.inverters.x1_mini_v34.X1MiniV34 object at 0x7fca9c1ca3b0>.__class__
E        +    where <solax.inverters.x1_mini_v34.X1MiniV34 object at 0x7fca9c1ca3b0> = <solax.RealTimeAPI object at 0x7fca9c1ca770>.inverter

tests/test_discovery.py:13: AssertionError
--------------------------------------------------------------- Captured log call ----------------------------------------------------------------
INFO     werkzeug:_internal.py:187 127.0.0.1 - - [22/Jul/2023 23:27:29] "GET /api/realTimeData.htm HTTP/1.1" 500 -
INFO     werkzeug:_internal.py:187 127.0.0.1 - - [22/Jul/2023 23:27:29] "POST / HTTP/1.1" 500 -
INFO     werkzeug:_internal.py:187 127.0.0.1 - - [22/Jul/2023 23:27:29] "POST /?optType=ReadRealTimeData HTTP/1.1" 200 -
================================================================ warnings summary ================================================================
tests/test_smoke.py: 17 warnings
tests/test_solax.py: 3 warnings
  /home/olg/scratch/solax/solax/__init__.py:25: DeprecationWarning: with timeout() is deprecated, use async with timeout() instead
    with async_timeout.timeout(REQUEST_TIMEOUT):

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html

---------- coverage: platform linux, python 3.10.12-final-0 ----------
Name                                 Stmts   Miss Branch BrPart  Cover   Missing
--------------------------------------------------------------------------------
solax/__init__.py                       30      0      6      0   100%
solax/discovery.py                      24      0      6      0   100%
solax/http_client.py                    73      0     14      0   100%
solax/inverter.py                      128      0     32      0   100%
solax/inverter_error.py                  1      0      0      0   100%
solax/inverters/__init__.py             12      0      0      0   100%
solax/inverters/qvolt_hyb_g3_3p.py      22      0      0      0   100%
solax/inverters/x1.py                    9      0      0      0   100%
solax/inverters/x1_boost.py             12      0      0      0   100%
solax/inverters/x1_hybrid_gen4.py       12      0      0      0   100%
solax/inverters/x1_mini.py              12      0      0      0   100%
solax/inverters/x1_mini_v34.py          12      0      0      0   100%
solax/inverters/x1_smart.py             12      0      0      0   100%
solax/inverters/x3.py                   12      0      0      0   100%
solax/inverters/x3_hybrid_g4.py         16      0      0      0   100%
solax/inverters/x3_v34.py               12      0      0      0   100%
solax/inverters/x_hybrid.py             11      0      0      0   100%
solax/response_parser.py                 0      0      0      0   100%
solax/units.py                          17      0      0      0   100%
solax/utils.py                          41      0     10      0   100%
--------------------------------------------------------------------------------
TOTAL                                  468      0     68      0   100%

Required test coverage of 100% reached. Total coverage: 100.00%
============================================================ short test summary info =============================================================
FAILED tests/test_discovery.py::test_discovery[X1Boost_http(post_query)_    X1_BOOST_RESPONSE_produces_X1_BOOST_VALUES] - AssertionError: assert <class 'solax.inverters.x1_mini_v34.X1MiniV34'> == <class 'solax.inverters.x1_boost.X1Boost'>
=================================================== 1 failed, 111 passed, 20 warnings in 1.75s ===================================================