Based on reverse engineering the wireless signal for one of these devices: iRIS Lighting Controller — Spa Electrics
The transmission parameters for mine are:
Frequency: 916.02
Modulation: FSK (with terrible filtering - there’s extreme wideband noise)
Frequency separation: 155KHz
Data rate: 9.6KHz
Preamble: 32 bits (0xaa, 0xaa, 0xaa, 0xaa)
The packet from my remote looks like this:
0x2d, 0xd4, 0x69, 0x88, 0x01, 0x27, 0x03, 0xe3
And seems to be split into (mostly guessing, I have only a single remote - would love to see more captures):
0x2d, 0xd4, 0x69, 0x88 - remote identifier
0x01 - unknown, but probably light number since you can drive 2
0x27 - colour (in this case white)
0x03 - unknown
0xe3 - checksum
The checksum is not CRC, but some simple arithmetic - I’d love to get more samples from other remotes to compare. It looks like it’s just 0x100-(sum(packet)%0x100)
… which is stupid for a checksum, but
The colours are:
0x27 - white
0x26 - aqua
0x21 - blue
0x22 - pink
0x23 - red
0x24 - yellow
0x25 - green
0x11 - off
0x31, 0x32, 0x33, 0x34 - presets 1-4
Using radiolib with ESP32 HAL and RF69 type radio, you can drive them like this:
script:
- id: setup_radiolib
then:
- lambda: |-
radio.reset();
int16_t state = radio.begin(
916.02,
9.6,
155.0,
RADIOLIB_RF69_DEFAULT_RXBW,
RADIOLIB_RF69_DEFAULT_POWER,
0);
state = radio.disableAES();
state = radio.packetMode();
state = radio.setOOK(false);
state = radio.setOutputPower(20, true);
state = radio.disableAddressFiltering();
state = radio.disableSyncWordFiltering();
state = radio.setCrcFiltering(0);
button:
- platform: template
name: Pool Light white
on_press:
- lambda: |-
uint8_t data[] = {
0xaa, 0xaa, 0xaa, 0xaa, 0x2d, 0xd4, 0x69, 0x88, 0x1, 0x27, 0x3, 0xe3,
};
radio.transmit(data, sizeof(data), 0);
radio.standby();
(I need a lot of power to reach the pool - please turn down your power if possible)