Bedjetting with ESPHOME

Around Xmas of 2022 I was gifted a used bedjet off of ebay. It came with name BUTTHOLE LOVER and since I'm still a teenage boy at heart it made me laugh and I decided to keep the name.

Around that time I noticed that ESPHome added support for the bedjet. Naturally I decided I needed to add it into Home Assistant. So I did! I just never got around to writing up the how and some of the workarounds to the quirks I've had with it.

I did figure it out why it was turning on by itself. It was the magic areas addon trying to be helpful. So entirely self inflicted… :D

The main quirk is it turning on by itself! Which I'm assuming has to do with the climate controls in HA/ESPHome. So I could have go about figuring those out, but who has time for that!? Instead I just wasted some time getting it to read a input boolean from HA and enable (or disable BLE) based on that. The thing that you'll want to watch out for is that as of this writing turning off BLE crashes the ESP32. I don't know if it's just related to the board I have or it's just quirk of all them. Nonetheless here's what you do need to do to work around it.

Create a new helper in HA, call it whatever you want, I went with input_boolean.enable_butthole_lover for mine.

Next disable ble on boot:

esp32_ble:
  enable_on_boot: false

Now create your binary sensor for your new helper:

binary_sensor:
  - platform: homeassistant
    id: bj_ble_enabled
    name: "Enable Butthole Lover"
    entity_id: input_boolean.enable_butthole_lover

Then add some logic to control the ble state by attaching an automation to your binary sensor, so that when the state changes it checks to see if it's on or off:

binary_sensor:
  - platform: homeassistant
    id: bj_ble_enabled
    name: "Enable Butthole Lover"
    entity_id: input_boolean.enable_butthole_lover
    on_state:
      then:
        - if:
            condition: 
              - binary_sensor.is_on: bj_ble_enabled
            then:
              - ble.enable
            else:
              - logger.log: "BLE Off triggers panic. Rebooting as a work around"
              # - ble.disable
              - button.press: hugh_room_esp_restart

Then bring it all together! I also have mine set to sync the time whenever it connects. Because who wants to keep setting that damned clock all the time!?

esphome:
  name: hugh-bedroom-bj
  friendly_name: hugh-bedroom-bedjet

esp32:
  board: wemos_d1_mini32
  framework:
    type: arduino

logger:

api:
  encryption:
    key: "XXXXXXXXXXXXX"

ota:
  password: "XXXXXXXXXXXXX"
  on_begin:
    then:
      - logger.log: "Disconnecting clients for OTA update…"

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

  ap:
    ssid: "Hugh-Bedroom-BJ Fallback Hotspot"
    password: "XXXXXXXXXXXXX"

captive_portal:

network:
    enable_ipv6: true

time:
  - platform: homeassistant
    id: homeassistant_time
    on_time_sync:
      then:
      - logger.log: "Synchronized system clock"  

sensor:
  - platform: uptime
    name: Uptime Sensor

binary_sensor:
  - platform: homeassistant
    id: bj_ble_enabled
    name: "Enable Butthole Lover"
    entity_id: input_boolean.enable_butthole_lover
    on_state:
      then:
        - if:
            condition: 
              - binary_sensor.is_on: bj_ble_enabled
            then:
              - ble.enable
            else:
              - logger.log: "BLE Off triggers panic. Rebooting as a work around"
              # - ble.disable
              - button.press: hugh_room_esp_restart

esp32_ble:
  enable_on_boot: false

esp32_ble_tracker:

ble_client:
  - mac_address: XX:XX:XX:XX:XX:XX
    id: bedjet_ble_id1
    on_connect:
      then:
        - lambda: |ESP_LOGD("ble_client_lambda", "Connected to Bedjet");
        - button.press: bj_clock_sync
    on_disconnect:
      then:
        - lambda: |ESP_LOGD("ble_client_lambda", "Disconnected from Bedjet");

bedjet:
  - id: bedjet_1
    ble_client_id: bedjet_ble_id1
    time_id: homeassistant_time

climate:
  - platform: bedjet
    id: hugh_bedjet
    name: "Butthole Lover"
    bedjet_id: bedjet_1

fan:
  - platform: bedjet
    id: hugh_bedjet_fan
    name: "Butthole Lover Fan"
    bedjet_id: bedjet_1

button:
  - platform: safe_mode
    name: "Hugh Roome ESP Safe Mode"
    entity_category: diagnostic

  - platform: restart
    id: hugh_room_bj_restart
    name: "Hugh Room ESP Restart"
    entity_category: diagnostic

  - platform: factory_reset
    name: "Hugh Roome ESP Factory Default Settings"
    entity_category: diagnostic

  - platform: template
    name: "Check Bedjet Firmware"
    on_press:
      then:
      - lambda: |id(bedjet_1).upgrade_firmware();

  - platform: template
    name: "Sync Clock on BedJet"
    id: bj_clock_sync
    on_press:
      then:
      - lambda: |id(bedjet_1).send_local_time();