-
Notifications
You must be signed in to change notification settings - Fork 46
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
Unable to connect to alternative brand of lights - incorrect base code? #5
Comments
Hi, Two things:
|
The app I'm using is from https://play.google.com/store/apps/details?id=com.jingyuan.lamp - v1.2.3 I'll see if I can get "unwhitened" packets into the console so I have a better idea of what's going on. I'm not particularly at home with C but will give it a try. NB: Which app have you been basing your work off? Doing a quick search I can also see https://play.google.com/store/apps/details?id=com.alllink.smart_lighting which appears to be functionally equivalent. I wouldn't be surprised if there are others. |
Yep - it's the same app and version that I disassembled (LampSmart Pro 1.2.3). Very strange. |
I've unwhitened the packets for you. Here's a Python code to do that: XBOXES = [
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
]
def unwhiten(buf, size, seed):
res = []
for i in range(size):
res.append(buf[i] ^ XBOXES[(seed + i + 9) & 0x1f])
res[i] ^= seed
res[i] &= 0xff
return res As expected, the output of the packet from the app is absolutely garbled (i.e., it probably wasn't "whitened" with that function to begin with). Are you sure you're capturing the correct packet from the app? Maybe there are additional packets going out that you're missing? |
Thanks, getting more info. I may have had the wrong packet earlier. Latest transmit from here: So, I can extract that into a packet and seed:
and plugging it into your unwhiten function:
|
That looks much better - but then, it also looks exactly like the packet sent by the ESP32, so I'm not sure why it's not working... This is the packet sent by the ESP32 (from your first message):
The 2nd byte seems to be just a counter, so it makes sense it differs. And the 4 bytes starting at index 4 ( You can make a few changes to the code and force it to send the same packet as the app, see if that works.
|
Yeah, the app definitely appears to be sending two distinct codes (although not every time, or maybe I'm just missing some of them), one which I can "unlighten" and one which I can't. Locking down the identifier to my light (yes, it's little-endian) I can send packets that look almost exactly like some of the ones coming from the phone, but still no response from the light itself. Here's a sample
Not sure where to go from here. I might just set up something to send the exact codes I'm receiving back and see if I can get a response. |
OK. So it looks like the main difference between the app and the ESP32 (assuming the garbage packets are irrelevant) is the byte right after the identifier and before the command, which is set to 0 on the ESP32 (hard-coded), and seems to be 1 in the app. Try setting it to 1 (on this line: https://github.com/aronsky/esphome-components/blob/main/components/lampsmart_pro_light/lampsmart_pro_light.cpp#L163), and see if that helps? I don't remember whether I set it to 0 because it's what the app does, or because I had no other values to go off, and assumed it to be 0 - but it looks like 1 is the correct value, at least for you. Let me know if that works. |
Hello guys, I also have issues with pairing my Lampsmart Pro compatible Lamp with the esp32. What do you mean with setting to 1? I am not good at programming, but I can manage to change the code. Can you please write what I have to write instead of 0x0?
|
Change the However, I'm not sure it will work - I was hoping it would, but @jymbob hasn't come back with positive results, which, I suspect, means that it didn't help... |
I've just tested it - unfortunately it didn't work either.
|
Sorry, yeah, no joy yet. Will try some more things this week and
report back.
…On Sat, 1 Jul 2023, 22:11 cekosss, ***@***.***> wrote:
I've just tested it - unfortunately it didn't work either.
Below my message, I have attached the log from my esp32 tracker when I
controlled the Lamp from my iPhone with the beloved Lampsmart Pro iOS App.
Maybe it can be useful for you.
[22:27:10][VV][esp32_ble_tracker:396]: Ad Flag: 26
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0xF877
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0x5FB6
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0x5E2B
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0xFC00
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0x5131
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0x935C
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0x0892
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0xCBBC
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0xFC7E
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0xC030
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0x36F4
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0x0ADD
[22:27:10][VV][esp32_ble_tracker:399]: Service UUID: 0x8B58
[22:27:10][VV][esp32_ble_tracker:418]: Adv data:
>02.01.1A.1B.03.77.F8.B6.5F.2B.5E.00.FC.31.51.5C.93.92.08.BC.CB.7E.FC.30.C0.F4.36.DD.0A.58.8B
(31)
—
Reply to this email directly, view it on GitHub
<#5 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA7U2FKGQ4Y3LKWQQTXOAMDXOCG7TANCNFSM6AAAAAAZJVUBEI>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Hello again, I just have logged the signal of the remote control, which was delivered with the lamp. The button I pressed was the SETUP button for pairing with the lamp. I hope, that this could be useful for you, since the adv data of the pairing command looks a little bit different.
|
I'll need to unwhiten that message to check its contents. But at least as far as the beginning goes, it looks similar to what the compnent transmits. @jymbob @cekosss has any of you used lampify successfully? If so, a fallback to lampify's algorithm (which seems quite different from what I disassembled from the app), could work. |
@cekosss so the unwhitened data in this packet looks like this:
Broken down, that is (note, it's little-endian, so the bytes for each field are reversed):
So, that matches what this component sends out pretty well, except:
So, if that button press worked, and the lamp was paired - I'm quite at a loss as to what may cause this. The current code is really spot-on, other than the above 2 points. I made a branch with those changes for you to test out: https://github.com/aronsky/esphome-components/tree/support-additional-lamps If that doesn't help, you can take the
0x00 ). I really doubt that it will help, but worth trying if all the other options fail.
Finally, if none of the above works - I'm not sure what else can be done. Clearly the code works the same as the remote control, so if the remote control works - so should the code... Any chance the lights are simply too far away from the ESP32? |
The lights are part of an ongoing extension so I'm only able to test this
out when the builders aren't around. I'll try to do some more testing
shortly. My understanding is that the BLE remote is doing a far simpler
interaction with the light compared to the app, although the end result
appears to be the same. I'm also not sure it can support a rolling code,
but haven't yet fully tested that with my sniffer.
…On Mon, Jul 3, 2023 at 10:09 AM Lev Aronsky ***@***.***> wrote:
I'll need to unwhiten that message to check its contents. But at least as
far as the beginning goes, it looks similar to what the compnent transmits.
@jymbob <https://github.com/jymbob> @cekosss <https://github.com/cekosss>
has any of you used lampify successfully? If so, a fallback to lampify's
algorithm (which seems quite different from what I disassembled from the
app), could work.
—
Reply to this email directly, view it on GitHub
<#5 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA7U2FPEPT2UBNY3O6BAL43XOKD4DANCNFSM6AAAAAAZJVUBEI>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
GMail. Marvellous
|
Unfortunately lampify doesn't work on my Raspberry Pi Zero 2W, which is supposed to support BLE...
|
Hi Aronsky, Great work !! Used this for a month and then because of a crack in the housing I had to replace the entire fixture. Anyway, same issue as OP, your code or the fork can't pair, lampify similarly doesn't connect - no light flicker to confirm. Is there a guide or a script I can use to sniff what the remote or the app send (BT codes I mean, ideally unwhitened) ?? Also, couldn't you code be simplified ? I.e. separating the static part of the bytes sent for setup from the dynamic part to make it easier to try some combinations for other devices as such ? Have a linux with a BT dongle and a few ESPs, HA, a RPi, etc |
Sorry, if that fixture doesn't work with LampSmart Pro, it's out of scope for this repo. A different app means that the protocol is probably completely different (otherwise it would support the other apps). |
Thank for the reply. From the Remote: 18f90849b2ce2c109a9efd050320c9412c10111213141516171819
Don't know yet how to alter your code for ESP locally (without publishing my own GitHub repo) but I can use the base Lampify code locally where I can easily change the base bytes that are sent. Tried with a few combinations without any luck. Alternatively I can unpack the apk and decompile it but I'm not sure what to look for there also. |
I think I'm close... Remote Control: Aronsky ESP: Now, I tried altering the lampify script to send these hex values, but I may be doing something wrong, as not all the array elements need to be updated, only some of them... will try some more later this evening. |
Hi, However, be advised, that this may be more difficult than you expect. There are multiple apps that work with the lamps supported by this repo, so clearly there is some protocol that remains shared between all those apps. Since you say that you had to switch to a different app, and other apps don't work - it's quite possible that underneath a similar appearance, the protocol is completely different. In any case, guessing what bytes need to be changed based on BLE monitoring alone is moot. The data you see is encoded, and without decoding it properly, there's no chance you will see a single byte or two of difference - the whole packet will look different. You'll have to disassemble the app and see what it's doing. |
Since I am not a programmer, I may not be very useful in developing the code, but I can offer you me testing your work with my ESP32 and my lamp. If you like to get more information about the specific remote control of my lamp, just let me know and I will do my best to provide the information you need. Never give up :-) |
:) never give up, indeed, until I decompiled that chinese apk (about 35MB) and got a bit scared... it tries to constantly send data to some chinese servers... With ESP what I managed to do is grab Aronsky's code and put it locally so I can play with it, tried a few byte changes but it's pretty much pointless, as after decompiling the APK I saw that every packet sent to the light is followed by another packet... so somehow they always send a pair of packets. |
I was running at the same issue as @jymbob . Tried the
All are not able to pair with the light. Could it be the board I am using? (NodeMCU-32S). Logs are always saying the device is trying to pair: I have managed to sniff out the 'setup' button on the BLE controller that was provided with the light:
I also tried to see what the code would be after a few clicks and also after reconnecting (2 times).
It seems like the only thing that is changing is the counter, as you already figured. I am not sure how to go on from here, it does not seem to match with the signal we are sending out if I read correctly above. I also noticed that you mention 0x28 is the command for pairing, however, it looks like 0x40 is used here. (@aronsky , any clue what the 40 does? It might also just be a verification which is send later). So here I also tried too just change the 0x28 definition by 0x40, however that also did not do the trick unfortunately. I am really not sure where to go from here actually. |
I also had the same issues as described above -- the commands would send to the esp32 (light flashes) but lamp does not respond, even after trying the various branches |
What do you mean the light flashes? The light on the ESP32, or the lamp you're trying to control flashes after using the ESP32 to pair? |
Sorry should have been clearer -- I meant the led on the esp32, not the lamp itself :-) |
In that case (especially since lampify works for you), it seems like the protocol emulated in this repo is not supported by your lamp. Does LampSmart Pro work for you? |
The phone will use a random MAC address for privacy. Use the nRF Connect
app (it is for Android, not sure if there’s an iOS version) to find the MAC
of the lights, then look for packets directed to it.
However, that probably won’t work, either. Most of Bluetooth traffic
(except the broadcasts, I think) uses channel hopping, so sniffing it
without specialized hardware is hard. You’ll be better off impersonating
the lights, and seeing the traffic reaching you from the app/remote that
way.
…On Tue, 21 Nov 2023 at 18:23 Georgerdx ***@***.***> wrote:
Hello All,
Interesting reading here.
i would be interested to know how are you guys able to sniff the remote
and the pairing command from the phone.
I’ve got wireshark & nrf52840 setup, but i can’t recognoze the phone or
the lamp remote in the traffic. I know the bluetooth mac address of my
phone but there are no packets visible unfortunately.
I am using iphone xr with the lampsmart pro app on it.
Thank you
—
Reply to this email directly, view it on GitHub
<#5 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABD52DBFUGSTZOI5W3WJAFLYFTIPTAVCNFSM6AAAAAAZJVUBEKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMRRGI2DMOBRGA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
@Georgerdx the easiest way I've found of reliably sniffing packets is to get a second ESP32 and install https://esphome.io/components/esp32_ble_tracker.html to scan for packets, although how useful that will be depends on the number of other chatty BLE devices in your vicinity. |
It is possible to capture packets using a Rasperry Pi. The command I use is |
The code in this repository didn't work for my lights either, but Lampify worked perfectly. I wanted to use an ESP however, so I ported the Lampify code over to ESPHome. https://github.com/StevenReitsma/esphome-lampsmart-pro It's basically a merge of the ESPHome component in this repository and the Lampify protocol. Hopefully it's of some use to others as well! |
Hey aronsky, thanks for all your work getting this far. I have a lamp that works wtih LampSmartPro, but sadly doesn't pair using this repo. I'm technical, and reasonably familiar with Wireshark, but not a dev by any stretch. 02.01.01.1b.03.77.f8.b6.5f.2b.5e.00.fc.31.51.cc.46.92.f4.2e.4a.eb.fc.00.59.f4.af.7c.75.ef.3f I wondered if anyone could help 'unwhiten' this so help me see if perhaps my light uses a different number for the pairing command. Here's the packet info:
Really appreciate any support. |
This is also working for at least one of my lights! |
Also worked for my light without any hassle, thanks/bedankt Steven! |
Glad that it worked for you, and it looks like it's working for additional people. If you feel like it, you're welcome to merge the code so that the two repos can be combined, and the end-user can choose the subtype of the lights (i.e., the protocol to use) in the configuration. |
I'm also trying to reverse-engineer RC protocol for these lamps. Unfortunately, now I have two different remotes at hands and zero lights (they are installed at friend's home, we will try to control them someday). Both remotes send TWO different advertisements each time. One adv comes with MAC 10:9E:3A:10:25:5D and second with MAC 59:BA:2B:D2:57:8D. Advertisements come really fast, interval is about 1-2ms. nRF Connect catches ~200 copies of each message, except for Setup, which does ~800 copies. This violates BLE specs, AFAIK, because proper advertisement interval cannot be less than ~20ms. Those two advertisements are very different. Type1 (10:9E:3A:10:25:5D) is almost the same as used in this repo (with several slight differences), and Type2 (59:BA:2B:D2:57:8D) is similar to lampify protocol, but with important differences in layout and CRC calculation. I'm not sure which of advs (or both) is needed for our lights. They carry almost the same information. Also, I'm unsure if emulator should fake those MACs to gain control. 10:9E: looks like regular random address and can be sent from ESP32, but 59:BA: is RPA address and ESP32 is, AFAIK, unable to fake it. 0x56 from the discussion above is somewhat like variant number. One remote with white lights has 0x56, and second one for RGB light has 0x57. This number appear in different places: at the beginning of Type1 packet, in header of Type2 packet (you may see it as manufacturer data with id 0x5556 or 0x5557), and in Setup request of Type2. Also, ble_whiten from this repo is not proper BLE whitening, it is some kind of encryption for Type1. Whereas the lampify tool use proper BLE whitening for channel 37. In fact, it looks that this part of message is transmitted over the air unwhitened, which is somewhat strange and may be legacy of some non-bluetooth radio receivers. |
Unfortunately, this packet is using some different format. The app is sending three (as far as I can see from BT logs) different setup commands. Only one of them follow known protocol. 0201021b03f0083080b864e1279cfb26d76544a49f67f6b67f0e8b532ba064 - this one can be deciphered. |
Thanks for taking a look - Just to be clear the one I posted starts 020101, not 020102 0201011b03f0083080b86ee127dbfc4be76544a49f67f6b65db88b532bddbe 0201011b03f9084913f069254e3151baae6402d8c1bacc71528e551259a64c 0201011b03f0083080b86fe127dbfc4be76544a49f67f6b6d6a88b532b4ab5 |
@oxcid3 Implemented is v2, and I'd like to find out where v1 was used. Presumably, it is the thing which lampify does. It is unclear which one is needed for your lamps. Update: v3 algorithm is almost the same as v2, but it implements additional AES message signature. It is these random-looking 2 bytes near the end of the packet: It is easy to replicate. |
I'd like to come with PR to add v3 to this code, but I'm afraid it won't be soon. So, here is a snippet from my python code which calculates and checks the signature.
Also, I would confirm that the app (LampSmart Pro 1.2.9) supports three different messages to lamps. Two of them are probably encoded in flutter libapp.so. They are most likely "v1". |
Someone may try this: In this branch, I've implemented two lampify-like versions of control protocol, but I am unable to test it on real lamps. See sample config. Still, there are many more variants. |
Nice. That's a much better approach than mine - I was just creating multiple components in one repo. I'll give it a test tomorrow. Maybe I'll finally get some response out of this ceiling light |
|
@Di1Ly, As for the error, "error putting command to queue" means that there are too many commands had been submitted, and waiting for a chance to be sent. For now, the queue is static and limited to 10. I see multiple write_state calls with the same (low) brightness in the same second. |
@flicker581 fogot about pair... I have try to pair now but no results. No blinking by lamp after pair was started. I have power off lamp by switch every time before pair. her is the log: |
@Di1Ly please update from my repository and try 1b one more time. There was an mistake. |
@flicker581 Thank you for rapid reply. I have changed ESP32 board from ESP32-CAM to ESP32 NodeMCU and now I can succefuly pair and control lamp by V1a. It is works! I will try updated repo now and will give feedback. |
To everyone who's been involved so far. Can confirm that my light now works with @flicker581 's V1b variant. For those still struggling, ensure to review the example code as I wasn't setting the 'Variant' attribute and that's what allowed mine to work. https://github.com/flicker581/esphome-lampsmart/blob/main/example_lampsmart_pro_light.yaml This is game changing. Thanks so much again. |
I can confirm @oxcid3 last post! V1b variant works really great on my Lamp too!! Unbelievable work!!! @flicker581 |
Thanks for everyone's work on the issue. Please note that I pushed a refactored the structure of the repo. I left the I believe that with this new structure, it should be easier to extend the code to support different kinds of messages. It's still not perfectly generalized, but please see the way the new ZhiJia light is implemented - the code in I should probably write a better guide for contributing, but not sure I'll find the time - for now, feel free to open PRs and we'll discuss changes as we go. |
After reading through this decoding the ble code was something that needed to happen when I was decoding the fan data I had on a similar app, so I wrote a page to do this work for you |
I was able to use the nRF Connect app on my phone to intercept the signal from the tablet on which the LampSmart Pro was installed. I was able to clone the on and off signals, now I can turn the lamp on and off via the phone's nRF Connect. |
@maxotkin , you can checkout this fork.
From your previously logged messages I would say the following would do the job without pairing if you have not changed anything: ble_adv_controller:
- id: my_controller_id
encoding: lampsmart_pro
variant: v3
forced_id: 0xB4555A3F
light:
- platform: ble_adv_controller
ble_adv_controller_id: my_controller_id
name: My Light If you want to test I am available for support! |
@NicoIIT You are a genius! Thanks! It's working! The lamp turns on and off! It changes brightness and color! That's just the colors white and yellow have changed places |
@NicoIIT , I have already managed to find and deal with this problem! Thank you so much again! |
I'm not having any success pairing any of the three lights I've got here.
I've set up a second ESP32 as a sniffer to help me debug what's going on.
ESP32 controller sends:
Whereas hitting “pair” in the Android app sends (example):
The first 5 digits always appear to be
02.01.01.1B.03
, but just swapping those in theprefix
doesn't work either.I'm working on the assumption that the command needed is very slightly different for my brand of light, but altering these bits manually is then throwing off some sort of checksum value?
I'm not familiar enough with C to fully understand what manipulation takes place for the rest of the values. I expect if I replayed a working command it'd work as expected, but can't see how to build the right packet
The text was updated successfully, but these errors were encountered: