I recently took ownership of a Meaco 1056AC desk fan and it seems to be missing the remote. This remote (if I had it) talks IR, like a TV remote, and I just happened to have a 940nm IR LED.
Starting with the hardware: I used a half breadboard, an ESP32-S3 baguette, a single jumper wire, a 220 Ohm resistor and the 940nm IR LED.

The LED has a forward voltage (the voltage across the LED when it is on) of ≈1.2 V. With no resistor the LED would have the full 3.3 V across it pulling too much current through the GPIO4 pin, potentially damaging it.
We are estimating that the pin resistance across the board is ≈40 ohms.
If we add a 220 ohm resistor we can set the current in the loop to safer levels, therefore sparing the GPIO4 pin from harm.

You might be thinking that a breadboard sat right next to the fan receiver doesn't look very remote... well you would be right. This is because it has to sit on the IR window. And it doesn't need to move (unless the fan moves) as we can connect to the ESP32 on its own network, allowing us to control it from a phone or laptop as long as we are connected.
To get connected we need to be able to talk to the ESP32. We create a hotspot for the ESP32 so that we can connect to it.
WiFi.mode(WIFI_AP);
WiFi.softAP("Meaco-Fan", "meacofan1");
server.begin();
If we join the Meaco-Fan hotspot and open a browser window on a phone or laptop and type http://192.168.4.1/ we can send requests to the board.

Next up, how the buttons become numbers:
void handle(const char* name, uint8_t cmd) {
pendingCmd = cmd;
server.send(200, "text/plain", name);
}
server.on("/power", [] { handle("power", 0x92); });
The page hits /power; this just queues 0x92, the reply is made first, then the IR is sent a moment later, ensuring the Wi-Fi does not stall.
And here is how that number becomes IR:
void loop() {
server.handleClient();
if (pendingCmd >= 0) {
uint8_t cmd = pendingCmd;
pendingCmd = -1;
sendNec(0x80, cmd);
}
}
0x80 is the fan, cmd is the button (if you follow the previous example, power). Then sendNec wiggles GPIO4 in the NEC pattern.
Power on the fan is a toggle, so the sketch sends that code once. If we send it twice then we turn the fan on and straight back off.
The rest of the firmware is just timing for this pattern. The full sketch is on GitHub.