Pesetech Artificial Skylight: my first attempt at creating an integration

Hi everyone,
I recently came across the following device: https://www.artificialsky.tech/. I don’t need to mention that I bought it straight away because: i) my bathroom lacks a window (therefore natural light); ii) in the office of the company I used to work for they did have several original Coelux products and the result stunned me.

What is it
It is a smart light that simulates incredibly well a window in your ceiling. It is “inspired” (aka: copied) from the famous Italian Coelux that retails in the order of magnitude of 10k€.
It is made in China and the quality is extremely good. The effect is incredible: it really looks like you have a window in your ceiling; the pictures on the website don’t lie! It retails for a fraction of the price of Coelux and on top of that it has WiFi and Bluetooth mesh network.

What I want to achieve
t is very “simple”: I want to integrate it in Home Assistant. Through this post I will keep you updated on my progress in trying to reverse engineer it and integrate it in Home Assistant.

My understanding of how it works
It is comprised of three devices:

  • the Skylight: the light itself that is WiFi and Bluetooth (mesh network) enabled, and that can be controlled from your smartphone via Bluetooth;
  • the Smart Pad: (or whatever it is called) a small wall-mounted display (I think is around 4") through which you can control the Skylight itself (and all its settings, hour of the day simulation, change of color, change of temperature) and control two loads that can be connected directly to the Smart Pad;
  • your smartphone: iOS or Android, through which you can control the Skylight, the Smart Pad and enable the communication between the two devices.

The configuration process is as follows

  1. Connect the Skylight to your smartphone by pairing it via bluetooth;
  2. Configure the wifi on the Skylight through your smartphone;
  3. Connect the Smart Pad to your smartphone through bluetooth;
  4. Configure the wifi on the Smart Pad (directly on the screen).

What are wifi and bluetooth used for:
So far to my understanding, all the communication between the three devices is performed through the bluetooth mesh network, with the smartphone being the central node which connects the devices among themselves.
WiFi I believe so far that it is used only for setting the time on the devices and downloading firmware updates.

What I have done so far
I am currently at step number 1: reverse engineering the communication protocol of the Smart Pad and the Skylight.

Analysis of communication over WiFi:
I have analyzed the packets exchanged from the SmartPad from the Skylight using Wireshark. My conclusions are the following:

  • Smartpad
    • There is no data exchanged over WiFi between the Skylight and the Smart Pad
    • I could not sniff anything coming from or going to the Smart Pad, not even when forcing a firmware upgrade
  • Skylight
    • There might be data exchanged between the smartphone and the Skylight but I’m not sure
    • When I turn on/off the Skylight or I change the settings of the Skylight (e.g., change brightness) from my smartphone there are packets sent from the Skylight (to god knows where)
    • Here is an example of the packets transmitted from the Skylight when I turn it on and off:
No.     Time           Source                Destination           Protocol Length Info
    645 56.726440129   192.168.1.160         255.255.255.255       UDP      61     9988 → 8899 Len=19

Frame 645: 61 bytes on wire (488 bits), 61 bytes captured (488 bits) on interface wlp0s20f3, id 0
Ethernet II, Src: BeijingW_80:4f:21 (28:6d:cd:80:4f:21), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
Internet Protocol Version 4, Src: 192.168.1.160, Dst: 255.255.255.255
User Datagram Protocol, Src Port: 9988, Dst Port: 8899
Data (19 bytes)

0000  aa 55 00 64 b0 53 17 00 00 00 0e 00 03 03 01 01   .U.d.S..........
0010  01 ba 6e                                          ..n
    Data: aa550064b053170000000e000303010101ba6e
    [Length: 19]

No.     Time           Source                Destination           Protocol Length Info
    661 58.254181153   192.168.1.160         255.255.255.255       UDP      68     9988 → 8899 Len=26

Frame 661: 68 bytes on wire (544 bits), 68 bytes captured (544 bits) on interface wlp0s20f3, id 0
Ethernet II, Src: BeijingW_80:4f:21 (28:6d:cd:80:4f:21), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
Internet Protocol Version 4, Src: 192.168.1.160, Dst: 255.255.255.255
User Datagram Protocol, Src Port: 9988, Dst Port: 8899
Data (26 bytes)

0000  aa 55 00 64 b0 53 17 00 00 00 0e 00 03 0a 66 08   .U.d.S........f.
0010  01 01 ff ff 00 00 00 00 f5 36                     .........6
    Data: aa550064b053170000000e00030a66080101ffff00000000f536
    [Length: 26]

No.     Time           Source                Destination           Protocol Length Info
    675 58.959788972   192.168.1.160         255.255.255.255       UDP      61     9988 → 8899 Len=19

Frame 675: 61 bytes on wire (488 bits), 61 bytes captured (488 bits) on interface wlp0s20f3, id 0
Ethernet II, Src: BeijingW_80:4f:21 (28:6d:cd:80:4f:21), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
Internet Protocol Version 4, Src: 192.168.1.160, Dst: 255.255.255.255
User Datagram Protocol, Src Port: 9988, Dst Port: 8899
Data (19 bytes)

0000  aa 55 00 64 b0 53 17 00 00 00 0e 00 03 03 01 01   .U.d.S..........
0010  00 7b ae                                          .{.
    Data: aa550064b053170000000e0003030101007bae
    [Length: 19]

No.     Time           Source                Destination           Protocol Length Info
    718 63.894744981   192.168.1.160         255.255.255.255       UDP      61     9988 → 8899 Len=19

Frame 718: 61 bytes on wire (488 bits), 61 bytes captured (488 bits) on interface wlp0s20f3, id 0
Ethernet II, Src: BeijingW_80:4f:21 (28:6d:cd:80:4f:21), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
Internet Protocol Version 4, Src: 192.168.1.160, Dst: 255.255.255.255
User Datagram Protocol, Src Port: 9988, Dst Port: 8899
Data (19 bytes)

0000  aa 55 00 64 b0 53 17 00 00 00 0e 00 03 03 01 01   .U.d.S..........
0010  00 7b ae                                          .{.
    Data: aa550064b053170000000e0003030101007bae
    [Length: 19]

No.     Time           Source                Destination           Protocol Length Info
    733 65.534560776   192.168.1.160         255.255.255.255       UDP      61     9988 → 8899 Len=19

Frame 733: 61 bytes on wire (488 bits), 61 bytes captured (488 bits) on interface wlp0s20f3, id 0
Ethernet II, Src: BeijingW_80:4f:21 (28:6d:cd:80:4f:21), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
Internet Protocol Version 4, Src: 192.168.1.160, Dst: 255.255.255.255
User Datagram Protocol, Src Port: 9988, Dst Port: 8899
Data (19 bytes)

0000  aa 55 00 64 b0 53 17 00 00 00 0e 00 03 03 01 01   .U.d.S..........
0010  01 ba 6e                                          ..n
    Data: aa550064b053170000000e000303010101ba6e
    [Length: 19]
    • Here is a brief interpretation of the packets (initial hypothesis):
    Turning the light off: aa550064b053170000000e0003030101007bae
        "aa55": Possible start of the packet or a header identifier.
        "0064": Packet length, indicating a 100-byte packet.
        "b053": Identifier or protocol-specific information related to the smart light.
        "17000000": unclear
        "0e": Unclear 
        "000303010100": This portion likely contains control data specific to the smart light. The sequence "0100" might indicate a command to turn the light off.
        "7bae": Checksum or cryptographic value for error detection or verification.

    Turning the light on: aa550064b053170000000e000303010101ba6e
        "aa55": Possible start of the packet or a header identifier.
        "0064": Packet length, indicating a 100-byte packet.
        "b053": Identifier or protocol-specific information related to the smart light.
        "17000000": unclear
        "0e": Unclear
        "000303010101": This portion likely contains control data specific to the smart light. The sequence "0101" might indicate a command to turn the light on.
        "ba6e": Checksum or cryptographic value for error detection or verification.
  • This is all I got so far concerning the WiFi packets analysis. I don’t know where to go from here.

Analysis of communication over Bluetooth:
I have performed this analysis on the Smart Pad only because if I am able to control the Smart Pad, I am able to control the Skylight.

  • I wasn’t able to sniff bluetooth packets with my computer using Wireshark, although it is possible (but I don’t know how, if you could give me some directions it would be great).
  • Using bluetoothctl, btmgmt and gatttool, I was able to figure out the following handles:
[A4:C1:38:7C:BC:49][LE]> char-desc
handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb
handle: 0x0008, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0009, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000a, uuid: 00002a50-0000-1000-8000-00805f9b34fb
handle: 0x000b, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000c, uuid: 00002a26-0000-1000-8000-00805f9b34fb
handle: 0x000d, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x000e, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000f, uuid: 00010203-0405-0607-0809-0a0b0c0d2b12
handle: 0x0010, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0011, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0012, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0013, uuid: 00002adc-0000-1000-8000-00805f9b34fb
handle: 0x0014, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0015, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0016, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0017, uuid: 00002adb-0000-1000-8000-00805f9b34fb
handle: 0x0018, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0019, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x001a, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x001b, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x001c, uuid: 00002ade-0000-1000-8000-00805f9b34fb
handle: 0x001d, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x001e, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x001f, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0020, uuid: 00002add-0000-1000-8000-00805f9b34fb
handle: 0x0021, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0022, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0023, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0024, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0025, uuid: 00010203-0405-0607-0809-0a0b0c0d7fdf
handle: 0x0026, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x0027, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0028, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0029, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x002a, uuid: 00002901-0000-1000-8000-00805f9b34fb
handle: 0x002b, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x002c, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x002d, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x002e, uuid: 00010203-0405-0607-0809-0a0b0c0d1a11
handle: 0x002f, uuid: 00002901-0000-1000-8000-00805f9b34fb
  • And the following services:
[A4:C1:38:7C:BC:49][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0008, end grp handle: 0x000c uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle: 0x000d, end grp handle: 0x0010 uuid: 00010203-0405-0607-0809-0a0b0c0d1912
attr handle: 0x0011, end grp handle: 0x0019 uuid: 00001827-0000-1000-8000-00805f9b34fb
attr handle: 0x001a, end grp handle: 0x0022 uuid: 00007fdd-0000-1000-8000-00805f9b34fb
attr handle: 0x0023, end grp handle: 0x0026 uuid: 00010203-0405-0607-0809-0a0b0c0d7fde
attr handle: 0x0027, end grp handle: 0x002b uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x002c, end grp handle: 0x002f uuid: 00010203-0405-0607-0809-0a0b0c0d1a10

And I managed to figure out the following information about said handles (by interrogating the Smart Pad over bluetooth and interpreting in ASCII the answers I got):

This is all I got so far, I really don’t know where to go from here, I would really appreciate help from anyone! Any hint or direction I could take will be very much appreciated!

PS: In a moment of desperation, I reached out to the company asking if I could talk to the engineers. Obviously it won’t work, but it was worth giving it a try.

1 Like

Personally, I “reverse engineered” a BT controlled lamp by decompiling the APK of the Android APP.
Luckily, the code was not obfuscated and was thus readable.

That being said, I suspect BT is only used to configure the Wifi on the Skylight, then all commands go through a private cloud of theirs, which is how it usually works.

If so, the communication is surely encrypted, thus sniffing will lead to nothing.

Thank you for the input! I don’t own an android device so I don’t know how to download the .apk file. Unfortunately, it is not available on other repositories of .apk files such as apkmirror.com.
Do you think you could download the .apk file and send it to me? The app is called pesetech.

1 Like

Hi, Im wondering if anyone has had anymore luck with this? I love the skylight but controlling it with google integration is sketchy at best. There must be some way to get a local key for it. I have the bluetooth touch dimmer by the way. I was thinking maybe there would be a way to connect it using an ESP bluetooth scanner but I’m new to this

Hi there,
I have some updates. tl;dr no success yet.
I tried the following:

  1. Impersonate their MQTT server: basically I have sniffed the MQTT traffic between the skylight and their MQTT server. I then took note of the login and the MQTT topic and message. I created a MQTT server that accepts any password given a specific username (I coded a MQTT plugin using C). Outcome: negative. Unfortunately they have implemented a unique md5 hash inside the MQTT message that is used by the client to make sure the MQTT message was really sent by the server. Further details here: networking - Reverse engineering MQTT payload in a (apparently) sophisticated smart lamp - Reverse Engineering Stack Exchange

  2. Sniff BLE traffic: this is extremely complicated and it required specific hardware (nrf Bluetooth sniffer). It is very complicated because the only way to “hack” into the communication protocol is to impersonate a skylight, join the BLE mesh network created by your smartphone and sniff the BLE mesh network keys. This goes a bit beyond my capabilities, so I’m kind of stuck.

  3. Upgrade the firmware of the smart pad (yes I bought one) and sniff the binary image. I did succeed into doing this, but I have no idea how to reverse engineer the binary image of the firmware of the smartpad. I did try some basic tools but I did not obtain anything. I am happy to share the two files o have sniffed through the firmware upgrade.

  4. Decompile the android app. I did that, but honestly I have no clue how to proceed. There are thousands of files and I don’t know what to look for.

I doubt there are any other approaches, I believe the most viable one is number 2, but honestly I could not find much documentation on BLE mesh networks hacking. The software implementation of the skylight, despite the appearances, is really well done and very safe.

Hmm Good to know. Thanks so much. I sent them an email as well. I’ve found their customer service to be very useful so maybe they will have some information on how an integration might work or what their stance on matter might be.

I also contacted their support to ask if they could implement the possibility to set your own mqtt server, the development effort is 0 for them. I didn’t get any response however, which is not very nice as I helped them identify 3 bugs on the skylight itself and on the smartpad.

Let me know if you get any feedback from them.

This was the response I got from them:

Generally, when skylight in the app is online, it will only use wifi to send commands, and when offline, it will use Bluetooth. Dimmer directly uses Bluetooth to send commands to skylight.

Our engineers said that ESP32 is another module and we are not using this one. And we don’t support Home Assistant at the moment.

Thanks for trying that out. As of now, the only viable path I can see is to control it through BLE:

  • Join the BLE Mesh network by creating a fake device (it must advertise the same services as the skylight in order to be identified as a pesetech component by the smartphone app, that is the provisioner)
  • Sniff traffic going from the smartphone to the skylight or from the smartpad to the skylight
  • Reproduce the traffic, hoping that there is no hash embedded like it happens in the MQTT messages
  • Write a home assistant component that can send the BLE messages to the Mesh network

I don’t really have the time to try that now, I would have to learn everything from scratch.

Shall anybody have experience in BLE Mesh networks and wants to give me some direction on how to start, let me know :slight_smile:

The workaround I have come up with is to install a shelly m1 mini gen 3 behind the switch and to put it in decoupled mode. the smart pad seems to still be able to control it in this situation and then i use the schedule within the pesetech app to tell the light what color/brightness to be on at different times of day. I also have a backup (every now and then the switch will turn on but the light stays off) set up using the google SDK integration (which is very slow, hence the backup) where i tell it to tell google to tell pesetech to turn on the skylight and to tell it what brightness and warmth setting to set it to. Definitely hacked together and no perfect, but at least runs better with the automations than running it only through google or their native app

Thanks for sharing!
Not an option for me unfortunately, it’s cloud based :frowning: