Replace the software of the Rituals Genie ESP with ESPhome

Shouldn’t RX and TX be crossed? So TX → RX and vice versa?

Also, what is the voltage of the VCC pin on your TTL adapter? To be sure you could connect it to 3.3v instead of VCC.

I have the same USB stick, and I tied flashing it yesterday. Couldn’t get it to programming mode.
same as the picture above, except I connected it to the 3.3 Volt. Tried RX-RX + TX-TX and RX-TX + TX-RX combinations, but alas.

Something that came to me later,do we need to power the board ?.

Yes

:man_facepalming: I feel so stupid now.

Hi everyone,

I’ve been following this thread with great interest — thank you all for the amazing work so far! I had a question regarding the cartridge system: is it possible to reuse an empty Rituals cartridge and make it work again, possibly by resetting its name or counter, so it becomes a kind of “generic” cartridge?

The idea would be to refill it with our own essential oils instead of having to buy new Rituals cartridges every time. It feels a bit limiting not to be able to use other oils with this device.

Has anyone looked into this or found a way to make it work?

Thanks in advance!

Here you go https://www.reddit.com/r/essentialoils/comments/xi9mcz/comment/kaoy2aa/

Did anyone try this on the v1, and were any changes necessary? I’m getting to “Connecting”, and then nothing happens.

To answer my own question: exactly the same. I disconnected the battery before flashing.

Rituals genie ( multiple) not working after firmware update and reset( cant find wifi any more)

Other people with same issue ?

does any one have a original firmware file i can flash ( or knows how to down grade ?

stupid question… :stuck_out_tongue: newbee sry !

do i need to change the wifi settings in the yaml ?

Don’t edit the esphome config, but rather put your settings in the secrets.yaml (there is an editor in the top right corner of the web UI), should look something like this:

# Your Wi-Fi SSID and password
wifi_ssid: "my_network"
wifi_password: "MyNetwokrPassw0rd"

I also keep my ota password and ha encryption key there.

As for your other question - I am also experiencing the issue, and I only have the firmware that does not work :slight_smile: (v 5.something), however it might not be a matter of firmware as when you connect to the genie and open http://192.168.4.1/wifiin your browser (you can connect with laptop to the genie’s open network as well) - you will be able to see the networks discovered by the device. I’m thinking the problem is with the application, but I might be wrong.

None the less, now that both of my genies are rather expensive bricks (and even if they weren’t the HA integration has not been working for a long time) I’ve grabbed a multimeter and went over the board to discover how it all is put together. Here are the results of my discovery as well as some attempt to write an ESPHome config that mimics the original firmware: GitHub - KarolKozlowski/esp-geine: ESPHome configuration for Perfume Genie

Thank you so much for this guide, now my rituals has come back to life :wink:

I also added this might help someone:

esphome:
  name: rituals
  friendly_name: Rituals

esp8266:
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    # NOTE: Generate your own key here if copying this code
    key: "GENERATE_YOUR_OWN_KEY_HERE"

ota:
  - platform: esphome
    # NOTE: Set a password for wireless updates
    password: "YOUR_OTA_PASSWORD"

# --- LOGIC: Variable to store scent level ---
# Stores the remaining minutes of the cartridge.
# The value is saved to flash memory (restore_value: yes) to survive power cuts.
globals:
  - id: cartridge_remaining_minutes
    type: int
    restore_value: yes
    initial_value: '21600' # 360 hours (standard lifespan) * 60 minutes = 21600
# --------------------------------------------

wifi:
  # Fill in your own credentials here
  ssid: "YOUR_WIFI_SSID"
  password: "YOUR_WIFI_PASSWORD"

  # Status LED logic upon connection
  on_connect:
   - light.turn_on:
      id: status_led
      brightness: 100%
      red: 0%
      green: 0%
      blue: 100% # BLUE when connected
  on_disconnect:
   - light.turn_on:
      id: status_led
      brightness: 100%
      red: 100% # RED if wifi is lost
      green: 0%
      blue: 0%

  # Fallback Access Point if wifi connection fails
  ap:
    ssid: "Perfume-Genie-Esp8266"
    password: "PUT_A_PASSWORD_HERE"

captive_portal:

# --- LOGIC: Countdown Scent Level ---
# This loop runs every minute.
# If the fan is running -> decrease the remaining balance by 1 minute.
interval:
  - interval: 1min
    then:
      - if:
          condition:
            fan.is_on: fan_toggle
          then:
            - lambda: 'id(cartridge_remaining_minutes) -= 1;'
# ------------------------------------

binary_sensor:
  - platform: status
    name: "Wifi Status"
    icon: "mdi:wifi" 

  # Physical button on the back to control the fan manually
  - platform: gpio
    name: Genie button
    icon: "mdi:gesture-tap-button"
    internal: false
    pin:
      number: 3
      inverted: true
      mode:
        input: true
        pullup: true
    on_click:
      then:
      - fan.toggle:
          id: fan_toggle

# PWM configuration for the fan motor
output:                                                                                                                                                                         
  - platform: esp8266_pwm
    id: fan_speed
    pin: 4
    frequency: "25000 Hz"
    min_power: 0%
    max_power: 100%

# The actual Fan entity in Home Assistant
fan:
  - platform: speed
    output: fan_speed
    name: "Perfume Genie Fan"
    id: fan_toggle  
    speed_count: 4
    # Control the LED color based on fan state
    on_turn_off:
    - light.turn_on:
        id: status_led
        brightness: 100%
        red: 0%
        green: 0%
        blue: 100% # Blue = Standby/Off
    on_turn_on:
    - light.turn_on:
        id: status_led
        brightness: 100%
        red: 0%
        green: 100% # Green = Fan is running
        blue: 0%

# Status LED (NeoPixel)
light:
  - platform: neopixelbus
    name: status_leds
    id: status_led
    variant: WS2812
    pin: 15
    num_leds: 1
    type: GRB
    internal: true

# --- SENSORS & BUTTONS: Scent Level ---
sensor:
  # Calculates remaining percentage based on stored minutes
  - platform: template
    name: "Scent Level Remaining"
    id: scent_level
    unit_of_measurement: "%"
    icon: "mdi:flask-outline"
    accuracy_decimals: 0
    update_interval: 60s
    lambda: |-
      float total = 21600.0; // Must match the initial_value in globals
      float current = id(cartridge_remaining_minutes);
      if (current < 0) return 0;
      return (current / total) * 100.0;

# Button in Home Assistant to reset the counter when replacing the cartridge
button:
  - platform: template
    name: "Reset Cartridge"
    icon: "mdi:restart"
    on_press:
      - lambda: 'id(cartridge_remaining_minutes) = 21600;'
      - component.update: scent_level
# --------------------------------------

Very interesting discussion, thanks you all for that!
Since my Genie 1.0 (with battery) is still not working after more than 1.5 year(!) and those bunglers at Rituals cant seem to solve it, I am very much interested in this project.

Have flashed an ESP32 before with existing code and a how-to, but I am definitely no expert.
Is there an reasonable how-to somewhere of how to do it?

Have read all the posts (incl links) above, but still not very sure of where to start and what to do... :frowning: