Open source ESPHome IR blaster?

Looks like LibreTiny is opening up ESPHome takeovers for some more Tuya devices again.

Just got this one working… Code’s there in case it might help at all.
Anyone got any good ideas for improving it?
Theres a button that I havent used, and the LEDs only showing status in case of error…

You want to flash the status light after each command you send probably:

        - light.turn_on: status_light
        - delay: 60ms
        - light.turn_off: status_light

Personally I use a lazy “on” tracker, this way:

globals:
  - id: last_action
    type: int

binary_sensor:
  - platform: template
    name: "TV Tracker Internal"
    id: tv_tracker_internal
    internal: true
    on_state:
      then:
        - lambda: |-
            id(last_action) = millis()/1000ULL;
        - light.turn_on: status_light
        - delay: 60ms
        - light.turn_off: status_light

Then after each TX command I run this:

- lambda: id(tv_tracker_internal).publish_state(true);

(or false if it’s a power off command)

Thanks.
Light’s flashing with each command sent now. Probably the best use there is for the LED tbh
Added a bunch more buttons and icons for them too.

I like the idea of tracking if the TVs on or off, but the TVs own remote is used as well. I guess that’d mean it’d often end up wrong?

I like the idea of using a multidimensional array to hold the button details and their remote codes, rather than a long list of mixed code/data, but I’m still getting that working. It’d mean adding more buttons/codes would just be adding them to a ‘table’ rather than copy/pasting and then changing chunks of code for each.
It might just be complicating it unneccessarily though.

Some way to automate capturing codes would be good, but I’m not sure how to start with that yet. At least for me, capturing them is still hit-and-miss enough that it might have to stay a manual process.
I’ve settled on capturing a buttons codes maybe 5-10 times, then creating buttons for each and trying them out multiple times. The one that performs most reliably and/or fastest is kept.
There might be a way to automate that, but it’s beyond me at the moment… Learning a lot right now though, so maybe
I haven’t been able to find any existing examples of doing something like that, anyone aware of anything similar pls?

I haven’t done this myself but it might work out well to use yaml anchors for duplicating command sections actually… My templates are quite long so I should play with that :slight_smile:

Here’s what I do as far as a better way to learn commands - needs more customisation for the various protocols though, I just use pronto and sony here.

You switch the learn command switch on, fire an IR command, then the switch will turn off and you get the data in the sensor.


switch:
  - platform: template
    name: Learn Command
    id: remote_learn_switch
    optimistic: true

text_sensor:
  - platform: template
    name: Learned Command
    id: learned_command

remote_receiver:
  pin: 
    number: GPIO25
    inverted: true
  dump: all
  # on_sony:
  #   - if:
  #       condition:
  #         lambda: 'return id(remote_learn_switch).state;'
  #       then:
  #         - lambda: |-
  #             id(remote_learn_switch).publish_state(false);
  #             std::string log_output = "Sony: Data = 0x" + esphome::format_hex(x.data) + ", nbits = " + esphome::to_string(x.nbits);
  #             id(learned_command).publish_state(log_output.c_str());
  #         - delay: 80ms
  #         - light.turn_on: ir_status_light
  #         - delay: 500ms
  #         - light.turn_off: ir_status_light
  on_pronto:
    - if:
        condition:
          lambda: 'return id(remote_learn_switch).state;'
        then:
          - lambda: |-
              id(remote_learn_switch).publish_state(false);
              std::string log_output = "Pronto: Data = " + esphome::to_string(x.data);
              id(learned_command).publish_state(log_output.c_str());
          - delay: 80ms
          - light.turn_on: ir_status_light
          - delay: 500ms
          - light.turn_off: ir_status_light

3 Likes

I like how that sounds, but tbh I’m not able to read thorugh that code and really understand it yet.

Is it something like this?
If remote_learn_switch is on (done using a button?),
then take the IR command (that starts with "Pronto: Data = ") from the log and put it in learned_command?
publish_state is new to me, maybe something like ‘save and make available’?
I’ve got some reading to do :smile:

and thanks… I don’t want to trample all over this thread with me getting my head around things though, better in the one I started while getting mine going?

Hey All,

I found a simple schematic online for a IR blaster.
I made a simple kicad drawing for it:


Dont mind the fan header :rofl: that is supposed to be the IR reciever.

The schematic:

It is based on a wemos D1 mini (this way I dont have to design the usb and such). And it can be soldered closer to the PCB for a flatter design.

If any one is interested i could put the project somewhere on GIT :slight_smile:

1 Like

Just food for thought.

I use those cheap ($5 CAD) aliexpress tuya Wi-Fi based IR emitters that use the Beken microcontrollers and flash it with OpenBeken. They work very well and communicate using MQTT. OpenBeken works very well with HASS, the only downside is having to flash the chip which requires disassembly and soldering (or fly leads).

1 Like

Might be 5 bucks, But where is the fun in that :wink:
Also MQTT is nice, but it is yet another item in the chain.

This is just esp home - > IR Might be 10 bucks, maybe 20.

But I get to do it myself and point all the IR leds in the direction i need (from the couch to TV straight ahead :slight_smile: )

Cheap aliexpress is not always the answer

1 Like

Neither is reinventing the wheel.

1 Like

Must be hot weather… If its not for you then so be it :wink:

Just ignore it.

1 Like

That’s fair, I was just putting info out there for thought. Injection molded cases go a long way these days. I have a plethora of esp based ‘thingies’ everywhere, some are bare some have 3d printed cases. Sometimes it’s just easier to repurpose what others have already laid down the work for.

All that said, I also enjoy building things for the sake of building them, so I understand your train of thought.

1 Like

You can also control the Kincony KC868-AG without using ESPHome using RESTful Commands. You can apparently use MQTT also, but this is easier. Regardless I’m probably going to have to use ESPHome according to the docs due to the different RF commands because it only supports 2 EF protocols but the raw data can be used. They also have some device/brand automations for learning IR/RF.

Hi All,

I have made my own IR blasterV2. It has a range of about 5 meters now.

As you can see there is still one design flaw on my pcb, but not too bad.



It has 3 resistors (1k and 47 ohm) 1 transistor bc337, and a ir reciever
HX1838

Schematic:
Screenshot 2024-08-15 at 21.57.31

It has the following code:

esphome:
  name: ir-sender
  friendly_name: ir-sender
  
esp32:
  board: m5stack-atom
  framework:
    type: esp-idf


# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret ir-api

ota:
  - platform: esphome
    password: !secret ir-ota

wifi:
  ssid: !secret lot_wifi_ssid
  password: !secret lot_wifi_password
  fast_connect: true
  power_save_mode: light
  use_address: !secret ip-is-send
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Irsender Fallback Hotspot"
    password: !secret ir-fbw

captive_portal:
web_server:


remote_receiver:
  id: rcvr
  pin:
    number: GPIO33
    inverted: true
    mode:
      input: true
      pullup: true
  dump:
    - samsung
    - sony

remote_transmitter:
  pin: GPIO23
  carrier_duty_percent: 50%

button:
### 
# Samsung IR Remote:
  - platform: template
    name: "TV - On/Off"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E06798
      - remote_transmitter.transmit_samsung:
          data: 0xE0E06798
      - remote_transmitter.transmit_samsung:
          data: 0xE0E040BF
  - platform: template
    name: "TV - Source"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0807F
  - platform: template
    name: "TV - 1"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E020DF
  - platform: template
    name: "TV - 2"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0A05F
  - platform: template
    name: "TV - 3"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0609F
  - platform: template
    name: "TV - 4"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E010EF
  - platform: template
    name: "TV - 5"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0906F
  - platform: template
    name: "TV - 6"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E050AF
  - platform: template
    name: "TV - 7"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E030CF
  - platform: template
    name: "TV - 8"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0B04F
  - platform: template
    name: "TV - 9"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0708F
  - platform: template
    name: "TV - 0"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E08877

  - platform: template
    name: "TV - TTX/MIX"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E034CB
  - platform: template
    name: "TV - PRE-CH"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0C837

  - platform: template
    name: "TV - Vol Up"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0E01F
  - platform: template
    name: "TV - Vol Down"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0D02F
  - platform: template
    name: "TV - Mute"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0F00F
  - platform: template
    name: "TV - CH LST"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0D629
  - platform: template
    name: "TV - CH Up"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E048B7
  - platform: template
    name: "TV - Ch Down"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E008F7
  - platform: template
    name: "TV - Netflix"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0CF30
  - platform: template
    name: "TV - Prime"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E02FD0
  - platform: template
    name: "TV - Rakuten"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E03DC2
  - platform: template
    name: "TV - Guide"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0F20D
  - platform: template
    name: "TV - Home"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E09E61

  - platform: template
    name: "TV - Arr Up"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E09E61
  - platform: template
    name: "TV - Arr Left"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0A659
  - platform: template
    name: "TV - OK/Enter"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E016E9
  - platform: template
    name: "TV - Arr Right"
    on_press: 
      - remote_transmitter.transmit_samsung:
          data: 0xE0E046B9
  - platform: template
    name: "TV - Arr Down"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E08679
  - platform: template
    name: "TV - Return"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E01AE5
  - platform: template
    name: "TV - Exit"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0B44B
  - platform: template
    name: "TV - A"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E036C9
  - platform: template
    name: "TV - B"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E028D7
  - platform: template
    name: "TV - C"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0A857
  - platform: template
    name: "TV - D"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E06897
  - platform: template
    name: "TV - Settings"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E058A7
  - platform: template
    name: "TV - INFO"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0F807
  - platform: template
    name: "TV - AD/SUBT."
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0A45B
  - platform: template
    name: "TV - Stop"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0629D
  - platform: template
    name: "TV - Reverse"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0A25D
  - platform: template
    name: "TV - Play"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E0E21D
  - platform: template
    name: "TV - Pause"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E052AD
  - platform: template
    name: "TV - Forward"
    on_press:
      - remote_transmitter.transmit_samsung:
          data: 0xE0E012ED

### 
# Sony IR Remote:
  - platform: template
    name: "Soundbar - On/Off"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0000540C
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Source"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00004B0D
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - TV - On/Off"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00000A90
          repeat: 4
          nbits: 12
  - platform: template
    name: "Soundbar - TV - Source"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00000A50
          repeat: 4
          nbits: 12
  - platform: template
    name: "Soundbar - TV - CH Up"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00000090
          repeat: 4
          nbits: 12
  - platform: template
    name: "Soundbar - Display"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0000040D
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - SW Vol Up"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00001D0C
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - TV - CH Down"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00000890
          repeat: 4
          nbits: 12
  - platform: template
    name: "Soundbar - Clear Audio +"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x000F4116
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - SW Vol Down"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00005D0C
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Audio Standard"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x000B8116
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Audio Movie"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0000610D
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Audio Game"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0001E114
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Audio Music"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0000490D
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Audio P.Audio"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00098116
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Audio Sports"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00018116
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Voice"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0009C114
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Night"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0000020D
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Mute"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0000140C
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Return"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x000BE110
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Amp Menu"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0000770D
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Vol Up"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0000240C
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Vol Down"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0000640C
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Arr Up"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00000F0D
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Arr Down"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00004F0D
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Arr Left"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00002F0D
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - Arr Right"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x00006F0D
          repeat: 4
          nbits: 15
  - platform: template
    name: "Soundbar - OK"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0000180C
          repeat: 4
          nbits: 15 
  - platform: template
    name: "Soundbar - Skipp Back"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0000C110
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Pause"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0009C110
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Skipp Forward"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0008C110
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Rewind"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x000CC110
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Play"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0004C110
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Forward"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0002C110
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Pairing"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x000EE114
          repeat: 4
          nbits: 20
  - platform: template
    name: "Soundbar - Stop"
    on_press:
      - remote_transmitter.transmit_sony:
          data: 0x0001C110
          repeat: 4
          nbits: 20

Happy to share a gerber folder if you want to order one yourself :slight_smile:

2 Likes

Maybe the documentation explains this but, I havnt looked at it. What is the benefit of using multiple IR led"s?

It makes sense to me that increasing voltage/current close to the led max, that will increase IR range for sure but, how does just adding more led’s make it better especially when they’re all facing the same direction?

I could also see the benefits of putting IR led’s all around the circumference so it transmits 360 degrees but, whats it doing by having them all on one side and facing the same direction?

Its for my specific use case, and it works perfect. My TV is picky about the IR angle, and i point 3 straight at the soundbar and 3 straight at the TV ad a different angle but still pointing forwards :slight_smile:

Its an easy design and with 6 leds you could adapt it to make something like this:

Now you can point them all at a different direction. its opensource, do with it as you please :slight_smile:

1 Like

Oh, I see. That makes sense if its for a specific use. Did you not want to add or need RF too?

I was thinking about doing both if i make one because some devices use IR and others RF. Having both in a single box sounds like a good plan to me.

The simplest way to add RF or any other extra item is with the grove cable:

the m5 stack eco system is vast, you can add so many i2c devices behind it :slight_smile:

But if you must want it to be in a all in one package you can design the board in a manner that it accepts this:

then its a all in one package :slight_smile:

I already use several rf transmitter/receivers. I actually prefer rf way more than I do IR. It seems like the range is far better and there doesn’t need to be line of sight and there’s less signal loss from walls and obstructions that you get from IR.

Other than common transmitter and receivers, I’ve become very fond of these 4 way transmitters. They’re super easy to use and the range is very good.

1 Like

About?
Does receiver have raw non decoded output?