#VeSync

1 messages · Page 1 of 1 (latest)

regal river
#

vesync Chat to talk about VeSync development

#

@stone falcon @brave depot @stiff shadow

#

@stiff stratus

stiff stratus
#

Results (3.92s):
24 passed
67 failed

That's my first attempt of fixing the unit tests... pushed to cdnninja:3.xvesync-tests
I'm happy with that for today

brave depot
#

That’s awesome!!! Thank you for doing that.

brave depot
plain mortar
#

I wish VeSync would be local

regal river
#

I haven't checked the tests yet

stiff stratus
#

I'm starting to doubt if mocking the device responses is the way to go...

#

every device response has its own data model and now I would have to mock the correct data structure for every device

regal river
stiff stratus
#

yes

#

but I'm not too familiar with writing tests in python, might need a few pointers

regal river
#

Maybe it would be worth to do in a followup, as we now could have the same source files and then we should see the same results with the different lib version

stiff stratus
#

what do you mean? The old tests are not compatible with pyvesync v3

brave depot
regal river
#

As in, we have tests that test that when the endpoint returns A that a binary sensor is oin

#

and now if we change the library, that should still be valid

stiff stratus
#

hmm I just noticed we have a couple of device-specific fixtures currently. Maybe I'm not using them correctly - i'll check

regal river
#

but yea, I think at this point in time I would be in for just making sure the tests use aiohttp mocks, as that would validate that the library+changed integrations works the same like befor

stiff stratus
#

some device endpoints did change in the library.
For example, "Levoit 131s Air Purifier" used to call /131airPurifier/v1/device/deviceDetail, while pyvesync v3 calls the same endpoint for all purifiers (/cloud/v1/deviceManaged/deviceDetail), which has a different format.

#

To pass the test, I need to change the request mock and return a different data model (see air-purifier-131s-detail.json vs humidifier-200s.json for example)

#

But I don't know if it was tested with a real 131S when the library was updated

brave depot
#

I have a 131s. I have tested, bugs have been created for it in the library.

stiff stratus
#

so you tested it with v3? it works with the common bypassV2 endpoint?

#

sorry I mean /cloud/v1/deviceManaged/deviceDetail

brave depot
#

Yes tested with v3 for my 131s. I’m not familiar with what endpoint library uses but started it up as recently as yesterday with v3.

#

We have sniffs floating around if need that for the tests.

#

The 131s is a bit unique.

#

Ideally I think it stays as it’s own json in the mapping for tests.

stiff stratus
#

yes sure. but it still changed a bit: /131airPurifier/v1/device/deviceDetail->/cloud/v1/deviceManaged/deviceDetail

brave depot
#

Yup that makes sense.

#

I can see if I can find the new json response. I may have it saved.

brave depot
#

Here is an example 131s deviceDetail response

#
{

    "traceId": "1741145662974",
    "code": 0,
    "msg": "request success",
    "module": null,
    "stacktrace": null,
    "result": {
        "screenStatus": "on",
        "filterLife": {
            "change": false,
            "useHour": 2086,
            "percent": 48
        },
        "activeTime": 90022,
        "timer": null,
        "scheduleCount": 0,
        "schedule": null,
        "levelNew": 0,
        "airQuality": "excellent",
        "level": null,
        "mode": "sleep",
        "deviceName": "Levoit 131S Air Purifier",
        "currentFirmVersion": "2.0.58",
        "childLock": "off",
        "deviceStatus": "on",
        "deviceImg": "https://image.vesync.com/defaultImages/deviceDefaultImages/airpurifier131_240.png",
        "connectionStatus": "online"
    }
}
brave depot
#

I added that to your tests repo in the 131s file.

stiff stratus
#

Results (3.97s):
90 passed
3 failed

Almost there CasitaHappy

brave depot
#

That’s awesome! I just got back from vacation today so hoping to spend some time on it this week.

#

You should add yourself as a code owner on the integration!

stiff stratus
#

that's probably a good idea - I'll look into that!

#

my pyvesync PR also got merged - so 3.0.0b4 should include all necessary fixes on the library side

brave depot
#

I created a pr to move your test work over to the same branch. Feel free to merge

stiff stratus
#

will do that once I figured out the last few tests

brave depot
#

Sounds good.

#

Do you want me to work on that discovery code?

regal river
brave depot
#

New device. A service exists if a new device shows up you can call it to add. I don’t mind removing it but existed before. Discovery is maybe wrong word.

regal river
stiff stratus
#

I think I remember working on a unit test for that, which passed. Maybe it works out of the box with the new changes

#

But not sure if that was the tested scenario exactly

brave depot
regal river
#

Ah

#

Dynamic devices

stiff stratus
brave depot
#

No I haven’t.

stiff stratus
#

Finally done with all tests 😄 merged to the main pr branch
They should all pass after these fixes in pyvesync:
https://github.com/webdjoe/pyvesync/pull/348
https://github.com/webdjoe/pyvesync/pull/347

GitHub

Issue
The new implementation of the login flow always raises an exception when login fails, but the login method still returns bool.
The effective return value will always be True.
Changes

Removed...

GitHub

Issue
Purifiers using the VeSyncAirBypass class (mainly Core 200S/300S/400S/600S) will always have the state.nightlight_status be ON, regardless of the actual state.
Reason
_set_purifier_state set...

brave depot
#

I just took a look at discovery, I think you are correct. Since we aren't using a new list to track devices anymore it will work really easily. I will remove that commented out code.

#

Actually scratch that. Need to dispatch I think. Let me play with it.

brave depot
#

@stiff stratus I am switching the login to catch just the VesyncLoginError exception since ConfigEntryAuthFailed stops retries and triggers re-auth flow. Which we only want when the API shows. General failures like network shouldn't stop the retry loop.

#

What is everyones feel on timing for this? While it is really close my gut is we should wait until 2025.10 but plan to have it merged early in September for first beta etc. Thoughts?

stiff stratus
#

Early September sounds good - better spend a bit more time on it than to release a broken version...

#

I know everyone is eager to update but I wouldn't rush it

#

Especially since many of the supported devices have changed even in the library and weren't really tested

brave depot
#

Gives us time to also get more testers on that PR. Also want to make sure we merge this in a time period when @stiff shadow as some cycles to merge/fix items into the library. Recognizing we all have personal lives.

worldly wind
#

Hi, I'd like to try out the updated VeSync integration. I've added it to config/custom_components and added a version to the manifest.json. How can I be certain, that I'm using the custom integration, instead of the official one in the HA UI? Or did I miss a step? Because the "Invalid Authentification" error persists.

brave depot
#

Did you restart after doing that?

worldly wind
brave depot
#

Let us know if you find any issues! More we can fix pre beta the better!

worldly wind
#

Hi, I've encountered a bug while using the integration along with a "Levoit Humidifier" (called "Classic300S" in HA).

When trying to turn the device on/off, an error occurs, which hinders me from turning it on or off:

Logger: homeassistant.components.websocket_api.http.connection
Quelle: components/websocket_api/commands.py:317
Integration: Home Assistant WebSocket API (Dokumentation, Probleme)
Erstmals aufgetreten: 12:51:06 (9 Vorkommnisse)
Zuletzt protokolliert: 12:54:15

[547860706336] Error during service call to switch.turn_on: An error occurred while turning on.
[547860706336] Error during service call to switch.turn_off: An error occurred while turning off.
[547383464864] Error during service call to switch.turn_on: An error occurred while turning on.

Debug Log:

Logger: aiohttp.server
Quelle: /usr/local/lib/python3.13/site-packages/aiohttp/web_protocol.py:481
Erstmals aufgetreten: 12:51:19 (8 Vorkommnisse)
Zuletzt protokolliert: 13:14:43

Error handling request from 192.168.188.193
Error handling request from 192.168.188.30
Traceback (most recent call last):
  File "/usr/local/lib/python3.13/site-packages/aiohttp/web_protocol.py", line 510, in _handle_request
    resp = await request_handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/aiohttp/web_app.py", line 569, in _handle
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/aiohttp/web_middlewares.py", line 117, in impl
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/security_filter.py", line 92, in security_filter_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/forwarded.py", line 83, in forwarded_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/request_context.py", line 26, in request_context_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 86, in ban_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 242, in auth_middleware
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/http/headers.py", line 41, in headers_middleware
    response = await handler(request)
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/http.py", line 73, in handle
    result = await handler(request, **request.match_info)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/diagnostics/__init__.py", line 313, in get
    data = await info.device_diagnostics(hass, config_entry, device)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/vesync/diagnostics.py", line 63, in async_get_device_diagnostics
    data = _redact_device_values(vesync_device)
  File "/config/custom_components/vesync/diagnostics.py", line 120, in _redact_device_values
    data[key] = _redact_device_values(getattr(obj, key))
                ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/vesync/diagnostics.py", line 117, in _redact_device_values
    if callable(getattr(obj, key)):
                ~~~~~~~^^^^^^^^^^
AttributeError: 'pyvesync.base_devices.humidifier_base.HumidifierState' object has no attribute 'child_lock_status'
brave depot
#

Second error is fixed in latest. As for the first you can either update and use the diagnostics feature or enable debug logs and see what the message is above the on off error.

stiff stratus
#

Updated the PR to use a different aio mocking strategy.
Tests are at 100% ✅ again

brave depot
#

@regal river I think we are ready for an initial review for the tests in particular. We still need to sort out a few things but getting very close.

Considering the amount of updates since last review I think ready for you.

worldly wind
brave depot
#

@stiff stratus FYI I reverted the change in fan.py where it switched the modes to a dict instead of list. Since a list is the correct return type and it also created a bug where preset wouldn't change when manual mode was enabled.

It does cause a test to fail for the smart tower fan. I opened this: https://github.com/webdjoe/pyvesync/issues/352 to talk about how we want to deal with that as may be a library thing.

GitHub

Smart tower fan has duplicate modes in its list. I wanted to open an issue before correcting as I am wondering if this is for a specific reason. pyvesync/src/pyvesync/device_map.py Lines 855 to 862...

stiff stratus
#

Ah ok, that wasn't clear to me as well, gotta admit I used AI for this quick fix ^^

brave depot
#

Yeah it would fix it but also created a bug.

#

On the HA side would could duplicate check but wonder if the library should just not have duplicates in the list in the first place.

#

So other than that tests all pass but on github they also fail like this:

stiff stratus
#

It makes sense to remove the duplicates in the library itself. Given that the large amount of breaking changes in v3 it doesn't make much sense to just have these aliases there for backwards compatibility (?)

brave depot
stiff stratus
# brave depot

Yes I've also seen this, but couldn't figure out yet how this only happens on GitHub actions?

brave depot
#

If i had to guess some encoding thing. Odd

stiff stratus
brave depot
#

AI is telling me: This test failure is caused by a mismatch in the Unicode character used for "micro" in the unit string:

Snapshot expects: 'unit_of_measurement': 'µg/m³' (U+00B5, MICRO SIGN)
Test output gives: 'unit_of_measurement': 'μg/m³' (U+03BC, GREEK SMALL LETTER MU)
These two characters look similar but are different Unicode code points. This often happens when code, libraries, or test data use different sources for the "micro" symbol.

stiff stratus
#

Woow

brave depot
#

Since passes on windows I assume this is because github is running it with a different platform or encoding.

#

I don't know how to make windows and github use the same though.

brave depot
#

Figured it out. I asked in integration owners. A PR was merged a few days ago that changed the constants between what encoding it uses for those characters. So the constants we were using are different locally vs remote. I merged changes from dev branch into ours now tests failed locally, so updating snapshots and will push it back up to make all tests pass in the cloud and locally.

#

Except for the smart tower fan extra modes that is. That will fail until library is fixed!

brave depot
#

I have set the PR to ready for review. It isn't ready for merge yet, which I outlined in the PR however all tests pass and minor items left.

Code coverage is failing at 91.9% with a target is 100%, is that a hard goal or just general goal?

stiff stratus
#

I think I can find some time today or tomorrow to spend on that

regal river
#

I don't recommend aiming for that per se in this pr

stiff shadow
#

Outlets work perfectly, found a bug in the library for bulbs and fixed it. One minor thing is, for offline devices the logs are showing:

stiff shadow
#

Just pushed a new pre-release. I'll have some time this weekend if you need any assistance with the HA side

brave depot
#

Sounds good! At this point just need to bump the version in the integration pr and confirm all tests now pass again.

If so ready for review and merge from the HA team.

stiff shadow
#

And I just have to fix the tests now 😬

#

3.0.0b8 is the latest. Let me know if you would like me to make a full release

brave depot
#

@stiff stratus if you get a chance could you bump the package in the integration to see if tests pass? I won’t have a pc until Tuesday. We are out camping.

If it passes I would think a full release is good to go.

stiff stratus
#

Will check it later today

regal river
#

Okay I think the code is fine

#

as in

#

it's not perfect, but we have something to improve from

#

And since beta is cut, we have the whole month to look into issues and make sure its good

#

I think a next step would be, how can we improve the tests to test more devices at once and be easier to extend and not patching internals

brave depot
#

Thanks for the review! Absolutely open to input. I’m hesitant to touch them since I struggle with tests more than I would like to admit. 🙂

is that the key area you would like to see improvement in the code?

stiff stratus
#

Unit-test-wise i would see a big benefit in completely getting rid of all the vesync network mocks.
These details should remain in pyvesync and instead only mock the device models for homeassistant

regal river
#

Euh did my code change break something

#

the tests failed

regal river
brave depot
#

Very open to it. Just hesitant because of my skill not because isn’t the right thing to do.

The reality of this integration is we can never physically test each model of device for each change so pytest is needed to help test.

regal river
#

Yep, and there are cool ways of making sure we test a lot of devices with little tests

brave depot
#

Sounds great, is that the same as the parameters we run today for 10 or so models for state?

brave depot
regal river
#

But the tests now are failing, and I don't believe I just broke them

brave depot
#

Once I’m back by a PC can take a look unless someone beats me to it.

brave depot
#

Looks like the tests didn't actually run before on github so didn't actually pass. So it wasn't you.

A fixture was wrong in our tests, the last version bump corrected something in the library that caused that to show up in tests. Pushing the fixture change now.

regal river
#

Aight

brave depot
#

@regal river Thoughts on if we mock the APIs for the library in HA tests or leave that to the pyvesync tests? Was chatting with @stiff shadow on this. If we want to still mock the APIs thinking we align the fixtures between library tests and ours so can easily match them as new devices added.

@stiff stratus let me know if I am understanding that correctly.

regal river
#

With mashumaro we can still use the existing fixtures

#

Check the overseerr tests for example

regal river
brave depot
#

Very cool!

regal river
#

Gave them my business card, nobody relevant was there so let's see

brave depot
#

@regal river Could I ask @webdjoe and @stiff stratus get recognized in the beta/release notes? I want to make sure they are listed with credit since they put in as much if not more work than I did.

regal river
#

At this moment I don't expect this to be noted in the release notes as nothing really changed for the end user

#

As in, yes it was a lot of effort and the result is great, most of the end users won't notice something new

brave depot
#

Yup that’s the theory! Many users couldn’t login so that’s a big fix though. It also may work on devices it didn’t before because of no more manual device mapping like the old days.

regal river
#

Yep, but bugfixes aren't generally mentioned

regal river
stiff stratus
brave depot
#

Yes feedback from I assume core team asking for values on enum in the bump rather than the enum itself. This also reverts it to how it is pre library rewrite.

#

I suspect the library has “null” as a string in that value for the device type instead of None. I saw that in another spot.

#

Should be none.

#

Could revert the .value as the quick fix but should confirm if “null” as true root cause.

stiff stratus
#

Do you want to open a PR for pyvesync?

brave depot
#

I won’t be able to today. I could probably get to it Saturday. Do you have cycles?

stiff stratus
#

I will have a closer look at it tomorrow

stiff stratus
#

At least I can confirm my own purifier works perfectly now with the new Beta 🙂

brave depot
stiff stratus
#

strange that they claim it works in 2025.9.0 when the integration is broken there...

brave depot
#

It’s only broken for new users.

#

I have been using it for awhile without issues.

stiff stratus
#

aah I didn't know that

brave depot
#

This somewhat shows it. I assume the more recent uptick may be people installing as custom to workaround it:

brave depot
brave depot
regal river
#

this in theory changes the unique id

#

but this is like expected right

#

or did it now change from 2025.9 to 2025.10?

brave depot
#

Changed from 9 to 10 so putting it back

regal river
#

great

brave depot
brave depot
#

We will see if tests pass - was failing on github but pass locally. On an item that came up last time I did a PR too. Unrelated test failure within the same integration. Seems to come and go.

regal river
#

Should we add a test for it?

#

oh

#

tests are failing

brave depot
#

Yeah doesn't make sense they fail though.

#

Trying to figure out why. I had a PR before that failed the same way for a bit then it stopped. Passes locally.

#

I can probably adjust a fixture dataset to test this situation. Would that work?

#

I am rebuilding my local dev container to see if that will make tests fail locally but I did that once before without luck.

plain mortar
#

My VeSync integration stopped working after 2025.10 update. Is it expected? Do I need to switch something?

#

I have also received a Security warning email from Vesync

#

Since then its not working

brave depot
#

Security emails are normal. We do have a login bug being worked on that impacts some users.

plain mortar
#

🙏 thanks

brave depot
brave depot
regal river
regal river
#

Did y'all once check if it was possible to discover these devices on the network?

brave depot
regal river
#

At the bottom there are 3 network discovery panel links

brave depot
#

I renamed a device in app to see if those change. Not sure how long I wait to see.

#

As a side not - nicely growing now that past those login issues:

brave depot
regal river
brave depot
# regal river So, if it would you don't have to add any unique id thing

Is fyta integration doing it correctly if name always starts with levoit? I want it to prompt if not configured but since can't align to what username etc only promt if not configured. I don't see anything in the config flow for DHCP. In my case it would want to just trigger normal user flow since need cloud config.

regal river
#

Yes

#

That's what happens

vivid shadow
#

Speaking of levoit, I have a branch with virtual integration for vesync. Is this the only kind of integration levoit devices would have? I have a core 300s which uses vesync, but not sure if there are any others that brand uses