Mercator ceiling fan remote 433MHz protocol
RC switch type with timing:
Time per pulse: 320µs
Sync: [36, 1]
Zero: [1, 2]
One: [3, 1] # but when transmitting, [2, 1] works also.
Inverted: true # i.e. it goes low-high not high-low
TL;DR: How to send the codes using ESPHome remote_transmitter
...
# Example of using a physical button press to trigger sending the code -- you could use any other component that supports `on_xxx` events.
binary_sensor:
- platform: gpio
pin:
number: GPIO9
mode:
input: true
pullup: true
inverted: true
name: rfclick
internal: true
on_click:
then:
# Light toggle
- remote_transmitter.transmit_rc_switch_raw:
code: '010001111110'
protocol:
pulse_length: 320
sync: [36, 1]
zero: [1, 2]
one: [3, 1]
inverted: true
repeat:
times: 5
wait_time: 0ms
...
Packet Structure
| Sync 1b | Preamble 1b | Address 4b (Little Endian inverted) | Fan control 6b (inverted) | Light control 1b (inverted) |
|---|---|---|---|---|
(00...) 1 |
0 |
xxxx |
xxxxxx |
x |
Commands
| Command | Fan Control | Light Control |
|---|---|---|
| Toggle Light | 111111 |
0 |
| Fan Off | 111110 |
1 |
| Fan High | 101111 |
1 |
| Fan Medium | 110111 |
1 |
| Fan Low | 111011 |
1 |
Reverse engineering
The structure as described above uses a variable-length off-on pulse for zero and one. Because these are always divisible by the pulse length, they can be decoded 'raw' in URH by setting the samples per bit to align with the pulse length. This is the longer bitstring in the reverse engineering values below, of equal length pulses. I was sampling at 1.8 Msps, and meant that 516 samples (corresponding to one pulse) equals approximately 290 µs per pulse. There's some flexibility in the clocking; 320µs seems to be a fairly common number and works fine.
Looking at the sequence, it's clear that it always begins with a single 1 preceded by some number of 0s (trimmed), as a sync. This produces the semi-arbitrary [36, 1] sync type.
Then it's always a pattern of 011 and 0001. Clearly these are two symbols for encoding a real message 0 or 1. These each start with a low pulse, not a high pulse, so are inverted compared to the 'standard' RC behaviour. This corresponds to the the above RC type definition of { zero: [1,2], one: [3,1], inverted: true }.
Looking at the commands breakdown, it's could be phrased to say that 0 in a bit position means 'trigger', and 1 means 'ignore', basically.
So 0 in the light control bit always toggles the light value (after a short gap of no transmissions -- it doesn't toggle it for every single packet), or if it's 1, doesn't change the light.
There's no obvious way to set the light to a specific value.
Addressing with DIP switch
all 0s/unset
10110001000100010001000100010001000100010001011
s011111111110
bit 1 set
1011011000100010001000100010001000100010001011
s001111111110
bit 2 set
1011000101100010001000100010001000100010001011
s010111111110
bit 3 set
1011000100010110001000100010001000100010001011
s011011111110
bit 4 set
1011000100010001011000100010001000100010001011
s011101111110
all bits set
1011011011011011000100010001000100010001011
s000001111110
Commands
Light toggle
10110001011011011000100010001000100010001011
s010001111110
Fan off
10110001011011011000100010001000100010110001
s010001111101
Fan High
10110001011011011000101100010001000100010001
s010001011111
Fan Medium
10110001011011011000100010110001000100010001
s010001101111
Fan Low
10110001011011011000100010001011000100010001
s010001110111
Tools
Used GQRX to capture Raw IQ data from RTL-SDR And then URH (Universal Radio Hacker) to analyse the data.

Pls do not come to my house and turn my fan on randomly xoxo