-
-
Notifications
You must be signed in to change notification settings - Fork 79
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
Question: Did you backwards engineer the UDP methods? #155
Comments
I was noticing that some of my bulbs became unresponsive after a software update. I wrote a library distantly based on this one, in C#, and I'm in the middle of updating the project, so I came here looking for some answers to interesting questions I had. This is definitely in the vicinity of the kind of questions I had been having. Actually, I've managed to solve a lot of those issues. I'm in the middle of working on a new version of my own library (it's C#, things can get hairy), and so, I've got some relatively recent familiar experience with all of this. Plus, my lib does have some features they haven't incorporated into pywizlight, but I've talked about it with them, like how the type of bulb is knowable (Lighting strip, A19, candelabra, flood light, etc.), but they don't want to program that information because they don't trust. However, in 3 years, I've found these specific markers to be reliable indicators of bulb type. Also, there are newer and older versions of the software, the reporting JSON is slightly different between the two. |
Hey, there can be an increasing variation in the bulb API (because Wiz is now part of Signify / Philips Hue). For having an overview of the API calls you can make and the returns, you can have a look into https://docs.pro.wizconnected.com/#introduction - this is the MQTT API which is partly also available via UDP. |
ESP24_SHRGBC_01 is reported as the moduleName if the module is an ESP32-C3-WIZ20212. The chip is an ESP32-C3FH4. |
With ESP24_SHRGBW_01 firmware version 1.28.0, the bulb is willing to connect via MQTT to a self-signed certificate. That means it can connect to another MQTT server, like mosquitto, with TLS enabled, or its conversation with its own servers can be intercepted and decrypted. Firmware updates might break this capability. I set up my router to give my PC as the DNS server and default gateway to the bulb via DHCP. Then I set up bind9 on my PC to resolve names to my PC's IP address. I set up mosquitto on my PC, generating a self-signed certificate. I also downloaded the latest mitmproxy to intercept communications between the bulb and the Wiz MQTT server. This all seemed excessively complicated and annoying, but eventually it worked. The bulb subscribes to a specific MQTT topic, with its unique identifiers. Then one can publish JSON to that topic to change its configuration. That JSON looks similar to what is sent via the UDP interface, but I guess some methods are only accepted via MQTT. I sent the exact same string via UDP and MQTT. It failed via UDP but worked via MQTT. Here is that example, changing the power on and off fade times. Note the
Edit: One can trigger an OTA firmware update attempt by publishing something like
I was also able to download http://firmware.wiz.world/firmwares/ESP24_SHRGBW_01/1.28.0/wizlight.bin , which is hopefully the firmware that is currently present in the bulb. Presumably the long hexadecimal string in the updateOta method is some kind of hash or something that is used to verify the download. Edit: These are standard ESP32 images and they may be examined via Edit: I changed the favourites by sending this via MQTT: The ESP32-C3 contains a RISC-V core, and the firmware can be disassembled via Ghidra. But the parser seems complicated, and use of favourites to change the turn on state was only a guess. Edit: Ghidra now works really well for this. I had two problems to fix. The file offsets printed by esptool are actually offsets of the header for that segment. The actual data for the segment starts 8 bytes after those offsets. Also, the ESP32-C3 chip is RISC-V RV32IMC. The parsing code is now fairly easy to understand. Edit: https://raw.githubusercontent.com/owntracks/tools/master/TLS/generate-CA.sh is a script to easily generate self signed certificates for mosquitto MQTT server. The favourites JSON arrays are sceneId, red, green, blue, warm white, cool white, colour temperature. For example: red PWM 255: All the get methods work via UDP, though
Few of the set methods seem available via UDP. Each method in an array in DROM consists of a pointer to a name string, a pointer to the function that handles it, and 4 bytes, with the first two used for flags. I think if the second flag byte is zero the method is unavailable via UDP. Via UDP you can use The most interesting one is |
The newest firmware for both the GU10's and G.E27's branded as Philips Wiz is 1.30.1 I've attempted to point them to my own mqtt broker without success, but that might've been me doing something wrong. The firmware dumps on device seem encrypted, but that doesn't necessarily mean that the OTA updates are as well. Did you check the OTA update wether or not it is encrypted? We might be able to trigger the update, pointing to a tasmota firmware image for example. |
Yes, their MQTT server was telling my bulb to download firmware 1.30.1. That is at http://firmware.wiz.world/firmwares/ESP24_SHRGBW_01/1.30.1/wizlight.bin and there is also http://firmware.wiz.world/firmwares/ESP24_SHRGBW_01/1.28.0/wizlight.bin . When the bulb makes the request, it appends its mac address and current firmware to it, like At sbidy/wiz_light#85 (comment) someone found that firmware 1.23 for their bulb stopped such insecure MQTT access. Maybe later firmware for my bulb would also, but I did not allow it to upgrade firmware. The OTA updates are certainly not encrypted, and can be easily disassembled via Ghidra. The file format is documented at https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/firmware-image-format.html . Note that the file consists of multiple segments that are loaded to different locations in memory. I used this simple Python script to transform the segment data output by esptool.py into dd commands for splitting the file:
Then I manually loaded the segments, using "Add to program" to load additional ones after the first one. I thought about loading Tasmota, but was still enjoying reverse exploring their firmware, and I don't want to brick the bulb because recovery may require physically breaking it to open it. Tasmota does support the ESP32-C3FH4 chip in the ESP32-C3-WIZ2012 module that is inside according to FCC ID info. The Tasmota release at https://ota.tasmota.com/tasmota32/tasmota32c3.bin is the same file format as the OTA file from Wiz. I don't know if the bulb makes some checks when installing firmware that would block Tasmota. The |
Meanwhile I've managed to get my Wiz devices to connect to my mosquitto instance. Steps to reproduce: The devices connect as I found out the first identifier is the homeId by publishing @dreamlayers thank you for bringing this back to my attention. I might seem like I'm repeating you, but just wanted to write down my findings for future reference. I have a spare GU10 with the encrypted firmware dumped. I will experiment with that one to see if I can trick it into installing tasmota. |
@s0ullight any luck flashing Tasmota? I'm not sure that would succeed even if the original firmware permitted it. The first installation of Tasmota involves flashing the bootloader and partition table. That is normally done by flashing the appropriate *.factory.bin via esptool over serial. If only the application partition is flashed, that might not work with the bootloader and partition table from original firmware. Edit: I was able to flash the 1.30.1 WiZ firmware for my bulb locally, using BIND 9, Mosquitto and |
I bought another bulb. This one came with firmware 1.22.59. The WiZ MQTT server wanted it to upgrade to 1.30.1, using the same BTW. The old style Android WiZ app couldn't talk to firmware 1.22.59 using Bluetooth, and had to use the manual configuration method, via the bulb's unsecured WiFi network. 1.22.59 also didn't have the white temperature discontinuity between 4200 K and 4201 K. It seems to still be available at http://firmware.wiz.world/firmwares/ESP24_SHRGBW_01/1.22.59/wizlight.bin |
If you did, how did you do it?
I'm asking because I'm working on a project for interfacing with WiZ Lights and basing most of my functionality on your documentation of the UDP methods.
While investigating I've found that some of the methods don't work with my bulbs (ESP24_SHRGBC_01) and some that you are missing.
For example,
{"method":"getDevInfo","params":{}}
returns:The first number in each array is the scene code for my selected favorite scenes, but I don't know about the rest.
Also I've been trying to change the fade time with
{"method":"setUserConfig","params":{"fadeIn": 0, "fadeOut": 0}}
but get back"error": {"code": -32600, "message": "Invalid Request"}
I would love to collaborate in expanding the documentation and knowledge about the inner functioning of the API , but I don't know how I could go about helping you.
The text was updated successfully, but these errors were encountered: