Switchbot Universal Remote

You can only do this with a custom receiver integration like I did.
basically,

  • Create a new device and set volume IR with logitech ones manually
  • Set random (or unused) IR signals for other things and set automations on home assistant to control Fire TV.

But if you set separate integrations for Fire TV and IR Speaker, that would work out of the box.

1 Like

This is one of the most basic requirements of a universal remote and I haven’t figured out how to do this (I’m assuming it isn’t possible).

I have an Apple TV, a Vizio TV, and a Denon receiver. I want a single button to turn everything on and off, and I want to be able to control receiver volume while controlling the Apple TV. No, I don’t want to use HDMI-CEC (frequently misbehaves, and is difficult to determine which device is misbehaving).

I’ve ordered an RF remote that presents itself as a keyboard and will attempt to trigger HA actions with that, which control my devices (all network attached, but can use an IR blaster if required).

I’ll be returning this “universal remote”.

2 Likes

So it’s not a good Harmony replacement?

puuuh. just 3 more days. So sad that nobody is able to privide some internal photos. Hacking a device like this could potentially result in something like this:
joBr99/nspanel-lovelace-ui: Custom Firmware for NsPanel with the design of HomeAssistant’s lovelace UI in mind, works with Tasmota. (github.com)

Why don’t you buy and open yourself?

I guess I dont use it and and I guess the chip is non a good one to work with tasmota or esp-home.
I want avoid having one more useless device at home. But if I already have one and use it and a community member ask about inside pics, would be no problem for me.

I do this with the Apple TV remote and a broadlink IR blaster. HA detects when Apple TV wakes/sleeps and sends IR remote commands to the receiver and/or TV screen to sync. The Apple Remote can natively control the receiver/soundbar volume with its own IR. A power-monitoring plug helps to know if the devices are on or off, but isn’t required. I also managed to get volume control working via the Apple Remote app, exporting a template receiver to HomeKit, but that was just extra.

On-topic, I was also curious about the internals of this remote, as switchbot commonly uses esp32 in products (e.g. plugs and bulbs). However I would be surprised if this battery-powered Bluetooth remote has a WiFi ESP, as other switchbot BLE devices like the curtain motor only contain a Bluetooth SoC, and I’m not aware of any open firmware that can use BLE for control traffic. Pictures welcome though, maybe we’ll be pleasantly surprised.

If anyone else gets an IR Controller like I did, here is the ESPHome config I use to receive and send events from and to home assistant:

substitutions:
  name: "ir-controller"
  friendly_name: "Living Room IR"

esphome:
  name: "${name}"
  friendly_name: "${friendly_name}"

esp8266:
  board: esp8285
  restore_from_flash: true

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret key
  services:
    - service: send_ir
      variables:
        protocol: string
        code: string
        command: string
        repeats: string
      then:
        - lambda: 'ESP_LOGD("main", "Protocol: %s - Code: %s - Command: %s",  protocol.c_str(), code.c_str(), command.c_str() ); '
        - if:
            condition: # --=[ *** LG *** ]=--
              lambda: 'return protocol == "LG";'
            then:
              - logger.log: "Sending LG data...!"
              - remote_transmitter.transmit_lg:
                  data: !lambda |-
                        return std::stoi( code );
                  nbits: !lambda |-
                        return std::stoi( command );                    
        - if:
            condition: # --=[ *** PANASONIC *** ]=--
              lambda: 'return protocol == "PANASONIC";'
            then:
              - logger.log: "Sending PANASONIC data...!"
              - remote_transmitter.transmit_panasonic:
                  address: !lambda |-
                      int i;
                      sscanf( code.c_str(), "%x", &i );
                      return i; 
                  command: !lambda |-
                      int i;
                      sscanf( command.c_str(), "%x", &i );
                      return i;
        - if:
            condition: # --=[ *** PIONEER *** ]=--
              lambda: 'return protocol == "PIONEER";'
            then:
              - logger.log: "Sending PIONEER data...!"
              - remote_transmitter.transmit_pioneer:
                  rc_code_1: !lambda |-
                      int i;
                      sscanf( code.c_str(), "%x", &i );
                      return i;
                  rc_code_2: !lambda |-
                      int i;
                      sscanf( command.c_str(), "%x", &i );
                      return i;
                  repeat:
                    times: !lambda |-
                        return std::stoi( repeats );
        - if:
            condition: # --=[ *** PRONTO *** ]=--
              lambda: 'return protocol == "PRONTO";'
            then:
              - logger.log: "Sending PRONTO data...!"
              - remote_transmitter.transmit_pronto:
                  data: !lambda |-
                      return code.c_str();
        - if:
            condition: # --=[ *** SAMSUNG *** ]=--
              lambda: 'return protocol == "SAMSUNG";'
            then:
              - logger.log: "Sending SAMSUNG data...!"
              - remote_transmitter.transmit_samsung:
                  data: !lambda |-
                      int i;
                      sscanf( code.c_str(), "%x", &i );
                      return i; 
                  nbits: !lambda |-
                        return std::stoi( command );   
        - if:
            condition: # --=[ *** SONY *** ]=--
              lambda: 'return protocol == "SONY";'
            then:
              - logger.log: "Sending SONY data...!"
              - remote_transmitter.transmit_sony:
                  data: !lambda |-
                      int i;
                      sscanf( code.c_str(), "%x", &i );
                      return i; 
                  nbits: !lambda |-
                        return std::stoi( command );

ota:
  - platform: esphome
    password: !secret ota_password

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${friendly_name} AP"
    password: !secret wifi_ap_password

captive_portal:

web_server:
  port: 80

sensor:
  - platform: wifi_signal
    name: "${friendly_name} WiFi Signal"
    update_interval: 60s

  - platform: uptime
    name: "${friendly_name} Uptime"

text_sensor:
  - platform: wifi_info
    ip_address:
      name: "${friendly_name} IP Address"
      disabled_by_default: true
    ssid:
      name: "${friendly_name} SSID"
    bssid:
      name: "${friendly_name} BSSID"
    mac_address:
      name: "${friendly_name} Mac Wifi Address"
    scan_results:
      name: "${friendly_name} Latest Scan Results"

switch:
  - platform: restart
    name: "${friendly_name} restart"

binary_sensor:
  - platform: status
    name: "${friendly_name} IR Status"

  - platform: gpio
    pin: GPIO0
    id: physical_button

status_led:
  pin: GPIO13

remote_transmitter:
  pin:
    number: GPIO4
  carrier_duty_percent: 50%

remote_receiver:
  pin:
    number: GPIO5
    inverted: true
  dump: all
  on_pronto:
    then:
       - homeassistant.event:
          event: esphome.ir_pronto_code_received
          data:
            code: !lambda 'return x.data;'
  on_lg:
    then:
       - homeassistant.event:
          event: esphome.ir_lg_code_received
          data:
            data: !lambda 'return x.data;'
            nbits: !lambda 'return x.nbits;'
  on_nec: 
    then:
       - homeassistant.event:
          event: esphome.ir_nec_code_received
          data:
            address: !lambda 'return x.address;'
            command: !lambda 'return x.command;'          
  on_panasonic:
    then:
       - homeassistant.event:
          event: esphome.ir_panasonic_code_received
          data:
            address: !lambda 'return x.address;'
            command: !lambda 'return x.command;'
4 Likes

The site says “home assistant can add matter devices through hub2”, does that mean that if you have the hub you can add HA devices to the remote directly ?

I never bothered with the switchbot hub myself since HA supports all the devices anyway, but that could be a compelling feature. Presumably the hub is there to do bluetooth ↔ matter, I wonder if HA could do that at some point

That’s a good approach I didn’t consider.

I ended up going with a cheap generic RF keyboard remote for now (MX3 Air Mouse). Mapped the corresponding /dev/input devices to my HA container, setup the keyboard_remote integration, and created an automation to handle the keyboard_remote_command_received events.

The power button and colored buttons on the bottom don’t appear to send key codes that HA is able to detect (I believe the colored buttons are IR only), but I use different buttons to trigger actions like “Watch Apple TV”, “Watch Kodi”, etc. anyway. It would be nice if the colored buttons sent key codes over RF though.

Eventually I might splurge for something like an Unfolded Circle remote, but for now this at least lets me control everything.

I got me both (remote and Hub2) but so far, I can only add (learn from remote) my old Logitech remote commands to control my TV and Home theater. Can’t add anything from HA . Switchbot devices visible, but it’s in the other room, so I didn’t try to add them to remote

Maybe an alternative?

https://www.sofabaton.com/products/x1s/

I considered that, however I really like the ability to control my devices over IP via HA now that I have it set up that way. I might still go with that (or something similar) though if I run into any issues with my approach.

Doing the Lord’s work here! Brilliant! I just got the IR receiver you suggested in your earlier post, and will try this out this weekend. I briefly considered sticking with MQTT, but I’d much rather this be an ESPhome thing – so I enormously appreciate you posting your config here.

My biggest gripe with this product is how shortsighted it was for Switchbot to not expose the Hub2 as an IR receiver, and not to provide that with an ‘always listening for IR’ option. To be honest, I initially assumed that was how this thing was envisioned to work when I bought it… Perhaps with a future firmware update, exposing Hub2 IR stuff becomes possible?

Your approach here demonstrates how clever it can be to essentially use “dummy IR codes” to trigger any HA action you want with an ESP IR receiver – while in the Switchbot ecosystem, setup those same respective codes as “appliances” in the Hub2, which will ultimately sync back into the remote. Wacky workaround, but I’ll take it!

The Matter integration seems like a total flop, I have pretty low faith in it. It’s proven to be slow, unreliable, and bafflingly limited in my testing. Amusingly, old school local IR is looking like it’s the perfect fit here – the range limitation is moot if it’s just a remote used from your couch.

In the meantime, I’m very happy there’s a path here to actually make this pretty looking brick of a product actually useful in my setup! Just a bit silly to need a “second” receiver.

Will report back results for others who have google’d there way here. Cheers!

As an update: using @eliz config (THANK YOU!!) – confirming I got this working! This essentially provides full and complete local control of virtually anything in Home Assistant with the switchbot remote. Here’s some more deetz –

1: Hardware:
I used the same Anthom IR Receiver linked earlier. Set it up, killed Tasmota, flashed ESPHome with the config. I have the Switchbot Hub 2 (required to learn new IR codes and sync to the Switchbot Remote), and of course, the Switchbot Universal Remote.

2: Finding IR Codes in HA
Once the IR Receiver is in HA, there’s some additional stuff required that involves listening to IR codes in the developer tools, and playing around with HA Events. I went into the Events tab in the devtools tab of HA, told it to listen to “esphome.ir_nec_code_received” – and used an old remote to test some different buttons which I will use as “dummy IR codes” to trigger whatever I want. (Note: I’m unclear what the other event listeners here are, as some didn’t spit out unique codes on press. The NEC one worked for me, but some physical buttons didn’t work. I have a vague understanding that the other listeners relate to different IR standards? Practically speaking: the old “dummy IR trainer” remote will likely dictate which event listener you should test & use here. Observe the espconfig + raw logs on which event listener to use.)

3: Creating HA Automation on IR Trigger
I created an automation, told it to listen to the event “esphome.ir_nec_code_received” – and used the data previously observed on the desired remote press, IE:

device_id: eb04d2cce8cfe1b2481e1691ac4cce33
address: "21891"
command: "35955"

4: Configuring Switchbot
In the Switchbot App, I first navigated to the Hub 2 setup, and proceeded to configure an “IR Appliance,” using the same respective IR Codes used in the initial test. In this instance, it’s just a On/Off toggle intended for a light group based on two arbitrary old-remote IR buttons.

Then, I navigate to the Switchbot Remote in the app, “add existing device” (from the Hub2), and sync it to the remote. Success!! In my testing, it’s been exceptionally reliable and responsive.

Other Thoughts:
I’ve now got light groups setup for two rooms, a fireplace, and some various peripherals. Im interested in playing around more with sequenced & actions conditional actions. (turn on TV, sound system, lights).

There’s plenty of room to experiment and explore using the switchbot “Appliance” templates to have some pretty robust controls. In my setup, I have multiple light controls integrated into one “appliance.” Toggle-all, or individual lights is what I was really looking for: (button D with the ellipses on remote is a submenu. I park my individual room lights there). I definitely didn’t want the individual devices to be verbosely listed on the remote, so I’m going to continue to explore playing around with using “appliances” as “thematically grouped devices” – a hacky room card basically.

Hope this more detailed writeup helps others – I’m super happy to have unlocked the potential of this remote to do anything in HA, fully local and super fast & reliable. No Switchbot HA integration was needed for this setup!

Hopefully in the future, there’s some way to get the SB Hub2 to work as the IR Receiver so additional hardware isn’t required.

2 Likes

Great to hear you found it useful.

One “hack” I found is you can use any code you want by sending from home assistant.

Go to developer tools > actions and send any IR code you want. You can use the Switchbot Hub to “learn” these to set up however you want. You can also find codes online to enhance the default remotes. For example I added HDMI selection to the LG remote this way.

If you want to listen the sent codes, you can use the events tab:

1 Like

Ah that’s pretty clever! I feel like a caveman now using an old remote to essentially train a new remote. I don’t care to admit how much trial & error was involved in getting a good pool of unique codes to use for my initial config.

Really dig the “enhanced remote,” example – I’m coming to appreciate that IR has some pretty fun and creative applications with the right hardware.

//
If interesting to anyone, the fourth ellipses button D on the switchbot remote is a navigable submenu for several appliances. If you use an appliance template and setup a red “other,” command at the bottom of the hub config, it fills out this submenu.

UX design wise, this was a really helpful option in my setup where I wanted to park a bunch of devices and actions/scenes in a separate menu. Probably plenty of other uses there too.

@eliz @Cornmacabre
Hello!

I am wondering why you were replacing Tasmota (never used but i think it works locally) by ESPHome?

What were the issues, what did it solved and why is it better?

I do this with scripts. I have a script that turns on the Roku TV, the receiver, sets the correct input. Then, with one button press, it calls he script and turns everything on.

If you can assign he “on” button on this device to call a script, thats all you need to do.

I don’t personally use much MQTT in my setup (which I believe would be Tasmota’s main communication method, maybe not?), so that was my main reason for flashing ESPHome.

Local Wi-Fi connection is perfectly fine for my use case, and just have ESPhome send IR sensor data straight into HA and the events section.

I much preferred ESPHome with a custom config that I can directly edit and and manage OTA. I manage many other devices this way, no reason to change. It also helped significantly that the other poster pasted their configuration as a starting point, which – once configured “just worked.”

My use case just needed a simple method to manage and adopt the device, receive IR codes, and work locally and reliably. It’s been incredibly fast and 100% reliable in my weeks of usage and testing. Wouldn’t even consider changing approaches personally, no benefit to me.

Sticking with Tasmota meant more stuff to solve using a protocol (MQTT) that I personally don’t prefer – although I totally recognize some folks strongly prefer it. My choice just came down to preference and familiarity, really.

1 Like