I wonder if it would be possible to figure out which pins are connected to what on the device's board and just flash the thing completely with ESPHome and write a custom yaml config for it, rather than adapting the existing vendor firmware.
I have just finished doing this and writing replacement firmware for the Aqara E1 series of Zigbee switches, after getting fed up with them not supporting basic Zigbee binding functionality.
I've done exactly this on my own air filter, and it's about 200 lines of config. The hardest part is mapping binary outputs to a percentage:
switch:
- platform: gpio
pin: GPIO21
id: fan_low
interlock_wait_time: 250ms
interlock: &interlock_group [fan_low, fan_mid, fan_high, fan_turbo]
- platform: gpio
pin: GPIO25
id: fan_mid
interlock_wait_time: 250ms
interlock: *interlock_group
- platform: gpio
pin: GPIO22
id: fan_high
interlock_wait_time: 250ms
interlock: *interlock_group
- platform: gpio
pin: GPIO17
id: fan_turbo
interlock_wait_time: 250ms
interlock: *interlock_group
output:
- platform: template
id: fan_speed_output
type: float
write_action:
- lambda: |-
id(fan_low).turn_off();
id(fan_mid).turn_off();
id(fan_high).turn_off();
id(fan_turbo).turn_off();
auto light = ((AddressableLight*)id(status_light).get_output());
for (int i = 6; i <= 9; i++) {
light->get(i).set(Color::BLACK);
}
if (state < 0.24) {
} else if (state < 0.26) {
id(fan_low).turn_on();
light->get(6).set(Color(255,0,0,0));
} else if (state < 0.51) {
id(fan_mid).turn_on();
light->get(7).set(Color(255,0,0,0));
} else if (state < 0.76) {
id(fan_high).turn_on();
light->get(8).set(Color(255,0,0,0));
} else {
id(fan_turbo).turn_on();
light->get(9).set(Color(255,0,0,0));
}
light->schedule_show();
fan:
- platform: speed
name: "Filter Speed"
output: fan_speed_output
speed_count: 4
id: my_fan