Okay, as promised, it's time to live-tweet as I "quickly" reverse the RF protocols associated with this wonderfully-named JOOFOO floor lamp:
https://www.amazon.com/JOOFO-Torchiere-Temperatures-Lamps-Tall-Standing/dp/B082HL775Z
The lamp's pretty bright; but it's defining features are accessed via a small remote control.
https://www.amazon.com/JOOFO-Torchiere-Temperatures-Lamps-Tall-Standing/dp/B082HL775Z
The lamp's pretty bright; but it's defining features are accessed via a small remote control.
The remote allows one to adjust the lamp’s brightness and color temperature— and despite having no FCC identifying label, seems to communicate over RF.
At a glance we can guess this slightly dopey looking remote uses a simple modulation in one of the ISM bands.
At a glance we can guess this slightly dopey looking remote uses a simple modulation in one of the ISM bands.
When looking at a device like this, my instinct tends to be to check ~433.92MHz first; lots of these kinds of devices broadcast over little pulse-width modulations up there.
Sure enough, monitoring around 433MHz using gr-fosphor quickly shows us a signal on button presses:
Sure enough, monitoring around 433MHz using gr-fosphor quickly shows us a signal on button presses:
I like to grab signals quickly osmocom-fft; and then explore them using @assortedhackery's Inspectrum.
A quick bit of fiddling, and we can easily see the little train of pulses our remote emits as we press the "brightness up" button:
A quick bit of fiddling, and we can easily see the little train of pulses our remote emits as we press the "brightness up" button:
This is a very simple type of encoding: a single bit is sent at regular intervals by generating an RF pulse. The value of the bit to be sent is encoded into the _length_ of that pulse.
If we mark each bit period, we can easily see our "long pulse" and "short pulse" periods.
If we mark each bit period, we can easily see our "long pulse" and "short pulse" periods.
At this point, we could very easily start comparing this signal with other similar protocols--there are lots of devices that use very similar encodings up at 433MHz!
To make a better post, I'm going to ignore all of them, and reverse this simple protocol from "first principles".
To make a better post, I'm going to ignore all of them, and reverse this simple protocol from "first principles".
Inspectrum gives us an awesome ability to easily extract the signal's vitals by tweaking cursors; which gives us an easy approximate measurement of our per-bit timing.
We'll put these values aside for later reference, and use them in a bit!
We'll put these values aside for later reference, and use them in a bit!
Holding the "brightness up" button for a bit gives us one more important piece of information: this protocol is super simple: it sends the same data repeatedly while the button is held.
This makes RE'ing easy; we'll only need to interpret a short burst for each of the buttons.
This makes RE'ing easy; we'll only need to interpret a short burst for each of the buttons.
To make this data a bit easier to describe, let's assign bit values to the "short" and "long" pulses.
We'll call the short values '0', and the long values '1', which makes this pattern:
BRIGHTNESS UP: 0100_1000_0110_0101_0110_1000_0
We'll call the short values '0', and the long values '1', which makes this pattern:
BRIGHTNESS UP: 0100_1000_0110_0101_0110_1000_0
We'll do the same thing for each of our other buttons.
Fortunately, there are only four buttons total, so we can do this pretty quickly!
P: 0100_1000_0110_0101_0110_0001_0
C: 0100_1000_0110_0101_0110_0010_0
+: 0100_1000_0110_0101_0110_0100_0
-: 0100_1000_0110_0101_0110_1000_0
Fortunately, there are only four buttons total, so we can do this pretty quickly!
P: 0100_1000_0110_0101_0110_0001_0
C: 0100_1000_0110_0101_0110_0010_0
+: 0100_1000_0110_0101_0110_0100_0
-: 0100_1000_0110_0101_0110_1000_0
[An astute reader will notice a slight change in the code here from what I reported earlier. This is because of human error: I misinterpreted the pictures on my remote, and thought 'brightness up' was 'brightness down'.
This doesn't change much, so we'll roll with it.]
This doesn't change much, so we'll roll with it.]
Looking at each of the four codes, you'll notice that only four of the bits really seem to encode which button is being pressed.
So, why are the remainder there? I'm going to assume for two reasons:
1) to help both sides sync up (a "sync word"); &
2) to carry a unique remote ID
So, why are the remainder there? I'm going to assume for two reasons:
1) to help both sides sync up (a "sync word"); &
2) to carry a unique remote ID
There's a very real chance that someone might buy multiple of these lamps; and it'd probably suck if every lamp responded to every remote.
As fun as it might be to have control over your neighbors' lights, I imagine the fun would dim when you realize they have the same power
.
As fun as it might be to have control over your neighbors' lights, I imagine the fun would dim when you realize they have the same power

This raises one last little question: if they're using one bit for each button, what happens if you jam your fingers down on multiple buttons at once?
You guessed it: multi-track drifting!
brightness up -and- down:
0100_1000_0110_0101_0110_1100_0
You guessed it: multi-track drifting!
brightness up -and- down:
0100_1000_0110_0101_0110_1100_0
I'm going to end -this- thread here; and start another one in a bit in which we'll implement our own simple transmitter capable of controlling these lamps. :)
(I'll follow up with a lab notebook post shortly; and it'll have full alt-text for accessibility. Apologies for forgetting on twitter.
)
