Faking an IR remote control using ESPHome

Yes, absolutely!

To call such a set_brightness function from HA and transfer the needed integer value for the target brightness you could use a user-defined service.

The ESPhome coding could use global variables to hold the current brightness level and the steps up or down need to reach a desired target level.

The loop to send the commands to brighten or dim the light would typically be implemented using an interval that regularly checks if there are up or down commands remaining to be sent.

Some of the coding will need lambdas with C++ code. But don’t be afraid of it. You’ll find many examples how to do that. I did all my lambdas without any prior knowledge of C++ with some Googling and experimenting.

1 Like

Thank you so much! I’ll look into it.

I actually already bumped into lambdas when implementing 433MHz control for my sockets. (ESPHome didn’t allow me to set sync values for custom protocol to more than 255 * pulse_length but my sockets actually require 590, so I had to basically rewrite my old arduino code in lambda to make it work.)

1 Like

I have changed Dump: to pioneer and get nothing. I then tried raw and all I get is raw data. Here is my yaml file

esphome:
  name: irtest
  friendly_name: irtest

esp8266:
  board: d1_mini

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password  

# Enable logging
logger:
  level: VERBOSE

# Enable Home Assistant API
api:
  
ota:

# Enable Web server.
web_server:
  port: 80

remote_receiver:
  pin:
    number: D5
    inverted: true
  dump: all

This is strange. Do you get a lot of “raw” lines, even if you are not sending? Is there any strong source of IR in the room, that might saturate your receiver (sun light, heating,…)? Is your sender too close to your receiver, so it saturates? Is there another IR emitter or IR remote in the room that you are not aware of? Have you tried to move your receiver away from your ESP to reduce WIFI crosstalk into the receiver circuit? Have you tried leaving the “web:” component out (not needed at that point)? Have you tried changing the room?
If none of these solves the puzzle I would tend to try and replace the components one by one. Another IR receiver, another ESP.

Thanks for all the suggestions.
I plugged my ir receiver into my D1-mini that I use to turn my LG tv on and off. This the one that I set up several months ago.
It was exactly the same giving me only pronto codes. Strange, cause it definetly worked before.
I then decided to replace the three Dupont wires to the receiver and would you believe it, it now works.

However, moving it back my iMac, I now get pronto codes received about every three seconds and you can see the led flashing. Even if I cover the receiver it still does it. Weird.

I’ve now set Dump: to pioneer so can capture all the codes I need.

1 Like

I did it! I made a slider to change brightness that simulates repeated button presses.
And I didn’t even need half of the things you mentioned because I discovered Number component, so I made the thing using that, a global variable and a lambda:

globals:
  - id: brightness_prev
    type: int
    restore_value: no
    initial_value: '-1'

remote_transmitter: 
  - id: infra
    pin: GPIO04
    carrier_duty_percent: 50%

button:
  - platform: template
    name: "ir5"
    id: bright_up
    on_press:
      - remote_transmitter.transmit_nec:
          address: 0xFF00
          command: 0xFA05
          command_repeats: 2
          transmitter_id: infra
  - platform: template
    name: "ir4"
    id: bright_down
    on_press:
      - remote_transmitter.transmit_nec:
          address: 0xFF00
          command: 0xFB04
          command_repeats: 2
          transmitter_id: infra

number:
  - platform: template
    name: brightness
    id: brightness_slider
    min_value: 0
    max_value: 9
    initial_value: 0
    step: 1
    optimistic: true
    on_value:
      then:
        - lambda: |-
            int steps = 0;
            //Just booted up? Get the LED strip to known value (0), otherwise get the difference
            if (id(brightness_prev) == -1)
                steps = -9;
            else
                steps = x - id(brightness_prev);
                
            //No difference? Don't do anything.
            if (steps==0)
                return;
            
            //Should we go up or down?
            auto button = steps>0 ? bright_up : bright_down;            
            //How many steps?
            steps = abs(steps);
            
            //Press the button repeatedly
            for (int i=0;i<steps;i++)
            {
                button->press();
                delay(50);
            }
            ESP_LOGI("main", "Brigthness: %d -> %d", id(brightness_prev), id(brightness_slider).state);
            //Save current value for future change
            id(brightness_prev) = x;

The on_value action triggers when device boots up, so it sets the LED strip to minimum brightness and then I can change it however I want.
The strip has few more quirks that I have to account for, but that’ll probable be no problem.

Just one more thing. Is possible to change the value of a component (be it toggling a switch, or changing a number from one value to a different one in this case) without triggering its action?
In a specific circumstances, my LED strip can get reset and it changes its brightness to “9” but its needless to set the value in ESPHome the normal way and then wait until it cycles through 9 command repeats before I can actually lower it to a normal level.

1 Like

This is nice. Congratulations!

But are you sure that your code works as intended if you quickly change the brightness several times, i.e. 0, 9, 0, 9?
I think if you change again while your last change is still being processed your code might fail.

This is exactly the reason why I proposed to use an independent interval loop. This would decouple the counting and sending from any change of the target brightness and it would always work correctly. Your number component would simply store a target value. The interval would compare the target with the current value and would bright_up or bright_down only one step per interval if they differ (and increment/decrement the current value).

Correcting the number without action would be possible too: Simply change the target and the current value at the same time.

I’m trying to get a fireplace/heater set up, I’ve received the following from the included remote:

[I][remote.pronto:233]: Received Pronto: data=
[I][remote.pronto:235]: 0000 006D 0060 0000 0030 0011 0030 0011 0010 0032 002F 0011 0030 0011 000F 0032 000F 0032 000F 0032 000F 0032 000F 0032 000F 0032 002F 0113 0030 0011 0030 0011 000F 0032 002F 0011 0030 0011 0010 0032 000F 0032 000F 0032 000F 0032 
[I][remote.pronto:235]: 000F 0032 000F 0032 002F 0113 0030 0011 0030 0011 000F 0031 0030 0011 0030 0011 000F 0031 000F 0031 000F 0031 000F 0031 000F 0031 0010 0031 0030 0114 002F 0011 0030 0011 000F 0031 0030 0011 0030 0011 000F 0031 000F 0031 000F 0031 
[I][remote.pronto:235]: 000F 0031 000F 0031 000F 0031 0030 0113 0030 0011 0030 0011 000F 0031 0030 0011 0030 0011 000F 0031 000F 0031 000F 0032 000E 0032 000E 0032 000E 0032 002F 0114 002F 0011 002F 0012 000E 0032 002F 0012 002F 0012 000E 0032 000E 0032 
[I][remote.pronto:235]: 000E 0033 000E 0033 000E 0034 000D 0033 002E 0116 002D 0012 002E 0012 000E 0034 002D 0012 002E 0012 000E 0034 000D 0034 000D 0034 000D 0034 000D 0034 000D 0034 002D 0116 002D 0013 002D 0013 000D 0034 002C 0014 002C 0014 000C 0036 
[I][remote.pronto:235]: 000B 0035 000B 0036 000B 0035 000B 0036 000B 0036 002B 0181 06C3
[V][remote.drayton:176]: Decode Drayton: Fail 1, - 0
[I][remote.rc_switch:261]: Received RCSwitch Raw: protocol=1 data='11011000000'

I tried using the RCSwitch Raw with the following:

remote_transmitter:
  pin: GPIO13
  carrier_duty_percent: 50%

button:
  - platform: template
    name: "Toggle_Fireplace"
    on_press:
      - remote_transmitter.transmit_rc_switch_raw:
          code: '11011000000'
          protocol: 1

However I’ve had no luck. I even tried capturing the raw data and using that, but no luck there either. I also tried using JUST the pronto codes, nothing there either (although its possible I didn’t have the codes set up correctly. I wasn’t 100% how to send the multiple lines of codes) I am using this set of transmitter & receiver: (https://www.amazon.com/dp/B08X2MFS6S?psc=1&ref=ppx_yo2ov_dt_b_product_details)

I know I have it wired correctly, as I can see the red light on the transmitter board flash when I attempt to send a signal. I couldn’t find any codes online for my fireplace unit, however, I do know that my fireplace remote also turns on/off my Lasko fan. I tried any Lasko codes I could find online, no luck there either. Any help is greatly appreciated!

Hi,

I’m probably doing something wrong but i cant figure out what!

I have a Freenove ESP32 Wroom board.
I can receive ir codes from my air heat pumps remote in the following formats to my board without any problem:
Coolix, Pronto, RAW, Samsung, Toshiba AC

remote_receiver:
  pin: 
    number: GPIO32
    inverted: true
  dump: all

The problem is sending the different remote codes via remote_transmitter

remote_transmitter:
  pin: 
    number: GPIO19
  carrier_duty_percent: 50%

I started with trying to send Coolix but that gave me nothing in the logs so i moved on to try to send the rest of the codes to test.
I have the following for testning the different codes i my .yaml

button:
  - platform: template
    name: "Toshiba AC"
    id: toshiba_id
    on_press:
      - remote_transmitter.transmit_toshiba_ac:
          rc_code_1: 0xB24DBF4040BF
      - logger.log: "My Log: Toshiba AC"
  - platform: template
    name: "Samsung"
    id: samsung_id
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xB946F50A09F6
          nbits: 48
      - logger.log: "My Log: Samsung"
  - platform: template
    name: "Pronto"
    id: pronto_id
    on_press:
      - remote_transmitter.transmit_pronto:
          data: "0000 006D 0010 0000 0008 0020 0008 0046 000A 0020 0008 0020 0008 001E 000A 001E 000A 0046 000A 001E 0008 0020 0008 0020 0008 0046 000A 0046 000A 0046 000A 001E 000A 001E 0008 06C3"
      - logger.log: "My Log: Pronto"
  - platform: template
    name: "RAW"
    id: raw_id
    on_press:
      - remote_transmitter.transmit_raw:
          code: [2000,-1000, 400,-1000, 400, -400,1000,-1000, 400,-1000, 400, -400,1000,-1000, 400,-1000, 400, -400,2000,-5600,
                 2000,-1000, 400,-1000, 400, -400,1000,-1000, 400,-1000, 400, -400,1000,-1000, 400,-1000, 400, -400,2000,-5600,
                 2000,-1000, 400,-1000, 400, -400,1000,-1000, 400,-1000, 400, -400,1000,-1000, 400,-1000, 400, -400,2000,-5600]
          carrier_frequency: 38kHz
          repeat:
            times: 5
            wait_time: 16ms
      - logger.log: "My Log: RAW"

This is what i get in the logs for the respective codes:

Pronto
[19:20:06][D][button:010]: ‘Pronto’ Pressed.
[19:20:06][D][remote.pronto:101]: Send Pronto: frequency=38kHz
[19:20:06][D][remote.pronto:106]: Send Pronto: intros=32
[19:20:06][D][remote.pronto:107]: Send Pronto: repeats=0
[19:20:06][D][main:459]: My Log: Pronto

RAW
[19:20:15][D][button:010]: ‘RAW’ Pressed.
[19:20:15][D][main:561]: My Log: RAW

Samsung
[19:20:16][D][button:010]: ‘Samsung’ Pressed.
[19:20:16][D][main:424]: My Log: Samsung

Toshiba AC
[19:20:17][D][button:010]: ‘Toshiba AC’ Pressed.
[19:20:17][D][main:389]: My Log: Toshiba AC

If i try my code on a different board from another manufacturer i get the same results…

But if i use NEC it for some reason seam to work.

button:
  - platform: template
    name: "NEC"
    id: nec_id
    on_press:
      - remote_transmitter.transmit_nec:
          address: 0x1234
          command: 0x78AB
          command_repeats: 1
      - logger.log: "My Log: Nec"

[20:02:11][D][button:010]: ‘NEC’ Pressed.
[20:02:11][D][remote.nec:017]: Sending NEC: address=0x1234, command=0x78AB command_repeats=1
[20:02:11][D][main:576]: My Log: Nec

Can someone point me in the right direction of what I’m doing wrong or what the problem could be?