Closed rwl4 closed 3 years ago
I appreciate that, but I'd be more that happy to add support if you posted the packet captures
I've sent the packet captures for the various functions to webdjoe.
Here are roughly the modes of the humidifier:
It has a setting to turn on/off the front display (except in sleep mode where it's off).
It has a setting to turn off the mini night light, or set it to a "dim" or "medium" level.
It has a timer for turning on or off in x mins. It has a scheduler for turning it on or off (with specific settings) at a certain time of day. There's also a push notification if the water level is zero. Presumably these features don't need to be supported though. :)
Thanks!
@webdjoe I'd love to help get support for this added. I recently purchased 4 of these for my house and am itching to get them into HA. You mentioned packet captures; do you mean you need to see what API calls the VeSync app is making to control the units?
I was just sent the packet captures so I am working on it. These new devices have slightly different call structures that make the coding a little different than the library was built. I don't want to put a quick patch that makes the code difficult so I am redesigning some of the underlying structure that will make adding devices easier
Awesome; thanks for working on this, it is much appreciated. Please let me know if I can help in any way.
Also happy to help in any way possible.
Thank you @webdjoe for working on this.
Hi @SandroGrzicic would you mind sending me the packet captures you have for various functions? Thanks a lot!
Thank you for wanting to assist. I refactored the main vesync class to make it easier to add devices. I’m also working with mark to transfer the repo to my account and add CI. Would you mind holding off until I merge the changes? I should have the master updated by tonight or tomorrow the latest.
On Thu, Jan 28, 2021 at 9:12 AM Sandro Gržičić notifications@github.com wrote:
Hi @SandroGrzicic https://github.com/SandroGrzicic would you mind sending me the packet captures you have for various functions? Thanks a lot!
Sure, just send me an email at ivan.abrahimovic (gmail) and I'll e-mail you the ZIP.
— You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/markperdue/pyvesync/issues/66#issuecomment-769080324, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB6JJBQDJGF3PMEW4LJHIODS4FWGFANCNFSM4VJHKL5A .
I've updated the master branch with CI and new changes. I have a rough update for the 300S humidifier, please test it out here: https://github.com/webdjoe-bot/pyvesync/tree/Levoit300S
I tried it out with this script
from pyvesync import VeSync
manager = VeSync("","")
manager.login()
manager.update()
for device in manager.fans:
if device.device_type == "Classic300S":
device.display()
device.turn_off()
I had to make the fix in this pr linked below to make it work, but i think there is more wrong than that. I have a different version of the app, 3.0.54 vs the 2.5.1 that I think the code was written to so i'm not sure if the requests body's are different because of a bug in the code or because the api is different for the two versions.
The first big difference i saw is on the getHumidifierStatus
call the code sets the two different method variables:
{ ... method: "devicedetail", "payload": { "method": "getHumidifierStatus", ... }
but the app i'm running does:
{ ... method: "bypassV2", "payload": { "method": "getHumidifierStatus", ... }
I didn't see a quick way to try to test changing that method.
I've only been looking at the request format I don't have a full set of packet captures at this time from the version of the app i have.
I have tried the Levoit300S branch, however I have a problem when I call manager.update()
- I think it's the same issue that obi11235 had:
PyDev console: starting.
Python 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)] on win32
from pyvesync import VeSync
manager = VeSync("<redacted>", "<redacted>")
manager.login()
True
manager.update()
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "D:\_\HomeAssistant\pyvesync\src\pyvesync\vesync.py", line 285, in update
device.update()
File "D:\_\HomeAssistant\pyvesync\src\pyvesync\vesyncfan.py", line 360, in update
self.get_details()
File "D:\_\HomeAssistant\pyvesync\src\pyvesync\vesyncfan.py", line 344, in get_details
inner_result = r.get('result', {}).get('result')
AttributeError: 'NoneType' object has no attribute 'get'
I had to make the fix in this pr linked below to make it work, but i think there is more wrong than that. I have a different version of the app, 3.0.54 vs the 2.5.1 that I think the code was written to so i'm not sure if the requests body's are different because of a bug in the code or because the api is different for the two versions.
The first big difference i saw is on the
getHumidifierStatus
call the code sets the two different method variables:{ ... method: "devicedetail", "payload": { "method": "getHumidifierStatus", ... }
but the app i'm running does:
{ ... method: "bypassV2", "payload": { "method": "getHumidifierStatus", ... }
I think I can confirm that, by looking at my packet captures I can see the following HTTP request for getHumidifierStatus
:
POST /cloud/v2/deviceManaged/bypassV2 HTTP/1.1 User-Agent: VeSync/VeSync 3.0.51(F5321;Android 8.0.0) Content-Type: application/json; charset=UTF-8 Content-Length: 476 Host: smartapi.vesync.com Connection: Keep-Alive Accept-Encoding: gzip
{"acceptLanguage":"en","accountID":"[redacted]","appVersion":"VeSync 3.0.51","cid":"[redacted]","configModule":"WiFiBTOnboardingNotify_AirHumidifier_Classic300S_US","deviceRegion":"US","phoneBrand":"F5321","phoneOS":"Android 8.0.0","timeZone":"[redacted]","token":"[redacted]","traceId":"[redacted]","method":"bypassV2","debugMode":false,"payload":{"method":"getHumidifierStatus","source":"APP","data":{}}}
Thanks!
I did some more testing with it, i think i got a clean fix for all of it. I tested all the functions and they seem to work for me. I have not tested that it collects the data correctly, but don't have time to look into that now.
This pr has all my changes in it https://github.com/webdjoe-bot/pyvesync/pull/2
Thank you @SandroGrzicic for testing and @obi11235 for your PR. I was hoping you could clear up a few things:
Does changing the changing the mist level via this library change the mode to manual?
Does the auto stop mode work correctly?
Should there be an off mode in the change mode method?
Changing the mist level via the library switches the unit to manual mode. Auto stop does flip the setting in the app.
there is no need for an off mode, turn_on and turn_off work. I tested this list of functions and they all seem to work:
manager.login()
manager.update()
for device in manager.fans:
if device.device_type == "Classic300S":
device.display()
# device.turn_off()
# device.turn_on()
# device.set_humidity(40)
# device.set_humidity_mode('auto')
# device.automatic_stop_on()
# device.automatic_stop_off()
# device.set_mist_level(1)
I had a chance to test the data that was coming back in get_details method and updated my PR to get that to work now. So the data in self.details and self.config are correctly updated with the results from the api. To help debugging I added the display functions from the air filter in the same class and fixed a bug in the displayJSON() function on the filter since I have one to test it on.
I can confirm @obi11235's branch works, I tried it with my 300S. A few notes:
set_humidity
does nothing if the unit is not in auto
or sleep
mode already set_mist_level
works as expected - if the unit is in auto
or sleep
mode it also switches it to manual
modevesyncfan.py
, in the function set_humidity_mode
, manual
should also a valid mode - it would set the device to Manual mode where you manually set the mist level (currently only auto
and sleep
are allowed in the code)sleep
mode, as expected, sets the unit to sleep
mode (turning off the display)set_night_light_brightness
works great from 0 (off) to 100 (max), in 1% increments, unlike in the official app (or the button on the device) which only support 2 light intensity levelsautomatic_stop
family of functions seem to work well (with a delay in updating in the app)details.get('humidity')
matches the humidity shown on the device displaydetails.get('water_tank_lifted')
gives the correct resultSo the only two app features that are currently "missing" are the:
Presumably these don't really need to be implemented, as nobody will presumably use them, since the timer or schedule functionality should be implemented in any automation software (such as HA). Therefore I would say that this is feature-complete. Thank you for all the work!
Hi @webdjoe thank you for your library!
With the code for the Levoit Classic 300S the device status (displayed e.g. by displayJSON()) will only be updated on startup in the process_device function and then will never be updated again.
My quick'n'dirty fix:
vesyncfan.py - add the following lines on line 347:
r2, _ = Helpers.call_api(
'/cloud/v1/deviceManaged/devices',
'post',
headers=Helpers.req_headers(self.manager),
json=Helpers.req_body(self.manager, 'devicelist'),
)
if r2 and Helpers.code_check(r2):
if 'result' in r2 and 'list' in r2['result']:
devices = r2['result']['list']
for dev in devices:
if dev["cid"] == self.cid:
self.device_status = dev["deviceStatus"]
Hi @webdjoe ! First of all - thank you for your work, it's amazing! Just wanted to ask, if there are plans to extend existing HA VeSync integration with this new functionality.
Thank you in advance!
I will do my best to get to it, but it will take some time. If anyone wants to share some work that they've already done, I will gladly contribute.
@webdjoe sorry for digging this out of grave, just wanted to paste link to related pull-request - both for you and those desperate people, who will come here seeking help. :) https://github.com/home-assistant/core/pull/49956
Not much done there, but proven to work, just needs polishing.
It would be great to have support for the Levoit Classic 300S humidifier. In fact, if one of you wants to reach out to me, I'll have Amazon ship you one at my expense! Let me know!