Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fan support #16

Open
timmcfly85 opened this issue Jul 2, 2024 · 4 comments
Open

Fan support #16

timmcfly85 opened this issue Jul 2, 2024 · 4 comments

Comments

@timmcfly85
Copy link

I installed your code in my ESPHome configuration. It paired perfectly the first time with my ceiling light and Home Assistant. I am now able to turn the light on using a better switch and button configuration.

My light has a ceiling fan on it and I would love to be able to control the fan going off and on and changing speeds depending on the temp of the room.

I have zero idea how to add that functionality to your repository. Is this something that you think you could add and/or get me started on adding in a branch. I'm using the lampsmart_pro_light component.

I think your code works for my fan even though it was not designed for that model. Just looking to add more functionality.
If you are interested, the fan I have is https://a.co/d/0bQsB0o1

Thanks and keep up the great work.

@aronsky
Copy link
Owner

aronsky commented Jul 3, 2024

Hi Tim,

Unfortunately, adding the fan controlling functionality requires quite a bit of time that I don't have. If you feel comfortable with disassembly and reverse engineering, I can point you to the parts of the application that needs analysis - and afterwards, a fan component emulating that functionality needs to be added to the repo.

@yacko1975
Copy link

I have a fan that uses a similar app by the same author (FanLamp Pro) I have downloaded and decompiled the APK and have some experience reverse engineering. If you want to point me in the direction of what parts of the app need analyzed to get the codes, I will see if I can pull the pieces that are needed and see if I can add them to a Pull. Thanks for all your work on this project.

@aronsky
Copy link
Owner

aronsky commented Jul 5, 2024

Hi @yacko1975 - so, I took a look at FanLamp Pro APK, version 1.3.6 (downloaded from APK Pure).

After opening it in JADX, the relevant code is in package j0, class a, method f(i, j$d) (it's Flutter, and everything is obfuscated badly). In that method, you can see 2 switch cases. The first simply sets the value that chooses the branch in the second switch - you should focus on the 2nd switch. In it, most branches call various methods of ToolV3 with various arguments. The method names are self-evidend: blevbBinding is for binding to the fan/light, blevbLampOnOff toggles the lamp, blevbDimming dims the lamp, and so on. The issue is that the arguments to that method are generated dynamically, so you need a way to figure them out. Assuming you have a rooted phone, Frida would be the best way to get that information. Notice that while the first argument - type - should be the same, the values for the other arguments might be different from call to call, they can represent the dimming level, for instance - and so on.

Once you have that information (i.e., for each ToolV3.blevb... method that you want to implement, the actual argument values that are passed), it's time to jump into the native code. From the resources of the APK, get the native library called libencodeV3.so (there are arm64, armeabi, and x86-64 varieties - choose whichever arch you feel most comfortable with). Open it in your favorite disassembler (I recommend Ghidra), and find the methods that match the Java native method names (they are all exported so that Java can find them, and start with Java_.... Follow the code in those methods - they should all be pretty similar, and take the values passed and run it through an encoding procedure that returns a byte array (in fact, 2 byte arrays - V2 and V3). Then jump back to the Java code, and see what's done after the native method call. I haven't verified it, but I think that at this point the V2 and V3 byte arrays are simply advertised multiple times.

Once you know how to build the BLE advertising data for each method you want to implement, it's time to jump back to the ESPHome component code and develop. Create the fan component in Python and add the corresponding C++ implementation. You can use the code for lamps for reference. The trickiest part is the encoding procedure in libencodeV3, that generates the byte array - decompilers usually fail to create proper code for it, so you'll have to play around to get a working implementation - that's where the multiple architectures come in handy (some may end up with better decompilation results than others). Note that if the current code in the repository works with the lamp part of the fan, I believe it means that the encoding that's already implemented here is the same, and you should be able to use it in your code.

Good luck!

@sssushi
Copy link

sssushi commented Jul 17, 2024

Hello,
I tried your code to control my ceiling fan…. Light works like a charm…. However the Fan controlling would be really great. It would be worth a good donation from my side…. Anyone had luck to implement the commands ? The Fan would be even more important than the light because there is no other solution like bluetooth and remote.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants